Add new components, styles, and services for user management and navigation
This commit is contained in:
+21
@@ -0,0 +1,21 @@
|
||||
<li data-username="mantis dashboard" class="nav-item coded-hasmenu" [routerLinkActive]="['active']">
|
||||
<a [routerLinkActive]="['active']" (click)="navCollapse($event)">
|
||||
@if (item.icon) {
|
||||
<span class="coded-micon">
|
||||
<i antIcon type="{{ item.icon }}" theme="outline"></i>
|
||||
</span>
|
||||
}
|
||||
<span class="coded-mtext">
|
||||
{{ item.title }}
|
||||
</span>
|
||||
</a>
|
||||
<ul class="coded-submenu" [routerLinkActive]="['active']" [ngClass]="item.classes!">
|
||||
@for (item of item.children; track item) {
|
||||
@if (item.type === 'item') {
|
||||
<app-nav-item [item]="item"></app-nav-item>
|
||||
} @else if (item.type === 'collapse') {
|
||||
<app-nav-collapse [item]="item"></app-nav-collapse>
|
||||
}
|
||||
}
|
||||
</ul>
|
||||
</li>
|
||||
+88
@@ -0,0 +1,88 @@
|
||||
// Angular import
|
||||
import {Component, inject, Input, OnInit, output} from '@angular/core';
|
||||
import { animate, style, transition, trigger } from '@angular/animations';
|
||||
import {CommonModule, DOCUMENT} from '@angular/common';
|
||||
import { RouterModule } from '@angular/router';
|
||||
|
||||
// project import
|
||||
import { NavigationItem } from '../../navigation';
|
||||
|
||||
import { NavItemComponent } from '../nav-item/nav-item.component';
|
||||
import { IconDirective } from '@ant-design/icons-angular';
|
||||
|
||||
@Component({
|
||||
selector: 'app-nav-collapse',
|
||||
imports: [CommonModule, IconDirective, RouterModule, NavItemComponent],
|
||||
templateUrl: './nav-collapse.component.html',
|
||||
styleUrls: ['./nav-collapse.component.scss'],
|
||||
animations: [
|
||||
trigger('slideInOut', [
|
||||
transition(':enter', [
|
||||
style({ transform: 'translateY(-100%)', display: 'block' }),
|
||||
animate('250ms ease-in', style({ transform: 'translateY(0%)' }))
|
||||
]),
|
||||
transition(':leave', [animate('250ms ease-in', style({ transform: 'translateY(-100%)' }))])
|
||||
])
|
||||
]
|
||||
})
|
||||
export class NavCollapseComponent implements OnInit{
|
||||
|
||||
private document = inject(DOCUMENT);
|
||||
|
||||
// public props
|
||||
|
||||
// Compact Menu in use For Sub Child Open in sidebar menu
|
||||
showCollapseItem = output();
|
||||
|
||||
// all Version Get Item(Component Name Take)
|
||||
@Input() item!: NavigationItem;
|
||||
|
||||
windowWidth: number | undefined = 1000;
|
||||
|
||||
// Constructor
|
||||
constructor() {
|
||||
//this.windowWidth = window.innerWidth;
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.windowWidth = this.document.defaultView?.innerWidth;throw new Error('Method not implemented.');
|
||||
}
|
||||
|
||||
// public method
|
||||
navCollapse(e: MouseEvent) {
|
||||
let parent = e.target as HTMLElement;
|
||||
|
||||
if (parent?.tagName === 'SPAN') {
|
||||
parent = parent.parentElement!;
|
||||
}
|
||||
|
||||
parent = (parent as HTMLElement).parentElement as HTMLElement;
|
||||
|
||||
const sections = document.querySelectorAll('.coded-hasmenu');
|
||||
for (let i = 0; i < sections.length; i++) {
|
||||
if (sections[i] !== parent) {
|
||||
sections[i].classList.remove('coded-trigger');
|
||||
}
|
||||
}
|
||||
|
||||
let first_parent = parent.parentElement;
|
||||
let pre_parent = ((parent as HTMLElement).parentElement as HTMLElement).parentElement as HTMLElement;
|
||||
if (first_parent?.classList.contains('coded-hasmenu')) {
|
||||
do {
|
||||
first_parent?.classList.add('coded-trigger');
|
||||
first_parent = ((first_parent as HTMLElement).parentElement as HTMLElement).parentElement as HTMLElement;
|
||||
} while (first_parent.classList.contains('coded-hasmenu'));
|
||||
} else if (pre_parent.classList.contains('coded-submenu')) {
|
||||
do {
|
||||
pre_parent?.parentElement?.classList.add('coded-trigger');
|
||||
pre_parent = (((pre_parent as HTMLElement).parentElement as HTMLElement).parentElement as HTMLElement).parentElement as HTMLElement;
|
||||
} while (pre_parent.classList.contains('coded-submenu'));
|
||||
}
|
||||
parent.classList.toggle('coded-trigger');
|
||||
}
|
||||
|
||||
// for Compact Menu
|
||||
subMenuCollapse(item: void) {
|
||||
this.showCollapseItem.emit(item);
|
||||
}
|
||||
}
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
<!-- Vertical layout -->
|
||||
<ng-scrollbar style="height: calc(100vh - 49px)" visibility="hover" id="nav-ps-mantis">
|
||||
<div class="navbar-content">
|
||||
<ul class="nav coded-inner-navbar" (clickOutside)="fireOutClick()" (mouseleave)="navMob()">
|
||||
@for (item of navigations; track item) {
|
||||
@if (item.type === 'group') {
|
||||
<app-nav-group [item]="item"></app-nav-group>
|
||||
}
|
||||
}
|
||||
</ul>
|
||||
<div class="m-4 mb-0">
|
||||
<div class="card nav-card">
|
||||
<div class="card-body">
|
||||
<div class="d-flex flex-column align-items-center">
|
||||
<img src="assets/images/avatar-group.png" alt="user" class="img-fluid" />
|
||||
<div class="m-t-20 text-center">
|
||||
<h5 class="mb-0">Mantis Pro</h5>
|
||||
<span class="text-muted">Checkout pro features</span>
|
||||
</div>
|
||||
<div class="m-t-20 text-center">
|
||||
<a
|
||||
href="https://codedthemes.com/item/mantis-angular-admin-template/?utm_source=free_demo&utm_medium=codedthemes&utm_campaign=button_download_premium"
|
||||
target="_blank"
|
||||
class="btn btn-primary text-white"
|
||||
>
|
||||
Pro
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ng-scrollbar>
|
||||
+106
@@ -0,0 +1,106 @@
|
||||
// Angular import
|
||||
import { Component, OnInit, inject, output } from '@angular/core';
|
||||
import {CommonModule, DOCUMENT, Location, LocationStrategy} from '@angular/common';
|
||||
import { RouterModule } from '@angular/router';
|
||||
|
||||
// project import
|
||||
import { NavigationItem, NavigationItems } from '../navigation';
|
||||
//import { environment } from 'src/environments/environment';
|
||||
|
||||
import { NavGroupComponent } from './nav-group/nav-group.component';
|
||||
|
||||
// icon
|
||||
import { IconService } from '@ant-design/icons-angular';
|
||||
import {
|
||||
DashboardOutline,
|
||||
CreditCardOutline,
|
||||
LoginOutline,
|
||||
QuestionOutline,
|
||||
ChromeOutline,
|
||||
FontSizeOutline,
|
||||
ProfileOutline,
|
||||
BgColorsOutline,
|
||||
AntDesignOutline
|
||||
} from '@ant-design/icons-angular/icons';
|
||||
import { NgScrollbarModule } from 'ngx-scrollbar';
|
||||
|
||||
@Component({
|
||||
selector: 'app-nav-content',
|
||||
imports: [CommonModule, RouterModule, NavGroupComponent, NgScrollbarModule],
|
||||
templateUrl: './nav-content.component.html',
|
||||
styleUrls: ['./nav-content.component.scss']
|
||||
})
|
||||
export class NavContentComponent implements OnInit {
|
||||
private location = inject(Location);
|
||||
private locationStrategy = inject(LocationStrategy);
|
||||
private iconService = inject(IconService)
|
||||
private document = inject(DOCUMENT);
|
||||
|
||||
// public props
|
||||
NavCollapsedMob = output();
|
||||
|
||||
navigations: NavigationItem[];
|
||||
|
||||
// version
|
||||
title = 'Demo application for version numbering';
|
||||
//currentApplicationVersion = environment.appVersion;
|
||||
|
||||
navigation = NavigationItems;
|
||||
windowWidth: number | undefined = 1000;
|
||||
|
||||
// Constructor
|
||||
constructor() {
|
||||
this.iconService.addIcon(
|
||||
...[
|
||||
DashboardOutline,
|
||||
CreditCardOutline,
|
||||
FontSizeOutline,
|
||||
LoginOutline,
|
||||
ProfileOutline,
|
||||
BgColorsOutline,
|
||||
AntDesignOutline,
|
||||
ChromeOutline,
|
||||
QuestionOutline
|
||||
]
|
||||
);
|
||||
this.navigations = NavigationItems;
|
||||
}
|
||||
|
||||
// Life cycle events
|
||||
ngOnInit() {
|
||||
if (!!this.windowWidth && this.windowWidth < 1025) {
|
||||
(this.document.querySelector('.coded-navbar') as HTMLDivElement)?.classList.add('menupos-static');
|
||||
}
|
||||
}
|
||||
|
||||
fireOutClick() {
|
||||
let current_url = this.location.path();
|
||||
const baseHref = this.locationStrategy.getBaseHref();
|
||||
if (baseHref) {
|
||||
current_url = baseHref + this.location.path();
|
||||
}
|
||||
const link = "a.nav-link[ href='" + current_url + "' ]";
|
||||
const ele = document?.querySelector(link);
|
||||
if (ele !== null && ele !== undefined) {
|
||||
const parent = ele.parentElement;
|
||||
const up_parent = parent?.parentElement?.parentElement;
|
||||
const last_parent = up_parent?.parentElement;
|
||||
if (parent?.classList.contains('coded-hasmenu')) {
|
||||
parent.classList.add('coded-trigger');
|
||||
parent.classList.add('active');
|
||||
} else if (up_parent?.classList.contains('coded-hasmenu')) {
|
||||
up_parent.classList.add('coded-trigger');
|
||||
up_parent.classList.add('active');
|
||||
} else if (last_parent?.classList.contains('coded-hasmenu')) {
|
||||
last_parent.classList.add('coded-trigger');
|
||||
last_parent.classList.add('active');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
navMob() {
|
||||
if (!!this.windowWidth && this.windowWidth < 1025 && document.querySelector('app-navigation.coded-navbar')?.classList.contains('mob-open')) {
|
||||
this.NavCollapsedMob.emit();
|
||||
}
|
||||
}
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
<li class="nav-item coded-menu-caption">
|
||||
<label>{{ item().title }}</label>
|
||||
</li>
|
||||
@for (item of item().children; track item) {
|
||||
@if (item.type === 'collapse') {
|
||||
<app-nav-collapse [item]="item"></app-nav-collapse>
|
||||
} @else if (item.type === 'item') {
|
||||
<app-nav-item [item]="item"></app-nav-item>
|
||||
}
|
||||
}
|
||||
+67
@@ -0,0 +1,67 @@
|
||||
// Angular import
|
||||
import { Component, OnInit, inject, input } from '@angular/core';
|
||||
import {CommonModule, DOCUMENT, Location} from '@angular/common';
|
||||
|
||||
// project import
|
||||
import { NavigationItem } from '../../navigation';
|
||||
|
||||
import { NavCollapseComponent } from '../nav-collapse/nav-collapse.component';
|
||||
import { NavItemComponent } from '../nav-item/nav-item.component';
|
||||
|
||||
@Component({
|
||||
selector: 'app-nav-group',
|
||||
imports: [CommonModule, NavCollapseComponent, NavItemComponent],
|
||||
templateUrl: './nav-group.component.html',
|
||||
styleUrls: ['./nav-group.component.scss']
|
||||
})
|
||||
export class NavGroupComponent implements OnInit {
|
||||
private location = inject(Location);
|
||||
private document = inject(DOCUMENT);
|
||||
// public props
|
||||
|
||||
// All Version in Group Name
|
||||
item = input.required<NavigationItem>();
|
||||
|
||||
// Life cycle events
|
||||
ngOnInit() {
|
||||
// at reload time active and trigger link
|
||||
let current_url: string | any = this.location.path();
|
||||
// eslint-disable-next-line
|
||||
// @ts-ignore
|
||||
if (this.location['_baseHref']) {
|
||||
// eslint-disable-next-line
|
||||
|
||||
|
||||
// @ts-ignore
|
||||
current_url = this.location['_baseHref'] + this.location.path();
|
||||
}
|
||||
|
||||
const link = "a.nav-link[ href='" + current_url + "' ]";
|
||||
//if(this.document === undefined) return;
|
||||
const ele = this.document?.querySelector(link);
|
||||
if (ele !== null && ele !== undefined) {
|
||||
const parent = ele.parentElement;
|
||||
const up_parent = parent?.parentElement?.parentElement;
|
||||
const pre_parent = up_parent?.parentElement;
|
||||
const last_parent = up_parent?.parentElement?.parentElement?.parentElement?.parentElement;
|
||||
if (parent?.classList.contains('coded-hasmenu')) {
|
||||
parent?.classList.add('coded-trigger');
|
||||
parent?.classList.add('active');
|
||||
} else if (up_parent?.classList.contains('coded-hasmenu')) {
|
||||
up_parent?.classList.add('coded-trigger');
|
||||
up_parent?.classList.add('active');
|
||||
} else if (pre_parent?.classList.contains('coded-hasmenu')) {
|
||||
pre_parent?.classList.add('coded-trigger');
|
||||
pre_parent?.classList.add('active');
|
||||
}
|
||||
|
||||
if (last_parent?.classList.contains('coded-hasmenu')) {
|
||||
last_parent?.classList.add('coded-trigger');
|
||||
if (pre_parent?.classList.contains('coded-hasmenu')) {
|
||||
pre_parent?.classList.add('coded-trigger');
|
||||
}
|
||||
}
|
||||
last_parent?.classList.add('active');
|
||||
}
|
||||
}
|
||||
}
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
@if (item.url && !item.external) {
|
||||
<li [ngClass]="item.classes!" [routerLinkActive]="['active']">
|
||||
<a [target]="item.target ? '_blank' : '_self'" [routerLink]="[item.url]" (click)="closeOtherMenu($event)">
|
||||
@if (item.icon) {
|
||||
<span class="coded-micon">
|
||||
<i antIcon type="{{ item.icon }}" theme="outline"></i>
|
||||
</span>
|
||||
}
|
||||
@if (item.icon) {
|
||||
<span class="coded-mtext">{{ item.title }}</span>
|
||||
} @else {
|
||||
{{ item.title }}
|
||||
}
|
||||
</a>
|
||||
</li>
|
||||
}
|
||||
@if (item.url && item.external) {
|
||||
<li [ngClass]="item.classes!">
|
||||
<a [target]="item.target ? '_blank' : '_self'" [href]="item.url">
|
||||
@if (item.icon) {
|
||||
<span class="coded-micon">
|
||||
<i antIcon type="{{ item.icon }}" theme="outline"></i>
|
||||
</span>
|
||||
}
|
||||
@if (item.icon) {
|
||||
<span class="coded-mtext">{{ item.title }}</span>
|
||||
} @else {
|
||||
{{ item.title }}
|
||||
}
|
||||
</a>
|
||||
</li>
|
||||
}
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
// Angular import
|
||||
import {Component, inject, Input} from '@angular/core';
|
||||
import {CommonModule, DOCUMENT} from '@angular/common';
|
||||
import { RouterModule } from '@angular/router';
|
||||
|
||||
// Project import
|
||||
import { NavigationItem } from '../../navigation';
|
||||
|
||||
import { IconDirective } from '@ant-design/icons-angular';
|
||||
|
||||
@Component({
|
||||
selector: 'app-nav-item',
|
||||
imports: [CommonModule, IconDirective, RouterModule],
|
||||
templateUrl: './nav-item.component.html',
|
||||
styleUrls: ['./nav-item.component.scss']
|
||||
})
|
||||
export class NavItemComponent {
|
||||
private document = inject(DOCUMENT);
|
||||
|
||||
// public props
|
||||
@Input() item!: NavigationItem;
|
||||
|
||||
// public method
|
||||
closeOtherMenu(event: MouseEvent) {
|
||||
const ele = event.target as HTMLElement;
|
||||
if (ele !== null && ele !== undefined) {
|
||||
const parent = ele.parentElement as HTMLElement;
|
||||
const up_parent = ((parent.parentElement as HTMLElement).parentElement as HTMLElement).parentElement as HTMLElement;
|
||||
const last_parent = up_parent.parentElement;
|
||||
const sections = this.document.querySelectorAll('.coded-hasmenu');
|
||||
for (let i = 0; i < sections.length; i++) {
|
||||
sections[i].classList.remove('active');
|
||||
sections[i].classList.remove('coded-trigger');
|
||||
}
|
||||
|
||||
if (parent.classList.contains('coded-hasmenu')) {
|
||||
parent.classList.add('coded-trigger');
|
||||
parent.classList.add('active');
|
||||
} else if (up_parent.classList.contains('coded-hasmenu')) {
|
||||
up_parent.classList.add('coded-trigger');
|
||||
up_parent.classList.add('active');
|
||||
} else if (last_parent?.classList.contains('coded-hasmenu')) {
|
||||
last_parent.classList.add('coded-trigger');
|
||||
last_parent.classList.add('active');
|
||||
}
|
||||
}
|
||||
if ((document.querySelector('app-navigation.pc-sidebar') as HTMLDivElement).classList.contains('mob-open')) {
|
||||
(document.querySelector('app-navigation.pc-sidebar') as HTMLDivElement).classList.remove('mob-open');
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user