Reputation: 11
Side-nav.component.html
<mat-sidenav-container class="sidenav-container">
<mat-sidenav
#drawer
[ngClass]="sidenavToggle ? 'sidenav' : 'sidenavToggle'"
fixedInViewport
mode="side"
[opened]="true"
disableClose="true"
>
<mat-toolbar class="app-logo secondaryblue">
<div class="app-header__logo">
<div class="app-logo__wrapper">
<img
src="assets/images/Rishabh-Software-logo.png"
alt=""
class="desktop-logo sidenavToggle-logo"
/>
<img
src="assets/images/r-logo.svg"
alt=""
class="desktop-logo sidenav-logo"
/>
<img
src="assets/images/Rishabh-Software-logo.png"
alt=""
class="mobile-logo"
/>
</div>
</div>
</mat-toolbar>
<mat-nav-list>
<ng-container *ngFor="let item of sidebarItems">
<!-- <ng-template [ngIf]="shouldDisplayMenuItem(item)"> -->
<ng-template
[ngIf]="item.role.includes(this.role) && item?.viewPermission"
>
<app-menu-list-item
[sidenavToggle]="sidenavToggle"
[item]="item"
></app-menu-list-item>
</ng-template>
</ng-container>
</mat-nav-list>
</mat-sidenav>
<mat-sidenav-content
class="app-content_wrapper"
[ngClass]="sidenavToggle ? 'marginChange' : ''"
>
<mat-toolbar class="app-header" color="primary">
<button
mat-icon-button
class="menu-icon"
aria-label="Example icon-button with menu icon"
(click)="toggleSidenav()"
>
<mat-icon>menu</mat-icon>
</button>
<app-header-title
[title]="breadcumbsTitle"
home="Home"
[subTitle]="breadcumbsSubTitle"
></app-header-title>
<button mat-button class="display-name" disabled="true">
{{ fullName }} <span><img class="me-2" src="assets/images/user.svg" alt="" />
</span> <span style="color: rgb(192, 189, 189);">|</span>
</button>
<button
mat-raised-button
color="primary"
role="listitem"
(click)="signOut()"
class="app-nav__item"
>
<mat-icon class="logout-icon">power_settings_new</mat-icon>Logout
</button>
</mat-toolbar>
<div class="container-fluid">
<div class="row">
<div class="col-12 mt-5 mb-5 pb-3 pt-5">
<router-outlet></router-outlet>
</div>
</div>
</div>
<app-footer></app-footer>
</mat-sidenav-content>
</mat-sidenav-container>
side-nav.component.ts
@Component({
selector: 'app-side-nav',
templateUrl: './side-nav.component.html',
styleUrls: ['./side-nav.component.scss'],
})
export class SideNavComponent implements OnInit {
sidenavToggle = false;
sidebarItems: any = [];
loggedInUserData: any;
sub!: Subscription;
role: any;
@Input() title: string | undefined = undefined;
@Input() home: string | undefined = undefined;
breadcumbsSubTitle = '';
private breakpointObserver = inject(BreakpointObserver);
fullName!: string;
testSideNav!: string;
sideNavTestArray: any = [];
componentName: any;
constructor(private router: Router, private loginService: LoginService, private activatedRoute: ActivatedRoute,
private common: CommonService) {
this.router.events.pipe(
filter(event => event instanceof ActivationEnd),
map(event => (<ActivationEnd>event).snapshot),
map(snapshot => (<ActivatedRouteSnapshot>snapshot).data)).subscribe(data => {
if (data && data['breadcumbs']) {
this.breadcumbsTitle = data['breadcumbs'].title;
this.breadcumbsSubTitle = data['breadcumbs'].subTitle;
}
});
}
ngOnInit(): void {
this.role = localStorage.getItem('Role');
let userDataId = JSON.parse(localStorage.getItem('userData')!).id;
this.componentName = localStorage.getItem('componentName');
let userPermissions = JSON.parse(localStorage.getItem('Permissions')!);
if (userDataId && userPermissions == undefined) {
this.getUserPermissions(userDataId);
}
else {
this.loadMenuItems(SidePanel_Item);
}
this.fullName = JSON.parse(localStorage.getItem('userData')!)?.firstName;
const userData: any = localStorage.getItem('Role');
this.loggedInUserData = userData;
}
getUserPermissions(id: any) {
this.common.getPermissionsOfUser(id).subscribe((res: any) => {
localStorage.setItem('Permissions', JSON.stringify(res.items));
this.sub = this.loginService.roleOBS.subscribe((x) => {
this.role = localStorage.getItem('Role');
this.sidebarItems = [];
this.loadMenuItems(SidePanel_Item);
});
})
}
loadMenuItems(menuItems: any[]) {
menuItems.forEach((obj: { children: any[]; role: any[]; title: string; viewPermission?: boolean }) => {
if (
obj.role &&
obj.children &&
obj.children.length === 0 &&
obj.role.length > 0 &&
obj.role.some((item: any) => item === this.role) &&
(obj.viewPermission || (obj.viewPermission && this.hasViewPermission(obj.title))
)
) {
this.sidebarItems.push(obj);
}
if (obj.children && obj.children.length > 0 && (obj.title == this.componentName || obj.title == 'Settings' || obj.title == 'Important Links')) {
obj.viewPermission = this.hasViewPermission(obj.title)
obj.children = this.filterMenuItems(obj.children);
if (obj.children.length > 0) {
this.sidebarItems.push(obj);
}
}
});
}
filterMenuItems(children: any[]): any[] {
return children.filter((child: any) => {
if (!child.viewPermission) {
child.viewPermission = this.hasViewPermission(child.title);
}
if (
(child.role &&
Array.isArray(child.role) &&
child.role.some((item: any) => item === this.role) &&
child.viewPermission)
) {
if (child.children && child.children.length > 0) {
child.children = this.filterMenuItems(child.children);
}
return true;
}
child.viewPermission = false;
return false;
});
}
isHandset$: Observable<boolean> = this.breakpointObserver
.observe(Breakpoints.Handset)
.pipe(
map((result) => result.matches),
shareReplay()
);
toggleSidenav() {
this.sidenavToggle = !this.sidenavToggle;
}
public signOut(): void {
this.loginService.logOut();
this.loadMenuItems([]);
this.filterMenuItems([]);
this.loggedInUserData = '';
this.sidebarItems = [];
this.loginService.currentUserSubject.next(null);
localStorage.removeItem('Permissions');
setTimeout(() => {
window.location.reload();
}, 1000);
}
hasViewPermission(title: any) {
let permissions = JSON.parse(localStorage.getItem('Permissions')!);
if (!permissions) {
return false; // or handle as needed
}
let permission = permissions.find((p: { subProjectName: string; }) => p.subProjectName === title);
if (!permission) {
return false; // or handle as needed
}
return permission?.viewPermission ? permission?.viewPermission : false;
};
}
menu-list-item.html
<ng-template [ngIf]="item?.viewPermission" >
<mat-list-item
(click)="onItemSelected(item)"
[ngStyle]="{ 'padding-left': !sidenavToggle ? depth * 12 + 'px' : '' }"
[ngClass]="{
active: item.routeLink ? isRouteActive(item.routeLink) : false,
expanded: expanded
}"
class="app-menu__item"
>
<mat-icon class="routeIcon">{{ item.icon }}</mat-icon>
<span *ngIf="!sidenavToggle" class="app-menu__label">
{{ item.title }}</span>
<span
class="treeview-indicator"
fxFlex
*ngIf="item.children && item.children.length"
>
<span fxFlex></span>
<mat-icon
*ngIf="!sidenavToggle"
class="align-middle"
[@indicatorRotate]="expanded ? 'expanded' : 'collapsed'"
>
expand_more
</mat-icon>
</span>
</mat-list-item>
</ng-template>
<div *ngIf="expanded">
<app-menu-list-item
*ngFor="let child of item.children"
[item]="child"
[depth]="depth + 1"
>
</app-menu-list-item>
</div>
menu-list-item.ts
import { Component, HostBinding, Input, OnInit } from '@angular/core';
import { Router } from '@angular/router';
import {
animate,
state,
style,
transition,
trigger,
} from '@angular/animations';
import { NavService } from '../../service/nav.service';
import { SidePanel_Item } from '../../model/side-panel.model';
import { SideNavComponent } from '../side-nav/side-nav.component';
@Component({
selector: 'app-menu-list-item',
templateUrl: './menu-list-item.component.html',
styleUrls: ['./menu-list-item.component.scss'],
animations: [
trigger('indicatorRotate', [
state('collapsed', style({ transform: 'rotate(0deg)' })),
state('expanded', style({ transform: 'rotate(180deg)' })),
transition(
'expanded <=> collapsed',
animate('225ms cubic-bezier(0.4,0.0,0.2,1)')
),
]),
],
})
export class MenuListItemComponent implements OnInit {
expanded!: boolean;
@HostBinding('attr.aria-expanded') ariaExpanded = this.expanded;
@Input() item: any;
@Input() depth!: number;
@Input() sidenavToggle: any;
constructor(public navService: NavService, public router: Router) {
if (this.depth === undefined) {
this.depth = 0;
}
}
ngOnInit() {
SidePanel_Item;
this.navService.currentUrl.subscribe((url: string) => {
if (this.item.route && url) {
this.expanded = url.indexOf(`/${this.item.route}`) === 0;
this.ariaExpanded = this.expanded;
}
});
}
onItemSelected(item: any) {
if (!item.children || !item.children.length) {
this.router.navigate([item.routeLink]);
this.navService?.closeNav();
}
if (item.children && item.children.length) {
this.expanded = !this.expanded;
}
}
isRouteActive(route: string): boolean {
const currentRouteWithoutQueryParams = this.router.url.split('?')[0];
return currentRouteWithoutQueryParams === route;
}
}
The issue occurs is described as follows:
Drop Down 1 item-1 item-2 item-3
Drop Down 2 item-1 item-2 Drop down 3 item-1 item-2
first when I click on the drop down 1 it expands and then I click on the any item from the drop down 1 the page of that item opens successfully the I click on the drop down 2 it expands and then when I click on any item of another drop down all the dropdown gets collapsed.
the expected result should be the drop drop should only collapsed when clicked on the dropdown and should not get collapsed after clicking on the item from other drop down.
Upvotes: 0
Views: 58