@mediusinc/mng-commons-layout 5.2.0-rc.2 → 5.3.0-rc.0

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,28 +1,31 @@
1
1
  import { AsyncPipe, NgOptimizedImage, NgClass, NgTemplateOutlet } from '@angular/common';
2
2
  import * as i0 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';
3
+ import { InjectionToken, inject, Injectable, DestroyRef, input, signal, computed, Component, ChangeDetectionStrategy, output, viewChild, effect, untracked, ElementRef, Injector, Renderer2 } from '@angular/core';
4
4
  import * as i1$1 from '@ngx-translate/core';
5
- import { TranslateModule } from '@ngx-translate/core';
5
+ import { TranslateModule, TranslateService } 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, NotificationWrapperComponent, createRoute, CommonsFeatureTypeEnum } from '@mediusinc/mng-commons/core';
7
+ import { LoggerService, JsonPathPipe, CommonsService, ComponentDirective, LocalStorageService, CommonsRouterService, adjustRouteMenuLazyChildrenRouterLinks, doesUrlMatchRouterLink, PermissionService, toObservable as toObservable$1, EnumerateAsyncPipe, NotificationWrapperComponent, createRoute, CommonsFeatureTypeEnum } from '@mediusinc/mng-commons/core';
8
8
  import { toObservable, takeUntilDestroyed, toSignal } from '@angular/core/rxjs-interop';
9
- import { ReplaySubject, catchError, of, switchMap, take, Subject, Observable, BehaviorSubject, combineLatest, distinctUntilChanged } from 'rxjs';
9
+ import { ReplaySubject, catchError, of, switchMap, take, Subject, startWith, distinctUntilChanged } from 'rxjs';
10
10
  import { map, filter } from 'rxjs/operators';
11
11
  import * as i1 from '@angular/common/http';
12
12
  import * as i1$3 from '@angular/router';
13
13
  import { Router, NavigationEnd, RouterModule, ActivatedRoute } from '@angular/router';
14
- import * as i2$1 from '@angular/forms';
14
+ import * as i3 from '@angular/forms';
15
15
  import { FormsModule } from '@angular/forms';
16
- import { ButtonModule } from 'primeng/button';
17
- import * as i1$4 from 'primeng/dropdown';
16
+ import { Button, ButtonModule } from 'primeng/button';
17
+ import * as i4 from 'primeng/dropdown';
18
18
  import { DropdownModule } from 'primeng/dropdown';
19
19
  import * as i1$2 from 'primeng/ripple';
20
20
  import { RippleModule } from 'primeng/ripple';
21
- import * as i3 from 'primeng/styleclass';
21
+ import * as i3$1 from 'primeng/styleclass';
22
22
  import { StyleClassModule } from 'primeng/styleclass';
23
23
  import { trigger, state, style, transition, animate } from '@angular/animations';
24
24
  import { TooltipModule } from 'primeng/tooltip';
25
25
  import { DomSanitizer } from '@angular/platform-browser';
26
+ import { DynamicDialogConfig, DynamicDialogRef, DialogService } from 'primeng/dynamicdialog';
27
+ import * as i2$1 from 'primeng/radiobutton';
28
+ import { RadioButtonModule } from 'primeng/radiobutton';
26
29
 
27
30
  const COMMONS_LAYOUT_FEATURE_CONFIG_IT = new InjectionToken('COMMONS_LAYOUT_FEATURE_CONFIG');
28
31
 
@@ -184,7 +187,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.5", ngImpor
184
187
 
185
188
  class MainLayoutComponentService {
186
189
  constructor() {
190
+ this.typeName = 'MainLayoutComponentService';
191
+ this.storageMenuModeKey = 'menuMode';
187
192
  this.config = inject(COMMONS_LAYOUT_FEATURE_CONFIG_IT, { optional: true });
193
+ this.storageService = inject(LocalStorageService);
188
194
  this.state = signal({
189
195
  staticMenuDesktopInactive: false,
190
196
  overlayMenuActive: false,
@@ -197,6 +203,24 @@ class MainLayoutComponentService {
197
203
  });
198
204
  this.overlayOpen = new Subject();
199
205
  this.overlayOpen$ = this.overlayOpen.asObservable();
206
+ this.menuModes = this.config?.menuModes ?? ['static', 'overlay', 'reveal', 'drawer', 'slim', 'slim-plus'];
207
+ this._menuMode = signal(this.initMenuMode());
208
+ this.menuMode = this._menuMode.asReadonly();
209
+ this.isOverlay = computed(() => this.menuMode() === 'overlay');
210
+ this.isSlim = computed(() => this.menuMode() === 'slim');
211
+ this.isSlimPlus = computed(() => this.menuMode() === 'slim-plus');
212
+ }
213
+ onMenuModeChange(mode) {
214
+ if (!this.menuModes.includes(mode)) {
215
+ return;
216
+ }
217
+ if (mode === this.config?.menuMode) {
218
+ this.storageService.removeItem(this.typeName, this.storageMenuModeKey);
219
+ }
220
+ else {
221
+ this.storageService.setItem(this.typeName, this.storageMenuModeKey, mode);
222
+ }
223
+ this._menuMode.set(mode);
200
224
  }
201
225
  onMenuToggle() {
202
226
  if (this.isOverlay()) {
@@ -227,21 +251,19 @@ class MainLayoutComponentService {
227
251
  onOverlaySubmenuOpen() {
228
252
  this.overlayOpen.next(null);
229
253
  }
230
- isOverlay() {
231
- return this.config?.menuMode === 'overlay';
232
- }
233
- isSlim() {
234
- return this.config?.menuMode === 'slim';
235
- }
236
- isSlimPlus() {
237
- return this.config?.menuMode === 'slim-plus';
238
- }
239
254
  isDesktop() {
240
255
  return window.innerWidth > 991;
241
256
  }
242
257
  isMobile() {
243
258
  return !this.isDesktop();
244
259
  }
260
+ initMenuMode() {
261
+ const lsMode = this.storageService.getItem(this.typeName, this.storageMenuModeKey);
262
+ if (lsMode && this.menuModes.includes(lsMode)) {
263
+ return lsMode;
264
+ }
265
+ return this.config?.menuMode ?? 'static';
266
+ }
245
267
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.5", ngImport: i0, type: MainLayoutComponentService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
246
268
  static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.0.5", ngImport: i0, type: MainLayoutComponentService }); }
247
269
  }
@@ -249,56 +271,76 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.5", ngImpor
249
271
  type: Injectable
250
272
  }] });
251
273
 
274
+ function prepareMenuItemsToInternal(menuItems, parentKey = '') {
275
+ const newItems = menuItems.map((item, idx) => {
276
+ const itemsProp = signal([]);
277
+ const lazyChildrenProp = signal(item.lazyChildren ?? false);
278
+ const hasItemsProp = computed(() => itemsProp().length > 0);
279
+ const newItem = {
280
+ ...item,
281
+ isVisible: typeof item.isVisible !== 'undefined' ? item.isVisible : item.visible,
282
+ key: parentKey ? parentKey + '-' + idx : idx.toString(),
283
+ config: item,
284
+ items: itemsProp,
285
+ lazyChildren: lazyChildrenProp,
286
+ itemsVisibility: signal([]),
287
+ hasItems: hasItemsProp,
288
+ hasItemsOrLazyChildren: computed(() => lazyChildrenProp() || hasItemsProp())
289
+ };
290
+ if (Array.isArray(item.items) && item.items.length > 0) {
291
+ newItem.items.set(prepareMenuItemsToInternal(item.items, newItem.key));
292
+ newItem.itemsVisibility.set(newItem.items()?.map(i => signal(true)));
293
+ }
294
+ return newItem;
295
+ });
296
+ return newItems;
297
+ }
298
+
252
299
  class MenuService {
253
300
  constructor() {
254
301
  this.destroyRef = inject(DestroyRef);
255
302
  this.logger = LoggerService.create('MenuService');
256
303
  this.router = inject(Router);
257
304
  this.commonsRouter = inject(CommonsRouterService);
258
- this.menuSource = new ReplaySubject(1);
259
- this.resetSource = new Subject();
260
- this.menuSource$ = this.menuSource.asObservable();
261
- this.resetSource$ = this.resetSource.asObservable();
262
- this.menuItems = [];
305
+ this._menuItems = signal([]);
306
+ this.menuItems = this._menuItems.asReadonly();
307
+ this.menuChangeSubject = new ReplaySubject(1);
308
+ this.menuChange$ = this.menuChangeSubject.asObservable();
263
309
  this.routeLoadedChildrenSubscriptions = [];
264
310
  }
265
- initialize(menuItems) {
266
- this.menuItems = menuItems;
311
+ setItems(menuItems) {
267
312
  this.routeLoadedChildrenSubscriptions.forEach(s => s.unsubscribe());
268
313
  this.routeLoadedChildrenSubscriptions = [];
269
- this.generateMenuItemKeys(menuItems);
314
+ this._menuItems.set(prepareMenuItemsToInternal(menuItems));
315
+ this.appendListenersToLazyChildren(this._menuItems());
316
+ this.router.events;
270
317
  this.router.events
271
- .pipe(filter(event => event instanceof NavigationEnd), takeUntilDestroyed(this.destroyRef))
318
+ .pipe(startWith(new NavigationEnd(0, this.router.url, this.router.url)), filter(event => event instanceof NavigationEnd), map(e => e), takeUntilDestroyed(this.destroyRef))
272
319
  .subscribe(e => {
273
320
  this.findAndSetActiveMenuItem(e.urlAfterRedirects);
274
321
  });
275
- this.findAndSetActiveMenuItem(this.router.url);
276
322
  }
277
- generateMenuItemKeys(menuItems, parentKey = '') {
278
- menuItems.forEach((item, idx) => {
279
- if (!item.index) {
280
- item.index = idx;
281
- item.key = parentKey ? parentKey + '-' + idx : idx.toString();
282
- }
283
- if (item.items) {
284
- this.generateMenuItemKeys(item.items, item.key);
285
- }
286
- else if (item.lazyChildren) {
323
+ appendListenersToLazyChildren(menuItems) {
324
+ menuItems.forEach(item => {
325
+ if (item.lazyChildren()) {
287
326
  this.listenToMenuItemLazyChildrenLoad(item);
288
327
  }
328
+ else if (item.items()) {
329
+ this.appendListenersToLazyChildren(item.items());
330
+ }
289
331
  });
290
332
  }
291
333
  findAndSetActiveMenuItem(url) {
292
- const matches = this.findActiveRouteMatches(this.menuItems, url);
334
+ const matches = this.findActiveRouteMatches(this.menuItems(), url);
293
335
  if (matches.length === 0) {
294
336
  this.reset();
295
337
  }
296
338
  else {
297
339
  const matchKey = matches[0][matches[0].length - 1].key;
298
340
  if (matchKey) {
299
- this.menuSource.next({
341
+ this.menuChangeSubject.next({
300
342
  key: matchKey,
301
- routeEvent: true
343
+ eventType: 'routeChange'
302
344
  });
303
345
  }
304
346
  else {
@@ -316,13 +358,14 @@ class MenuService {
316
358
  .pipe(take(1))
317
359
  .subscribe({
318
360
  next: routes => {
319
- let menuItems = routes
361
+ const menuItemsFromRoutes = routes
320
362
  .filter(r => Array.isArray(r.data?.menuItems))
321
363
  .flatMap(r => r.data.menuItems);
322
- menuItems = adjustRouteMenuLazyChildrenRouterLinks(menuItem, menuItems);
323
- menuItem.items = menuItems;
324
- menuItem.lazyChildren = false;
325
- this.generateMenuItemKeys(menuItem.items, menuItem.key);
364
+ const menuItems = adjustRouteMenuLazyChildrenRouterLinks(menuItem, menuItemsFromRoutes);
365
+ menuItem.items.set(prepareMenuItemsToInternal(menuItems, menuItem.key));
366
+ this.appendListenersToLazyChildren(menuItem.items());
367
+ menuItem.itemsVisibility.set(menuItem.items()?.map(i => signal(true)));
368
+ menuItem.lazyChildren.set(false);
326
369
  this.findAndSetActiveMenuItem(this.router.url);
327
370
  }
328
371
  }));
@@ -330,11 +373,12 @@ class MenuService {
330
373
  findActiveRouteMatches(menuItems, url) {
331
374
  const matches = [];
332
375
  for (const menuItem of menuItems) {
376
+ const chidldren = menuItem.items();
333
377
  if (menuItem.routerLink) {
334
378
  const isActive = doesUrlMatchRouterLink(menuItem.routerLink, url);
335
379
  if (isActive) {
336
- if (Array.isArray(menuItem.items)) {
337
- const itemsMatches = this.findActiveRouteMatches(menuItem.items, url);
380
+ if (Array.isArray(chidldren)) {
381
+ const itemsMatches = this.findActiveRouteMatches(chidldren, url);
338
382
  if (itemsMatches.length > 0) {
339
383
  matches.push(...itemsMatches.map(c => [menuItem, ...c]));
340
384
  }
@@ -347,8 +391,8 @@ class MenuService {
347
391
  }
348
392
  }
349
393
  }
350
- else if (Array.isArray(menuItem.items)) {
351
- const itemsMatches = this.findActiveRouteMatches(menuItem.items, url);
394
+ else if (Array.isArray(chidldren)) {
395
+ const itemsMatches = this.findActiveRouteMatches(chidldren, url);
352
396
  if (itemsMatches.length > 0) {
353
397
  matches.push(...itemsMatches.map(c => [menuItem, ...c]));
354
398
  }
@@ -357,7 +401,9 @@ class MenuService {
357
401
  return matches;
358
402
  }
359
403
  reset() {
360
- this.resetSource.next(true);
404
+ this.menuChangeSubject.next({
405
+ eventType: 'reset'
406
+ });
361
407
  }
362
408
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.5", ngImport: i0, type: MenuService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
363
409
  static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.0.5", ngImport: i0, type: MenuService }); }
@@ -368,87 +414,70 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.5", ngImpor
368
414
 
369
415
  class MenuItemComponent {
370
416
  constructor() {
371
- this.router = inject(Router);
372
- this.injector = inject(Injector);
373
- this.destroyRef = inject(DestroyRef);
374
417
  this.menuService = inject(MenuService);
375
418
  this.permissionService = inject(PermissionService);
376
419
  this.layoutService = inject(MainLayoutComponentService);
377
- this.isPermitted = signal(true);
378
- this.childrenVisibilitySubject = [];
379
- this.root = false;
380
- this.visibleChangeEventEmitter = new EventEmitter();
381
- this.active = signal(false);
382
- this.visible = signal(false);
383
- this.menuService.menuSource$.pipe(takeUntilDestroyed()).subscribe(value => {
384
- setTimeout(() => {
385
- this.active.set(this.item.key === value.key || value.key.startsWith((this.item.key ?? '') + '-'));
386
- });
387
- });
388
- this.menuService.resetSource$.pipe(takeUntilDestroyed()).subscribe(() => {
389
- this.active.set(false);
420
+ this.item = input.required();
421
+ this.root = input(false);
422
+ this.visibleChange = output();
423
+ this.submenuElRef = viewChild('submenu');
424
+ this.isPermitted = toSignal(toObservable(this.item).pipe(switchMap(i => (i.permissions ? this.permissionService.isMenuItemVisible(i.permissions, i.config) : of(true)))));
425
+ this.isVisibleFromItemSettings = toSignal(toObservable(this.item).pipe(switchMap(i => (typeof i.isVisible === 'function' ? toObservable$1(i.isVisible(i.config)) : of(i.isVisible ?? true)))));
426
+ this.menuChangeEvents = toSignal(this.menuService.menuChange$.pipe(distinctUntilChanged((v1, v2) => v1.key === v2.key)));
427
+ this.active = computed(() => {
428
+ if (!this.isPermitted()) {
429
+ return false;
430
+ }
431
+ const menuChangeEvent = this.menuChangeEvents();
432
+ if (menuChangeEvent) {
433
+ return menuChangeEvent.eventType === 'reset' || !menuChangeEvent.key
434
+ ? false
435
+ : this.item().key === menuChangeEvent.key || menuChangeEvent.key.startsWith((this.item().key ?? '') + '-');
436
+ }
437
+ return false;
390
438
  });
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
- }
439
+ this.visible = computed(() => {
440
+ const isPermitted = this.isPermitted();
441
+ if (!isPermitted) {
442
+ return false;
443
+ }
444
+ if (!this.isVisibleFromItemSettings()) {
445
+ return false;
446
+ }
447
+ const items = this.item().items();
448
+ if (Array.isArray(items) &&
449
+ items.length > 0 &&
450
+ this.item()
451
+ .itemsVisibility()
452
+ .every(v => !v())) {
453
+ return false;
454
+ }
455
+ return true;
400
456
  });
401
457
  effect(() => {
402
- if (this.isPermitted()) {
403
- this.active.set(false);
404
- this.visible.set(true);
405
- }
406
- else {
407
- this.active.set(true);
408
- this.visible.set(false);
409
- }
410
- }, { allowSignalWrites: true });
411
- }
412
- ngOnInit() {
413
- if (this.item.routerLink) {
414
- if (typeof this.item.routerLink === 'string') {
415
- this.itemUrl = this.item.routerLink;
416
- }
417
- else {
418
- this.itemUrl = this.router.parseUrl(this.item.routerLink.join('/'));
458
+ if (this.root() && this.active() && this.layoutService.isDesktop() && (this.layoutService.isSlim() || this.layoutService.isSlimPlus())) {
459
+ this.calculatePosition(this.submenuElRef()?.nativeElement, this.submenuElRef()?.nativeElement.parentElement);
419
460
  }
420
- }
421
- this.processItemVisibility();
422
- this.processItemChildrenVisibility();
423
- }
424
- ngAfterViewChecked() {
425
- if (this.root && this.active() && this.layoutService.isDesktop() && (this.layoutService.isSlim() || this.layoutService.isSlimPlus())) {
426
- this.calculatePosition(this.submenu?.nativeElement, this.submenu?.nativeElement.parentElement);
427
- }
428
- }
429
- ngOnDestroy() {
430
- this.isVisibleSubscription?.unsubscribe();
461
+ });
431
462
  }
432
463
  get submenuAnimation() {
433
464
  if (this.layoutService.isDesktop() && (this.layoutService.isSlim() || this.layoutService.isSlimPlus())) {
434
465
  return this.active() ? 'visible' : 'hidden';
435
466
  }
436
467
  else {
437
- return this.root ? 'expanded' : this.active() ? 'expanded' : 'collapsed';
468
+ return this.root() ? 'expanded' : this.active() ? 'expanded' : 'collapsed';
438
469
  }
439
470
  }
440
- get activeClass() {
441
- return this.active() && !this.root;
442
- }
443
471
  itemClick(event) {
472
+ const item = this.item();
444
473
  // avoid processing disabled items
445
- if (this.item.disabled) {
474
+ if (item.disabled) {
446
475
  event.preventDefault();
447
476
  return;
448
477
  }
449
478
  // toggle active state
450
- if (this.item.items || this.item.lazyChildren) {
451
- if ((this.root || this.active()) && (this.layoutService.isSlim() || this.layoutService.isSlimPlus())) {
479
+ if (item.hasItemsOrLazyChildren()) {
480
+ if ((this.root() || this.active()) && (this.layoutService.isSlim() || this.layoutService.isSlimPlus())) {
452
481
  this.layoutService.onOverlaySubmenuOpen();
453
482
  }
454
483
  }
@@ -476,7 +505,7 @@ class MenuItemComponent {
476
505
  }
477
506
  }
478
507
  onChildVisibleChange(visible, item, idx) {
479
- this.childrenVisibilitySubject[idx].next(visible);
508
+ this.item().itemsVisibility()[idx]?.set(visible);
480
509
  }
481
510
  calculatePosition(overlay, target) {
482
511
  if (overlay) {
@@ -492,57 +521,8 @@ class MenuItemComponent {
492
521
  }
493
522
  }
494
523
  }
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);
503
- }
504
- });
505
- }
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));
518
- }
519
- }
520
- updateActiveStateFromRoute() {
521
- if (this.itemUrl) {
522
- this.active.set(this.router.isActive(this.itemUrl, {
523
- matrixParams: 'ignored',
524
- queryParams: 'ignored',
525
- paths: this.item.items ? 'subset' : 'exact',
526
- fragment: 'ignored'
527
- }));
528
- }
529
- else {
530
- this.active.set(false);
531
- }
532
- }
533
- processItemChildrenVisibility() {
534
- if (this.item.items) {
535
- this.childrenVisibilitySubject = this.item.items.map(() => new BehaviorSubject(true));
536
- combineLatest(this.childrenVisibilitySubject.map(s => s.asObservable().pipe(distinctUntilChanged())))
537
- .pipe(takeUntilDestroyed(this.destroyRef))
538
- .subscribe(visible => {
539
- const anyChildVisible = visible.some(v => v === true);
540
- this.active.set(!anyChildVisible);
541
- });
542
- }
543
- }
544
524
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.5", ngImport: i0, type: MenuItemComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
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: [
525
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.0.5", type: MenuItemComponent, isStandalone: true, selector: "[mng-menuitem]", inputs: { item: { classPropertyName: "item", publicName: "item", isSignal: true, isRequired: true, transformFunction: null }, root: { classPropertyName: "root", publicName: "root", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { visibleChange: "visibleChange" }, host: { properties: { "class.active-menuitem": "!root() && active()", "class.layout-root-menuitem": "root()" } }, providers: [PermissionService], viewQueries: [{ propertyName: "submenuElRef", first: true, predicate: ["submenu"], descendants: true, isSignal: 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().hasItems()) {\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().hasItemsOrLazyChildren()) {\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().hasItems()) {\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().hasItemsOrLazyChildren()) {\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().hasItems()) {\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().hasItemsOrLazyChildren()) {\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().hasItems()) {\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, child, 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: [
546
526
  trigger('children', [
547
527
  state('collapsed', style({
548
528
  height: '0'
@@ -578,34 +558,20 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.5", ngImpor
578
558
  })),
579
559
  transition('collapsed <=> expanded', animate('400ms cubic-bezier(0.86, 0, 0.07, 1)'))
580
560
  ])
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" }]
582
- }], ctorParameters: () => [], propDecorators: { item: [{
583
- type: Input,
584
- args: [{ required: true }]
585
- }], root: [{
586
- type: Input
587
- }, {
588
- type: HostBinding,
589
- args: ['class.layout-root-menuitem']
590
- }], visibleChangeEventEmitter: [{
591
- type: Output,
592
- args: ['visibleChange']
593
- }], submenu: [{
594
- type: ViewChild,
595
- args: ['submenu']
596
- }], activeClass: [{
597
- type: HostBinding,
598
- args: ['class.active-menuitem']
599
- }] } });
561
+ ], host: {
562
+ '[class.active-menuitem]': '!root() && active()',
563
+ '[class.layout-root-menuitem]': 'root()'
564
+ }, 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().hasItems()) {\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().hasItemsOrLazyChildren()) {\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().hasItems()) {\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().hasItemsOrLazyChildren()) {\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().hasItems()) {\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().hasItemsOrLazyChildren()) {\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().hasItems()) {\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, child, i)\"></li>\n }\n </ul>\n }\n}\n" }]
565
+ }], ctorParameters: () => [] });
600
566
 
601
567
  class MenuComponent {
602
568
  constructor() {
603
569
  this.route = inject(ActivatedRoute);
604
- this.menuService = inject(MenuService);
605
570
  this.config = inject(COMMONS_LAYOUT_FEATURE_CONFIG_IT, { optional: true });
606
571
  this.layoutService = inject(MainLayoutComponentService);
572
+ this.menuService = inject(MenuService);
607
573
  this.routeData = toSignal(this.route.data);
608
- this.menuItems = computed(() => {
574
+ effect(() => {
609
575
  let items = [];
610
576
  if (this.config?.menuItems && Array.isArray(this.config.menuItems)) {
611
577
  items = this.config.menuItems;
@@ -617,18 +583,15 @@ class MenuComponent {
617
583
  if (!(this.layoutService.isSlim() || this.layoutService.isSlimPlus())) {
618
584
  items = [{ items }];
619
585
  }
620
- return items;
621
- });
622
- effect(() => {
623
- this.menuService.initialize(this.menuItems());
586
+ untracked(() => this.menuService.setItems(items));
624
587
  });
625
588
  }
626
589
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.5", ngImport: i0, type: MenuComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
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 }); }
590
+ 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 menuService.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 }); }
628
591
  }
629
592
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.5", ngImport: i0, type: MenuComponent, decorators: [{
630
593
  type: Component,
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" }]
594
+ args: [{ standalone: true, selector: 'mng-menu', imports: [MenuItemComponent], changeDetection: ChangeDetectionStrategy.OnPush, template: "<ul class=\"layout-menu\">\n @for (item of menuService.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
595
  }], ctorParameters: () => [] });
633
596
 
634
597
  class SidebarComponent {
@@ -676,8 +639,46 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.5", ngImpor
676
639
  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
640
  }] });
678
641
 
642
+ class SettingsComponent {
643
+ constructor() {
644
+ this.dynamicDialogConfig = inject(DynamicDialogConfig);
645
+ this.dynamicDialogRef = inject(DynamicDialogRef);
646
+ this.injector = this.dynamicDialogConfig.data.injector;
647
+ this.translate = this.injector.get(TranslateService);
648
+ this.commons = this.injector.get(CommonsService);
649
+ this.layoutService = this.injector.get(MainLayoutComponentService);
650
+ this.menuModes = this.layoutService.menuModes;
651
+ this.translate
652
+ .stream('mngSettings.title')
653
+ .pipe(takeUntilDestroyed())
654
+ .subscribe(t => {
655
+ setTimeout(() => (this.dynamicDialogConfig.header = t));
656
+ });
657
+ }
658
+ switchLocale(language) {
659
+ this.commons.setAppLocale(language);
660
+ }
661
+ switchDataLocale(language) {
662
+ this.commons.setAppDataLocale(language);
663
+ }
664
+ onMenuModeChange(mode) {
665
+ this.layoutService.onMenuModeChange(mode);
666
+ }
667
+ closeDialog() {
668
+ this.dynamicDialogRef.close();
669
+ }
670
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.5", ngImport: i0, type: SettingsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
671
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.0.5", type: SettingsComponent, isStandalone: true, selector: "mng-settings", ngImport: i0, template: "<div class=\"h-full flex flex-column\">\n <div class=\"flex-grow-1 mng-action-editor-form-container\">\n @if (commons.appLocales().length > 1 || commons.appDataLocales().length > 1) {\n <h5>{{ 'mngSettings.locales' | translate }}</h5>\n <div class=\"formgrid grid\">\n @if (commons.appLocales().length > 1) {\n <div class=\"field pr-4\">\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 </div>\n }\n @if (commons.appDataLocales().length > 1) {\n <div class=\"field pr-4\">\n <i class=\"pi pi-fw pi-database\"></i>\n <p-dropdown [ngModel]=\"commons.appDataLocale()\" [options]=\"commons.appDataLocales()\" (onChange)=\"switchDataLocale($event.value)\"></p-dropdown>\n </div>\n }\n </div>\n }\n\n @if (menuModes.length > 1) {\n <h5>{{ 'mngSettings.menuMode.title' | translate }}</h5>\n <div class=\"formgrid grid\">\n @for (mode of menuModes; track mode) {\n <div class=\"field-radiobutton col-6 md:col-4\">\n <p-radioButton name=\"category\" [value]=\"mode\" [ngModel]=\"layoutService.menuMode()\" (ngModelChange)=\"onMenuModeChange(mode)\" />\n <label [for]=\"mode\" class=\"ml-2\">\n {{ 'mngSettings.menuMode.' + mode | translate }}\n </label>\n </div>\n }\n </div>\n }\n\n <div class=\"flex flex-row justify-content-between mng-action-editor-footer-container\">\n <div></div>\n <div>\n <p-button (onClick)=\"closeDialog()\" [label]=\"'general.close' | translate\" icon=\"pi pi-times\" styleClass=\"p-button-primary p-button-text\" />\n </div>\n </div>\n </div>\n</div>\n", dependencies: [{ kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i1$1.TranslatePipe, name: "translate" }, { kind: "ngmodule", type: RadioButtonModule }, { kind: "component", type: i2$1.RadioButton, selector: "p-radioButton", inputs: ["value", "formControlName", "name", "disabled", "label", "variant", "tabindex", "inputId", "ariaLabelledBy", "ariaLabel", "style", "styleClass", "labelStyleClass", "autofocus"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: Button, selector: "p-button", inputs: ["type", "iconPos", "icon", "badge", "label", "disabled", "loading", "loadingIcon", "raised", "rounded", "text", "plain", "severity", "outlined", "link", "tabindex", "size", "style", "styleClass", "badgeClass", "ariaLabel", "autofocus"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: DropdownModule }, { kind: "component", type: i4.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"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
672
+ }
673
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.5", ngImport: i0, type: SettingsComponent, decorators: [{
674
+ type: Component,
675
+ args: [{ standalone: true, selector: 'mng-settings', imports: [TranslateModule, RadioButtonModule, FormsModule, Button, DropdownModule], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"h-full flex flex-column\">\n <div class=\"flex-grow-1 mng-action-editor-form-container\">\n @if (commons.appLocales().length > 1 || commons.appDataLocales().length > 1) {\n <h5>{{ 'mngSettings.locales' | translate }}</h5>\n <div class=\"formgrid grid\">\n @if (commons.appLocales().length > 1) {\n <div class=\"field pr-4\">\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 </div>\n }\n @if (commons.appDataLocales().length > 1) {\n <div class=\"field pr-4\">\n <i class=\"pi pi-fw pi-database\"></i>\n <p-dropdown [ngModel]=\"commons.appDataLocale()\" [options]=\"commons.appDataLocales()\" (onChange)=\"switchDataLocale($event.value)\"></p-dropdown>\n </div>\n }\n </div>\n }\n\n @if (menuModes.length > 1) {\n <h5>{{ 'mngSettings.menuMode.title' | translate }}</h5>\n <div class=\"formgrid grid\">\n @for (mode of menuModes; track mode) {\n <div class=\"field-radiobutton col-6 md:col-4\">\n <p-radioButton name=\"category\" [value]=\"mode\" [ngModel]=\"layoutService.menuMode()\" (ngModelChange)=\"onMenuModeChange(mode)\" />\n <label [for]=\"mode\" class=\"ml-2\">\n {{ 'mngSettings.menuMode.' + mode | translate }}\n </label>\n </div>\n }\n </div>\n }\n\n <div class=\"flex flex-row justify-content-between mng-action-editor-footer-container\">\n <div></div>\n <div>\n <p-button (onClick)=\"closeDialog()\" [label]=\"'general.close' | translate\" icon=\"pi pi-times\" styleClass=\"p-button-primary p-button-text\" />\n </div>\n </div>\n </div>\n</div>\n" }]
676
+ }], ctorParameters: () => [] });
677
+
679
678
  class TopbarUserComponent {
680
679
  constructor() {
680
+ this.injector = inject(Injector);
681
+ this.dialogService = inject(DialogService);
681
682
  this.commons = inject(CommonsService);
682
683
  this.hrefJsVoid = inject(DomSanitizer).bypassSecurityTrustUrl('javascript:void(0)');
683
684
  this.user = computed(() => this.commons.user());
@@ -690,12 +691,21 @@ class TopbarUserComponent {
690
691
  user.logout();
691
692
  }
692
693
  }
694
+ openSettings() {
695
+ this.dialogService.open(SettingsComponent, {
696
+ modal: true,
697
+ styleClass: 'mng-dialog mng-action-editor-dialog mng-dialog-xs',
698
+ data: {
699
+ injector: this.injector
700
+ }
701
+ });
702
+ }
693
703
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.5", ngImport: i0, type: TopbarUserComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
694
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.0.5", type: TopbarUserComponent, isStandalone: true, selector: "mng-topbar-user-component", ngImport: i0, template: "<a\n class=\"cursor-pointer lg:pr-4\"\n pStyleClass=\"@next\"\n enterFromClass=\"ng-hidden\"\n enterActiveClass=\"px-scalein\"\n leaveToClass=\"ng-hidden\"\n leaveActiveClass=\"px-fadeout\"\n [hideOnOutsideClick]=\"true\"\n pRipple>\n <i class=\"pi pi-fw pi-user text-2xl\"></i>\n <span class=\"hidden sm:inline-block\">&nbsp; {{ user()?.displayName ?? user()?.username }}</span>\n</a>\n<ul class=\"topbar-menu active-topbar-menu w-15rem z-5 ng-hidden border-round\">\n <li role=\"menuitem\">\n <a\n class=\"flex align-items-center transition-duration-200\"\n pStyleClass=\"@grandparent\"\n enterFromClass=\"ng-hidden\"\n enterActiveClass=\"px-scalein\"\n leaveToClass=\"ng-hidden\"\n leaveActiveClass=\"px-fadeout\">\n <i class=\"pi pi-fw pi-user text-base mr-2\"></i>\n <div>\n <strong>{{ user()?.displayName ?? user()?.username }}</strong>\n @if (userRoles().length > 0) {\n <small>\n <br />\n {{ userRoles() }}\n </small>\n }\n </div>\n </a>\n </li>\n @if (user()?.logout || user()?.logoutUrl) {\n <li role=\"menuitem\">\n <a\n [href]=\"user()?.logoutUrl ?? hrefJsVoid\"\n (click)=\"logout(user(), $event)\"\n class=\"flex align-items-center hover:text-primary-500 transition-duration-200\"\n pStyleClass=\"@grandparent\"\n enterFromClass=\"ng-hidden\"\n enterActiveClass=\"px-scalein\"\n leaveToClass=\"ng-hidden\"\n leaveActiveClass=\"px-fadeout\">\n <i class=\"pi pi-fw pi-sign-out text-base mr-2\"></i>\n <span>{{ 'mngTopbar.logout' | translate }}</span>\n </a>\n </li>\n }\n</ul>\n", dependencies: [{ kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i1$1.TranslatePipe, name: "translate" }, { kind: "ngmodule", type: RippleModule }, { kind: "directive", type: i1$2.Ripple, selector: "[pRipple]" }, { kind: "ngmodule", type: StyleClassModule }, { kind: "directive", type: i3.StyleClass, selector: "[pStyleClass]", inputs: ["pStyleClass", "enterClass", "enterFromClass", "enterActiveClass", "enterToClass", "leaveClass", "leaveFromClass", "leaveActiveClass", "leaveToClass", "hideOnOutsideClick", "toggleClass", "hideOnEscape"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
704
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.0.5", type: TopbarUserComponent, isStandalone: true, selector: "mng-topbar-user-component", ngImport: i0, template: "<a\n class=\"cursor-pointer lg:pr-4\"\n pStyleClass=\"@next\"\n enterFromClass=\"ng-hidden\"\n enterActiveClass=\"px-scalein\"\n leaveToClass=\"ng-hidden\"\n leaveActiveClass=\"px-fadeout\"\n [hideOnOutsideClick]=\"true\"\n pRipple>\n <i class=\"pi pi-fw pi-user text-2xl\"></i>\n <span class=\"hidden sm:inline-block\">&nbsp; {{ user()?.displayName ?? user()?.username }}</span>\n</a>\n<ul class=\"topbar-menu active-topbar-menu w-15rem z-5 ng-hidden border-round\">\n <li role=\"menuitem\">\n <a\n class=\"flex align-items-center transition-duration-200\"\n pStyleClass=\"@grandparent\"\n enterFromClass=\"ng-hidden\"\n enterActiveClass=\"px-scalein\"\n leaveToClass=\"ng-hidden\"\n leaveActiveClass=\"px-fadeout\">\n <i class=\"pi pi-fw pi-user text-base mr-2\"></i>\n <div>\n <strong>{{ user()?.displayName ?? user()?.username }}</strong>\n @if (userRoles().length > 0) {\n <small>\n <br />\n {{ userRoles() }}\n </small>\n }\n </div>\n </a>\n </li>\n <li role=\"menuitem\">\n <a\n [href]=\"hrefJsVoid\"\n (click)=\"openSettings()\"\n class=\"flex align-items-center transition-duration-200\"\n pStyleClass=\"@grandparent\"\n enterFromClass=\"ng-hidden\"\n enterActiveClass=\"px-scalein\"\n leaveToClass=\"ng-hidden\"\n leaveActiveClass=\"px-fadeout\">\n <i class=\"pi pi-fw pi-cog text-base mr-2\"></i>\n {{ 'mngSettings.title' | translate }}\n </a>\n </li>\n @if (user()?.logout || user()?.logoutUrl) {\n <li role=\"menuitem\">\n <a\n [href]=\"user()?.logoutUrl ?? hrefJsVoid\"\n (click)=\"logout(user(), $event)\"\n class=\"flex align-items-center hover:text-primary-500 transition-duration-200\"\n pStyleClass=\"@grandparent\"\n enterFromClass=\"ng-hidden\"\n enterActiveClass=\"px-scalein\"\n leaveToClass=\"ng-hidden\"\n leaveActiveClass=\"px-fadeout\">\n <i class=\"pi pi-fw pi-sign-out text-base mr-2\"></i>\n <span>{{ 'mngTopbar.logout' | translate }}</span>\n </a>\n </li>\n }\n</ul>\n", dependencies: [{ kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i1$1.TranslatePipe, name: "translate" }, { kind: "ngmodule", type: RippleModule }, { kind: "directive", type: i1$2.Ripple, selector: "[pRipple]" }, { kind: "ngmodule", type: StyleClassModule }, { kind: "directive", type: i3$1.StyleClass, selector: "[pStyleClass]", inputs: ["pStyleClass", "enterClass", "enterFromClass", "enterActiveClass", "enterToClass", "leaveClass", "leaveFromClass", "leaveActiveClass", "leaveToClass", "hideOnOutsideClick", "toggleClass", "hideOnEscape"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
695
705
  }
696
706
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.5", ngImport: i0, type: TopbarUserComponent, decorators: [{
697
707
  type: Component,
698
- args: [{ standalone: true, selector: 'mng-topbar-user-component', imports: [AsyncPipe, EnumerateAsyncPipe, TranslateModule, RippleModule, StyleClassModule], changeDetection: ChangeDetectionStrategy.OnPush, template: "<a\n class=\"cursor-pointer lg:pr-4\"\n pStyleClass=\"@next\"\n enterFromClass=\"ng-hidden\"\n enterActiveClass=\"px-scalein\"\n leaveToClass=\"ng-hidden\"\n leaveActiveClass=\"px-fadeout\"\n [hideOnOutsideClick]=\"true\"\n pRipple>\n <i class=\"pi pi-fw pi-user text-2xl\"></i>\n <span class=\"hidden sm:inline-block\">&nbsp; {{ user()?.displayName ?? user()?.username }}</span>\n</a>\n<ul class=\"topbar-menu active-topbar-menu w-15rem z-5 ng-hidden border-round\">\n <li role=\"menuitem\">\n <a\n class=\"flex align-items-center transition-duration-200\"\n pStyleClass=\"@grandparent\"\n enterFromClass=\"ng-hidden\"\n enterActiveClass=\"px-scalein\"\n leaveToClass=\"ng-hidden\"\n leaveActiveClass=\"px-fadeout\">\n <i class=\"pi pi-fw pi-user text-base mr-2\"></i>\n <div>\n <strong>{{ user()?.displayName ?? user()?.username }}</strong>\n @if (userRoles().length > 0) {\n <small>\n <br />\n {{ userRoles() }}\n </small>\n }\n </div>\n </a>\n </li>\n @if (user()?.logout || user()?.logoutUrl) {\n <li role=\"menuitem\">\n <a\n [href]=\"user()?.logoutUrl ?? hrefJsVoid\"\n (click)=\"logout(user(), $event)\"\n class=\"flex align-items-center hover:text-primary-500 transition-duration-200\"\n pStyleClass=\"@grandparent\"\n enterFromClass=\"ng-hidden\"\n enterActiveClass=\"px-scalein\"\n leaveToClass=\"ng-hidden\"\n leaveActiveClass=\"px-fadeout\">\n <i class=\"pi pi-fw pi-sign-out text-base mr-2\"></i>\n <span>{{ 'mngTopbar.logout' | translate }}</span>\n </a>\n </li>\n }\n</ul>\n" }]
708
+ args: [{ standalone: true, selector: 'mng-topbar-user-component', imports: [AsyncPipe, EnumerateAsyncPipe, TranslateModule, RippleModule, StyleClassModule], changeDetection: ChangeDetectionStrategy.OnPush, template: "<a\n class=\"cursor-pointer lg:pr-4\"\n pStyleClass=\"@next\"\n enterFromClass=\"ng-hidden\"\n enterActiveClass=\"px-scalein\"\n leaveToClass=\"ng-hidden\"\n leaveActiveClass=\"px-fadeout\"\n [hideOnOutsideClick]=\"true\"\n pRipple>\n <i class=\"pi pi-fw pi-user text-2xl\"></i>\n <span class=\"hidden sm:inline-block\">&nbsp; {{ user()?.displayName ?? user()?.username }}</span>\n</a>\n<ul class=\"topbar-menu active-topbar-menu w-15rem z-5 ng-hidden border-round\">\n <li role=\"menuitem\">\n <a\n class=\"flex align-items-center transition-duration-200\"\n pStyleClass=\"@grandparent\"\n enterFromClass=\"ng-hidden\"\n enterActiveClass=\"px-scalein\"\n leaveToClass=\"ng-hidden\"\n leaveActiveClass=\"px-fadeout\">\n <i class=\"pi pi-fw pi-user text-base mr-2\"></i>\n <div>\n <strong>{{ user()?.displayName ?? user()?.username }}</strong>\n @if (userRoles().length > 0) {\n <small>\n <br />\n {{ userRoles() }}\n </small>\n }\n </div>\n </a>\n </li>\n <li role=\"menuitem\">\n <a\n [href]=\"hrefJsVoid\"\n (click)=\"openSettings()\"\n class=\"flex align-items-center transition-duration-200\"\n pStyleClass=\"@grandparent\"\n enterFromClass=\"ng-hidden\"\n enterActiveClass=\"px-scalein\"\n leaveToClass=\"ng-hidden\"\n leaveActiveClass=\"px-fadeout\">\n <i class=\"pi pi-fw pi-cog text-base mr-2\"></i>\n {{ 'mngSettings.title' | translate }}\n </a>\n </li>\n @if (user()?.logout || user()?.logoutUrl) {\n <li role=\"menuitem\">\n <a\n [href]=\"user()?.logoutUrl ?? hrefJsVoid\"\n (click)=\"logout(user(), $event)\"\n class=\"flex align-items-center hover:text-primary-500 transition-duration-200\"\n pStyleClass=\"@grandparent\"\n enterFromClass=\"ng-hidden\"\n enterActiveClass=\"px-scalein\"\n leaveToClass=\"ng-hidden\"\n leaveActiveClass=\"px-fadeout\">\n <i class=\"pi pi-fw pi-sign-out text-base mr-2\"></i>\n <span>{{ 'mngTopbar.logout' | translate }}</span>\n </a>\n </li>\n }\n</ul>\n" }]
699
709
  }] });
700
710
 
701
711
  class TopbarComponent {
@@ -714,7 +724,7 @@ class TopbarComponent {
714
724
  this.commons.setAppLocale(language);
715
725
  }
716
726
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.5", ngImport: i0, type: TopbarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
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 }); }
727
+ 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: i4.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: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
718
728
  }
719
729
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.5", ngImport: i0, type: TopbarComponent, decorators: [{
720
730
  type: Component,
@@ -730,7 +740,6 @@ class MainLayoutComponent {
730
740
  this.renderer = inject(Renderer2);
731
741
  this.appTopbar = viewChild('topbarCmp');
732
742
  this.colorScheme = computed(() => this.commonsService.colorScheme() ?? 'light');
733
- this.menuMode = signal(this.config?.menuMode ?? 'static');
734
743
  this.ripple = signal(this.config?.ripple ?? true);
735
744
  this.topbarComponent = signal(this.config?.components?.topbar === false ? undefined : this.config?.components?.topbar ?? TopbarComponent);
736
745
  this.breadcrumbsComponent = signal(this.config?.components?.breadcrumb === false ? undefined : this.config?.components?.breadcrumb ?? BreadcrumbComponent);
@@ -786,11 +795,11 @@ class MainLayoutComponent {
786
795
  }
787
796
  }
788
797
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.5", ngImport: i0, type: MainLayoutComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
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 }); }
798
+ 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': layoutService.menuMode() === 'overlay',\n 'layout-static': layoutService.menuMode() === 'static',\n 'layout-reveal': layoutService.menuMode() === 'reveal',\n 'layout-drawer': layoutService.menuMode() === 'drawer',\n 'layout-slim': layoutService.menuMode() === 'slim',\n 'layout-slim-plus': layoutService.menuMode() === 'slim-plus',\n 'layout-static-inactive': layoutService.state().staticMenuDesktopInactive && layoutService.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 }); }
790
799
  }
791
800
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.5", ngImport: i0, type: MainLayoutComponent, decorators: [{
792
801
  type: Component,
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" }]
802
+ 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': layoutService.menuMode() === 'overlay',\n 'layout-static': layoutService.menuMode() === 'static',\n 'layout-reveal': layoutService.menuMode() === 'reveal',\n 'layout-drawer': layoutService.menuMode() === 'drawer',\n 'layout-slim': layoutService.menuMode() === 'slim',\n 'layout-slim-plus': layoutService.menuMode() === 'slim-plus',\n 'layout-static-inactive': layoutService.state().staticMenuDesktopInactive && layoutService.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
803
  }], ctorParameters: () => [] });
795
804
 
796
805
  /**
@@ -828,5 +837,5 @@ function withLayout(config) {
828
837
  * Generated bundle index. Do not edit.
829
838
  */
830
839
 
831
- export { BreadcrumbComponent, COMMONS_LAYOUT_FEATURE_CONFIG_IT, FooterComponent, MainLayoutComponent, MainLayoutComponentService, MenuComponent, MenuItemComponent, MenuService, SidebarComponent, TopbarComponent, TopbarUserComponent, VersionComponent, VersionService, createLayoutRoute, withLayout };
840
+ export { BreadcrumbComponent, COMMONS_LAYOUT_FEATURE_CONFIG_IT, FooterComponent, MainLayoutComponent, MainLayoutComponentService, MenuComponent, MenuItemComponent, MenuService, SettingsComponent, SidebarComponent, TopbarComponent, TopbarUserComponent, VersionComponent, VersionService, createLayoutRoute, withLayout };
832
841
  //# sourceMappingURL=mediusinc-mng-commons-layout.mjs.map