@mediusinc/mng-commons-layout 6.0.0-rc.2 → 6.0.0-rc.3

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.
Files changed (84) hide show
  1. package/components/README.md +3 -0
  2. package/components/index.d.ts +10 -0
  3. package/{lib → components/lib}/components/footer.component.d.ts +1 -1
  4. package/{lib → components/lib}/components/main-layout.component.d.ts +1 -1
  5. package/{lib → components/lib}/components/menu-item.component.d.ts +2 -2
  6. package/{lib → components/lib}/components/menu.component.d.ts +1 -1
  7. package/{lib → components/lib}/components/settings.component.d.ts +1 -2
  8. package/{lib → components/lib}/components/sidebar.component.d.ts +1 -1
  9. package/{lib → components/lib}/components/topbar.component.d.ts +2 -2
  10. package/components/pages/error/README.md +3 -0
  11. package/components/pages/error/index.d.ts +2 -0
  12. package/{lib/components/pages/error → components/pages/error/lib}/error.page.component.d.ts +1 -1
  13. package/components/pages/main/README.md +3 -0
  14. package/components/pages/main/index.d.ts +2 -0
  15. package/components/pages/main/lazy/README.md +3 -0
  16. package/components/pages/main/lazy/index.d.ts +1 -0
  17. package/components/pages/main/lazy/lib/route-builder.d.ts +8 -0
  18. package/components/pages/main/lib/main-layout.component.d.ts +23 -0
  19. package/components/pages/not-found/README.md +3 -0
  20. package/components/pages/not-found/index.d.ts +2 -0
  21. package/{lib/components/pages/not-found → components/pages/not-found/lib}/not-found.page.component.d.ts +1 -1
  22. package/esm2022/components/index.mjs +12 -0
  23. package/esm2022/components/lib/components/breadcrumb.component.mjs +29 -0
  24. package/esm2022/components/lib/components/footer.component.mjs +23 -0
  25. package/esm2022/components/lib/components/main-layout.component.mjs +86 -0
  26. package/esm2022/components/lib/components/menu-item.component.mjs +169 -0
  27. package/esm2022/components/lib/components/menu.component.mjs +36 -0
  28. package/esm2022/components/lib/components/settings.component.mjs +87 -0
  29. package/esm2022/components/lib/components/sidebar.component.mjs +51 -0
  30. package/esm2022/components/lib/components/topbar-user.component.mjs +51 -0
  31. package/esm2022/components/lib/components/topbar.component.mjs +37 -0
  32. package/esm2022/components/lib/components/version.component.mjs +95 -0
  33. package/esm2022/components/mediusinc-mng-commons-layout-components.mjs +5 -0
  34. package/esm2022/components/pages/error/index.mjs +3 -0
  35. package/esm2022/components/pages/error/lib/error.page.component.mjs +20 -0
  36. package/esm2022/components/pages/error/mediusinc-mng-commons-layout-components-pages-error.mjs +5 -0
  37. package/esm2022/components/pages/main/index.mjs +3 -0
  38. package/esm2022/components/pages/main/lazy/index.mjs +2 -0
  39. package/esm2022/components/pages/main/lazy/lib/route-builder.mjs +11 -0
  40. package/esm2022/components/pages/main/lazy/mediusinc-mng-commons-layout-components-pages-main-lazy.mjs +5 -0
  41. package/esm2022/components/pages/main/lib/main-layout.component.mjs +84 -0
  42. package/esm2022/components/pages/main/lib/route-builder.mjs +12 -0
  43. package/esm2022/components/pages/main/mediusinc-mng-commons-layout-components-pages-main.mjs +5 -0
  44. package/esm2022/components/pages/not-found/index.mjs +3 -0
  45. package/esm2022/components/pages/not-found/lib/not-found.page.component.mjs +20 -0
  46. package/esm2022/components/pages/not-found/mediusinc-mng-commons-layout-components-pages-not-found.mjs +5 -0
  47. package/esm2022/index.mjs +2 -15
  48. package/esm2022/lib/helpers/menu-items.mjs +4 -1
  49. package/esm2022/lib/services/layout-feature-config.token.mjs +1 -1
  50. package/fesm2022/mediusinc-mng-commons-layout-components-pages-error.mjs +25 -0
  51. package/fesm2022/mediusinc-mng-commons-layout-components-pages-error.mjs.map +1 -0
  52. package/fesm2022/mediusinc-mng-commons-layout-components-pages-main-lazy.mjs +18 -0
  53. package/fesm2022/mediusinc-mng-commons-layout-components-pages-main-lazy.mjs.map +1 -0
  54. package/fesm2022/mediusinc-mng-commons-layout-components-pages-main.mjs +101 -0
  55. package/fesm2022/mediusinc-mng-commons-layout-components-pages-main.mjs.map +1 -0
  56. package/fesm2022/mediusinc-mng-commons-layout-components-pages-not-found.mjs +25 -0
  57. package/fesm2022/mediusinc-mng-commons-layout-components-pages-not-found.mjs.map +1 -0
  58. package/fesm2022/mediusinc-mng-commons-layout-components.mjs +600 -0
  59. package/fesm2022/mediusinc-mng-commons-layout-components.mjs.map +1 -0
  60. package/fesm2022/mediusinc-mng-commons-layout.mjs +69 -683
  61. package/fesm2022/mediusinc-mng-commons-layout.mjs.map +1 -1
  62. package/index.d.ts +1 -13
  63. package/lib/helpers/menu-items.d.ts +3 -0
  64. package/lib/services/layout-feature-config.token.d.ts +2 -2
  65. package/lib/services/layout.service.d.ts +2 -2
  66. package/package.json +32 -2
  67. package/version-info.json +6 -6
  68. package/esm2022/lib/components/breadcrumb.component.mjs +0 -29
  69. package/esm2022/lib/components/footer.component.mjs +0 -25
  70. package/esm2022/lib/components/main-layout.component.mjs +0 -88
  71. package/esm2022/lib/components/menu-item.component.mjs +0 -170
  72. package/esm2022/lib/components/menu.component.mjs +0 -38
  73. package/esm2022/lib/components/pages/error/error.page.component.mjs +0 -20
  74. package/esm2022/lib/components/pages/not-found/not-found.page.component.mjs +0 -20
  75. package/esm2022/lib/components/settings.component.mjs +0 -87
  76. package/esm2022/lib/components/sidebar.component.mjs +0 -52
  77. package/esm2022/lib/components/topbar-user.component.mjs +0 -52
  78. package/esm2022/lib/components/topbar.component.mjs +0 -39
  79. package/esm2022/lib/components/version.component.mjs +0 -96
  80. package/esm2022/lib/helpers/route-builder.mjs +0 -12
  81. /package/{lib → components/lib}/components/breadcrumb.component.d.ts +0 -0
  82. /package/{lib → components/lib}/components/topbar-user.component.d.ts +0 -0
  83. /package/{lib → components/lib}/components/version.component.d.ts +0 -0
  84. /package/{lib/helpers → components/pages/main/lib}/route-builder.d.ts +0 -0
@@ -1,35 +1,41 @@
1
1
  import * as i0 from '@angular/core';
2
- import { InjectionToken, inject, PLATFORM_ID, signal, computed, afterNextRender, effect, Injectable, Component, ChangeDetectionStrategy, DestroyRef, input, output, viewChild, untracked, ElementRef, Injector, Renderer2 } from '@angular/core';
3
- import * as i1$4 from '@angular/router';
4
- import { RouterLink, Router, NavigationEnd, RouterModule, ActivatedRoute } from '@angular/router';
5
- import * as i1$1 from '@ngx-translate/core';
6
- import { TranslateModule, TranslateService } from '@ngx-translate/core';
7
- import * as i1 from 'primeng/button';
8
- import { ButtonModule, Button } from 'primeng/button';
9
- import { DOCUMENT, AsyncPipe, NgOptimizedImage, NgClass, NgTemplateOutlet } from '@angular/common';
10
- import { Subject, ReplaySubject, catchError, of, switchMap, take, startWith, distinctUntilChanged } from 'rxjs';
2
+ import { signal, computed, InjectionToken, inject, PLATFORM_ID, afterNextRender, effect, Injectable, DestroyRef } from '@angular/core';
3
+ import { DOCUMENT } from '@angular/common';
4
+ import { Subject, ReplaySubject, startWith, take } from 'rxjs';
11
5
  import * as i2 from '@mediusinc/mng-commons/core';
12
- import { COMMONS_MODULE_CONFIG_IT, CommonsStorageService, LoggerService, CommonsConfigurationService, JsonPathPipe, CommonsService, ComponentDirective, CommonsRouterService, adjustRouteMenuLazyChildrenRouterLinks, doesUrlMatchRouterLink, PermissionService, toObservable as toObservable$1, EnumerateAsyncPipe, NotificationWrapperComponent, createRoute, CommonsFeatureTypeEnum } from '@mediusinc/mng-commons/core';
13
- import { toObservable, takeUntilDestroyed, toSignal } from '@angular/core/rxjs-interop';
14
- import { map, filter } from 'rxjs/operators';
15
- import * as i1$2 from '@angular/common/http';
16
- import * as i3 from '@angular/forms';
17
- import { FormsModule } from '@angular/forms';
18
- import * as i4 from 'primeng/dropdown';
19
- import { DropdownModule } from 'primeng/dropdown';
20
- import * as i1$3 from 'primeng/ripple';
21
- import { RippleModule } from 'primeng/ripple';
22
- import * as i3$1 from 'primeng/styleclass';
23
- import { StyleClassModule } from 'primeng/styleclass';
24
- import { trigger, state, style, transition, animate } from '@angular/animations';
25
- import { TooltipModule } from 'primeng/tooltip';
26
- import { DomSanitizer } from '@angular/platform-browser';
27
- import { DynamicDialogConfig, DynamicDialogRef, DialogService } from 'primeng/dynamicdialog';
28
- import { InputSwitchModule } from 'primeng/inputswitch';
29
- import * as i2$1 from 'primeng/radiobutton';
30
- import { RadioButtonModule } from 'primeng/radiobutton';
31
- import * as i5 from 'primeng/selectbutton';
32
- import { SelectButtonModule } from 'primeng/selectbutton';
6
+ import { COMMONS_MODULE_CONFIG_IT, CommonsStorageService, LoggerService, CommonsRouterService, adjustRouteMenuLazyChildrenRouterLinks, doesUrlMatchRouterLink, CommonsFeatureTypeEnum } from '@mediusinc/mng-commons/core';
7
+ import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
8
+ import { Router, NavigationEnd } from '@angular/router';
9
+ import { filter, map } from 'rxjs/operators';
10
+ import * as i1 from '@angular/common/http';
11
+
12
+ /**
13
+ * @internal
14
+ */
15
+ function prepareMenuItemsToInternal(menuItems, parentKey = '') {
16
+ const newItems = menuItems.map((item, idx) => {
17
+ const itemsProp = signal([]);
18
+ const lazyChildrenProp = signal(item.lazyChildren ?? false);
19
+ const hasItemsProp = computed(() => itemsProp().length > 0);
20
+ const newItem = {
21
+ ...item,
22
+ isVisible: item.isVisible,
23
+ key: parentKey ? parentKey + '-' + idx : idx.toString(),
24
+ config: item,
25
+ items: itemsProp,
26
+ lazyChildren: lazyChildrenProp,
27
+ itemsVisibility: signal([]),
28
+ hasItems: hasItemsProp,
29
+ hasItemsOrLazyChildren: computed(() => lazyChildrenProp() || hasItemsProp())
30
+ };
31
+ if (Array.isArray(item.items) && item.items.length > 0) {
32
+ newItem.items.set(prepareMenuItemsToInternal(item.items, newItem.key));
33
+ newItem.itemsVisibility.set(newItem.items()?.map(() => signal(true)));
34
+ }
35
+ return newItem;
36
+ });
37
+ return newItems;
38
+ }
33
39
 
34
40
  const COMMONS_LAYOUT_FEATURE_CONFIG_IT = new InjectionToken('COMMONS_LAYOUT_FEATURE_CONFIG');
35
41
 
@@ -194,221 +200,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.12", ngImpo
194
200
  type: Injectable
195
201
  }], ctorParameters: () => [] });
196
202
 
197
- class ErrorPageComponent {
198
- constructor() {
199
- this.layout = inject(LayoutService);
200
- }
201
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.12", ngImport: i0, type: ErrorPageComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
202
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.12", type: ErrorPageComponent, isStandalone: true, selector: "mng-error-page", ngImport: i0, template: "<div [class]=\"'exception-body min-h-screen ' + (layout.colorSchemeIsLight() ? 'layout-light' : 'layout-dark')\">\n <div class=\"exception-container min-h-screen flex align-items-center justify-content-center flex-column bg-auto md:bg-contain bg-no-repeat\">\n <div class=\"exception-panel text-center flex align-items-center justify-content-center flex-column\">\n <h1 class=\"text-red-400 mb-0\">{{ 'pages.notFound.title' | translate }}</h1>\n <h3 class=\"text-red-300\">{{ 'pages.notFound.subtitle' | translate }}</h3>\n <button type=\"button\" pButton [label]=\"'general.returnHome' | translate\" [routerLink]=\"['/']\"></button>\n </div>\n <div class=\"exception-footer align-items-center flex\">\n <img [src]=\"layout.appLogo()\" class=\"exception-logo\" alt=\"App logo\" />\n <img [src]=\"layout.appLogoName()\" class=\"exception-appname ml-3\" alt=\"App name\" />\n </div>\n </div>\n</div>\n", styles: [".exception-body{background:var(--surface-ground)}.exception-body .exception-container{background:var(--exception-pages-image);background-repeat:no-repeat;background-size:contain;box-sizing:border-box}.exception-body .exception-container .exception-panel{box-sizing:border-box;flex-grow:1;margin-top:3rem;margin-bottom:3rem}.exception-body .exception-container .exception-panel h1{font-size:140px;font-weight:900;text-shadow:0 0 50px rgba(252,97,97,.2)}.exception-body .exception-container .exception-panel h3{font-size:80px;font-weight:900;margin-top:-90px;margin-bottom:50px}.exception-body .exception-container .exception-panel button{margin-top:50px}.exception-body .exception-container .exception-footer{margin-bottom:2rem}.exception-body .exception-container .exception-footer .exception-logo{width:34px}.exception-body .exception-container .exception-footer .exception-appname{width:72px}\n"], dependencies: [{ kind: "ngmodule", type: ButtonModule }, { kind: "directive", type: i1.ButtonDirective, selector: "[pButton]", inputs: ["iconPos", "loadingIcon", "label", "icon", "loading", "severity", "raised", "rounded", "text", "outlined", "size", "plain"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i1$1.TranslatePipe, name: "translate" }, { kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
203
- }
204
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.12", ngImport: i0, type: ErrorPageComponent, decorators: [{
205
- type: Component,
206
- args: [{ standalone: true, selector: 'mng-error-page', imports: [ButtonModule, TranslateModule, RouterLink], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div [class]=\"'exception-body min-h-screen ' + (layout.colorSchemeIsLight() ? 'layout-light' : 'layout-dark')\">\n <div class=\"exception-container min-h-screen flex align-items-center justify-content-center flex-column bg-auto md:bg-contain bg-no-repeat\">\n <div class=\"exception-panel text-center flex align-items-center justify-content-center flex-column\">\n <h1 class=\"text-red-400 mb-0\">{{ 'pages.notFound.title' | translate }}</h1>\n <h3 class=\"text-red-300\">{{ 'pages.notFound.subtitle' | translate }}</h3>\n <button type=\"button\" pButton [label]=\"'general.returnHome' | translate\" [routerLink]=\"['/']\"></button>\n </div>\n <div class=\"exception-footer align-items-center flex\">\n <img [src]=\"layout.appLogo()\" class=\"exception-logo\" alt=\"App logo\" />\n <img [src]=\"layout.appLogoName()\" class=\"exception-appname ml-3\" alt=\"App name\" />\n </div>\n </div>\n</div>\n", styles: [".exception-body{background:var(--surface-ground)}.exception-body .exception-container{background:var(--exception-pages-image);background-repeat:no-repeat;background-size:contain;box-sizing:border-box}.exception-body .exception-container .exception-panel{box-sizing:border-box;flex-grow:1;margin-top:3rem;margin-bottom:3rem}.exception-body .exception-container .exception-panel h1{font-size:140px;font-weight:900;text-shadow:0 0 50px rgba(252,97,97,.2)}.exception-body .exception-container .exception-panel h3{font-size:80px;font-weight:900;margin-top:-90px;margin-bottom:50px}.exception-body .exception-container .exception-panel button{margin-top:50px}.exception-body .exception-container .exception-footer{margin-bottom:2rem}.exception-body .exception-container .exception-footer .exception-logo{width:34px}.exception-body .exception-container .exception-footer .exception-appname{width:72px}\n"] }]
207
- }] });
208
-
209
- class NotFoundPageComponent {
210
- constructor() {
211
- this.layout = inject(LayoutService);
212
- }
213
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.12", ngImport: i0, type: NotFoundPageComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
214
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.12", type: NotFoundPageComponent, isStandalone: true, selector: "mng-not-found-page", ngImport: i0, template: "<div [class]=\"'exception-body min-h-screen ' + (layout.colorSchemeIsLight() ? 'layout-light' : 'layout-dark')\">\n <div class=\"exception-container min-h-screen flex align-items-center justify-content-center flex-column bg-auto md:bg-contain bg-no-repeat\">\n <div class=\"exception-panel text-center flex align-items-center justify-content-center flex-column\">\n <h1 class=\"text-red-400 mb-0\">{{ 'pages.notFound.title' | translate }}</h1>\n <h3 class=\"text-red-300\">{{ 'pages.notFound.subtitle' | translate }}</h3>\n <p>{{ 'pages.notFound.message' | translate }}</p>\n <button type=\"button\" pButton [label]=\"'general.returnHome' | translate\" [routerLink]=\"['/']\"></button>\n </div>\n <div class=\"exception-footer align-items-center flex\">\n <img [src]=\"layout.appLogo()\" class=\"exception-logo\" alt=\"App logo\" />\n <img [src]=\"layout.appLogoName()\" class=\"exception-appname ml-3\" alt=\"App name\" />\n </div>\n </div>\n</div>\n", styles: [".exception-body{background:var(--surface-ground)}.exception-body .exception-container{background:var(--exception-pages-image);background-repeat:no-repeat;background-size:contain;box-sizing:border-box}.exception-body .exception-container .exception-panel{box-sizing:border-box;flex-grow:1;margin-top:3rem;margin-bottom:3rem}.exception-body .exception-container .exception-panel h1{font-size:140px;font-weight:900;text-shadow:0 0 50px rgba(252,97,97,.2)}.exception-body .exception-container .exception-panel h3{font-size:80px;font-weight:900;margin-top:-90px;margin-bottom:50px}.exception-body .exception-container .exception-panel p{font-size:24px;font-weight:400;max-width:320px}.exception-body .exception-container .exception-panel button{margin-top:50px}.exception-body .exception-container .exception-footer{margin-bottom:2rem}.exception-body .exception-container .exception-footer .exception-logo{width:34px}.exception-body .exception-container .exception-footer .exception-appname{width:72px}\n"], dependencies: [{ kind: "ngmodule", type: ButtonModule }, { kind: "directive", type: i1.ButtonDirective, selector: "[pButton]", inputs: ["iconPos", "loadingIcon", "label", "icon", "loading", "severity", "raised", "rounded", "text", "outlined", "size", "plain"] }, { kind: "directive", type: 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" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
215
- }
216
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.12", ngImport: i0, type: NotFoundPageComponent, decorators: [{
217
- type: Component,
218
- args: [{ standalone: true, selector: 'mng-not-found-page', imports: [ButtonModule, RouterLink, TranslateModule], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div [class]=\"'exception-body min-h-screen ' + (layout.colorSchemeIsLight() ? 'layout-light' : 'layout-dark')\">\n <div class=\"exception-container min-h-screen flex align-items-center justify-content-center flex-column bg-auto md:bg-contain bg-no-repeat\">\n <div class=\"exception-panel text-center flex align-items-center justify-content-center flex-column\">\n <h1 class=\"text-red-400 mb-0\">{{ 'pages.notFound.title' | translate }}</h1>\n <h3 class=\"text-red-300\">{{ 'pages.notFound.subtitle' | translate }}</h3>\n <p>{{ 'pages.notFound.message' | translate }}</p>\n <button type=\"button\" pButton [label]=\"'general.returnHome' | translate\" [routerLink]=\"['/']\"></button>\n </div>\n <div class=\"exception-footer align-items-center flex\">\n <img [src]=\"layout.appLogo()\" class=\"exception-logo\" alt=\"App logo\" />\n <img [src]=\"layout.appLogoName()\" class=\"exception-appname ml-3\" alt=\"App name\" />\n </div>\n </div>\n</div>\n", styles: [".exception-body{background:var(--surface-ground)}.exception-body .exception-container{background:var(--exception-pages-image);background-repeat:no-repeat;background-size:contain;box-sizing:border-box}.exception-body .exception-container .exception-panel{box-sizing:border-box;flex-grow:1;margin-top:3rem;margin-bottom:3rem}.exception-body .exception-container .exception-panel h1{font-size:140px;font-weight:900;text-shadow:0 0 50px rgba(252,97,97,.2)}.exception-body .exception-container .exception-panel h3{font-size:80px;font-weight:900;margin-top:-90px;margin-bottom:50px}.exception-body .exception-container .exception-panel p{font-size:24px;font-weight:400;max-width:320px}.exception-body .exception-container .exception-panel button{margin-top:50px}.exception-body .exception-container .exception-footer{margin-bottom:2rem}.exception-body .exception-container .exception-footer .exception-logo{width:34px}.exception-body .exception-container .exception-footer .exception-appname{width:72px}\n"] }]
219
- }] });
220
-
221
- class VersionService {
222
- constructor(http, configurationService) {
223
- this.http = http;
224
- this.configurationService = configurationService;
225
- this.logger = inject(LoggerService).create('VersionService');
226
- this.cache = {};
227
- }
228
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
229
- loadVersion(path, baseConfigKey, jsonPath = '$') {
230
- const urlSegments = [];
231
- if (baseConfigKey) {
232
- const baseUrl = this.configurationService.getConfigValue(baseConfigKey);
233
- urlSegments.push(baseUrl.endsWith('/') ? baseUrl.substring(0, baseUrl.length - 1) : baseUrl);
234
- }
235
- if (path) {
236
- urlSegments.push(!path.startsWith('/') ? `/${path}` : path);
237
- }
238
- const url = urlSegments.join('');
239
- if (!this.cache[url]) {
240
- this.cache[url] = new ReplaySubject(1);
241
- this.http.get(urlSegments.join('')).subscribe({
242
- next: res => {
243
- this.cache[url].next(res);
244
- },
245
- error: err => {
246
- this.logger.error('Version could not be retreived', err);
247
- }
248
- });
249
- }
250
- return this.cache[url].asObservable();
251
- }
252
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.12", ngImport: i0, type: VersionService, deps: [{ token: i1$2.HttpClient }, { token: i2.CommonsConfigurationService }], target: i0.ɵɵFactoryTarget.Injectable }); }
253
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.12", ngImport: i0, type: VersionService }); }
254
- }
255
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.12", ngImport: i0, type: VersionService, decorators: [{
256
- type: Injectable
257
- }], ctorParameters: () => [{ type: i1$2.HttpClient }, { type: i2.CommonsConfigurationService }] });
258
-
259
- class VersionComponent {
260
- constructor() {
261
- this.versionService = inject(VersionService);
262
- this.configService = inject(CommonsConfigurationService);
263
- this.destroyRef = inject(DestroyRef);
264
- this.jsonPathPipe = new JsonPathPipe();
265
- this.versionInput = input(undefined, { alias: 'version' });
266
- this.isLoading = signal(false);
267
- this.loadedVersion = signal(undefined);
268
- this.versionAsArray = computed(() => {
269
- if (Array.isArray(this.versionInput())) {
270
- return this.versionInput();
271
- }
272
- return undefined;
273
- });
274
- this.versionInfo = computed(() => {
275
- if (this.versionAsArray() !== undefined) {
276
- return undefined; // Each version will be processed separately in child component
277
- }
278
- const initVersion = this.versionInput();
279
- if (typeof initVersion === 'string') {
280
- return initVersion;
281
- }
282
- else if (typeof initVersion !== 'undefined' && !Array.isArray(initVersion)) {
283
- const source = initVersion.source;
284
- switch (source) {
285
- case 'config':
286
- return this.configService.getConfigValue(initVersion.configKey);
287
- case 'httpResource':
288
- return this.loadedVersion();
289
- case 'info':
290
- return initVersion.info;
291
- default:
292
- return initVersion;
293
- }
294
- }
295
- return undefined;
296
- });
297
- this.versionAsString = computed(() => {
298
- const versionInfo = this.versionInfo();
299
- if (versionInfo == null) {
300
- return undefined;
301
- }
302
- else if (typeof versionInfo === 'string') {
303
- return versionInfo;
304
- }
305
- else {
306
- return versionInfo.raw;
307
- }
308
- });
309
- this.displayName = computed(() => this.versionInput()?.displayName);
310
- this.displayText = computed(() => `${this.displayName() ?? ''}${this.displayName() && this.versionAsString() ? ': ' : ''}${!this.isLoading() ? (this.versionAsString() ?? '') : ''}`);
311
- toObservable(this.versionInput)
312
- .pipe(catchError(() => of(undefined)), switchMap(version => {
313
- if (typeof version !== 'undefined' && !Array.isArray(version)) {
314
- const config = version;
315
- if (config.source === 'httpResource') {
316
- this.isLoading.set(true);
317
- const infoJsonPath = config.infoJsonPath;
318
- return this.versionService.loadVersion(config.urlPath, config.urlBaseConfigKey).pipe(take(1), map(res => ({ res, infoJsonPath })));
319
- }
320
- }
321
- return of({ res: undefined, infoJsonPath: undefined });
322
- }), takeUntilDestroyed(this.destroyRef))
323
- .subscribe({
324
- next: ({ res, infoJsonPath }) => {
325
- if (typeof res !== 'undefined') {
326
- this.loadedVersion.set(this.jsonPathPipe.transform(res, infoJsonPath ?? '$'));
327
- }
328
- else {
329
- this.loadedVersion.set(undefined);
330
- }
331
- this.isLoading.set(false);
332
- },
333
- error: () => {
334
- this.loadedVersion.set('');
335
- this.isLoading.set(false);
336
- }
337
- });
338
- }
339
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.12", ngImport: i0, type: VersionComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
340
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.12", type: VersionComponent, isStandalone: true, selector: "mng-version", inputs: { versionInput: { classPropertyName: "versionInput", publicName: "version", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "@if (versionAsArray()) {\n @for (v of versionAsArray(); track v; let last = $last) {\n <mng-version [version]=\"v\"></mng-version>\n @if (!last) {\n <br />\n }\n }\n} @else if (displayText()) {\n {{ displayText() }}\n}\n", dependencies: [{ kind: "component", type: VersionComponent, selector: "mng-version", inputs: ["version"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
341
- }
342
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.12", ngImport: i0, type: VersionComponent, decorators: [{
343
- type: Component,
344
- args: [{ standalone: true, selector: 'mng-version', imports: [AsyncPipe], changeDetection: ChangeDetectionStrategy.OnPush, template: "@if (versionAsArray()) {\n @for (v of versionAsArray(); track v; let last = $last) {\n <mng-version [version]=\"v\"></mng-version>\n @if (!last) {\n <br />\n }\n }\n} @else if (displayText()) {\n {{ displayText() }}\n}\n" }]
345
- }], ctorParameters: () => [] });
346
-
347
- class FooterComponent {
348
- constructor() {
349
- this.config = inject(COMMONS_LAYOUT_FEATURE_CONFIG_IT, { optional: true });
350
- this.layout = inject(LayoutService);
351
- this.commons = inject(CommonsService);
352
- this.currentYear = signal(new Date().getFullYear());
353
- this.versionComponent = signal(this.config?.components?.version === false ? undefined : (this.config?.components?.version ?? VersionComponent));
354
- }
355
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.12", ngImport: i0, type: FooterComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
356
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.12", 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]=\"layout.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 }); }
357
- }
358
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.12", ngImport: i0, type: FooterComponent, decorators: [{
359
- type: Component,
360
- 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]=\"layout.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" }]
361
- }] });
362
-
363
- class BreadcrumbComponent {
364
- constructor() {
365
- this.commons = inject(CommonsService);
366
- this.mappedBreadcrumbs = computed(() => {
367
- const items = this.commons.breadcrumbs();
368
- return items.map(el => this.mapMenuItem(el));
369
- });
370
- }
371
- mapMenuItem(item) {
372
- return {
373
- ...item,
374
- url: item.href,
375
- badgeStyleClass: item.badgeClassName,
376
- styleClass: item.className
377
- };
378
- }
379
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.12", ngImport: i0, type: BreadcrumbComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
380
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.12", 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 }); }
381
- }
382
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.12", ngImport: i0, type: BreadcrumbComponent, decorators: [{
383
- type: Component,
384
- 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" }]
385
- }] });
386
-
387
- function prepareMenuItemsToInternal(menuItems, parentKey = '') {
388
- const newItems = menuItems.map((item, idx) => {
389
- const itemsProp = signal([]);
390
- const lazyChildrenProp = signal(item.lazyChildren ?? false);
391
- const hasItemsProp = computed(() => itemsProp().length > 0);
392
- const newItem = {
393
- ...item,
394
- isVisible: item.isVisible,
395
- key: parentKey ? parentKey + '-' + idx : idx.toString(),
396
- config: item,
397
- items: itemsProp,
398
- lazyChildren: lazyChildrenProp,
399
- itemsVisibility: signal([]),
400
- hasItems: hasItemsProp,
401
- hasItemsOrLazyChildren: computed(() => lazyChildrenProp() || hasItemsProp())
402
- };
403
- if (Array.isArray(item.items) && item.items.length > 0) {
404
- newItem.items.set(prepareMenuItemsToInternal(item.items, newItem.key));
405
- newItem.itemsVisibility.set(newItem.items()?.map(() => signal(true)));
406
- }
407
- return newItem;
408
- });
409
- return newItems;
410
- }
411
-
412
203
  class MenuService {
413
204
  constructor() {
414
205
  this.destroyRef = inject(DestroyRef);
@@ -522,448 +313,43 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.12", ngImpo
522
313
  type: Injectable
523
314
  }] });
524
315
 
525
- class MenuItemComponent {
526
- constructor() {
527
- this.menuService = inject(MenuService);
528
- this.permissionService = inject(PermissionService);
529
- this.layout = inject(LayoutService);
530
- this.item = input.required();
531
- this.root = input(false);
532
- this.visibleChange = output();
533
- this.submenuElRef = viewChild('submenu');
534
- this.isPermitted = toSignal(toObservable(this.item).pipe(switchMap(i => (i.permissions ? this.permissionService.isMenuItemVisible(i.permissions, i.config) : of(true)))));
535
- this.isVisibleFromItemSettings = toSignal(toObservable(this.item).pipe(switchMap(i => (typeof i.isVisible === 'function' ? toObservable$1(i.isVisible(i.config)) : of(i.isVisible ?? true)))));
536
- this.menuChangeEvents = toSignal(this.menuService.menuChange$.pipe(distinctUntilChanged((v1, v2) => v1.key === v2.key)));
537
- this.active = computed(() => {
538
- if (!this.isPermitted()) {
539
- return false;
540
- }
541
- const menuChangeEvent = this.menuChangeEvents();
542
- if (menuChangeEvent) {
543
- return menuChangeEvent.eventType === 'reset' || !menuChangeEvent.key
544
- ? false
545
- : this.item().key === menuChangeEvent.key || menuChangeEvent.key.startsWith((this.item().key ?? '') + '-');
546
- }
547
- return false;
548
- });
549
- this.visible = computed(() => {
550
- const isPermitted = this.isPermitted();
551
- if (!isPermitted) {
552
- return false;
553
- }
554
- if (!this.isVisibleFromItemSettings()) {
555
- return false;
556
- }
557
- const items = this.item().items();
558
- if (Array.isArray(items) &&
559
- items.length > 0 &&
560
- this.item()
561
- .itemsVisibility()
562
- .every(v => !v())) {
563
- return false;
564
- }
565
- return true;
566
- });
567
- this.submenuAnimation = computed(() => {
568
- if (this.layout.isDesktop() && (this.layout.isSlim() || this.layout.isSlimPlus())) {
569
- return this.layout.submenuOverlayKey() === this.item().key ? 'visible' : 'hidden';
570
- }
571
- else {
572
- return this.root() ? 'expanded' : this.active() ? 'expanded' : 'collapsed';
573
- }
574
- });
575
- effect(() => {
576
- if (this.root() && this.active() && this.layout.isDesktop() && (this.layout.isSlim() || this.layout.isSlimPlus())) {
577
- this.calculatePosition(this.submenuElRef()?.nativeElement, this.submenuElRef()?.nativeElement.parentElement);
578
- }
579
- });
580
- }
581
- itemClick(event) {
582
- const item = this.item();
583
- // avoid processing disabled items
584
- if (item.disabled) {
585
- event.preventDefault();
586
- return;
587
- }
588
- if (item.hasItemsOrLazyChildren()) {
589
- // open submenu in slim/slim+ mode
590
- if (this.root() && (this.layout.isSlim() || this.layout.isSlimPlus())) {
591
- this.layout.onOverlaySubmenuOpen(item.key);
592
- }
593
- }
594
- else {
595
- if (this.layout.isMobile()) {
596
- this.layout.state.update(state => ({
597
- ...state,
598
- staticMenuMobileActive: false
599
- }));
600
- }
601
- if (this.layout.isSlim() || this.layout.isSlimPlus()) {
602
- this.layout.state.update(state => ({
603
- ...state,
604
- menuHoverActive: false
605
- }));
606
- }
607
- if (this.layout.submenuOverlayKey() !== undefined) {
608
- this.layout.onOverlaySubmenuClose();
609
- }
610
- }
611
- }
612
- onSubmenuAnimated(event) {
613
- if (event.toState === 'visible' && this.layout.isDesktop() && (this.layout.isSlim() || this.layout.isSlimPlus())) {
614
- const el = event.element;
615
- const elParent = el.parentElement;
616
- this.calculatePosition(el, elParent);
617
- }
618
- }
619
- onChildVisibleChange(visible, item, idx) {
620
- this.item().itemsVisibility()[idx]?.set(visible);
621
- }
622
- calculatePosition(overlay, target) {
623
- if (overlay) {
624
- const top = target.getBoundingClientRect().top;
625
- const vHeight = window.innerHeight;
626
- const oHeight = overlay.offsetHeight;
627
- // reset
628
- overlay.style.top = '';
629
- overlay.style.left = '';
630
- if (this.layout.isSlim() || this.layout.isSlimPlus()) {
631
- const height = top + oHeight;
632
- overlay.style.top = vHeight < height ? `${top - (height - vHeight)}px` : `${top}px`;
633
- }
634
- }
635
- }
636
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.12", ngImport: i0, type: MenuItemComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
637
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.12", 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 [routerLink]=\"layout.isSlim() || layout.isSlimPlus() ? null : item().routerLink\"\n (click)=\"itemClick($event)\"\n (keydown.enter)=\"itemClick($event)\"\n [attr.target]=\"item().target\"\n [attr.tabindex]=\"0\"\n [ngClass]=\"item().className ?? '' + (this.active() ? ' active-route' : '')\"\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$3.Ripple, selector: "[pRipple]" }, { kind: "ngmodule", type: TooltipModule }, { kind: "ngmodule", type: RouterModule }, { kind: "directive", type: i1$4.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: [
638
- trigger('children', [
639
- state('collapsed', style({
640
- height: '0'
641
- })),
642
- state('expanded', style({
643
- height: '*'
644
- })),
645
- state('hidden', style({
646
- display: 'none'
647
- })),
648
- state('visible', style({
649
- display: 'block'
650
- })),
651
- transition('collapsed <=> expanded', animate('400ms cubic-bezier(0.86, 0, 0.07, 1)'))
652
- ])
653
- ], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
654
- }
655
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.12", ngImport: i0, type: MenuItemComponent, decorators: [{
656
- type: Component,
657
- args: [{ standalone: true, selector: '[mng-menuitem]', imports: [NgClass, RippleModule, TooltipModule, RouterModule, TranslateModule, AsyncPipe], changeDetection: ChangeDetectionStrategy.OnPush, animations: [
658
- trigger('children', [
659
- state('collapsed', style({
660
- height: '0'
661
- })),
662
- state('expanded', style({
663
- height: '*'
664
- })),
665
- state('hidden', style({
666
- display: 'none'
667
- })),
668
- state('visible', style({
669
- display: 'block'
670
- })),
671
- transition('collapsed <=> expanded', animate('400ms cubic-bezier(0.86, 0, 0.07, 1)'))
672
- ])
673
- ], host: {
674
- '[class.active-menuitem]': '!root() && active()',
675
- '[class.layout-root-menuitem]': 'root()'
676
- }, 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 [routerLink]=\"layout.isSlim() || layout.isSlimPlus() ? null : item().routerLink\"\n (click)=\"itemClick($event)\"\n (keydown.enter)=\"itemClick($event)\"\n [attr.target]=\"item().target\"\n [attr.tabindex]=\"0\"\n [ngClass]=\"item().className ?? '' + (this.active() ? ' active-route' : '')\"\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" }]
677
- }], ctorParameters: () => [] });
678
-
679
- class MenuComponent {
680
- constructor() {
681
- this.route = inject(ActivatedRoute);
682
- this.config = inject(COMMONS_LAYOUT_FEATURE_CONFIG_IT, { optional: true });
683
- this.layout = inject(LayoutService);
684
- this.menuService = inject(MenuService);
685
- this.routeData = toSignal(this.route.data);
686
- effect(() => {
687
- let items = [];
688
- if (this.config?.menuItems && Array.isArray(this.config.menuItems)) {
689
- items = this.config.menuItems;
690
- }
691
- else if (Array.isArray(this.routeData()?.menuItems)) {
692
- items = this.routeData().menuItems;
693
- }
694
- // Wraps menu items
695
- if (!(this.layout.isSlim() || this.layout.isSlimPlus())) {
696
- items = [{ items }];
697
- }
698
- untracked(() => this.menuService.setItems(items));
699
- });
700
- }
701
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.12", ngImport: i0, type: MenuComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
702
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.12", 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 }); }
703
- }
704
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.12", ngImport: i0, type: MenuComponent, decorators: [{
705
- type: Component,
706
- 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" }]
707
- }], ctorParameters: () => [] });
708
-
709
- class SidebarComponent {
710
- constructor() {
711
- this.config = inject(COMMONS_LAYOUT_FEATURE_CONFIG_IT, { optional: true });
712
- this.layout = inject(LayoutService);
713
- this.el = inject(ElementRef);
714
- this.menuComponent = signal(this.config?.components?.menu === false ? undefined : (this.config?.components?.menu ?? MenuComponent));
715
- this.timeout = null;
716
- }
717
- onMouseEnter() {
718
- if (!this.layout.state().anchored) {
719
- if (this.timeout) {
720
- clearTimeout(this.timeout);
721
- this.timeout = null;
722
- }
723
- this.layout.state.update(state => ({
724
- ...state,
725
- sidebarActive: true
726
- }));
727
- }
728
- }
729
- onMouseLeave() {
730
- if (!this.layout.state().anchored) {
731
- if (!this.timeout) {
732
- this.timeout = setTimeout(() => this.layout.state.update(state => ({
733
- ...state,
734
- sidebarActive: false
735
- })), 300);
736
- }
737
- }
738
- }
739
- anchor() {
740
- this.layout.state.update(state => ({
741
- ...state,
742
- anchored: !state.anchored
743
- }));
744
- }
745
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.12", ngImport: i0, type: SidebarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
746
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.12", 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]=\"layout.appLogo()\" [alt]=\"'App logo'\" />\n </div>\n <div class=\"app-logo-normal\">\n <img class=\"h-2rem\" [src]=\"layout.appLogo()\" [alt]=\"'App logo'\" />\n <img class=\"h-2rem ml-3\" [src]=\"layout.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$4.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 }); }
747
- }
748
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.12", ngImport: i0, type: SidebarComponent, decorators: [{
749
- type: Component,
750
- 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]=\"layout.appLogo()\" [alt]=\"'App logo'\" />\n </div>\n <div class=\"app-logo-normal\">\n <img class=\"h-2rem\" [src]=\"layout.appLogo()\" [alt]=\"'App logo'\" />\n <img class=\"h-2rem ml-3\" [src]=\"layout.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" }]
751
- }] });
752
-
753
- const defaultColorSchemeOpts = [
754
- {
755
- value: 'auto',
756
- label: 'system'
757
- },
758
- {
759
- value: 'light',
760
- label: 'light'
761
- },
762
- {
763
- value: 'dark',
764
- label: 'dark'
765
- }
766
- ];
767
- class SettingsComponent {
768
- constructor() {
769
- this.dynamicDialogConfig = inject(DynamicDialogConfig);
770
- this.dynamicDialogRef = inject(DynamicDialogRef);
771
- this.colorSchemeOptions = signal(defaultColorSchemeOpts);
772
- this.injector = this.dynamicDialogConfig.data.injector;
773
- this.translate = this.injector.get(TranslateService);
774
- this.commons = this.injector.get(CommonsService);
775
- this.layout = this.injector.get(LayoutService);
776
- this.menuModes = this.layout.menuModes;
777
- this.translate
778
- .stream('mngSettings.title')
779
- .pipe(takeUntilDestroyed())
780
- .subscribe(t => {
781
- setTimeout(() => (this.dynamicDialogConfig.header = t));
782
- });
783
- const translateKey = 'mngSettings.colorScheme.options';
784
- this.translate
785
- .stream(translateKey)
786
- .pipe(takeUntilDestroyed())
787
- .subscribe(t => {
788
- if (t === translateKey) {
789
- this.colorSchemeOptions.set(defaultColorSchemeOpts);
790
- }
791
- else {
792
- this.colorSchemeOptions.update(options => options.map(o => ({
793
- value: o.value,
794
- label: `${t[o.value]}`
795
- })));
796
- }
797
- });
798
- }
799
- switchLocale(language) {
800
- this.commons.setAppLocale(language);
801
- }
802
- switchDataLocale(language) {
803
- this.commons.setAppDataLocale(language);
804
- }
805
- onMenuModeChange(mode) {
806
- this.layout.onMenuModeChange(mode);
807
- }
808
- onColorSchemeChange(scheme) {
809
- this.layout.setColorScheme(scheme);
810
- }
811
- closeDialog() {
812
- this.dynamicDialogRef.close();
813
- }
814
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.12", ngImport: i0, type: SettingsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
815
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.12", 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 <h5>{{ 'mngSettings.colorScheme.title' | translate }}</h5>\n <div class=\"formgrid grid\">\n <p-selectButton\n [options]=\"colorSchemeOptions()\"\n [ngModel]=\"layout.colorSchemeSetting()\"\n (ngModelChange)=\"onColorSchemeChange($event)\"\n optionLabel=\"label\"\n optionValue=\"value\"\n allowEmpty=\"false\" />\n </div>\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]=\"layout.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", "autoShowPanelOnPrintableCharacterKeyDown", "disabled", "itemSize", "autoZIndex", "baseZIndex", "showTransitionOptions", "hideTransitionOptions", "filterValue", "options"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }, { kind: "ngmodule", type: InputSwitchModule }, { kind: "ngmodule", type: SelectButtonModule }, { kind: "component", type: i5.SelectButton, selector: "p-selectButton", inputs: ["options", "optionLabel", "optionValue", "optionDisabled", "unselectable", "tabindex", "multiple", "allowEmpty", "style", "styleClass", "ariaLabelledBy", "disabled", "dataKey", "autofocus"], outputs: ["onOptionClick", "onChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
816
- }
817
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.12", ngImport: i0, type: SettingsComponent, decorators: [{
818
- type: Component,
819
- args: [{ standalone: true, selector: 'mng-settings', imports: [TranslateModule, RadioButtonModule, FormsModule, Button, DropdownModule, InputSwitchModule, SelectButtonModule], 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 <h5>{{ 'mngSettings.colorScheme.title' | translate }}</h5>\n <div class=\"formgrid grid\">\n <p-selectButton\n [options]=\"colorSchemeOptions()\"\n [ngModel]=\"layout.colorSchemeSetting()\"\n (ngModelChange)=\"onColorSchemeChange($event)\"\n optionLabel=\"label\"\n optionValue=\"value\"\n allowEmpty=\"false\" />\n </div>\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]=\"layout.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" }]
820
- }], ctorParameters: () => [] });
821
-
822
- class TopbarUserComponent {
823
- constructor() {
824
- this.injector = inject(Injector);
825
- this.dialogService = inject(DialogService);
826
- this.commons = inject(CommonsService);
827
- this.hrefJsVoid = inject(DomSanitizer).bypassSecurityTrustUrl('javascript:void(0)');
828
- this.config = inject(COMMONS_LAYOUT_FEATURE_CONFIG_IT, { optional: true });
829
- this.user = computed(() => this.commons.user());
830
- this.userRoles = computed(() => this.commons.userRoles());
831
- this.settingsDisabled = signal(this.config?.components?.settings === false);
832
- }
833
- logout(user, event) {
834
- if (typeof user?.logout === 'function') {
835
- event.preventDefault();
836
- event.stopPropagation();
837
- user.logout();
838
- }
839
- }
840
- openSettings() {
841
- if (this.config?.components?.settings === false) {
842
- return;
843
- }
844
- this.dialogService.open(this.config?.components?.settings ?? SettingsComponent, {
845
- modal: true,
846
- styleClass: 'mng-dialog mng-action-editor-dialog mng-dialog-xs',
847
- data: {
848
- injector: this.injector
849
- }
850
- });
851
- }
852
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.12", ngImport: i0, type: TopbarUserComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
853
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.12", 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 (!settingsDisabled()) {\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 }\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$3.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 }); }
854
- }
855
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.12", ngImport: i0, type: TopbarUserComponent, decorators: [{
856
- type: Component,
857
- 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 (!settingsDisabled()) {\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 }\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" }]
858
- }] });
859
-
860
- class TopbarComponent {
861
- constructor() {
862
- this.el = inject(ElementRef);
863
- this.commons = inject(CommonsService);
864
- this.layout = inject(LayoutService);
865
- this.config = inject(COMMONS_LAYOUT_FEATURE_CONFIG_IT, { optional: true });
866
- this.topbarUserComponent = signal(this.config?.components?.topbarUser === false ? undefined : (this.config?.components?.topbarUser ?? TopbarUserComponent));
867
- this.breadcrumbComponent = signal(this.config?.components?.breadcrumb === false ? undefined : (this.config?.components?.breadcrumb ?? BreadcrumbComponent));
868
- }
869
- onMenuButtonClick() {
870
- this.layout.onMenuToggle();
871
- }
872
- switchLocale(language) {
873
- this.commons.setAppLocale(language);
874
- }
875
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.12", ngImport: i0, type: TopbarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
876
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.12", 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", "autoShowPanelOnPrintableCharacterKeyDown", "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 }); }
877
- }
878
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.12", ngImport: i0, type: TopbarComponent, decorators: [{
879
- type: Component,
880
- 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" }]
881
- }] });
882
-
883
- class MainLayoutComponent {
884
- constructor() {
885
- // private readonly commonsService = inject(CommonsService);
886
- this.config = inject(COMMONS_LAYOUT_FEATURE_CONFIG_IT, { optional: true });
887
- this.layout = inject(LayoutService);
888
- this.menuService = inject(MenuService);
889
- this.renderer = inject(Renderer2);
890
- this.appTopbar = viewChild('topbarCmp');
891
- this.ripple = signal(this.config?.ripple ?? true);
892
- this.topbarComponent = signal(this.config?.components?.topbar === false ? undefined : (this.config?.components?.topbar ?? TopbarComponent));
893
- this.breadcrumbsComponent = signal(this.config?.components?.breadcrumb === false ? undefined : (this.config?.components?.breadcrumb ?? BreadcrumbComponent));
894
- this.footerComponent = signal(this.config?.components?.footer === false ? undefined : (this.config?.components?.footer ?? FooterComponent));
895
- this.useNotificationWrapper = signal(!this.config?.disableNotificationWrapper);
896
- this.layout.overlayOpen$.pipe(takeUntilDestroyed()).subscribe(() => {
897
- if (!this.menuOutsideClickListener) {
898
- this.menuOutsideClickListener = this.renderer.listen('document', 'click', event => {
899
- const isOutsideClicked = !(this.appTopbar()?.nativeElement.isSameNode(event.target) || this.appTopbar()?.nativeElement.contains(event.target));
900
- if (isOutsideClicked) {
901
- this.hideMenu();
902
- }
903
- });
904
- }
905
- if (this.layout.state().staticMenuMobileActive) {
906
- this.blockBodyScroll();
907
- }
908
- });
909
- }
910
- blockBodyScroll() {
911
- if (document.body.classList) {
912
- document.body.classList.add('blocked-scroll');
913
- }
914
- else {
915
- document.body.className += ' blocked-scroll';
916
- }
917
- }
918
- unblockBodyScroll() {
919
- if (document.body.classList) {
920
- document.body.classList.remove('blocked-scroll');
921
- }
922
- else {
923
- document.body.className = document.body.className.replace(new RegExp('(^|\\b)' + 'blocked-scroll'.split(' ').join('|') + '(\\b|$)', 'gi'), ' ');
924
- }
316
+ class VersionService {
317
+ constructor(http, configurationService) {
318
+ this.http = http;
319
+ this.configurationService = configurationService;
320
+ this.logger = inject(LoggerService).create('VersionService');
321
+ this.cache = {};
925
322
  }
926
- hideMenu() {
927
- this.layout.state.update(state => ({
928
- ...state,
929
- overlayMenuActive: false,
930
- staticMenuMobileActive: false,
931
- menuHoverActive: false
932
- }));
933
- if (this.layout.submenuOverlayKey() !== undefined) {
934
- this.layout.onOverlaySubmenuClose();
935
- }
936
- if (!(this.layout.isSlim() || this.layout.isSlimPlus())) {
937
- this.menuService.reset();
323
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
324
+ loadVersion(path, baseConfigKey, jsonPath = '$') {
325
+ const urlSegments = [];
326
+ if (baseConfigKey) {
327
+ const baseUrl = this.configurationService.getConfigValue(baseConfigKey);
328
+ urlSegments.push(baseUrl.endsWith('/') ? baseUrl.substring(0, baseUrl.length - 1) : baseUrl);
938
329
  }
939
- if (this.menuOutsideClickListener) {
940
- this.menuOutsideClickListener();
941
- this.menuOutsideClickListener = null;
330
+ if (path) {
331
+ urlSegments.push(!path.startsWith('/') ? `/${path}` : path);
942
332
  }
943
- this.unblockBodyScroll();
944
- }
945
- ngOnDestroy() {
946
- if (this.menuOutsideClickListener) {
947
- this.menuOutsideClickListener();
333
+ const url = urlSegments.join('');
334
+ if (!this.cache[url]) {
335
+ this.cache[url] = new ReplaySubject(1);
336
+ this.http.get(urlSegments.join('')).subscribe({
337
+ next: res => {
338
+ this.cache[url].next(res);
339
+ },
340
+ error: err => {
341
+ this.logger.error('Version could not be retreived', err);
342
+ }
343
+ });
948
344
  }
345
+ return this.cache[url].asObservable();
949
346
  }
950
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.12", ngImport: i0, type: MainLayoutComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
951
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.12", type: MainLayoutComponent, isStandalone: true, selector: "mng-main-layout", 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': layout.colorScheme() === 'light',\n 'layout-dark': layout.colorScheme() === 'dark',\n 'layout-overlay': layout.menuMode() === 'overlay',\n 'layout-static': layout.menuMode() === 'static',\n 'layout-reveal': layout.menuMode() === 'reveal',\n 'layout-drawer': layout.menuMode() === 'drawer',\n 'layout-slim': layout.menuMode() === 'slim',\n 'layout-slim-plus': layout.menuMode() === 'slim-plus',\n 'layout-static-inactive': layout.state().staticMenuDesktopInactive && layout.menuMode() === 'static',\n 'layout-overlay-active': layout.state().overlayMenuActive,\n 'layout-mobile-active': layout.state().staticMenuMobileActive,\n 'p-ripple-disabled': !ripple(),\n 'layout-sidebar-active': layout.state().sidebarActive,\n 'layout-sidebar-anchored': layout.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$4.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 }); }
952
- }
953
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.12", ngImport: i0, type: MainLayoutComponent, decorators: [{
954
- type: Component,
955
- args: [{ standalone: true, selector: 'mng-main-layout', imports: [NgClass, RouterModule, TopbarComponent, BreadcrumbComponent, ComponentDirective, AsyncPipe, NotificationWrapperComponent, NgTemplateOutlet], 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': layout.colorScheme() === 'light',\n 'layout-dark': layout.colorScheme() === 'dark',\n 'layout-overlay': layout.menuMode() === 'overlay',\n 'layout-static': layout.menuMode() === 'static',\n 'layout-reveal': layout.menuMode() === 'reveal',\n 'layout-drawer': layout.menuMode() === 'drawer',\n 'layout-slim': layout.menuMode() === 'slim',\n 'layout-slim-plus': layout.menuMode() === 'slim-plus',\n 'layout-static-inactive': layout.state().staticMenuDesktopInactive && layout.menuMode() === 'static',\n 'layout-overlay-active': layout.state().overlayMenuActive,\n 'layout-mobile-active': layout.state().staticMenuMobileActive,\n 'p-ripple-disabled': !ripple(),\n 'layout-sidebar-active': layout.state().sidebarActive,\n 'layout-sidebar-anchored': layout.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" }]
956
- }], ctorParameters: () => [] });
957
-
958
- /**
959
- * Creates a layout route on the specified path.
960
- *
961
- * @param {String} path - The path of the route.
962
- * @return {RouteBuilder} - The route builder for the layout route.
963
- */
964
- function createLayoutRoute(path) {
965
- return createRoute(path, MainLayoutComponent);
347
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.12", ngImport: i0, type: VersionService, deps: [{ token: i1.HttpClient }, { token: i2.CommonsConfigurationService }], target: i0.ɵɵFactoryTarget.Injectable }); }
348
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.12", ngImport: i0, type: VersionService }); }
966
349
  }
350
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.12", ngImport: i0, type: VersionService, decorators: [{
351
+ type: Injectable
352
+ }], ctorParameters: () => [{ type: i1.HttpClient }, { type: i2.CommonsConfigurationService }] });
967
353
 
968
354
  /**
969
355
  * Prepares providers for usage of the layout functionalities.
@@ -985,11 +371,11 @@ function withLayout(config) {
985
371
  };
986
372
  }
987
373
 
988
- // components
374
+ // helpers
989
375
 
990
376
  /**
991
377
  * Generated bundle index. Do not edit.
992
378
  */
993
379
 
994
- export { BreadcrumbComponent, COMMONS_LAYOUT_FEATURE_CONFIG_IT, ErrorPageComponent, FooterComponent, LayoutService, MainLayoutComponent, MenuComponent, MenuItemComponent, MenuService, NotFoundPageComponent, SettingsComponent, SidebarComponent, TopbarComponent, TopbarUserComponent, VersionComponent, VersionService, createLayoutRoute, withLayout };
380
+ export { COMMONS_LAYOUT_FEATURE_CONFIG_IT, LayoutService, MenuService, VersionService, prepareMenuItemsToInternal, withLayout };
995
381
  //# sourceMappingURL=mediusinc-mng-commons-layout.mjs.map