feature/refactor-login #19
|
@ -46,6 +46,11 @@ const protectedRoutes: Routes = [
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: 'foo',
|
||||||
|
loadComponent: () =>
|
||||||
|
import('./pages/foo-root/foo.component').then((m) => m.FooComponent),
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
export const routes: Routes = [
|
export const routes: Routes = [
|
||||||
|
|
|
@ -1,14 +1,16 @@
|
||||||
<!-- app.component.html -->
|
|
||||||
<div class="flex flex-col h-screen overflow-hidden">
|
<div class="flex flex-col h-screen overflow-hidden">
|
||||||
<!-- Header -->
|
<!-- Header -->
|
||||||
<header class="w-full navbar bg-primary text-primary-content z-20">
|
<header class="w-full navbar bg-primary text-primary-content z-40">
|
||||||
<div class="flex-1">
|
<div class="flex-1">
|
||||||
<a class="btn btn-ghost normal-case text-xl text-primary-content">
|
<a class="btn btn-ghost normal-case text-xl text-primary-content">
|
||||||
[APP-NAME]
|
[APP-NAME]
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
<!-- Der Button wird nur auf mobilen Geräten angezeigt -->
|
||||||
<div class="flex-none lg:hidden">
|
<div class="flex-none lg:hidden">
|
||||||
<label for="my-drawer" class="btn btn-square btn-ghost drawer-button">
|
<button
|
||||||
|
(click)="toggleDrawer()"
|
||||||
|
class="btn btn-square btn-ghost drawer-button">
|
||||||
<svg
|
<svg
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
fill="none"
|
fill="none"
|
||||||
|
@ -20,65 +22,119 @@
|
||||||
stroke-width="2"
|
stroke-width="2"
|
||||||
d="M4 6h16M4 12h16M4 18h16"></path>
|
d="M4 6h16M4 12h16M4 18h16"></path>
|
||||||
</svg>
|
</svg>
|
||||||
</label>
|
</button>
|
||||||
</div>
|
|
||||||
<div class="flex-none hidden lg:block">
|
|
||||||
<!-- Zusätzliche Header-Elemente für große Bildschirme -->
|
|
||||||
</div>
|
</div>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
<!-- Hauptcontainer -->
|
<!-- Hauptcontainer -->
|
||||||
<div class="drawer lg:drawer-open flex-1 overflow-hidden">
|
<div class="flex-1 flex overflow-hidden relative">
|
||||||
<input id="my-drawer" type="checkbox" class="drawer-toggle" />
|
<!-- Backdrop -->
|
||||||
|
<div
|
||||||
<!-- Hauptinhalt -->
|
*ngIf="isDrawerOpen"
|
||||||
<div class="drawer-content flex flex-col bg-base-100">
|
class="fixed inset-0 bg-black bg-opacity-50 z-20 lg:hidden"
|
||||||
<main class="flex-1 overflow-y-auto p-4">
|
(click)="toggleDrawer()"></div>
|
||||||
<div class="w-full h-full flex items-center justify-center">
|
|
||||||
<div class="w-full max-w-5xl">
|
|
||||||
<router-outlet></router-outlet>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</main>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Drawer -->
|
<!-- Drawer -->
|
||||||
<div class="drawer-side h-full">
|
<div
|
||||||
<label for="my-drawer" class="drawer-overlay"></label>
|
class="h-full transition-transform duration-300 ease-in-out bg-primary text-primary-content w-64 flex flex-col lg:translate-x-0"
|
||||||
<aside class="bg-primary text-primary-content w-64 h-full flex flex-col">
|
[ngClass]="{
|
||||||
<div class="flex-1 overflow-y-auto py-4 pt-0">
|
'translate-x-0': isDrawerOpen,
|
||||||
|
'-translate-x-full': !isDrawerOpen,
|
||||||
|
'fixed lg:relative': true,
|
||||||
|
'top-0 left-0 z-30': true
|
||||||
|
}">
|
||||||
|
<aside class="h-full flex flex-col">
|
||||||
|
<!-- Drawer-Inhalt -->
|
||||||
|
<div class="flex-1 overflow-y-auto pt-16 lg:pt-0">
|
||||||
<ul class="w-full p-0 m-0 [&_li>*]:rounded-none">
|
<ul class="w-full p-0 m-0 [&_li>*]:rounded-none">
|
||||||
<ng-container *ngFor="let item of menuItems">
|
<ng-container *ngFor="let item of menuItems">
|
||||||
<li class="w-full">
|
<li class="w-full">
|
||||||
|
<ng-container *ngIf="!item.subitems; else submenu">
|
||||||
<a
|
<a
|
||||||
[routerLink]="item.route"
|
[routerLink]="item.route"
|
||||||
routerLinkActive="bg-base-100 text-base-content"
|
[class.active]="item.active"
|
||||||
[routerLinkActiveOptions]="{ exact: false }"
|
class="flex items-center w-full px-4 py-3 transition-colors duration-200 ease-in-out focus:outline-none hover:bg-base-300 hover:text-primary"
|
||||||
class="flex items-center w-full px-4 py-3 text-base-content transition-colors duration-200 ease-in-out focus:outline-none"
|
[class.bg-base-100]="item.active"
|
||||||
|
[class.text-base-content]="item.active"
|
||||||
|
[class.text-primary]="item.active"
|
||||||
|
[class.font-semibold]="item.active"
|
||||||
role="menuitem"
|
role="menuitem"
|
||||||
tabindex="0"
|
tabindex="0"
|
||||||
(keydown.enter)="
|
(click)="onLinkClick()">
|
||||||
$event.preventDefault(); navigateTo(item.route)
|
|
||||||
">
|
|
||||||
<span
|
<span
|
||||||
class="flex-shrink-0 w-6 h-6 mr-3"
|
class="flex-shrink-0 w-6 h-6 mr-3"
|
||||||
[innerHTML]="item.icon"></span>
|
[innerHTML]="item.icon"></span>
|
||||||
<span class="flex-grow">{{ item.name }}</span>
|
<span class="flex-grow">{{ item.name }}</span>
|
||||||
</a>
|
</a>
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
|
<ng-template #submenu>
|
||||||
|
<div
|
||||||
|
(click)="toggleSubmenu(item, $event)"
|
||||||
|
class="flex items-center w-full px-4 py-3 transition-colors duration-200 ease-in-out focus:outline-none hover:bg-base-300 hover:text-primary cursor-pointer"
|
||||||
|
[class.bg-base-300]="item.active"
|
||||||
|
[class.text-primary]="item.active"
|
||||||
|
[class.font-semibold]="item.active"
|
||||||
|
[class.bg-base-100]="item.isOpen"
|
||||||
|
[class.text-base-content]="item.isOpen">
|
||||||
|
<span
|
||||||
|
class="flex-shrink-0 w-6 h-6 mr-3"
|
||||||
|
[innerHTML]="item.icon"></span>
|
||||||
|
<span class="flex-grow">{{ item.name }}</span>
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
fill="none"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
stroke-width="1.5"
|
||||||
|
stroke="currentColor"
|
||||||
|
class="w-4 h-4 transition-transform"
|
||||||
|
[class.rotate-180]="item.isOpen">
|
||||||
|
<path
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
d="M19.5 8.25l-7.5 7.5-7.5-7.5" />
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
[@submenuAnimation]="item.isOpen ? 'open' : 'closed'"
|
||||||
|
class="overflow-hidden">
|
||||||
|
<ul class="bg-base-100">
|
||||||
|
<li *ngFor="let subItem of item.subitems" class="w-full">
|
||||||
|
<a
|
||||||
|
[routerLink]="subItem.route"
|
||||||
|
[class.active]="subItem.active"
|
||||||
|
class="flex items-center w-full px-4 pl-8 py-2 transition-colors duration-200 ease-in-out focus:outline-none hover:bg-base-300 hover:text-primary"
|
||||||
|
[class.bg-base-300]="subItem.active"
|
||||||
|
[class.text-primary]="subItem.active"
|
||||||
|
[class.font-semibold]="subItem.active"
|
||||||
|
[class.bg-base-100]="item.isOpen"
|
||||||
|
[class.text-base-content]="item.isOpen"
|
||||||
|
role="menuitem"
|
||||||
|
tabindex="0"
|
||||||
|
(click)="onLinkClick()">
|
||||||
|
<span
|
||||||
|
class="flex-shrink-0 w-5 h-5 mr-2"
|
||||||
|
[innerHTML]="subItem.icon"></span>
|
||||||
|
{{ subItem.name }}
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</ng-template>
|
||||||
</li>
|
</li>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<div class="p-4">
|
<hr class="border-t border-base-100" />
|
||||||
<ul class="menu w-full">
|
|
||||||
|
<div style="background-color: rgba(0, 0, 0, 0.2)">
|
||||||
|
<ul class="w-full px-2 py-4">
|
||||||
<ng-container *ngFor="let item of bottomMenuItems">
|
<ng-container *ngFor="let item of bottomMenuItems">
|
||||||
<li>
|
<li>
|
||||||
<button
|
<button
|
||||||
(click)="executeAction(item)"
|
(click)="executeAction(item)"
|
||||||
(keydown.enter)="executeAction(item)"
|
(keydown.enter)="executeAction(item)"
|
||||||
class="flex items-center space-x-2 hover:bg-primary-focus focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary-focus w-full text-left"
|
class="py-2 px-4 rounded flex items-center space-x-2 bg-base-100 text-base-content hover:text-primary hover:font-semibold w-full text-left">
|
||||||
role="menuitem"
|
|
||||||
tabindex="0">
|
|
||||||
<span [innerHTML]="item.icon"></span>
|
<span [innerHTML]="item.icon"></span>
|
||||||
<span>{{ item.name }}</span>
|
<span>{{ item.name }}</span>
|
||||||
</button>
|
</button>
|
||||||
|
@ -88,5 +144,16 @@
|
||||||
</div>
|
</div>
|
||||||
</aside>
|
</aside>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- Hauptinhalt -->
|
||||||
|
<div class="flex-1 overflow-y-auto p-4 bg-base-100">
|
||||||
|
<main class="flex-1">
|
||||||
|
<div class="w-full h-full flex items-center justify-center">
|
||||||
|
<div class="w-full max-w-5xl">
|
||||||
|
<router-outlet></router-outlet>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,8 +1,16 @@
|
||||||
|
import {
|
||||||
|
animate,
|
||||||
|
state,
|
||||||
|
style,
|
||||||
|
transition,
|
||||||
|
trigger,
|
||||||
|
} from '@angular/animations';
|
||||||
import { CommonModule } from '@angular/common';
|
import { CommonModule } from '@angular/common';
|
||||||
import {
|
import {
|
||||||
ChangeDetectionStrategy,
|
ChangeDetectionStrategy,
|
||||||
Component,
|
Component,
|
||||||
ElementRef,
|
ElementRef,
|
||||||
|
OnDestroy,
|
||||||
OnInit,
|
OnInit,
|
||||||
} from '@angular/core';
|
} from '@angular/core';
|
||||||
import { DomSanitizer, SafeHtml } from '@angular/platform-browser';
|
import { DomSanitizer, SafeHtml } from '@angular/platform-browser';
|
||||||
|
@ -14,7 +22,7 @@ import {
|
||||||
RouterOutlet,
|
RouterOutlet,
|
||||||
} from '@angular/router';
|
} from '@angular/router';
|
||||||
|
|
||||||
import { filter } from 'rxjs';
|
import { filter, Subject, takeUntil } from 'rxjs';
|
||||||
|
|
||||||
import { SuccessDtoApiModel } from '../../api';
|
import { SuccessDtoApiModel } from '../../api';
|
||||||
import { BackgroundPatternService, ThemeService } from '../../shared/service';
|
import { BackgroundPatternService, ThemeService } from '../../shared/service';
|
||||||
|
@ -23,8 +31,17 @@ import { AuthService } from '../../shared/service/auth.service';
|
||||||
interface TopMenuItem {
|
interface TopMenuItem {
|
||||||
name: string;
|
name: string;
|
||||||
icon: SafeHtml;
|
icon: SafeHtml;
|
||||||
|
route?: string;
|
||||||
|
active?: boolean;
|
||||||
|
subitems?: SubMenuItem[];
|
||||||
|
isOpen?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface SubMenuItem {
|
||||||
|
name: string;
|
||||||
route: string;
|
route: string;
|
||||||
active?: boolean;
|
active?: boolean;
|
||||||
|
icon?: SafeHtml;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface BottomMenuItem {
|
interface BottomMenuItem {
|
||||||
|
@ -39,12 +56,32 @@ interface BottomMenuItem {
|
||||||
providers: [],
|
providers: [],
|
||||||
imports: [RouterOutlet, CommonModule, RouterModule],
|
imports: [RouterOutlet, CommonModule, RouterModule],
|
||||||
templateUrl: './layout.component.html',
|
templateUrl: './layout.component.html',
|
||||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
changeDetection: ChangeDetectionStrategy.Default,
|
||||||
|
animations: [
|
||||||
|
trigger('submenuAnimation', [
|
||||||
|
state(
|
||||||
|
'closed',
|
||||||
|
style({
|
||||||
|
height: '0',
|
||||||
|
opacity: '0',
|
||||||
})
|
})
|
||||||
export class LayoutComponent implements OnInit {
|
),
|
||||||
|
state(
|
||||||
|
'open',
|
||||||
|
style({
|
||||||
|
height: '*',
|
||||||
|
opacity: '1',
|
||||||
|
})
|
||||||
|
),
|
||||||
|
transition('closed <=> open', [animate('200ms ease-in-out')]),
|
||||||
|
]),
|
||||||
|
],
|
||||||
|
})
|
||||||
|
export class LayoutComponent implements OnInit, OnDestroy {
|
||||||
public isCollapsed: boolean = false;
|
public isCollapsed: boolean = false;
|
||||||
public isDesktopCollapsed: boolean = false;
|
public isDesktopCollapsed: boolean = false;
|
||||||
public showMobileMenu: boolean = false;
|
public showMobileMenu: boolean = false;
|
||||||
|
public isDrawerOpen: boolean = true;
|
||||||
public menuItems: TopMenuItem[] = [
|
public menuItems: TopMenuItem[] = [
|
||||||
{
|
{
|
||||||
name: 'Dashboard',
|
name: 'Dashboard',
|
||||||
|
@ -56,11 +93,41 @@ export class LayoutComponent implements OnInit {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'Event',
|
name: 'Event',
|
||||||
route: '/event',
|
|
||||||
icon: this.sanitizer
|
icon: this.sanitizer
|
||||||
.bypassSecurityTrustHtml(`<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="size-6">
|
.bypassSecurityTrustHtml(`<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="size-6">
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" d="M16.5 6v.75m0 3v.75m0 3v.75m0 3V18m-9-5.25h5.25M7.5 15h3M3.375 5.25c-.621 0-1.125.504-1.125 1.125v3.026a2.999 2.999 0 0 1 0 5.198v3.026c0 .621.504 1.125 1.125 1.125h17.25c.621 0 1.125-.504 1.125-1.125v-3.026a2.999 2.999 0 0 1 0-5.198V6.375c0-.621-.504-1.125-1.125-1.125H3.375Z" />
|
<path stroke-linecap="round" stroke-linejoin="round" d="M16.5 6v.75m0 3v.75m0 3v.75m0 3V18m-9-5.25h5.25M7.5 15h3M3.375 5.25c-.621 0-1.125.504-1.125 1.125v3.026a2.999 2.999 0 0 1 0 5.198v3.026c0 .621.504 1.125 1.125 1.125h17.25c.621 0 1.125-.504 1.125-1.125v-3.026a2.999 2.999 0 0 1 0-5.198V6.375c0-.621-.504-1.125-1.125-1.125H3.375Z" />
|
||||||
</svg>`),
|
</svg>`),
|
||||||
|
route: '/event',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Profile',
|
||||||
|
route: '/profile',
|
||||||
|
icon: this.sanitizer
|
||||||
|
.bypassSecurityTrustHtml(`<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="size-6">
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" d="M15.75 6a3.75 3.75 0 11-7.5 0 3.75 3.75 0 017.5 0zM4.501 20.118a7.5 7.5 0 0114.998 0A17.933 17.933 0 0112 21.75c-2.676 0-5.216-.584-7.499-1.632z" />
|
||||||
|
</svg>`),
|
||||||
|
subitems: [
|
||||||
|
{
|
||||||
|
name: 'Edit Profile',
|
||||||
|
route: '/foo',
|
||||||
|
icon: this.sanitizer.bypassSecurityTrustHtml(`
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="size-5">
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" d="M15.232 5.232l3.536 3.536-8.678 8.678H6.554v-3.536l8.678-8.678z" />
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" d="M16.368 4.096a1.5 1.5 0 0 1 2.121 0l1.415 1.415a1.5 1.5 0 0 1 0 2.121l-.707.707-3.536-3.536.707-.707z" />
|
||||||
|
</svg>
|
||||||
|
`),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Delete Profile',
|
||||||
|
route: '/foo-1',
|
||||||
|
icon: this.sanitizer.bypassSecurityTrustHtml(`
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="size-5">
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" d="M19 7H5m3-4h8m1 4v12a2 2 0 0 1-2 2H8a2 2 0 0 1-2-2V7h12z" />
|
||||||
|
</svg>
|
||||||
|
`),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
isOpen: false,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
public bottomMenuItems: BottomMenuItem[] = [
|
public bottomMenuItems: BottomMenuItem[] = [
|
||||||
|
@ -75,6 +142,7 @@ export class LayoutComponent implements OnInit {
|
||||||
];
|
];
|
||||||
public mainContent: { 'background-image': string } | null = null;
|
public mainContent: { 'background-image': string } | null = null;
|
||||||
public navigation: { 'background-image': string } | null = null;
|
public navigation: { 'background-image': string } | null = null;
|
||||||
|
private destroy$: Subject<void> = new Subject<void>();
|
||||||
|
|
||||||
public constructor(
|
public constructor(
|
||||||
private readonly sanitizer: DomSanitizer,
|
private readonly sanitizer: DomSanitizer,
|
||||||
|
@ -87,14 +155,53 @@ export class LayoutComponent implements OnInit {
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
public ngOnInit(): void {
|
public ngOnInit(): void {
|
||||||
this.router.events
|
this.adjustDrawerState(window.innerWidth);
|
||||||
.pipe(filter((event) => event instanceof NavigationEnd))
|
|
||||||
.subscribe(() => {
|
window.addEventListener('resize', () => {
|
||||||
this.setActiveItemBasedOnRoute();
|
this.adjustDrawerState(window.innerWidth);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Initial set
|
this.updateMenuState(this.router.url);
|
||||||
this.setActiveItemBasedOnRoute();
|
|
||||||
|
this.router.events
|
||||||
|
.pipe(
|
||||||
|
filter(
|
||||||
|
(event): event is NavigationEnd => event instanceof NavigationEnd
|
||||||
|
),
|
||||||
|
takeUntil(this.destroy$)
|
||||||
|
)
|
||||||
|
.subscribe((event: NavigationEnd) => {
|
||||||
|
this.updateMenuState(event.urlAfterRedirects);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public onResize(): void {
|
||||||
|
this.adjustDrawerState(window.innerWidth);
|
||||||
|
}
|
||||||
|
|
||||||
|
public onLinkClick(): void {
|
||||||
|
if (window.innerWidth < 1024 && this.isDrawerOpen) {
|
||||||
|
this.isDrawerOpen = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public ngOnDestroy(): void {
|
||||||
|
window.removeEventListener('resize', this.onResize.bind(this));
|
||||||
|
this.destroy$.next();
|
||||||
|
this.destroy$.complete();
|
||||||
|
}
|
||||||
|
|
||||||
|
public toggleDrawer(): void {
|
||||||
|
this.isDrawerOpen = !this.isDrawerOpen;
|
||||||
|
}
|
||||||
|
|
||||||
|
public adjustDrawerState(width: number): void {
|
||||||
|
// Hier wird geprüft, ob wir uns im mobilen Bereich befinden.
|
||||||
|
if (width < 1024) {
|
||||||
|
this.toggleDrawer();
|
||||||
|
} else {
|
||||||
|
this.toggleDrawer();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public navigateTo(route: string): void {
|
public navigateTo(route: string): void {
|
||||||
|
@ -107,6 +214,38 @@ export class LayoutComponent implements OnInit {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public toggleSubmenu(item: TopMenuItem, event: Event): void {
|
||||||
|
event.preventDefault();
|
||||||
|
event.stopPropagation();
|
||||||
|
item.isOpen = !item.isOpen;
|
||||||
|
}
|
||||||
|
|
||||||
|
private updateMenuState(currentRoute: string): void {
|
||||||
|
this.menuItems.forEach((item: TopMenuItem) => {
|
||||||
|
// Set top-level items active state
|
||||||
|
if (item.route) {
|
||||||
|
item.active = currentRoute.startsWith(item.route);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle subitems
|
||||||
|
if (item.subitems) {
|
||||||
|
// Check if any subitem matches the current route
|
||||||
|
const activeSubItem = item.subitems.some((subItem) =>
|
||||||
|
currentRoute.startsWith(subItem.route)
|
||||||
|
);
|
||||||
|
|
||||||
|
// Set the parent item and subitem active state
|
||||||
|
item.active = activeSubItem;
|
||||||
|
item.isOpen = activeSubItem;
|
||||||
|
|
||||||
|
// Set active states for all subitems
|
||||||
|
item.subitems.forEach((subItem) => {
|
||||||
|
subItem.active = currentRoute.startsWith(subItem.route);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// @HostListener('window:resize', ['$event'])
|
// @HostListener('window:resize', ['$event'])
|
||||||
// public onResize(): void {
|
// public onResize(): void {
|
||||||
// if (window.innerWidth >= 768) {
|
// if (window.innerWidth >= 768) {
|
||||||
|
@ -177,14 +316,6 @@ export class LayoutComponent implements OnInit {
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
|
|
||||||
private setActiveItemBasedOnRoute(): void {
|
|
||||||
const currentRoute = this.router.url;
|
|
||||||
|
|
||||||
this.menuItems.forEach((item: TopMenuItem) => {
|
|
||||||
item.active = currentRoute.startsWith(item.route);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private signout(): void {
|
private signout(): void {
|
||||||
this.authService.signout().subscribe((response: SuccessDtoApiModel) => {
|
this.authService.signout().subscribe((response: SuccessDtoApiModel) => {
|
||||||
if (response.success) {
|
if (response.success) {
|
||||||
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
import { CommonModule } from '@angular/common';
|
||||||
|
import { Component, ChangeDetectionStrategy } from '@angular/core';
|
||||||
|
import { RouterOutlet, RouterModule } from '@angular/router';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-foo',
|
||||||
|
standalone: true,
|
||||||
|
template: '<h1>Foo</h1>',
|
||||||
|
providers: [],
|
||||||
|
imports: [RouterOutlet, CommonModule, RouterModule],
|
||||||
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||||
|
})
|
||||||
|
export class FooComponent {}
|
Loading…
Reference in New Issue