@mediusinc/mng-commons-layout 5.1.0 → 5.2.0-rc.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,20 +1,19 @@
1
1
  import { AsyncPipe, NgOptimizedImage, NgClass, NgTemplateOutlet } from '@angular/common';
2
2
  import * as i0 from '@angular/core';
3
- import { InjectionToken, inject, Injectable, Component, ChangeDetectionStrategy, Input, computed, signal, DestroyRef, Injector, EventEmitter, effect, runInInjectionContext, HostBinding, Output, ViewChild, ElementRef, Renderer2 } from '@angular/core';
3
+ import { InjectionToken, inject, Injectable, DestroyRef, input, signal, computed, Component, ChangeDetectionStrategy, Injector, EventEmitter, effect, runInInjectionContext, Input, HostBinding, Output, ViewChild, ElementRef, Renderer2, viewChild } from '@angular/core';
4
4
  import * as i1$1 from '@ngx-translate/core';
5
5
  import { TranslateModule } from '@ngx-translate/core';
6
6
  import * as i2 from '@mediusinc/mng-commons/core';
7
- import { LoggerService, JsonPathPipe, CommonsService, ComponentDirective, CommonsRouterService, adjustRouteMenuLazyChildrenRouterLinks, doesUrlMatchRouterLink, PermissionService, EnumerateAsyncPipe, COMMONS_MODULE_CONFIG_IT, NotificationWrapperComponent, createRoute, CommonsFeatureTypeEnum } from '@mediusinc/mng-commons/core';
8
- import { ReplaySubject, BehaviorSubject, take, Subject, Observable, from, of, combineLatest, distinctUntilChanged } from 'rxjs';
7
+ import { LoggerService, JsonPathPipe, CommonsService, ComponentDirective, CommonsRouterService, adjustRouteMenuLazyChildrenRouterLinks, doesUrlMatchRouterLink, PermissionService, EnumerateAsyncPipe, NotificationWrapperComponent, createRoute, CommonsFeatureTypeEnum } from '@mediusinc/mng-commons/core';
8
+ import { toObservable, takeUntilDestroyed, toSignal } from '@angular/core/rxjs-interop';
9
+ import { ReplaySubject, catchError, of, switchMap, take, Subject, Observable, BehaviorSubject, combineLatest, distinctUntilChanged } from 'rxjs';
10
+ import { map, filter } from 'rxjs/operators';
9
11
  import * as i1 from '@angular/common/http';
10
- import { ButtonModule } from 'primeng/button';
11
- import { InputTextModule } from 'primeng/inputtext';
12
- import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
13
12
  import * as i1$3 from '@angular/router';
14
- import { Router, NavigationEnd, ActivatedRoute, GuardsCheckEnd, RouterModule } from '@angular/router';
15
- import { filter, first, map } from 'rxjs/operators';
13
+ import { Router, NavigationEnd, RouterModule, ActivatedRoute } from '@angular/router';
16
14
  import * as i2$1 from '@angular/forms';
17
15
  import { FormsModule } from '@angular/forms';
16
+ import { ButtonModule } from 'primeng/button';
18
17
  import * as i1$4 from 'primeng/dropdown';
19
18
  import { DropdownModule } from 'primeng/dropdown';
20
19
  import * as i1$2 from 'primeng/ripple';
@@ -68,76 +67,95 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.5", ngImpor
68
67
  class VersionComponent {
69
68
  constructor() {
70
69
  this.versionService = inject(VersionService);
70
+ this.destroyRef = inject(DestroyRef);
71
71
  this.jsonPathPipe = new JsonPathPipe();
72
- this.loadingSubject = new BehaviorSubject(false);
73
- this.loading$ = this.loadingSubject.asObservable();
74
- }
75
- ngOnInit() {
76
- if (Array.isArray(this.initVersion)) {
77
- this.versions = this.initVersion;
78
- }
79
- else if (typeof this.initVersion === 'string') {
80
- this.displayVersion = this.initVersion;
81
- }
82
- else if (typeof this.initVersion !== 'undefined') {
83
- if (this.initVersion['info'] || this.initVersion['urlPath']) {
84
- const config = this.initVersion;
85
- this.displayName = config.displayName;
86
- if (config.urlPath) {
87
- this.loadingSubject.next(true);
88
- this.versionService
89
- .loadVersion(config.urlPath, config.urlBaseConfigKey)
90
- .pipe(take(1))
91
- .subscribe({
92
- next: res => {
93
- this.displayVersion = this.jsonPathPipe.transform(res, config.infoJsonPath ?? '$');
94
- this.loadingSubject.next(false);
95
- },
96
- error: () => {
97
- this.displayVersion = '';
98
- this.loadingSubject.next(false);
99
- }
100
- });
72
+ this.initVersion = input(undefined, { alias: 'version' });
73
+ this.isLoading = signal(false);
74
+ this.loadedVersion = signal(undefined);
75
+ this.displayVersion = computed(() => {
76
+ if (typeof this.initVersion() === 'string') {
77
+ return this.initVersion();
78
+ }
79
+ else if (typeof this.initVersion() !== 'undefined') {
80
+ if (this.initVersion()['info'] || this.initVersion()['urlPath']) {
81
+ if (typeof this.loadedVersion() !== 'undefined') {
82
+ return this.loadedVersion();
83
+ }
84
+ else if (this.initVersion()['info']) {
85
+ const config = this.initVersion();
86
+ return this.jsonPathPipe.transform(config.info, config.infoJsonPath ?? '$.raw');
87
+ }
101
88
  }
102
89
  else {
103
- this.displayVersion = this.jsonPathPipe.transform(config.info, config.infoJsonPath ?? '$.raw');
90
+ const info = this.initVersion();
91
+ return this.jsonPathPipe.transform(info, '$.raw');
104
92
  }
105
93
  }
106
- else {
107
- const info = this.initVersion;
108
- this.displayVersion = this.jsonPathPipe.transform(info, '$.raw');
94
+ return;
95
+ });
96
+ this.versions = computed(() => {
97
+ if (Array.isArray(this.initVersion())) {
98
+ return this.initVersion();
109
99
  }
110
- }
100
+ return;
101
+ });
102
+ this.displayName = computed(() => {
103
+ if (typeof this.initVersion() !== 'undefined') {
104
+ if (this.initVersion()['info'] || this.initVersion()['urlPath']) {
105
+ const config = this.initVersion();
106
+ return config.displayName;
107
+ }
108
+ }
109
+ return;
110
+ });
111
+ toObservable(this.initVersion)
112
+ .pipe(catchError(() => of(undefined)), switchMap(version => {
113
+ if (typeof version !== 'undefined' && (version['info'] || version['urlPath'])) {
114
+ const config = version;
115
+ if (config.urlPath) {
116
+ this.isLoading.set(true);
117
+ return this.versionService.loadVersion(config.urlPath, config.urlBaseConfigKey).pipe(take(1), map(res => ({ res, config })));
118
+ }
119
+ }
120
+ return of({ res: undefined, config: undefined });
121
+ }), takeUntilDestroyed(this.destroyRef))
122
+ .subscribe({
123
+ next: ({ res, config }) => {
124
+ if (typeof res !== 'undefined' && typeof config !== 'undefined') {
125
+ this.loadedVersion.set(this.jsonPathPipe.transform(res, config.infoJsonPath ?? '$'));
126
+ }
127
+ else {
128
+ this.loadedVersion.set(undefined);
129
+ }
130
+ this.isLoading.set(false);
131
+ },
132
+ error: () => {
133
+ this.loadedVersion.set('');
134
+ this.isLoading.set(false);
135
+ }
136
+ });
111
137
  }
112
138
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.5", ngImport: i0, type: VersionComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
113
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.0.5", type: VersionComponent, isStandalone: true, selector: "mng-version", inputs: { initVersion: ["version", "initVersion"] }, ngImport: i0, template: "@if (versions) {\n @for (v of versions; track v; let last = $last) {\n <mng-version [version]=\"v\"></mng-version>\n @if (!last) {\n <br />\n }\n }\n} @else {\n @if (displayName) {\n {{ displayName }}:\n }\n @if ((loading$ | async) === false) {\n {{ displayVersion }}\n }\n}\n", dependencies: [{ kind: "component", type: VersionComponent, selector: "mng-version", inputs: ["version"] }, { kind: "pipe", type: AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
139
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.0.5", type: VersionComponent, isStandalone: true, selector: "mng-version", inputs: { initVersion: { classPropertyName: "initVersion", publicName: "version", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "@if (versions()) {\n @for (v of versions(); track v; let last = $last) {\n <mng-version [version]=\"v\"></mng-version>\n @if (!last) {\n <br />\n }\n }\n} @else {\n @if (displayName()) {{{ displayName() }}}\n @if (displayName() && displayVersion()) {: }\n @if (!isLoading()) {{{ displayVersion() }}}\n}\n", dependencies: [{ kind: "component", type: VersionComponent, selector: "mng-version", inputs: ["version"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
114
140
  }
115
141
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.5", ngImport: i0, type: VersionComponent, decorators: [{
116
142
  type: Component,
117
- args: [{ standalone: true, selector: 'mng-version', imports: [AsyncPipe], changeDetection: ChangeDetectionStrategy.OnPush, template: "@if (versions) {\n @for (v of versions; track v; let last = $last) {\n <mng-version [version]=\"v\"></mng-version>\n @if (!last) {\n <br />\n }\n }\n} @else {\n @if (displayName) {\n {{ displayName }}:\n }\n @if ((loading$ | async) === false) {\n {{ displayVersion }}\n }\n}\n" }]
118
- }], propDecorators: { initVersion: [{
119
- type: Input,
120
- args: ['version']
121
- }] } });
143
+ args: [{ standalone: true, selector: 'mng-version', imports: [AsyncPipe], changeDetection: ChangeDetectionStrategy.OnPush, template: "@if (versions()) {\n @for (v of versions(); track v; let last = $last) {\n <mng-version [version]=\"v\"></mng-version>\n @if (!last) {\n <br />\n }\n }\n} @else {\n @if (displayName()) {{{ displayName() }}}\n @if (displayName() && displayVersion()) {: }\n @if (!isLoading()) {{{ displayVersion() }}}\n}\n" }]
144
+ }], ctorParameters: () => [] });
122
145
 
123
146
  class FooterComponent {
124
147
  constructor() {
125
148
  this.config = inject(COMMONS_LAYOUT_FEATURE_CONFIG_IT, { optional: true });
126
149
  this.commons = inject(CommonsService);
127
- this.currentYear = new Date().getFullYear();
128
- this.versionComponent = VersionComponent;
129
- }
130
- ngOnInit() {
131
- if (this.config?.components?.version !== undefined) {
132
- this.versionComponent = this.config?.components?.version;
133
- }
150
+ this.currentYear = signal(new Date().getFullYear());
151
+ this.versionComponent = signal(this.config?.components?.version === false ? undefined : this.config?.components?.version ?? VersionComponent);
134
152
  }
135
153
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.5", ngImport: i0, type: FooterComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
136
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.0.5", type: FooterComponent, isStandalone: true, selector: "mng-footer", ngImport: i0, template: "<div class=\"layout-footer\">\n <div class=\"footer-logo-container\">\n <img id=\"footer-logo\" [src]=\"commons.appLogo()\" alt=\"atlantis-layout\" />\n <span class=\"app-name\">{{ commons.appName() | translate }}</span>\n </div>\n <div class=\"flex flex-column\">\n <div>\n <span class=\"copyright\">&#169; {{ commons.appOwner() | translate }} - {{ currentYear }}</span>\n </div>\n @if (versionComponent) {\n <div class=\"version\" [mngComponent]=\"versionComponent\" [inputs]=\"{version: commons.appVersion()}\" [attachToHost]=\"true\"></div>\n }\n </div>\n</div>\n", dependencies: [{ kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i1$1.TranslatePipe, name: "translate" }, { kind: "directive", type: ComponentDirective, selector: "[mngComponent]", inputs: ["mngComponent", "injectionToken", "inputs", "attachToHost", "parentInjector"], outputs: ["instanceCreated"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
154
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.0.5", type: FooterComponent, isStandalone: true, selector: "mng-footer", ngImport: i0, template: "<div class=\"layout-footer\">\n <div class=\"footer-logo-container\">\n <img id=\"footer-logo\" [src]=\"commons.appLogo()\" alt=\"atlantis-layout\" />\n <span class=\"app-name\">{{ commons.appName() | translate }}</span>\n </div>\n <div class=\"flex flex-column\">\n <div>\n <span class=\"copyright\">&#169; {{ commons.appOwner() | translate }} - {{ currentYear() }}</span>\n </div>\n @if (versionComponent()) {\n <div class=\"version\" [mngComponent]=\"versionComponent()\" [inputs]=\"{version: commons.appVersion()}\" [attachToHost]=\"true\"></div>\n }\n </div>\n</div>\n", dependencies: [{ kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i1$1.TranslatePipe, name: "translate" }, { kind: "directive", type: ComponentDirective, selector: "[mngComponent]", inputs: ["mngComponent", "injectionToken", "inputs", "attachToHost", "parentInjector"], outputs: ["instanceCreated"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
137
155
  }
138
156
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.5", ngImport: i0, type: FooterComponent, decorators: [{
139
157
  type: Component,
140
- args: [{ standalone: true, selector: 'mng-footer', imports: [TranslateModule, NgOptimizedImage, VersionComponent, ComponentDirective], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"layout-footer\">\n <div class=\"footer-logo-container\">\n <img id=\"footer-logo\" [src]=\"commons.appLogo()\" alt=\"atlantis-layout\" />\n <span class=\"app-name\">{{ commons.appName() | translate }}</span>\n </div>\n <div class=\"flex flex-column\">\n <div>\n <span class=\"copyright\">&#169; {{ commons.appOwner() | translate }} - {{ currentYear }}</span>\n </div>\n @if (versionComponent) {\n <div class=\"version\" [mngComponent]=\"versionComponent\" [inputs]=\"{version: commons.appVersion()}\" [attachToHost]=\"true\"></div>\n }\n </div>\n</div>\n" }]
158
+ args: [{ standalone: true, selector: 'mng-footer', imports: [TranslateModule, NgOptimizedImage, VersionComponent, ComponentDirective], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"layout-footer\">\n <div class=\"footer-logo-container\">\n <img id=\"footer-logo\" [src]=\"commons.appLogo()\" alt=\"atlantis-layout\" />\n <span class=\"app-name\">{{ commons.appName() | translate }}</span>\n </div>\n <div class=\"flex flex-column\">\n <div>\n <span class=\"copyright\">&#169; {{ commons.appOwner() | translate }} - {{ currentYear() }}</span>\n </div>\n @if (versionComponent()) {\n <div class=\"version\" [mngComponent]=\"versionComponent()\" [inputs]=\"{version: commons.appVersion()}\" [attachToHost]=\"true\"></div>\n }\n </div>\n</div>\n" }]
141
159
  }] });
142
160
 
143
161
  class BreadcrumbComponent {
@@ -157,11 +175,11 @@ class BreadcrumbComponent {
157
175
  };
158
176
  }
159
177
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.5", ngImport: i0, type: BreadcrumbComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
160
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.0.5", type: BreadcrumbComponent, isStandalone: true, selector: "mng-breadcrumb", ngImport: i0, template: "<div class=\"layout-breadcrumb flex align-items-center relative h-3rem\">\n <nav>\n <ol class=\"relative z-2\">\n @for (item of mappedBreadcrumbs(); track item; let last = $last) {\n <li>{{ item.label! | translate }}</li>\n @if (!last) {\n <li class=\"layout-breadcrumb-chevron\">/</li>\n }\n }\n </ol>\n </nav>\n</div>\n", dependencies: [{ kind: "ngmodule", type: InputTextModule }, { kind: "ngmodule", type: ButtonModule }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i1$1.TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
178
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.0.5", type: BreadcrumbComponent, isStandalone: true, selector: "mng-breadcrumb", ngImport: i0, template: "<div class=\"layout-breadcrumb flex align-items-center relative h-3rem\">\n <nav>\n <ol class=\"relative z-2\">\n @for (item of mappedBreadcrumbs(); track item.id; let last = $last) {\n <li>{{ item.label! | translate }}</li>\n @if (!last) {\n <li class=\"layout-breadcrumb-chevron\">/</li>\n }\n }\n </ol>\n </nav>\n</div>\n", dependencies: [{ kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i1$1.TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
161
179
  }
162
180
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.5", ngImport: i0, type: BreadcrumbComponent, decorators: [{
163
181
  type: Component,
164
- args: [{ standalone: true, selector: 'mng-breadcrumb', imports: [NgClass, InputTextModule, ButtonModule, AsyncPipe, TranslateModule], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"layout-breadcrumb flex align-items-center relative h-3rem\">\n <nav>\n <ol class=\"relative z-2\">\n @for (item of mappedBreadcrumbs(); track item; let last = $last) {\n <li>{{ item.label! | translate }}</li>\n @if (!last) {\n <li class=\"layout-breadcrumb-chevron\">/</li>\n }\n }\n </ol>\n </nav>\n</div>\n" }]
182
+ args: [{ standalone: true, selector: 'mng-breadcrumb', imports: [TranslateModule], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"layout-breadcrumb flex align-items-center relative h-3rem\">\n <nav>\n <ol class=\"relative z-2\">\n @for (item of mappedBreadcrumbs(); track item.id; let last = $last) {\n <li>{{ item.label! | translate }}</li>\n @if (!last) {\n <li class=\"layout-breadcrumb-chevron\">/</li>\n }\n }\n </ol>\n </nav>\n</div>\n" }]
165
183
  }] });
166
184
 
167
185
  class MainLayoutComponentService {
@@ -353,12 +371,10 @@ class MenuItemComponent {
353
371
  this.router = inject(Router);
354
372
  this.injector = inject(Injector);
355
373
  this.destroyRef = inject(DestroyRef);
356
- this.route = inject(ActivatedRoute);
357
374
  this.menuService = inject(MenuService);
358
- this.authorization = inject(PermissionService);
375
+ this.permissionService = inject(PermissionService);
359
376
  this.layoutService = inject(MainLayoutComponentService);
360
377
  this.isPermitted = signal(true);
361
- this.guardsIsAllowed = signal(true);
362
378
  this.childrenVisibilitySubject = [];
363
379
  this.root = false;
364
380
  this.visibleChangeEventEmitter = new EventEmitter();
@@ -372,8 +388,18 @@ class MenuItemComponent {
372
388
  this.menuService.resetSource$.pipe(takeUntilDestroyed()).subscribe(() => {
373
389
  this.active.set(false);
374
390
  });
391
+ this.router.events.pipe(takeUntilDestroyed()).subscribe(next => {
392
+ if (next instanceof NavigationEnd) {
393
+ if (!this.layoutService.isMobile()) {
394
+ this.active.set(false);
395
+ }
396
+ else {
397
+ this.updateActiveStateFromRoute();
398
+ }
399
+ }
400
+ });
375
401
  effect(() => {
376
- if (this.isPermitted() && this.guardsIsAllowed()) {
402
+ if (this.isPermitted()) {
377
403
  this.active.set(false);
378
404
  this.visible.set(true);
379
405
  }
@@ -392,30 +418,7 @@ class MenuItemComponent {
392
418
  this.itemUrl = this.router.parseUrl(this.item.routerLink.join('/'));
393
419
  }
394
420
  }
395
- this.routerEventsSubscription = this.router.events.subscribe(next => {
396
- if (next instanceof GuardsCheckEnd && next.shouldActivate) {
397
- this.checkIfMenuItemIsAllowedFromGuard(next.state);
398
- }
399
- else if (next instanceof NavigationEnd) {
400
- if (!this.layoutService.isMobile()) {
401
- this.active.set(false);
402
- }
403
- else {
404
- this.updateActiveStateFromRoute();
405
- }
406
- }
407
- });
408
- if (this.item.permissions) {
409
- this.authorization
410
- .isPermitted(this.item.permissions)
411
- .pipe(takeUntilDestroyed(this.destroyRef))
412
- .subscribe({
413
- next: isPermitted => {
414
- this.isPermitted.set(isPermitted);
415
- }
416
- });
417
- }
418
- this.checkIfMenuItemIsAllowedFromGuard(this.router.routerState.snapshot);
421
+ this.processItemVisibility();
419
422
  this.processItemChildrenVisibility();
420
423
  }
421
424
  ngAfterViewChecked() {
@@ -424,8 +427,7 @@ class MenuItemComponent {
424
427
  }
425
428
  }
426
429
  ngOnDestroy() {
427
- this.routerEventsSubscription?.unsubscribe();
428
- this.guardsIsAllowedSubscription?.unsubscribe();
430
+ this.isVisibleSubscription?.unsubscribe();
429
431
  }
430
432
  get submenuAnimation() {
431
433
  if (this.layoutService.isDesktop() && (this.layoutService.isSlim() || this.layoutService.isSlimPlus())) {
@@ -490,39 +492,29 @@ class MenuItemComponent {
490
492
  }
491
493
  }
492
494
  }
493
- checkIfMenuItemIsAllowedFromGuard(routerState) {
494
- this.guardsIsAllowedSubscription?.unsubscribe();
495
- if (this.item.guards?.length) {
496
- const obs = [];
497
- for (const guard of this.item.guards) {
498
- if (guard && typeof guard === 'function') {
499
- const guardFnInstance = guard;
500
- runInInjectionContext(this.injector, () => {
501
- const canActivateRes = guardFnInstance(this.route.snapshot, routerState);
502
- let canActivateObs;
503
- if (canActivateRes instanceof Observable) {
504
- canActivateObs = canActivateRes;
505
- }
506
- else if (canActivateRes instanceof Promise) {
507
- canActivateObs = from(canActivateRes);
508
- }
509
- else {
510
- canActivateObs = of(canActivateRes);
511
- }
512
- obs.push(canActivateObs.pipe(first(), map(res => res === true) // if url tree is present, that means redirect and implies not allowed
513
- ));
514
- });
495
+ processItemVisibility() {
496
+ if (this.item.permissions) {
497
+ this.permissionService
498
+ .isMenuItemVisible(this.item.permissions, this.item)
499
+ .pipe(takeUntilDestroyed(this.destroyRef))
500
+ .subscribe({
501
+ next: isPermitted => {
502
+ this.isPermitted.set(isPermitted);
515
503
  }
516
- }
517
- this.guardsIsAllowedSubscription = combineLatest(obs)
518
- .pipe(first())
519
- .subscribe(next => {
520
- const result = next.every(n => n === true);
521
- this.guardsIsAllowed.set(result);
522
504
  });
523
505
  }
524
- else {
525
- this.guardsIsAllowed.set(true);
506
+ if (this.item.isVisible && typeof this.item.isVisible === 'function') {
507
+ let isVisibleObs;
508
+ runInInjectionContext(this.injector, () => {
509
+ const isVisibleRes = this.item.isVisible(this.item);
510
+ if (isVisibleRes instanceof Observable) {
511
+ isVisibleObs = isVisibleRes;
512
+ }
513
+ else {
514
+ isVisibleObs = of(isVisibleRes);
515
+ }
516
+ });
517
+ this.isVisibleSubscription = isVisibleObs?.subscribe(isVisible => this.isPermitted.set(isVisible));
526
518
  }
527
519
  }
528
520
  updateActiveStateFromRoute() {
@@ -550,7 +542,7 @@ class MenuItemComponent {
550
542
  }
551
543
  }
552
544
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.5", ngImport: i0, type: MenuItemComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
553
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.0.5", type: MenuItemComponent, isStandalone: true, selector: "[mng-menuitem]", inputs: { item: "item", root: "root" }, outputs: { visibleChangeEventEmitter: "visibleChange" }, host: { properties: { "class.layout-root-menuitem": "this.root", "class.active-menuitem": "this.activeClass" } }, viewQueries: [{ propertyName: "submenu", first: true, predicate: ["submenu"], descendants: true }], ngImport: i0, template: "@if (visible()) {\n @if (root) {\n <div class=\"layout-menuitem-root-text\">\n {{ item.label! | translate }}\n </div>\n }\n @if (!item.href) {\n @if (!item.routerLink || item.items) {\n <a\n [attr.href]=\"item.href\"\n (click)=\"itemClick($event)\"\n (keydown.enter)=\"itemClick($event)\"\n [routerLink]=\"item.routerLink\"\n [attr.target]=\"item.target\"\n [attr.tabindex]=\"0\"\n [ngClass]=\"item.className ?? ''\"\n pRipple>\n <i [ngClass]=\"item.icon ?? ''\" class=\"layout-menuitem-icon\"></i>\n <span class=\"layout-menuitem-text\">{{ item.label! | translate }}</span>\n @if (item.items || item.lazyChildren) {\n <i class=\"pi pi-fw pi-angle-down layout-submenu-toggler\"></i>\n }\n @if (item.badge) {\n <span class=\"menuitem-badge\">{{ item.badge }}</span>\n }\n </a>\n } @else if (item.routerLink && !item.items) {\n <a\n (click)=\"itemClick($event)\"\n [routerLink]=\"item.routerLink\"\n [attr.target]=\"item.target\"\n [attr.tabindex]=\"0\"\n [ngClass]=\"item.className ?? '' + (this.active() ? ' active-route' : '')\"\n [preserveFragment]=\"item.preserveFragment\"\n [skipLocationChange]=\"item.skipLocationChange\"\n [replaceUrl]=\"item.replaceUrl\"\n [queryParams]=\"item.queryParams\"\n pRipple>\n <i [ngClass]=\"item.icon ?? ''\" class=\"layout-menuitem-icon\"></i>\n <span class=\"layout-menuitem-text\">{{ item.label! | translate }}</span>\n @if (item.items || item.lazyChildren) {\n <i class=\"pi pi-fw pi-angle-down layout-submenu-toggler\"></i>\n }\n @if (item.badge) {\n <span class=\"menuitem-badge\">{{ item.badge }}</span>\n }\n </a>\n }\n } @else {\n @if (!item.items) {\n <a (click)=\"itemClick($event)\" [attr.href]=\"item.href\" [attr.target]=\"item.target\" [attr.tabindex]=\"0\" [ngClass]=\"item.className ?? ''\" pRipple>\n <i [ngClass]=\"item.icon ?? ''\" class=\"layout-menuitem-icon\"></i>\n <span class=\"layout-menuitem-text\">{{ item.label! | translate }}</span>\n @if (item.items || item.lazyChildren) {\n <i class=\"pi pi-fw pi-angle-down layout-submenu-toggler\"></i>\n }\n @if (item.badge) {\n <span class=\"menuitem-badge\">{{ item.badge }}</span>\n }\n </a>\n }\n }\n @if (item.items) {\n <ul #submenu [@children]=\"submenuAnimation\" (@children.done)=\"onSubmenuAnimated($event)\">\n @for (child of item.items; track child; let i = $index) {\n <li mng-menuitem [item]=\"child\" [class]=\"child.badgeClassName\" (visibleChange)=\"onChildVisibleChange($event, item, i)\"></li>\n }\n </ul>\n }\n}\n", dependencies: [{ kind: "component", type: MenuItemComponent, selector: "[mng-menuitem]", inputs: ["item", "root"], outputs: ["visibleChange"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: RippleModule }, { kind: "directive", type: i1$2.Ripple, selector: "[pRipple]" }, { kind: "ngmodule", type: TooltipModule }, { kind: "ngmodule", type: RouterModule }, { kind: "directive", type: i1$3.RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i1$1.TranslatePipe, name: "translate" }], animations: [
545
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.0.5", type: MenuItemComponent, isStandalone: true, selector: "[mng-menuitem]", inputs: { item: "item", root: "root" }, outputs: { visibleChangeEventEmitter: "visibleChange" }, host: { properties: { "class.layout-root-menuitem": "this.root", "class.active-menuitem": "this.activeClass" } }, providers: [PermissionService], viewQueries: [{ propertyName: "submenu", first: true, predicate: ["submenu"], descendants: true }], ngImport: i0, template: "@if (visible()) {\n @if (root) {\n <div class=\"layout-menuitem-root-text\">\n {{ item.label! | translate }}\n </div>\n }\n @if (!item.href) {\n @if (!item.routerLink || item.items) {\n <a\n [attr.href]=\"item.href\"\n (click)=\"itemClick($event)\"\n (keydown.enter)=\"itemClick($event)\"\n [routerLink]=\"item.routerLink\"\n [attr.target]=\"item.target\"\n [attr.tabindex]=\"0\"\n [ngClass]=\"item.className ?? ''\"\n pRipple>\n <i [ngClass]=\"item.icon ?? ''\" class=\"layout-menuitem-icon\"></i>\n <span class=\"layout-menuitem-text\">{{ item.label! | translate }}</span>\n @if (item.items || item.lazyChildren) {\n <i class=\"pi pi-fw pi-angle-down layout-submenu-toggler\"></i>\n }\n @if (item.badge) {\n <span class=\"menuitem-badge\">{{ item.badge }}</span>\n }\n </a>\n } @else if (item.routerLink && !item.items) {\n <a\n (click)=\"itemClick($event)\"\n [routerLink]=\"item.routerLink\"\n [attr.target]=\"item.target\"\n [attr.tabindex]=\"0\"\n [ngClass]=\"item.className ?? '' + (this.active() ? ' active-route' : '')\"\n [preserveFragment]=\"item.preserveFragment\"\n [skipLocationChange]=\"item.skipLocationChange\"\n [replaceUrl]=\"item.replaceUrl\"\n [queryParams]=\"item.queryParams\"\n pRipple>\n <i [ngClass]=\"item.icon ?? ''\" class=\"layout-menuitem-icon\"></i>\n <span class=\"layout-menuitem-text\">{{ item.label! | translate }}</span>\n @if (item.items || item.lazyChildren) {\n <i class=\"pi pi-fw pi-angle-down layout-submenu-toggler\"></i>\n }\n @if (item.badge) {\n <span class=\"menuitem-badge\">{{ item.badge }}</span>\n }\n </a>\n }\n } @else {\n @if (!item.items) {\n <a (click)=\"itemClick($event)\" [attr.href]=\"item.href\" [attr.target]=\"item.target\" [attr.tabindex]=\"0\" [ngClass]=\"item.className ?? ''\" pRipple>\n <i [ngClass]=\"item.icon ?? ''\" class=\"layout-menuitem-icon\"></i>\n <span class=\"layout-menuitem-text\">{{ item.label! | translate }}</span>\n @if (item.items || item.lazyChildren) {\n <i class=\"pi pi-fw pi-angle-down layout-submenu-toggler\"></i>\n }\n @if (item.badge) {\n <span class=\"menuitem-badge\">{{ item.badge }}</span>\n }\n </a>\n }\n }\n @if (item.items) {\n <ul #submenu [@children]=\"submenuAnimation\" (@children.done)=\"onSubmenuAnimated($event)\">\n @for (child of item.items; track child; let i = $index) {\n <li mng-menuitem [item]=\"child\" [class]=\"child.badgeClassName\" (visibleChange)=\"onChildVisibleChange($event, item, i)\"></li>\n }\n </ul>\n }\n}\n", dependencies: [{ kind: "component", type: MenuItemComponent, selector: "[mng-menuitem]", inputs: ["item", "root"], outputs: ["visibleChange"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: RippleModule }, { kind: "directive", type: i1$2.Ripple, selector: "[pRipple]" }, { kind: "ngmodule", type: TooltipModule }, { kind: "ngmodule", type: RouterModule }, { kind: "directive", type: i1$3.RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i1$1.TranslatePipe, name: "translate" }], animations: [
554
546
  trigger('children', [
555
547
  state('collapsed', style({
556
548
  height: '0'
@@ -586,7 +578,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.5", ngImpor
586
578
  })),
587
579
  transition('collapsed <=> expanded', animate('400ms cubic-bezier(0.86, 0, 0.07, 1)'))
588
580
  ])
589
- ], template: "@if (visible()) {\n @if (root) {\n <div class=\"layout-menuitem-root-text\">\n {{ item.label! | translate }}\n </div>\n }\n @if (!item.href) {\n @if (!item.routerLink || item.items) {\n <a\n [attr.href]=\"item.href\"\n (click)=\"itemClick($event)\"\n (keydown.enter)=\"itemClick($event)\"\n [routerLink]=\"item.routerLink\"\n [attr.target]=\"item.target\"\n [attr.tabindex]=\"0\"\n [ngClass]=\"item.className ?? ''\"\n pRipple>\n <i [ngClass]=\"item.icon ?? ''\" class=\"layout-menuitem-icon\"></i>\n <span class=\"layout-menuitem-text\">{{ item.label! | translate }}</span>\n @if (item.items || item.lazyChildren) {\n <i class=\"pi pi-fw pi-angle-down layout-submenu-toggler\"></i>\n }\n @if (item.badge) {\n <span class=\"menuitem-badge\">{{ item.badge }}</span>\n }\n </a>\n } @else if (item.routerLink && !item.items) {\n <a\n (click)=\"itemClick($event)\"\n [routerLink]=\"item.routerLink\"\n [attr.target]=\"item.target\"\n [attr.tabindex]=\"0\"\n [ngClass]=\"item.className ?? '' + (this.active() ? ' active-route' : '')\"\n [preserveFragment]=\"item.preserveFragment\"\n [skipLocationChange]=\"item.skipLocationChange\"\n [replaceUrl]=\"item.replaceUrl\"\n [queryParams]=\"item.queryParams\"\n pRipple>\n <i [ngClass]=\"item.icon ?? ''\" class=\"layout-menuitem-icon\"></i>\n <span class=\"layout-menuitem-text\">{{ item.label! | translate }}</span>\n @if (item.items || item.lazyChildren) {\n <i class=\"pi pi-fw pi-angle-down layout-submenu-toggler\"></i>\n }\n @if (item.badge) {\n <span class=\"menuitem-badge\">{{ item.badge }}</span>\n }\n </a>\n }\n } @else {\n @if (!item.items) {\n <a (click)=\"itemClick($event)\" [attr.href]=\"item.href\" [attr.target]=\"item.target\" [attr.tabindex]=\"0\" [ngClass]=\"item.className ?? ''\" pRipple>\n <i [ngClass]=\"item.icon ?? ''\" class=\"layout-menuitem-icon\"></i>\n <span class=\"layout-menuitem-text\">{{ item.label! | translate }}</span>\n @if (item.items || item.lazyChildren) {\n <i class=\"pi pi-fw pi-angle-down layout-submenu-toggler\"></i>\n }\n @if (item.badge) {\n <span class=\"menuitem-badge\">{{ item.badge }}</span>\n }\n </a>\n }\n }\n @if (item.items) {\n <ul #submenu [@children]=\"submenuAnimation\" (@children.done)=\"onSubmenuAnimated($event)\">\n @for (child of item.items; track child; let i = $index) {\n <li mng-menuitem [item]=\"child\" [class]=\"child.badgeClassName\" (visibleChange)=\"onChildVisibleChange($event, item, i)\"></li>\n }\n </ul>\n }\n}\n" }]
581
+ ], providers: [PermissionService], template: "@if (visible()) {\n @if (root) {\n <div class=\"layout-menuitem-root-text\">\n {{ item.label! | translate }}\n </div>\n }\n @if (!item.href) {\n @if (!item.routerLink || item.items) {\n <a\n [attr.href]=\"item.href\"\n (click)=\"itemClick($event)\"\n (keydown.enter)=\"itemClick($event)\"\n [routerLink]=\"item.routerLink\"\n [attr.target]=\"item.target\"\n [attr.tabindex]=\"0\"\n [ngClass]=\"item.className ?? ''\"\n pRipple>\n <i [ngClass]=\"item.icon ?? ''\" class=\"layout-menuitem-icon\"></i>\n <span class=\"layout-menuitem-text\">{{ item.label! | translate }}</span>\n @if (item.items || item.lazyChildren) {\n <i class=\"pi pi-fw pi-angle-down layout-submenu-toggler\"></i>\n }\n @if (item.badge) {\n <span class=\"menuitem-badge\">{{ item.badge }}</span>\n }\n </a>\n } @else if (item.routerLink && !item.items) {\n <a\n (click)=\"itemClick($event)\"\n [routerLink]=\"item.routerLink\"\n [attr.target]=\"item.target\"\n [attr.tabindex]=\"0\"\n [ngClass]=\"item.className ?? '' + (this.active() ? ' active-route' : '')\"\n [preserveFragment]=\"item.preserveFragment\"\n [skipLocationChange]=\"item.skipLocationChange\"\n [replaceUrl]=\"item.replaceUrl\"\n [queryParams]=\"item.queryParams\"\n pRipple>\n <i [ngClass]=\"item.icon ?? ''\" class=\"layout-menuitem-icon\"></i>\n <span class=\"layout-menuitem-text\">{{ item.label! | translate }}</span>\n @if (item.items || item.lazyChildren) {\n <i class=\"pi pi-fw pi-angle-down layout-submenu-toggler\"></i>\n }\n @if (item.badge) {\n <span class=\"menuitem-badge\">{{ item.badge }}</span>\n }\n </a>\n }\n } @else {\n @if (!item.items) {\n <a (click)=\"itemClick($event)\" [attr.href]=\"item.href\" [attr.target]=\"item.target\" [attr.tabindex]=\"0\" [ngClass]=\"item.className ?? ''\" pRipple>\n <i [ngClass]=\"item.icon ?? ''\" class=\"layout-menuitem-icon\"></i>\n <span class=\"layout-menuitem-text\">{{ item.label! | translate }}</span>\n @if (item.items || item.lazyChildren) {\n <i class=\"pi pi-fw pi-angle-down layout-submenu-toggler\"></i>\n }\n @if (item.badge) {\n <span class=\"menuitem-badge\">{{ item.badge }}</span>\n }\n </a>\n }\n }\n @if (item.items) {\n <ul #submenu [@children]=\"submenuAnimation\" (@children.done)=\"onSubmenuAnimated($event)\">\n @for (child of item.items; track child; let i = $index) {\n <li mng-menuitem [item]=\"child\" [class]=\"child.badgeClassName\" (visibleChange)=\"onChildVisibleChange($event, item, i)\"></li>\n }\n </ul>\n }\n}\n" }]
590
582
  }], ctorParameters: () => [], propDecorators: { item: [{
591
583
  type: Input,
592
584
  args: [{ required: true }]
@@ -612,32 +604,32 @@ class MenuComponent {
612
604
  this.menuService = inject(MenuService);
613
605
  this.config = inject(COMMONS_LAYOUT_FEATURE_CONFIG_IT, { optional: true });
614
606
  this.layoutService = inject(MainLayoutComponentService);
615
- this.menuItems = [];
616
- }
617
- ngOnInit() {
618
- if (this.config?.menuItems && Array.isArray(this.config.menuItems)) {
619
- this.menuItems = this.wrapMenuItems(this.config.menuItems);
620
- }
621
- else if (Array.isArray(this.route.snapshot.data?.menuItems)) {
622
- this.menuItems = this.wrapMenuItems(this.route.snapshot.data.menuItems);
623
- }
624
- this.menuService.initialize(this.menuItems);
625
- }
626
- wrapMenuItems(menuItems) {
627
- if (this.layoutService.isSlim() || this.layoutService.isSlimPlus()) {
628
- return menuItems;
629
- }
630
- else {
631
- return [{ items: menuItems }];
632
- }
607
+ this.routeData = toSignal(this.route.data);
608
+ this.menuItems = computed(() => {
609
+ let items = [];
610
+ if (this.config?.menuItems && Array.isArray(this.config.menuItems)) {
611
+ items = this.config.menuItems;
612
+ }
613
+ else if (Array.isArray(this.routeData()?.menuItems)) {
614
+ items = this.routeData().menuItems;
615
+ }
616
+ // Wraps menu items
617
+ if (!(this.layoutService.isSlim() || this.layoutService.isSlimPlus())) {
618
+ items = [{ items }];
619
+ }
620
+ return items;
621
+ });
622
+ effect(() => {
623
+ this.menuService.initialize(this.menuItems());
624
+ });
633
625
  }
634
626
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.5", ngImport: i0, type: MenuComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
635
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.0.5", type: MenuComponent, isStandalone: true, selector: "mng-menu", ngImport: i0, template: "<ul class=\"layout-menu\">\n @for (item of menuItems; track item) {\n @if (!item.separator) {\n <li mng-menuitem [item]=\"item\" [root]=\"true\"></li>\n }\n @if (item.separator) {\n <li class=\"menu-separator\"></li>\n }\n }\n</ul>\n", dependencies: [{ kind: "component", type: MenuItemComponent, selector: "[mng-menuitem]", inputs: ["item", "root"], outputs: ["visibleChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
627
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.0.5", type: MenuComponent, isStandalone: true, selector: "mng-menu", ngImport: i0, template: "<ul class=\"layout-menu\">\n @for (item of menuItems(); track item) {\n @if (!item.separator) {\n <li mng-menuitem [item]=\"item\" [root]=\"true\"></li>\n }\n @if (item.separator) {\n <li class=\"menu-separator\"></li>\n }\n }\n</ul>\n", dependencies: [{ kind: "component", type: MenuItemComponent, selector: "[mng-menuitem]", inputs: ["item", "root"], outputs: ["visibleChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
636
628
  }
637
629
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.5", ngImport: i0, type: MenuComponent, decorators: [{
638
630
  type: Component,
639
- args: [{ standalone: true, selector: 'mng-menu', imports: [MenuItemComponent], changeDetection: ChangeDetectionStrategy.OnPush, template: "<ul class=\"layout-menu\">\n @for (item of menuItems; track item) {\n @if (!item.separator) {\n <li mng-menuitem [item]=\"item\" [root]=\"true\"></li>\n }\n @if (item.separator) {\n <li class=\"menu-separator\"></li>\n }\n }\n</ul>\n" }]
640
- }] });
631
+ args: [{ standalone: true, selector: 'mng-menu', imports: [MenuItemComponent], changeDetection: ChangeDetectionStrategy.OnPush, template: "<ul class=\"layout-menu\">\n @for (item of menuItems(); track item) {\n @if (!item.separator) {\n <li mng-menuitem [item]=\"item\" [root]=\"true\"></li>\n }\n @if (item.separator) {\n <li class=\"menu-separator\"></li>\n }\n }\n</ul>\n" }]
632
+ }], ctorParameters: () => [] });
641
633
 
642
634
  class SidebarComponent {
643
635
  constructor() {
@@ -645,13 +637,8 @@ class SidebarComponent {
645
637
  this.commons = inject(CommonsService);
646
638
  this.layoutService = inject(MainLayoutComponentService);
647
639
  this.el = inject(ElementRef);
640
+ this.menuComponent = signal(this.config?.components?.menu === false ? undefined : this.config?.components?.menu ?? MenuComponent);
648
641
  this.timeout = null;
649
- this.menuComponent = MenuComponent;
650
- }
651
- ngOnInit() {
652
- if (this.config?.components?.menu !== undefined) {
653
- this.menuComponent = this.config.components.menu;
654
- }
655
642
  }
656
643
  onMouseEnter() {
657
644
  if (!this.layoutService.state().anchored) {
@@ -682,23 +669,19 @@ class SidebarComponent {
682
669
  }));
683
670
  }
684
671
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.5", ngImport: i0, type: SidebarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
685
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.0.5", type: SidebarComponent, isStandalone: true, selector: "mng-sidebar", viewQueries: [{ propertyName: "menuContainer", first: true, predicate: ["menuContainer"], descendants: true }], ngImport: i0, template: "<div class=\"layout-sidebar\" (mouseenter)=\"onMouseEnter()\" (mouseleave)=\"onMouseLeave()\">\n <div class=\"sidebar-header\">\n <a [routerLink]=\"['/']\" class=\"app-logo\">\n <div class=\"app-logo-small h-2rem\">\n <img [src]=\"commons.appLogo()\" [alt]=\"'App logo'\" />\n </div>\n <div class=\"app-logo-normal\">\n <img class=\"h-2rem\" [src]=\"commons.appLogo()\" [alt]=\"'App logo'\" />\n <img class=\"h-2rem ml-3\" [src]=\"commons.appLogoName()\" [alt]=\"'App name'\" />\n </div>\n </a>\n <button class=\"layout-sidebar-anchor p-link z-2\" type=\"button\" (click)=\"anchor()\"></button>\n </div>\n\n @if (menuComponent) {\n <div #menuContainer class=\"layout-menu-container\">\n <div [mngComponent]=\"menuComponent\" [attachToHost]=\"true\"></div>\n </div>\n }\n</div>\n", dependencies: [{ kind: "ngmodule", type: RouterModule }, { kind: "directive", type: i1$3.RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "directive", type: ComponentDirective, selector: "[mngComponent]", inputs: ["mngComponent", "injectionToken", "inputs", "attachToHost", "parentInjector"], outputs: ["instanceCreated"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
672
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.0.5", type: SidebarComponent, isStandalone: true, selector: "mng-sidebar", ngImport: i0, template: "<div class=\"layout-sidebar\" (mouseenter)=\"onMouseEnter()\" (mouseleave)=\"onMouseLeave()\">\n <div class=\"sidebar-header\">\n <a [routerLink]=\"['/']\" class=\"app-logo\">\n <div class=\"app-logo-small h-2rem\">\n <img [src]=\"commons.appLogo()\" [alt]=\"'App logo'\" />\n </div>\n <div class=\"app-logo-normal\">\n <img class=\"h-2rem\" [src]=\"commons.appLogo()\" [alt]=\"'App logo'\" />\n <img class=\"h-2rem ml-3\" [src]=\"commons.appLogoName()\" [alt]=\"'App name'\" />\n </div>\n </a>\n <button class=\"layout-sidebar-anchor p-link z-2\" type=\"button\" (click)=\"anchor()\"></button>\n </div>\n\n @if (menuComponent()) {\n <div #menuContainer class=\"layout-menu-container\">\n <div [mngComponent]=\"menuComponent()\" [attachToHost]=\"true\"></div>\n </div>\n }\n</div>\n", dependencies: [{ kind: "ngmodule", type: RouterModule }, { kind: "directive", type: i1$3.RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "directive", type: ComponentDirective, selector: "[mngComponent]", inputs: ["mngComponent", "injectionToken", "inputs", "attachToHost", "parentInjector"], outputs: ["instanceCreated"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
686
673
  }
687
674
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.5", ngImport: i0, type: SidebarComponent, decorators: [{
688
675
  type: Component,
689
- args: [{ standalone: true, selector: 'mng-sidebar', imports: [RouterModule, MenuComponent, ComponentDirective], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"layout-sidebar\" (mouseenter)=\"onMouseEnter()\" (mouseleave)=\"onMouseLeave()\">\n <div class=\"sidebar-header\">\n <a [routerLink]=\"['/']\" class=\"app-logo\">\n <div class=\"app-logo-small h-2rem\">\n <img [src]=\"commons.appLogo()\" [alt]=\"'App logo'\" />\n </div>\n <div class=\"app-logo-normal\">\n <img class=\"h-2rem\" [src]=\"commons.appLogo()\" [alt]=\"'App logo'\" />\n <img class=\"h-2rem ml-3\" [src]=\"commons.appLogoName()\" [alt]=\"'App name'\" />\n </div>\n </a>\n <button class=\"layout-sidebar-anchor p-link z-2\" type=\"button\" (click)=\"anchor()\"></button>\n </div>\n\n @if (menuComponent) {\n <div #menuContainer class=\"layout-menu-container\">\n <div [mngComponent]=\"menuComponent\" [attachToHost]=\"true\"></div>\n </div>\n }\n</div>\n" }]
690
- }], propDecorators: { menuContainer: [{
691
- type: ViewChild,
692
- args: ['menuContainer']
693
- }] } });
676
+ args: [{ standalone: true, selector: 'mng-sidebar', imports: [RouterModule, MenuComponent, ComponentDirective], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"layout-sidebar\" (mouseenter)=\"onMouseEnter()\" (mouseleave)=\"onMouseLeave()\">\n <div class=\"sidebar-header\">\n <a [routerLink]=\"['/']\" class=\"app-logo\">\n <div class=\"app-logo-small h-2rem\">\n <img [src]=\"commons.appLogo()\" [alt]=\"'App logo'\" />\n </div>\n <div class=\"app-logo-normal\">\n <img class=\"h-2rem\" [src]=\"commons.appLogo()\" [alt]=\"'App logo'\" />\n <img class=\"h-2rem ml-3\" [src]=\"commons.appLogoName()\" [alt]=\"'App name'\" />\n </div>\n </a>\n <button class=\"layout-sidebar-anchor p-link z-2\" type=\"button\" (click)=\"anchor()\"></button>\n </div>\n\n @if (menuComponent()) {\n <div #menuContainer class=\"layout-menu-container\">\n <div [mngComponent]=\"menuComponent()\" [attachToHost]=\"true\"></div>\n </div>\n }\n</div>\n" }]
677
+ }] });
694
678
 
695
679
  class TopbarUserComponent {
696
680
  constructor() {
697
- this.destroyRef = inject(DestroyRef);
698
681
  this.commons = inject(CommonsService);
682
+ this.hrefJsVoid = inject(DomSanitizer).bypassSecurityTrustUrl('javascript:void(0)');
699
683
  this.user = computed(() => this.commons.user());
700
684
  this.userRoles = computed(() => this.commons.userRoles());
701
- this.hrefJsVoid = inject(DomSanitizer).bypassSecurityTrustUrl('javascript:void(0)');
702
685
  }
703
686
  logout(user, event) {
704
687
  if (typeof user?.logout === 'function') {
@@ -721,20 +704,8 @@ class TopbarComponent {
721
704
  this.commons = inject(CommonsService);
722
705
  this.mainLayoutService = inject(MainLayoutComponentService);
723
706
  this.config = inject(COMMONS_LAYOUT_FEATURE_CONFIG_IT, { optional: true });
724
- this.breadcrumbComponent = BreadcrumbComponent;
725
- this.topbarUserComponent = TopbarUserComponent;
726
- this.locales = ['en'];
727
- this.selectedLocale = 'en';
728
- }
729
- ngOnInit() {
730
- if (this.config?.components?.topbarUser !== undefined) {
731
- this.topbarUserComponent = this.config.components.topbarUser;
732
- }
733
- if (this.config?.components?.breadcrumb !== undefined) {
734
- this.breadcrumbComponent = this.config.components.breadcrumb;
735
- }
736
- this.locales = this.commons.appLocales();
737
- this.selectedLocale = this.commons.appLocale();
707
+ this.topbarUserComponent = signal(this.config?.components?.topbarUser === false ? undefined : this.config?.components?.topbarUser ?? TopbarUserComponent);
708
+ this.breadcrumbComponent = signal(this.config?.components?.breadcrumb === false ? undefined : this.config?.components?.breadcrumb ?? BreadcrumbComponent);
738
709
  }
739
710
  onMenuButtonClick() {
740
711
  this.mainLayoutService.onMenuToggle();
@@ -743,37 +714,32 @@ class TopbarComponent {
743
714
  this.commons.setAppLocale(language);
744
715
  }
745
716
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.5", ngImport: i0, type: TopbarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
746
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.0.5", type: TopbarComponent, isStandalone: true, selector: "mng-topbar", viewQueries: [{ propertyName: "menuButton", first: true, predicate: ["menubutton"], descendants: true }, { propertyName: "appSidebar", first: true, predicate: SidebarComponent, descendants: true }], ngImport: i0, template: "<div class=\"layout-topbar\">\n <div class=\"topbar-start\">\n <button #menubutton type=\"button\" class=\"topbar-menubutton p-link p-trigger\" (click)=\"onMenuButtonClick()\">\n <i class=\"pi pi-bars\"></i>\n </button>\n\n @if (breadcrumbComponent) {\n <div class=\"topbar-breadcrumb\">\n <div [mngComponent]=\"breadcrumbComponent\" [attachToHost]=\"true\"></div>\n </div>\n }\n </div>\n <div class=\"layout-topbar-menu-section\">\n <mng-sidebar></mng-sidebar>\n </div>\n <div class=\"topbar-end\">\n <ul class=\"topbar-menu\">\n @if (locales.length > 1) {\n <li class=\"profile-item\">\n <i class=\"pi pi-fw pi-globe\"></i>\n <p-dropdown [ngModel]=\"selectedLocale\" [options]=\"locales\" (onChange)=\"switchLocale($event.value)\"></p-dropdown>\n </li>\n }\n @if (topbarUserComponent) {\n <li #userMenuItem class=\"profile-item topbar-item mr-3\" [mngComponent]=\"topbarUserComponent\" [attachToHost]=\"true\"></li>\n }\n </ul>\n </div>\n</div>\n", dependencies: [{ kind: "component", type: SidebarComponent, selector: "mng-sidebar" }, { kind: "ngmodule", type: ButtonModule }, { kind: "ngmodule", type: StyleClassModule }, { kind: "ngmodule", type: RippleModule }, { kind: "ngmodule", type: DropdownModule }, { kind: "component", type: i1$4.Dropdown, selector: "p-dropdown", inputs: ["id", "scrollHeight", "filter", "name", "style", "panelStyle", "styleClass", "panelStyleClass", "readonly", "required", "editable", "appendTo", "tabindex", "placeholder", "loadingIcon", "filterPlaceholder", "filterLocale", "variant", "inputId", "dataKey", "filterBy", "filterFields", "autofocus", "resetFilterOnHide", "checkmark", "dropdownIcon", "loading", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "autoDisplayFirst", "group", "showClear", "emptyFilterMessage", "emptyMessage", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "overlayOptions", "ariaFilterLabel", "ariaLabel", "ariaLabelledBy", "filterMatchMode", "maxlength", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "focusOnHover", "selectOnFocus", "autoOptionFocus", "autofocusFilter", "disabled", "itemSize", "autoZIndex", "baseZIndex", "showTransitionOptions", "hideTransitionOptions", "filterValue", "options"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }, { kind: "directive", type: ComponentDirective, selector: "[mngComponent]", inputs: ["mngComponent", "injectionToken", "inputs", "attachToHost", "parentInjector"], outputs: ["instanceCreated"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
717
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.0.5", type: TopbarComponent, isStandalone: true, selector: "mng-topbar", ngImport: i0, template: "<div class=\"layout-topbar\">\n <div class=\"topbar-start\">\n <button #menubutton type=\"button\" class=\"topbar-menubutton p-link p-trigger\" (click)=\"onMenuButtonClick()\">\n <i class=\"pi pi-bars\"></i>\n </button>\n\n @if (breadcrumbComponent()) {\n <div class=\"topbar-breadcrumb\">\n <div [mngComponent]=\"breadcrumbComponent()\" [attachToHost]=\"true\"></div>\n </div>\n }\n </div>\n <div class=\"layout-topbar-menu-section\">\n <mng-sidebar></mng-sidebar>\n </div>\n <div class=\"topbar-end\">\n <ul class=\"topbar-menu\">\n @if (commons.appLocales().length > 1) {\n <li class=\"profile-item\">\n <i class=\"pi pi-fw pi-globe\"></i>\n <p-dropdown [ngModel]=\"commons.appLocale()\" [options]=\"commons.appLocales()\" (onChange)=\"switchLocale($event.value)\"></p-dropdown>\n </li>\n }\n @if (topbarUserComponent()) {\n <li #userMenuItem class=\"profile-item topbar-item mr-3\" [mngComponent]=\"topbarUserComponent()\" [attachToHost]=\"true\"></li>\n }\n </ul>\n </div>\n</div>\n", dependencies: [{ kind: "component", type: SidebarComponent, selector: "mng-sidebar" }, { kind: "ngmodule", type: ButtonModule }, { kind: "ngmodule", type: StyleClassModule }, { kind: "ngmodule", type: RippleModule }, { kind: "ngmodule", type: DropdownModule }, { kind: "component", type: i1$4.Dropdown, selector: "p-dropdown", inputs: ["id", "scrollHeight", "filter", "name", "style", "panelStyle", "styleClass", "panelStyleClass", "readonly", "required", "editable", "appendTo", "tabindex", "placeholder", "loadingIcon", "filterPlaceholder", "filterLocale", "variant", "inputId", "dataKey", "filterBy", "filterFields", "autofocus", "resetFilterOnHide", "checkmark", "dropdownIcon", "loading", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "autoDisplayFirst", "group", "showClear", "emptyFilterMessage", "emptyMessage", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "overlayOptions", "ariaFilterLabel", "ariaLabel", "ariaLabelledBy", "filterMatchMode", "maxlength", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "focusOnHover", "selectOnFocus", "autoOptionFocus", "autofocusFilter", "disabled", "itemSize", "autoZIndex", "baseZIndex", "showTransitionOptions", "hideTransitionOptions", "filterValue", "options"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }, { kind: "directive", type: ComponentDirective, selector: "[mngComponent]", inputs: ["mngComponent", "injectionToken", "inputs", "attachToHost", "parentInjector"], outputs: ["instanceCreated"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
747
718
  }
748
719
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.5", ngImport: i0, type: TopbarComponent, decorators: [{
749
720
  type: Component,
750
- args: [{ standalone: true, selector: 'mng-topbar', imports: [SidebarComponent, NgClass, ButtonModule, StyleClassModule, RippleModule, BreadcrumbComponent, AsyncPipe, DropdownModule, ComponentDirective, FormsModule], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"layout-topbar\">\n <div class=\"topbar-start\">\n <button #menubutton type=\"button\" class=\"topbar-menubutton p-link p-trigger\" (click)=\"onMenuButtonClick()\">\n <i class=\"pi pi-bars\"></i>\n </button>\n\n @if (breadcrumbComponent) {\n <div class=\"topbar-breadcrumb\">\n <div [mngComponent]=\"breadcrumbComponent\" [attachToHost]=\"true\"></div>\n </div>\n }\n </div>\n <div class=\"layout-topbar-menu-section\">\n <mng-sidebar></mng-sidebar>\n </div>\n <div class=\"topbar-end\">\n <ul class=\"topbar-menu\">\n @if (locales.length > 1) {\n <li class=\"profile-item\">\n <i class=\"pi pi-fw pi-globe\"></i>\n <p-dropdown [ngModel]=\"selectedLocale\" [options]=\"locales\" (onChange)=\"switchLocale($event.value)\"></p-dropdown>\n </li>\n }\n @if (topbarUserComponent) {\n <li #userMenuItem class=\"profile-item topbar-item mr-3\" [mngComponent]=\"topbarUserComponent\" [attachToHost]=\"true\"></li>\n }\n </ul>\n </div>\n</div>\n" }]
751
- }], propDecorators: { menuButton: [{
752
- type: ViewChild,
753
- args: ['menubutton']
754
- }], appSidebar: [{
755
- type: ViewChild,
756
- args: [SidebarComponent]
757
- }] } });
721
+ args: [{ standalone: true, selector: 'mng-topbar', imports: [SidebarComponent, NgClass, ButtonModule, StyleClassModule, RippleModule, BreadcrumbComponent, AsyncPipe, DropdownModule, ComponentDirective, FormsModule], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"layout-topbar\">\n <div class=\"topbar-start\">\n <button #menubutton type=\"button\" class=\"topbar-menubutton p-link p-trigger\" (click)=\"onMenuButtonClick()\">\n <i class=\"pi pi-bars\"></i>\n </button>\n\n @if (breadcrumbComponent()) {\n <div class=\"topbar-breadcrumb\">\n <div [mngComponent]=\"breadcrumbComponent()\" [attachToHost]=\"true\"></div>\n </div>\n }\n </div>\n <div class=\"layout-topbar-menu-section\">\n <mng-sidebar></mng-sidebar>\n </div>\n <div class=\"topbar-end\">\n <ul class=\"topbar-menu\">\n @if (commons.appLocales().length > 1) {\n <li class=\"profile-item\">\n <i class=\"pi pi-fw pi-globe\"></i>\n <p-dropdown [ngModel]=\"commons.appLocale()\" [options]=\"commons.appLocales()\" (onChange)=\"switchLocale($event.value)\"></p-dropdown>\n </li>\n }\n @if (topbarUserComponent()) {\n <li #userMenuItem class=\"profile-item topbar-item mr-3\" [mngComponent]=\"topbarUserComponent()\" [attachToHost]=\"true\"></li>\n }\n </ul>\n </div>\n</div>\n" }]
722
+ }] });
758
723
 
759
724
  class MainLayoutComponent {
760
725
  constructor() {
761
- this.commonsConfig = inject(COMMONS_MODULE_CONFIG_IT, { optional: true });
726
+ this.commonsService = inject(CommonsService);
762
727
  this.config = inject(COMMONS_LAYOUT_FEATURE_CONFIG_IT, { optional: true });
763
728
  this.layoutService = inject(MainLayoutComponentService);
764
729
  this.menuService = inject(MenuService);
765
730
  this.renderer = inject(Renderer2);
766
- this.colorScheme = signal(this.commonsConfig?.app?.colorScheme ?? 'light');
731
+ this.appTopbar = viewChild('topbarCmp');
732
+ this.colorScheme = computed(() => this.commonsService.colorScheme() ?? 'light');
767
733
  this.menuMode = signal(this.config?.menuMode ?? 'static');
768
734
  this.ripple = signal(this.config?.ripple ?? true);
769
- this.useNotificationWrapper = true;
770
- this.topbarComponent = TopbarComponent;
771
- this.breadcrumbsComponent = BreadcrumbComponent;
772
- this.footerComponent = FooterComponent;
735
+ this.topbarComponent = signal(this.config?.components?.topbar === false ? undefined : this.config?.components?.topbar ?? TopbarComponent);
736
+ this.breadcrumbsComponent = signal(this.config?.components?.breadcrumb === false ? undefined : this.config?.components?.breadcrumb ?? BreadcrumbComponent);
737
+ this.footerComponent = signal(this.config?.components?.footer === false ? undefined : this.config?.components?.footer ?? FooterComponent);
738
+ this.useNotificationWrapper = signal(!this.config?.disableNotificationWrapper);
773
739
  this.layoutService.overlayOpen$.pipe(takeUntilDestroyed()).subscribe(() => {
774
740
  if (!this.menuOutsideClickListener) {
775
741
  this.menuOutsideClickListener = this.renderer.listen('document', 'click', event => {
776
- const isOutsideClicked = !(this.appTopbar?.nativeElement.isSameNode(event.target) || this.appTopbar?.nativeElement.contains(event.target));
742
+ const isOutsideClicked = !(this.appTopbar()?.nativeElement.isSameNode(event.target) || this.appTopbar()?.nativeElement.contains(event.target));
777
743
  if (isOutsideClicked) {
778
744
  this.hideMenu();
779
745
  }
@@ -784,18 +750,6 @@ class MainLayoutComponent {
784
750
  }
785
751
  });
786
752
  }
787
- ngOnInit() {
788
- this.useNotificationWrapper = !this.config?.disableNotificationWrapper;
789
- if (this.config?.components?.topbar !== undefined) {
790
- this.topbarComponent = this.config.components.topbar;
791
- }
792
- if (this.config?.components?.breadcrumb !== undefined) {
793
- this.breadcrumbsComponent = this.config.components.breadcrumb;
794
- }
795
- if (this.config?.components?.footer !== undefined) {
796
- this.footerComponent = this.config.components.footer;
797
- }
798
- }
799
753
  blockBodyScroll() {
800
754
  if (document.body.classList) {
801
755
  document.body.classList.add('blocked-scroll');
@@ -832,15 +786,12 @@ class MainLayoutComponent {
832
786
  }
833
787
  }
834
788
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.5", ngImport: i0, type: MainLayoutComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
835
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.0.5", type: MainLayoutComponent, isStandalone: true, selector: "mng-main-layout", providers: [MainLayoutComponentService], viewQueries: [{ propertyName: "appTopbar", first: true, predicate: ["topbarCmp"], descendants: true }], ngImport: i0, template: "@if (useNotificationWrapper) {\n <mng-notification-wrapper>\n <ng-template [ngTemplateOutlet]=\"content\"></ng-template>\n </mng-notification-wrapper>\n} @else {\n <ng-template [ngTemplateOutlet]=\"content\"></ng-template>\n}\n\n<ng-template #content>\n <div\n class=\"layout-container\"\n [ngClass]=\"{\n 'layout-light': colorScheme() === 'light',\n 'layout-dark': colorScheme() === 'dark',\n 'layout-overlay': menuMode() === 'overlay',\n 'layout-static': menuMode() === 'static',\n 'layout-reveal': menuMode() === 'reveal',\n 'layout-drawer': menuMode() === 'drawer',\n 'layout-slim': menuMode() === 'slim',\n 'layout-slim-plus': menuMode() === 'slim-plus',\n 'layout-static-inactive': layoutService.state().staticMenuDesktopInactive && menuMode() === 'static',\n 'layout-overlay-active': layoutService.state().overlayMenuActive,\n 'layout-mobile-active': layoutService.state().staticMenuMobileActive,\n 'p-ripple-disabled': !ripple(),\n 'layout-sidebar-active': layoutService.state().sidebarActive,\n 'layout-sidebar-anchored': layoutService.state().anchored\n }\">\n <div class=\"layout-content-wrapper\">\n @if (topbarComponent) {\n <div #topbarCmp class=\"layout-topbar-wrapper\" [mngComponent]=\"topbarComponent\" [attachToHost]=\"true\"></div>\n }\n @if (breadcrumbsComponent) {\n <div class=\"content-breadcrumb\">\n <div [mngComponent]=\"breadcrumbsComponent\" [attachToHost]=\"true\"></div>\n </div>\n }\n <div class=\"layout-content\">\n <router-outlet></router-outlet>\n </div>\n <div class=\"layout-mask\"></div>\n @if (footerComponent) {\n <div [mngComponent]=\"footerComponent\" [attachToHost]=\"true\"></div>\n }\n </div>\n </div>\n</ng-template>\n", dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: RouterModule }, { kind: "directive", type: i1$3.RouterOutlet, selector: "router-outlet", inputs: ["name"], outputs: ["activate", "deactivate", "attach", "detach"], exportAs: ["outlet"] }, { kind: "directive", type: ComponentDirective, selector: "[mngComponent]", inputs: ["mngComponent", "injectionToken", "inputs", "attachToHost", "parentInjector"], outputs: ["instanceCreated"] }, { kind: "component", type: NotificationWrapperComponent, selector: "mng-notification-wrapper" }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
789
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.0.5", type: MainLayoutComponent, isStandalone: true, selector: "mng-main-layout", providers: [MainLayoutComponentService], viewQueries: [{ propertyName: "appTopbar", first: true, predicate: ["topbarCmp"], descendants: true, isSignal: true }], ngImport: i0, template: "@if (useNotificationWrapper()) {\n <mng-notification-wrapper>\n <ng-template [ngTemplateOutlet]=\"content\"></ng-template>\n </mng-notification-wrapper>\n} @else {\n <ng-template [ngTemplateOutlet]=\"content\"></ng-template>\n}\n\n<ng-template #content>\n <div\n class=\"layout-container\"\n [ngClass]=\"{\n 'layout-light': colorScheme() === 'light',\n 'layout-dark': colorScheme() === 'dark',\n 'layout-overlay': menuMode() === 'overlay',\n 'layout-static': menuMode() === 'static',\n 'layout-reveal': menuMode() === 'reveal',\n 'layout-drawer': menuMode() === 'drawer',\n 'layout-slim': menuMode() === 'slim',\n 'layout-slim-plus': menuMode() === 'slim-plus',\n 'layout-static-inactive': layoutService.state().staticMenuDesktopInactive && menuMode() === 'static',\n 'layout-overlay-active': layoutService.state().overlayMenuActive,\n 'layout-mobile-active': layoutService.state().staticMenuMobileActive,\n 'p-ripple-disabled': !ripple(),\n 'layout-sidebar-active': layoutService.state().sidebarActive,\n 'layout-sidebar-anchored': layoutService.state().anchored\n }\">\n <div class=\"layout-content-wrapper\">\n @if (topbarComponent()) {\n <div #topbarCmp class=\"layout-topbar-wrapper\" [mngComponent]=\"topbarComponent()\" [attachToHost]=\"true\"></div>\n }\n @if (breadcrumbsComponent()) {\n <div class=\"content-breadcrumb\">\n <div [mngComponent]=\"breadcrumbsComponent()\" [attachToHost]=\"true\"></div>\n </div>\n }\n <div class=\"layout-content\">\n <router-outlet></router-outlet>\n </div>\n <div class=\"layout-mask\"></div>\n @if (footerComponent()) {\n <div [mngComponent]=\"footerComponent()\" [attachToHost]=\"true\"></div>\n }\n </div>\n </div>\n</ng-template>\n", dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: RouterModule }, { kind: "directive", type: i1$3.RouterOutlet, selector: "router-outlet", inputs: ["name"], outputs: ["activate", "deactivate", "attach", "detach"], exportAs: ["outlet"] }, { kind: "directive", type: ComponentDirective, selector: "[mngComponent]", inputs: ["mngComponent", "injectionToken", "inputs", "attachToHost", "parentInjector"], outputs: ["instanceCreated"] }, { kind: "component", type: NotificationWrapperComponent, selector: "mng-notification-wrapper" }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
836
790
  }
837
791
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.5", ngImport: i0, type: MainLayoutComponent, decorators: [{
838
792
  type: Component,
839
- args: [{ standalone: true, selector: 'mng-main-layout', imports: [NgClass, RouterModule, TopbarComponent, BreadcrumbComponent, ComponentDirective, AsyncPipe, NotificationWrapperComponent, NgTemplateOutlet], providers: [MainLayoutComponentService], changeDetection: ChangeDetectionStrategy.OnPush, template: "@if (useNotificationWrapper) {\n <mng-notification-wrapper>\n <ng-template [ngTemplateOutlet]=\"content\"></ng-template>\n </mng-notification-wrapper>\n} @else {\n <ng-template [ngTemplateOutlet]=\"content\"></ng-template>\n}\n\n<ng-template #content>\n <div\n class=\"layout-container\"\n [ngClass]=\"{\n 'layout-light': colorScheme() === 'light',\n 'layout-dark': colorScheme() === 'dark',\n 'layout-overlay': menuMode() === 'overlay',\n 'layout-static': menuMode() === 'static',\n 'layout-reveal': menuMode() === 'reveal',\n 'layout-drawer': menuMode() === 'drawer',\n 'layout-slim': menuMode() === 'slim',\n 'layout-slim-plus': menuMode() === 'slim-plus',\n 'layout-static-inactive': layoutService.state().staticMenuDesktopInactive && menuMode() === 'static',\n 'layout-overlay-active': layoutService.state().overlayMenuActive,\n 'layout-mobile-active': layoutService.state().staticMenuMobileActive,\n 'p-ripple-disabled': !ripple(),\n 'layout-sidebar-active': layoutService.state().sidebarActive,\n 'layout-sidebar-anchored': layoutService.state().anchored\n }\">\n <div class=\"layout-content-wrapper\">\n @if (topbarComponent) {\n <div #topbarCmp class=\"layout-topbar-wrapper\" [mngComponent]=\"topbarComponent\" [attachToHost]=\"true\"></div>\n }\n @if (breadcrumbsComponent) {\n <div class=\"content-breadcrumb\">\n <div [mngComponent]=\"breadcrumbsComponent\" [attachToHost]=\"true\"></div>\n </div>\n }\n <div class=\"layout-content\">\n <router-outlet></router-outlet>\n </div>\n <div class=\"layout-mask\"></div>\n @if (footerComponent) {\n <div [mngComponent]=\"footerComponent\" [attachToHost]=\"true\"></div>\n }\n </div>\n </div>\n</ng-template>\n" }]
840
- }], ctorParameters: () => [], propDecorators: { appTopbar: [{
841
- type: ViewChild,
842
- args: ['topbarCmp']
843
- }] } });
793
+ args: [{ standalone: true, selector: 'mng-main-layout', imports: [NgClass, RouterModule, TopbarComponent, BreadcrumbComponent, ComponentDirective, AsyncPipe, NotificationWrapperComponent, NgTemplateOutlet], providers: [MainLayoutComponentService], changeDetection: ChangeDetectionStrategy.OnPush, template: "@if (useNotificationWrapper()) {\n <mng-notification-wrapper>\n <ng-template [ngTemplateOutlet]=\"content\"></ng-template>\n </mng-notification-wrapper>\n} @else {\n <ng-template [ngTemplateOutlet]=\"content\"></ng-template>\n}\n\n<ng-template #content>\n <div\n class=\"layout-container\"\n [ngClass]=\"{\n 'layout-light': colorScheme() === 'light',\n 'layout-dark': colorScheme() === 'dark',\n 'layout-overlay': menuMode() === 'overlay',\n 'layout-static': menuMode() === 'static',\n 'layout-reveal': menuMode() === 'reveal',\n 'layout-drawer': menuMode() === 'drawer',\n 'layout-slim': menuMode() === 'slim',\n 'layout-slim-plus': menuMode() === 'slim-plus',\n 'layout-static-inactive': layoutService.state().staticMenuDesktopInactive && menuMode() === 'static',\n 'layout-overlay-active': layoutService.state().overlayMenuActive,\n 'layout-mobile-active': layoutService.state().staticMenuMobileActive,\n 'p-ripple-disabled': !ripple(),\n 'layout-sidebar-active': layoutService.state().sidebarActive,\n 'layout-sidebar-anchored': layoutService.state().anchored\n }\">\n <div class=\"layout-content-wrapper\">\n @if (topbarComponent()) {\n <div #topbarCmp class=\"layout-topbar-wrapper\" [mngComponent]=\"topbarComponent()\" [attachToHost]=\"true\"></div>\n }\n @if (breadcrumbsComponent()) {\n <div class=\"content-breadcrumb\">\n <div [mngComponent]=\"breadcrumbsComponent()\" [attachToHost]=\"true\"></div>\n </div>\n }\n <div class=\"layout-content\">\n <router-outlet></router-outlet>\n </div>\n <div class=\"layout-mask\"></div>\n @if (footerComponent()) {\n <div [mngComponent]=\"footerComponent()\" [attachToHost]=\"true\"></div>\n }\n </div>\n </div>\n</ng-template>\n" }]
794
+ }], ctorParameters: () => [] });
844
795
 
845
796
  /**
846
797
  * Creates a layout route on the specified path.