@lukfel/ng-scaffold 20.0.10 → 20.0.11

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 (104) hide show
  1. package/fesm2022/lukfel-ng-scaffold.mjs +1453 -0
  2. package/fesm2022/lukfel-ng-scaffold.mjs.map +1 -0
  3. package/index.d.ts +619 -0
  4. package/package.json +37 -28
  5. package/.eslintrc.json +0 -37
  6. package/ng-package.json +0 -8
  7. package/src/lib/components/bottom-bar/bottom-bar.component.html +0 -29
  8. package/src/lib/components/bottom-bar/bottom-bar.component.scss +0 -33
  9. package/src/lib/components/bottom-bar/bottom-bar.component.spec.ts +0 -24
  10. package/src/lib/components/bottom-bar/bottom-bar.component.ts +0 -31
  11. package/src/lib/components/content-title-card/content-title-card.component.html +0 -25
  12. package/src/lib/components/content-title-card/content-title-card.component.scss +0 -17
  13. package/src/lib/components/content-title-card/content-title-card.component.spec.ts +0 -108
  14. package/src/lib/components/content-title-card/content-title-card.component.ts +0 -24
  15. package/src/lib/components/drawer/drawer.component.html +0 -33
  16. package/src/lib/components/drawer/drawer.component.scss +0 -10
  17. package/src/lib/components/drawer/drawer.component.spec.ts +0 -52
  18. package/src/lib/components/drawer/drawer.component.ts +0 -30
  19. package/src/lib/components/floating-button/floating-button.component.html +0 -32
  20. package/src/lib/components/floating-button/floating-button.component.scss +0 -20
  21. package/src/lib/components/floating-button/floating-button.component.spec.ts +0 -84
  22. package/src/lib/components/floating-button/floating-button.component.ts +0 -57
  23. package/src/lib/components/footer/footer.component.html +0 -38
  24. package/src/lib/components/footer/footer.component.scss +0 -39
  25. package/src/lib/components/footer/footer.component.spec.ts +0 -118
  26. package/src/lib/components/footer/footer.component.ts +0 -14
  27. package/src/lib/components/header/header.component.html +0 -170
  28. package/src/lib/components/header/header.component.scss +0 -102
  29. package/src/lib/components/header/header.component.spec.ts +0 -134
  30. package/src/lib/components/header/header.component.ts +0 -53
  31. package/src/lib/components/loading-overlay/loading-overlay.component.html +0 -3
  32. package/src/lib/components/loading-overlay/loading-overlay.component.scss +0 -16
  33. package/src/lib/components/loading-overlay/loading-overlay.component.spec.ts +0 -24
  34. package/src/lib/components/loading-overlay/loading-overlay.component.ts +0 -10
  35. package/src/lib/components/navbar/navbar.component.html +0 -43
  36. package/src/lib/components/navbar/navbar.component.scss +0 -71
  37. package/src/lib/components/navbar/navbar.component.spec.ts +0 -43
  38. package/src/lib/components/navbar/navbar.component.ts +0 -35
  39. package/src/lib/components/scaffold/scaffold.component.html +0 -74
  40. package/src/lib/components/scaffold/scaffold.component.scss +0 -48
  41. package/src/lib/components/scaffold/scaffold.component.spec.ts +0 -119
  42. package/src/lib/components/scaffold/scaffold.component.ts +0 -191
  43. package/src/lib/interceptors/loading.interceptor.ts +0 -51
  44. package/src/lib/models/bottom-bar-config.model.ts +0 -8
  45. package/src/lib/models/confirm-dialog-config.model.ts +0 -6
  46. package/src/lib/models/content-title-card-config.model.ts +0 -6
  47. package/src/lib/models/drawer-config.model.ts +0 -6
  48. package/src/lib/models/floating-button-config.model.ts +0 -13
  49. package/src/lib/models/footer-config.model.ts +0 -10
  50. package/src/lib/models/header-config.model.ts +0 -26
  51. package/src/lib/models/index.ts +0 -15
  52. package/src/lib/models/library-config.model.ts +0 -4
  53. package/src/lib/models/menu-button.model.ts +0 -10
  54. package/src/lib/models/navbar-config.model.ts +0 -8
  55. package/src/lib/models/navigation-link.model.ts +0 -6
  56. package/src/lib/models/placeholder-config.model.ts +0 -7
  57. package/src/lib/models/scaffold-config.model.ts +0 -21
  58. package/src/lib/models/seo-config.model.ts +0 -6
  59. package/src/lib/scaffold.module.ts +0 -54
  60. package/src/lib/services/breakpoint.service.spec.ts +0 -15
  61. package/src/lib/services/breakpoint.service.ts +0 -16
  62. package/src/lib/services/dialog.service.spec.ts +0 -18
  63. package/src/lib/services/dialog.service.ts +0 -58
  64. package/src/lib/services/index.ts +0 -9
  65. package/src/lib/services/local-storage.service.spec.ts +0 -15
  66. package/src/lib/services/local-storage.service.ts +0 -125
  67. package/src/lib/services/logger.service.spec.ts +0 -15
  68. package/src/lib/services/logger.service.ts +0 -46
  69. package/src/lib/services/router.service.spec.ts +0 -15
  70. package/src/lib/services/router.service.ts +0 -91
  71. package/src/lib/services/scaffold.service.spec.ts +0 -15
  72. package/src/lib/services/scaffold.service.ts +0 -77
  73. package/src/lib/services/seo.service.spec.ts +0 -15
  74. package/src/lib/services/seo.service.ts +0 -75
  75. package/src/lib/services/snackbar.service.spec.ts +0 -18
  76. package/src/lib/services/snackbar.service.ts +0 -38
  77. package/src/lib/services/theme.service.spec.ts +0 -20
  78. package/src/lib/services/theme.service.ts +0 -71
  79. package/src/lib/shared/components/dialogs/confirm-dialog/confirm-dialog.component.html +0 -24
  80. package/src/lib/shared/components/dialogs/confirm-dialog/confirm-dialog.component.scss +0 -0
  81. package/src/lib/shared/components/dialogs/confirm-dialog/confirm-dialog.component.spec.ts +0 -85
  82. package/src/lib/shared/components/dialogs/confirm-dialog/confirm-dialog.component.ts +0 -14
  83. package/src/lib/shared/components/file-upload/file-upload.component.html +0 -21
  84. package/src/lib/shared/components/file-upload/file-upload.component.scss +0 -5
  85. package/src/lib/shared/components/file-upload/file-upload.component.spec.ts +0 -25
  86. package/src/lib/shared/components/file-upload/file-upload.component.ts +0 -43
  87. package/src/lib/shared/components/icon/icon.component.html +0 -17
  88. package/src/lib/shared/components/icon/icon.component.scss +0 -9
  89. package/src/lib/shared/components/icon/icon.component.spec.ts +0 -22
  90. package/src/lib/shared/components/icon/icon.component.ts +0 -17
  91. package/src/lib/shared/components/input/input.component.html +0 -38
  92. package/src/lib/shared/components/input/input.component.scss +0 -31
  93. package/src/lib/shared/components/input/input.component.spec.ts +0 -62
  94. package/src/lib/shared/components/input/input.component.ts +0 -72
  95. package/src/lib/shared/components/placeholder/placeholder.component.html +0 -21
  96. package/src/lib/shared/components/placeholder/placeholder.component.scss +0 -30
  97. package/src/lib/shared/components/placeholder/placeholder.component.spec.ts +0 -24
  98. package/src/lib/shared/components/placeholder/placeholder.component.ts +0 -16
  99. package/src/lib/shared/modules/material.module.ts +0 -77
  100. package/src/lib/shared/shared.module.ts +0 -18
  101. package/src/public-api.ts +0 -16
  102. package/tsconfig.lib.json +0 -14
  103. package/tsconfig.lib.prod.json +0 -10
  104. package/tsconfig.spec.json +0 -14
@@ -0,0 +1,1453 @@
1
+ import * as i0 from '@angular/core';
2
+ import { EventEmitter, Output, Input, Component, NgModule, inject, ChangeDetectorRef, ViewChild, Injectable, DOCUMENT, InjectionToken } from '@angular/core';
3
+ import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
4
+ import * as i2$2 from '@angular/router';
5
+ import { Router, RouteConfigLoadStart, RouteConfigLoadEnd, NavigationEnd, ActivatedRoute, RouterModule } from '@angular/router';
6
+ import * as i1 from '@angular/common';
7
+ import { CommonModule } from '@angular/common';
8
+ import * as i2 from '@angular/material/button';
9
+ import { MatButtonModule } from '@angular/material/button';
10
+ import * as i4 from '@angular/material/icon';
11
+ import { MatIconModule } from '@angular/material/icon';
12
+ import * as i4$1 from '@angular/material/tooltip';
13
+ import { MatTooltipModule } from '@angular/material/tooltip';
14
+ import * as i3 from '@angular/material/card';
15
+ import { MatCardModule } from '@angular/material/card';
16
+ import * as i2$1 from '@angular/material/sidenav';
17
+ import { MatSidenavModule } from '@angular/material/sidenav';
18
+ import * as i3$1 from '@angular/cdk/portal';
19
+ import { PortalModule, ComponentPortal } from '@angular/cdk/portal';
20
+ import * as i4$2 from '@angular/material/menu';
21
+ import { MatMenuModule } from '@angular/material/menu';
22
+ import * as i5 from '@angular/material/toolbar';
23
+ import { MatToolbarModule } from '@angular/material/toolbar';
24
+ import * as i7 from '@angular/material/progress-bar';
25
+ import { MatProgressBarModule } from '@angular/material/progress-bar';
26
+ import * as i2$3 from '@angular/material/dialog';
27
+ import { MatDialogModule, MatDialogRef, MAT_DIALOG_DATA, MatDialog } from '@angular/material/dialog';
28
+ import { MatAutocompleteModule } from '@angular/material/autocomplete';
29
+ import { MatButtonToggleModule } from '@angular/material/button-toggle';
30
+ import { MatCheckboxModule } from '@angular/material/checkbox';
31
+ import { MatChipsModule } from '@angular/material/chips';
32
+ import { MatRippleModule } from '@angular/material/core';
33
+ import { MatDatepickerModule } from '@angular/material/datepicker';
34
+ import { MatExpansionModule } from '@angular/material/expansion';
35
+ import { MatFormFieldModule } from '@angular/material/form-field';
36
+ import { MatGridListModule } from '@angular/material/grid-list';
37
+ import * as i3$2 from '@angular/material/input';
38
+ import { MatInputModule } from '@angular/material/input';
39
+ import { MatListModule } from '@angular/material/list';
40
+ import { MatPaginatorModule } from '@angular/material/paginator';
41
+ import * as i1$2 from '@angular/material/progress-spinner';
42
+ import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
43
+ import { MatRadioModule } from '@angular/material/radio';
44
+ import { MatSelectModule } from '@angular/material/select';
45
+ import { MatSlideToggleModule } from '@angular/material/slide-toggle';
46
+ import { MatSliderModule } from '@angular/material/slider';
47
+ import { MatSnackBarModule, MatSnackBar } from '@angular/material/snack-bar';
48
+ import { MatSortModule } from '@angular/material/sort';
49
+ import { MatStepperModule } from '@angular/material/stepper';
50
+ import { MatTableModule } from '@angular/material/table';
51
+ import { MatTabsModule } from '@angular/material/tabs';
52
+ import * as i1$1 from '@angular/forms';
53
+ import { FormsModule } from '@angular/forms';
54
+ import { BreakpointObserver, Breakpoints } from '@angular/cdk/layout';
55
+ import { distinctUntilChanged, firstValueFrom, BehaviorSubject, take, Subscription, fromEvent, debounceTime, finalize } from 'rxjs';
56
+ import { Title, Meta } from '@angular/platform-browser';
57
+ import * as i2$4 from '@angular/cdk/scrolling';
58
+
59
+ class BottomBarComponent {
60
+ constructor() {
61
+ this.bottomBarConfig = null;
62
+ this.isMobile = false;
63
+ this.navbarEnabled = false;
64
+ this.bottomBarCloseClickEvent = new EventEmitter();
65
+ this.bottomBarButtonClickEvent = new EventEmitter();
66
+ }
67
+ actionClicked(id) {
68
+ if (!id) {
69
+ return;
70
+ }
71
+ this.bottomBarButtonClickEvent.emit(id);
72
+ }
73
+ closeClicked() {
74
+ this.bottomBarCloseClickEvent.emit('bottom-bar_close');
75
+ }
76
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.5", ngImport: i0, type: BottomBarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
77
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.0.5", type: BottomBarComponent, isStandalone: false, selector: "lf-bottom-bar", inputs: { bottomBarConfig: "bottomBarConfig", isMobile: "isMobile", navbarEnabled: "navbarEnabled" }, outputs: { bottomBarCloseClickEvent: "bottomBarCloseClickEvent", bottomBarButtonClickEvent: "bottomBarButtonClickEvent" }, ngImport: i0, template: "@if (bottomBarConfig && bottomBarConfig.enable) {\r\n <div\r\n class=\"lf-bottom-bar px-4\"\r\n [ngClass]=\"bottomBarConfig.class\"\r\n [class.lf-bottom-bar-show-navbar]=\"!isMobile && navbarEnabled\"\r\n [class.lf-bottom-bar-show-navbar-mobile]=\"isMobile && navbarEnabled\">\r\n <button mat-icon-button (click)=\"closeClicked()\">\r\n <mat-icon>close</mat-icon>\r\n </button>\r\n @if (bottomBarConfig.message) {\r\n <span class=\"ml-2\">{{ bottomBarConfig.message }}</span>\r\n }\r\n @if (bottomBarConfig.actions) {\r\n <div class=\"lf-bottom-bar-actions ml-4\">\r\n @for (action of bottomBarConfig.actions; track action) {\r\n <button\r\n mat-button\r\n color=\"accent\"\r\n class=\"lf-bottom-bar-action ml-2\"\r\n [ngClass]=\"action.class\"\r\n (click)=\"actionClicked(action.id)\"\r\n [matTooltip]=\"action.tooltip!\">\r\n {{ action.label }}\r\n </button>\r\n }\r\n </div>\r\n }\r\n </div>\r\n}\r\n", styles: [".lf-bottom-bar{transition:bottom .3s;transition:left .3s;z-index:101;position:fixed;left:0;bottom:0;right:0;height:56px;display:flex;align-items:center;box-sizing:border-box;background-color:var(--color-accent);color:#fff}.lf-bottom-bar.lf-bottom-bar-show-navbar-mobile{bottom:64px!important}.lf-bottom-bar.lf-bottom-bar-show-navbar{left:80px!important}.lf-bottom-bar .lf-bottom-bar-actions .lf-bottom-bar-action{color:var(--color-accent)!important;background-color:#fff!important}\n"], dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: i2.MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i2.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i4.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: i4$1.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }] }); }
78
+ }
79
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.5", ngImport: i0, type: BottomBarComponent, decorators: [{
80
+ type: Component,
81
+ args: [{ selector: 'lf-bottom-bar', standalone: false, template: "@if (bottomBarConfig && bottomBarConfig.enable) {\r\n <div\r\n class=\"lf-bottom-bar px-4\"\r\n [ngClass]=\"bottomBarConfig.class\"\r\n [class.lf-bottom-bar-show-navbar]=\"!isMobile && navbarEnabled\"\r\n [class.lf-bottom-bar-show-navbar-mobile]=\"isMobile && navbarEnabled\">\r\n <button mat-icon-button (click)=\"closeClicked()\">\r\n <mat-icon>close</mat-icon>\r\n </button>\r\n @if (bottomBarConfig.message) {\r\n <span class=\"ml-2\">{{ bottomBarConfig.message }}</span>\r\n }\r\n @if (bottomBarConfig.actions) {\r\n <div class=\"lf-bottom-bar-actions ml-4\">\r\n @for (action of bottomBarConfig.actions; track action) {\r\n <button\r\n mat-button\r\n color=\"accent\"\r\n class=\"lf-bottom-bar-action ml-2\"\r\n [ngClass]=\"action.class\"\r\n (click)=\"actionClicked(action.id)\"\r\n [matTooltip]=\"action.tooltip!\">\r\n {{ action.label }}\r\n </button>\r\n }\r\n </div>\r\n }\r\n </div>\r\n}\r\n", styles: [".lf-bottom-bar{transition:bottom .3s;transition:left .3s;z-index:101;position:fixed;left:0;bottom:0;right:0;height:56px;display:flex;align-items:center;box-sizing:border-box;background-color:var(--color-accent);color:#fff}.lf-bottom-bar.lf-bottom-bar-show-navbar-mobile{bottom:64px!important}.lf-bottom-bar.lf-bottom-bar-show-navbar{left:80px!important}.lf-bottom-bar .lf-bottom-bar-actions .lf-bottom-bar-action{color:var(--color-accent)!important;background-color:#fff!important}\n"] }]
82
+ }], propDecorators: { bottomBarConfig: [{
83
+ type: Input
84
+ }], isMobile: [{
85
+ type: Input
86
+ }], navbarEnabled: [{
87
+ type: Input
88
+ }], bottomBarCloseClickEvent: [{
89
+ type: Output
90
+ }], bottomBarButtonClickEvent: [{
91
+ type: Output
92
+ }] } });
93
+
94
+ class ContentTitleCardComponent {
95
+ constructor() {
96
+ this.contentTitleCardConfig = null;
97
+ this.isMobile = false;
98
+ this.routeHistory = [];
99
+ this.backButtonClickEvent = new EventEmitter();
100
+ this.inputValue = '';
101
+ }
102
+ backButtonClicked() {
103
+ this.backButtonClickEvent.emit();
104
+ }
105
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.5", ngImport: i0, type: ContentTitleCardComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
106
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.0.5", type: ContentTitleCardComponent, isStandalone: false, selector: "lf-content-title-card", inputs: { contentTitleCardConfig: "contentTitleCardConfig", isMobile: "isMobile", routeHistory: "routeHistory" }, outputs: { backButtonClickEvent: "backButtonClickEvent" }, ngImport: i0, template: "@if (contentTitleCardConfig && contentTitleCardConfig.enable) {\r\n <mat-card\r\n class=\"lf-content-title-card mat-elevation-z2 px-4\"\r\n [ngClass]=\"contentTitleCardConfig.class\">\r\n <!-- back button -->\r\n @if (contentTitleCardConfig.showBackButton && routeHistory.length > 1) {\r\n <button mat-icon-button color=\"accent\" (click)=\"backButtonClicked()\">\r\n <mat-icon>arrow_back_ios</mat-icon>\r\n </button>\r\n }\r\n <!-- spacer -->\r\n <div style=\"flex: 1 1 auto\"></div>\r\n <!-- label -->\r\n <span class=\"lf-content-title-card-label\">\r\n {{ contentTitleCardConfig.label || \"\" }}\r\n </span>\r\n <!-- spacer -->\r\n <div style=\"flex: 1 1 auto\"></div>\r\n <!-- empty button spacer -->\r\n <div\r\n [style.width]=\"\r\n contentTitleCardConfig.showBackButton && routeHistory.length > 1 ? '48px' : '0px'\r\n \"></div>\r\n </mat-card>\r\n}\r\n", styles: [".lf-content-title-card{z-index:98;height:80px;display:flex;flex-flow:row nowrap;align-items:center;border-radius:0}.lf-content-title-card .lf-content-title-card-label{font-size:24px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}\n"], dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: i2.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i3.MatCard, selector: "mat-card", inputs: ["appearance"], exportAs: ["matCard"] }, { kind: "component", type: i4.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }] }); }
107
+ }
108
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.5", ngImport: i0, type: ContentTitleCardComponent, decorators: [{
109
+ type: Component,
110
+ args: [{ selector: 'lf-content-title-card', standalone: false, template: "@if (contentTitleCardConfig && contentTitleCardConfig.enable) {\r\n <mat-card\r\n class=\"lf-content-title-card mat-elevation-z2 px-4\"\r\n [ngClass]=\"contentTitleCardConfig.class\">\r\n <!-- back button -->\r\n @if (contentTitleCardConfig.showBackButton && routeHistory.length > 1) {\r\n <button mat-icon-button color=\"accent\" (click)=\"backButtonClicked()\">\r\n <mat-icon>arrow_back_ios</mat-icon>\r\n </button>\r\n }\r\n <!-- spacer -->\r\n <div style=\"flex: 1 1 auto\"></div>\r\n <!-- label -->\r\n <span class=\"lf-content-title-card-label\">\r\n {{ contentTitleCardConfig.label || \"\" }}\r\n </span>\r\n <!-- spacer -->\r\n <div style=\"flex: 1 1 auto\"></div>\r\n <!-- empty button spacer -->\r\n <div\r\n [style.width]=\"\r\n contentTitleCardConfig.showBackButton && routeHistory.length > 1 ? '48px' : '0px'\r\n \"></div>\r\n </mat-card>\r\n}\r\n", styles: [".lf-content-title-card{z-index:98;height:80px;display:flex;flex-flow:row nowrap;align-items:center;border-radius:0}.lf-content-title-card .lf-content-title-card-label{font-size:24px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}\n"] }]
111
+ }], propDecorators: { contentTitleCardConfig: [{
112
+ type: Input
113
+ }], isMobile: [{
114
+ type: Input
115
+ }], routeHistory: [{
116
+ type: Input
117
+ }], backButtonClickEvent: [{
118
+ type: Output
119
+ }] } });
120
+
121
+ class DrawerComponent {
122
+ constructor() {
123
+ this.drawerConfig = null;
124
+ this.isMobile = false;
125
+ this.fixedOffset = 0;
126
+ }
127
+ ngOnInit() {
128
+ // Avoid initializing an open drawer on mobile
129
+ if (this.isMobile && this.drawerConfig?.enable && this.drawerConfig?.open) {
130
+ this.drawerConfig.open = false;
131
+ }
132
+ }
133
+ // Detect when the drawer is closed without clicking a button
134
+ onDrawerClosed() {
135
+ if (this.drawerConfig)
136
+ this.drawerConfig.open = false;
137
+ }
138
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.5", ngImport: i0, type: DrawerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
139
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.0.5", type: DrawerComponent, isStandalone: false, selector: "lf-drawer", inputs: { drawerConfig: "drawerConfig", isMobile: "isMobile", fixedOffset: "fixedOffset", drawerPortal: "drawerPortal" }, ngImport: i0, template: "@if (drawerConfig && drawerConfig.enable) {\r\n <mat-sidenav-container class=\"lf-drawer-container\" [ngClass]=\"drawerConfig.class\">\r\n <!-- drawer -->\r\n <mat-sidenav\r\n class=\"lf-drawer mat-elevation-z2\"\r\n [mode]=\"isMobile ? 'over' : 'side'\"\r\n [opened]=\"drawerConfig.open\"\r\n [autoFocus]=\"false\"\r\n [fixedInViewport]=\"drawerConfig.fixed\"\r\n [fixedTopGap]=\"fixedOffset\"\r\n (closed)=\"onDrawerClosed()\"\r\n #drawer>\r\n <!-- drawer content -->\r\n <!-- <ng-content select=\"[drawerContent]\"></ng-content> -->\r\n @if (drawerPortal) {\r\n <ng-template [cdkPortalOutlet]=\"drawerPortal\"></ng-template>\r\n } @else {\r\n <ng-content select=\"[drawerContent]\"></ng-content>\r\n }\r\n </mat-sidenav>\r\n <mat-sidenav-content>\r\n <!-- main content -->\r\n <ng-container *ngTemplateOutlet=\"content\"></ng-container>\r\n </mat-sidenav-content>\r\n </mat-sidenav-container>\r\n} @else {\r\n <ng-container *ngTemplateOutlet=\"content\"></ng-container>\r\n}\r\n\r\n<!-- render content without drawer -->\r\n\r\n<!-- this template is required to allow multiple <ng-content></ng-content> -->\r\n<ng-template #content><ng-content></ng-content></ng-template>\r\n", styles: [".lf-drawer-container{z-index:unset!important}.lf-drawer-container .lf-drawer{width:208px;z-index:98}\n"], dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: i2$1.MatSidenav, selector: "mat-sidenav", inputs: ["fixedInViewport", "fixedTopGap", "fixedBottomGap"], exportAs: ["matSidenav"] }, { kind: "component", type: i2$1.MatSidenavContainer, selector: "mat-sidenav-container", exportAs: ["matSidenavContainer"] }, { kind: "component", type: i2$1.MatSidenavContent, selector: "mat-sidenav-content" }, { kind: "directive", type: i3$1.CdkPortalOutlet, selector: "[cdkPortalOutlet]", inputs: ["cdkPortalOutlet"], outputs: ["attached"], exportAs: ["cdkPortalOutlet"] }] }); }
140
+ }
141
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.5", ngImport: i0, type: DrawerComponent, decorators: [{
142
+ type: Component,
143
+ args: [{ selector: 'lf-drawer', standalone: false, template: "@if (drawerConfig && drawerConfig.enable) {\r\n <mat-sidenav-container class=\"lf-drawer-container\" [ngClass]=\"drawerConfig.class\">\r\n <!-- drawer -->\r\n <mat-sidenav\r\n class=\"lf-drawer mat-elevation-z2\"\r\n [mode]=\"isMobile ? 'over' : 'side'\"\r\n [opened]=\"drawerConfig.open\"\r\n [autoFocus]=\"false\"\r\n [fixedInViewport]=\"drawerConfig.fixed\"\r\n [fixedTopGap]=\"fixedOffset\"\r\n (closed)=\"onDrawerClosed()\"\r\n #drawer>\r\n <!-- drawer content -->\r\n <!-- <ng-content select=\"[drawerContent]\"></ng-content> -->\r\n @if (drawerPortal) {\r\n <ng-template [cdkPortalOutlet]=\"drawerPortal\"></ng-template>\r\n } @else {\r\n <ng-content select=\"[drawerContent]\"></ng-content>\r\n }\r\n </mat-sidenav>\r\n <mat-sidenav-content>\r\n <!-- main content -->\r\n <ng-container *ngTemplateOutlet=\"content\"></ng-container>\r\n </mat-sidenav-content>\r\n </mat-sidenav-container>\r\n} @else {\r\n <ng-container *ngTemplateOutlet=\"content\"></ng-container>\r\n}\r\n\r\n<!-- render content without drawer -->\r\n\r\n<!-- this template is required to allow multiple <ng-content></ng-content> -->\r\n<ng-template #content><ng-content></ng-content></ng-template>\r\n", styles: [".lf-drawer-container{z-index:unset!important}.lf-drawer-container .lf-drawer{width:208px;z-index:98}\n"] }]
144
+ }], propDecorators: { drawerConfig: [{
145
+ type: Input
146
+ }], isMobile: [{
147
+ type: Input
148
+ }], fixedOffset: [{
149
+ type: Input
150
+ }], drawerPortal: [{
151
+ type: Input
152
+ }] } });
153
+
154
+ class FloatingButtonComponent {
155
+ constructor() {
156
+ this.floatingButtonConfig = null;
157
+ this.onTop = false;
158
+ this.isMobile = false;
159
+ this.bottomBarEnabled = false;
160
+ this.floatingButtonClickEvent = new EventEmitter();
161
+ this.DEFAULT_OFFSET = 24;
162
+ this.navbarOffset = 64;
163
+ this.bottomBarOffset = 56;
164
+ }
165
+ ngOnInit() {
166
+ if (this.floatingButtonConfig) {
167
+ if (!this.floatingButtonConfig.horizontalPosition) {
168
+ this.floatingButtonConfig.horizontalPosition = 'right';
169
+ }
170
+ if (!this.floatingButtonConfig.matIcon && !this.floatingButtonConfig?.svgIcon) {
171
+ this.floatingButtonConfig.matIcon = 'arrow_upward';
172
+ }
173
+ if (!this.floatingButtonConfig.bottomPositionPx) {
174
+ this.floatingButtonConfig.bottomPositionPx = this.DEFAULT_OFFSET;
175
+ }
176
+ }
177
+ }
178
+ buttonClicked(id) {
179
+ this.floatingButtonClickEvent.emit(id);
180
+ }
181
+ getBottomPosition() {
182
+ let bottomPosition = this.floatingButtonConfig?.bottomPositionPx || this.DEFAULT_OFFSET;
183
+ if (this.isMobile) {
184
+ bottomPosition += this.navbarOffset;
185
+ }
186
+ if (this.bottomBarEnabled) {
187
+ bottomPosition += this.bottomBarOffset;
188
+ }
189
+ return bottomPosition;
190
+ }
191
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.5", ngImport: i0, type: FloatingButtonComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
192
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.0.5", type: FloatingButtonComponent, isStandalone: false, selector: "lf-floating-button", inputs: { floatingButtonConfig: "floatingButtonConfig", onTop: "onTop", isMobile: "isMobile", bottomBarEnabled: "bottomBarEnabled" }, outputs: { floatingButtonClickEvent: "floatingButtonClickEvent" }, ngImport: i0, template: "@if (\r\n floatingButtonConfig && floatingButtonConfig.enable && (!floatingButtonConfig.autoHide || !onTop)\r\n) {\r\n <button\r\n mat-fab\r\n color=\"accent\"\r\n class=\"lf-floating-button\"\r\n [style.bottom]=\"getBottomPosition() + 'px'\"\r\n [ngClass]=\"floatingButtonConfig.class\"\r\n [ngClass]=\"floatingButtonConfig.horizontalPosition\"\r\n [extended]=\"!!floatingButtonConfig.label\"\r\n (click)=\"buttonClicked(floatingButtonConfig.id)\"\r\n [matTooltip]=\"floatingButtonConfig.tooltip!\">\r\n <!-- mat icon -->\r\n @if (floatingButtonConfig.matIcon) {\r\n <mat-icon [class.material-icons-outlined]=\"floatingButtonConfig.outlineIcon\">\r\n {{ floatingButtonConfig.matIcon }}\r\n </mat-icon>\r\n } @else {\r\n @if (floatingButtonConfig.svgIcon) {\r\n <mat-icon [svgIcon]=\"floatingButtonConfig.svgIcon!\"></mat-icon>\r\n }\r\n }\r\n <!-- svg icon -->\r\n <!-- label -->\r\n @if (floatingButtonConfig.label) {\r\n <span class=\"lf-floating-button-label\">\r\n {{ floatingButtonConfig.label }}\r\n </span>\r\n }\r\n </button>\r\n}\r\n", styles: [".lf-floating-button{position:fixed;transition:bottom .3s;z-index:100}.lf-floating-button.left{left:24px}.lf-floating-button.center{left:50%;transform:translate(-50%)}.lf-floating-button.right{right:24px}\n"], dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: i2.MatFabButton, selector: "button[mat-fab], a[mat-fab], button[matFab], a[matFab]", inputs: ["extended"], exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i4.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: i4$1.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }] }); }
193
+ }
194
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.5", ngImport: i0, type: FloatingButtonComponent, decorators: [{
195
+ type: Component,
196
+ args: [{ selector: 'lf-floating-button', standalone: false, template: "@if (\r\n floatingButtonConfig && floatingButtonConfig.enable && (!floatingButtonConfig.autoHide || !onTop)\r\n) {\r\n <button\r\n mat-fab\r\n color=\"accent\"\r\n class=\"lf-floating-button\"\r\n [style.bottom]=\"getBottomPosition() + 'px'\"\r\n [ngClass]=\"floatingButtonConfig.class\"\r\n [ngClass]=\"floatingButtonConfig.horizontalPosition\"\r\n [extended]=\"!!floatingButtonConfig.label\"\r\n (click)=\"buttonClicked(floatingButtonConfig.id)\"\r\n [matTooltip]=\"floatingButtonConfig.tooltip!\">\r\n <!-- mat icon -->\r\n @if (floatingButtonConfig.matIcon) {\r\n <mat-icon [class.material-icons-outlined]=\"floatingButtonConfig.outlineIcon\">\r\n {{ floatingButtonConfig.matIcon }}\r\n </mat-icon>\r\n } @else {\r\n @if (floatingButtonConfig.svgIcon) {\r\n <mat-icon [svgIcon]=\"floatingButtonConfig.svgIcon!\"></mat-icon>\r\n }\r\n }\r\n <!-- svg icon -->\r\n <!-- label -->\r\n @if (floatingButtonConfig.label) {\r\n <span class=\"lf-floating-button-label\">\r\n {{ floatingButtonConfig.label }}\r\n </span>\r\n }\r\n </button>\r\n}\r\n", styles: [".lf-floating-button{position:fixed;transition:bottom .3s;z-index:100}.lf-floating-button.left{left:24px}.lf-floating-button.center{left:50%;transform:translate(-50%)}.lf-floating-button.right{right:24px}\n"] }]
197
+ }], propDecorators: { floatingButtonConfig: [{
198
+ type: Input
199
+ }], onTop: [{
200
+ type: Input
201
+ }], isMobile: [{
202
+ type: Input
203
+ }], bottomBarEnabled: [{
204
+ type: Input
205
+ }], floatingButtonClickEvent: [{
206
+ type: Output
207
+ }] } });
208
+
209
+ class FooterComponent {
210
+ constructor() {
211
+ this.footerConfig = null;
212
+ }
213
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.5", ngImport: i0, type: FooterComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
214
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.0.5", type: FooterComponent, isStandalone: false, selector: "lf-footer", inputs: { footerConfig: "footerConfig" }, ngImport: i0, template: "@if (footerConfig && footerConfig.enable) {\r\n <mat-card class=\"lf-footer mat-elevation-z2 p-4\" [ngClass]=\"footerConfig.class\">\r\n <!-- svg logo -->\r\n @if (footerConfig.svgLogo) {\r\n <mat-icon\r\n class=\"lf-footer-logo mb-4\"\r\n color=\"primary\"\r\n [svgIcon]=\"footerConfig.svgLogo!\"></mat-icon>\r\n } @else {\r\n @if (footerConfig.imgLogo) {\r\n <img class=\"lf-footer-logo mb-4\" [src]=\"footerConfig.imgLogo\" alt=\"Logo\" />\r\n }\r\n }\r\n <!-- img logo -->\r\n <!-- links -->\r\n @if (footerConfig.links) {\r\n <div class=\"lf-footer-links mb-4\">\r\n @for (link of footerConfig.links; track link; let i = $index) {\r\n <div class=\"lf-footer-link\" [class.mr-2]=\"i < footerConfig.links!.length - 1\">\r\n @if (link.routerLink) {\r\n <a [routerLink]=\"[link.routerLink]\">{{ link.label || \"\" }}</a>\r\n } @else {\r\n <a [href]=\"link.href\" [target]=\"link.externalTab ? '_blank' : null\">\r\n {{ link.label }}\r\n </a>\r\n }\r\n </div>\r\n }\r\n </div>\r\n }\r\n <!-- copyright -->\r\n @if (footerConfig.copyright) {\r\n <span class=\"lf-footer-copyright\">\r\n {{ footerConfig.copyright }}\r\n </span>\r\n }\r\n </mat-card>\r\n}\r\n", styles: [".lf-footer{overflow:hidden;flex-flow:column;align-items:center;justify-content:center;min-height:100px;border-radius:0;border-top:solid 1px rgba(0,0,0,.12)}.lf-footer .lf-footer-logo{width:96px;height:96px}.lf-footer .lf-footer-links{display:flex;flex-flow:row wrap;align-items:center;justify-content:center}.lf-footer .lf-footer-links .lf-footer-link a{text-decoration:none;color:unset;font-size:12px}.lf-footer .lf-footer-links .lf-footer-link a:hover{color:var(--color-primary)}.lf-footer .lf-footer-copyright{font-size:12px}\n"], dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i2$2.RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "component", type: i3.MatCard, selector: "mat-card", inputs: ["appearance"], exportAs: ["matCard"] }, { kind: "component", type: i4.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }] }); }
215
+ }
216
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.5", ngImport: i0, type: FooterComponent, decorators: [{
217
+ type: Component,
218
+ args: [{ selector: 'lf-footer', standalone: false, template: "@if (footerConfig && footerConfig.enable) {\r\n <mat-card class=\"lf-footer mat-elevation-z2 p-4\" [ngClass]=\"footerConfig.class\">\r\n <!-- svg logo -->\r\n @if (footerConfig.svgLogo) {\r\n <mat-icon\r\n class=\"lf-footer-logo mb-4\"\r\n color=\"primary\"\r\n [svgIcon]=\"footerConfig.svgLogo!\"></mat-icon>\r\n } @else {\r\n @if (footerConfig.imgLogo) {\r\n <img class=\"lf-footer-logo mb-4\" [src]=\"footerConfig.imgLogo\" alt=\"Logo\" />\r\n }\r\n }\r\n <!-- img logo -->\r\n <!-- links -->\r\n @if (footerConfig.links) {\r\n <div class=\"lf-footer-links mb-4\">\r\n @for (link of footerConfig.links; track link; let i = $index) {\r\n <div class=\"lf-footer-link\" [class.mr-2]=\"i < footerConfig.links!.length - 1\">\r\n @if (link.routerLink) {\r\n <a [routerLink]=\"[link.routerLink]\">{{ link.label || \"\" }}</a>\r\n } @else {\r\n <a [href]=\"link.href\" [target]=\"link.externalTab ? '_blank' : null\">\r\n {{ link.label }}\r\n </a>\r\n }\r\n </div>\r\n }\r\n </div>\r\n }\r\n <!-- copyright -->\r\n @if (footerConfig.copyright) {\r\n <span class=\"lf-footer-copyright\">\r\n {{ footerConfig.copyright }}\r\n </span>\r\n }\r\n </mat-card>\r\n}\r\n", styles: [".lf-footer{overflow:hidden;flex-flow:column;align-items:center;justify-content:center;min-height:100px;border-radius:0;border-top:solid 1px rgba(0,0,0,.12)}.lf-footer .lf-footer-logo{width:96px;height:96px}.lf-footer .lf-footer-links{display:flex;flex-flow:row wrap;align-items:center;justify-content:center}.lf-footer .lf-footer-links .lf-footer-link a{text-decoration:none;color:unset;font-size:12px}.lf-footer .lf-footer-links .lf-footer-link a:hover{color:var(--color-primary)}.lf-footer .lf-footer-copyright{font-size:12px}\n"] }]
219
+ }], propDecorators: { footerConfig: [{
220
+ type: Input
221
+ }] } });
222
+
223
+ class MaterialModule {
224
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.5", ngImport: i0, type: MaterialModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
225
+ static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.0.5", ngImport: i0, type: MaterialModule, exports: [MatCheckboxModule,
226
+ MatCheckboxModule,
227
+ MatButtonModule,
228
+ MatInputModule,
229
+ MatAutocompleteModule,
230
+ MatDatepickerModule,
231
+ MatFormFieldModule,
232
+ MatRadioModule,
233
+ MatSelectModule,
234
+ MatSliderModule,
235
+ MatSlideToggleModule,
236
+ MatMenuModule,
237
+ MatSidenavModule,
238
+ MatToolbarModule,
239
+ MatListModule,
240
+ MatGridListModule,
241
+ MatCardModule,
242
+ MatStepperModule,
243
+ MatTabsModule,
244
+ MatExpansionModule,
245
+ MatButtonToggleModule,
246
+ MatChipsModule,
247
+ MatIconModule,
248
+ MatProgressSpinnerModule,
249
+ MatProgressBarModule,
250
+ MatRippleModule,
251
+ MatDialogModule,
252
+ MatTooltipModule,
253
+ MatSnackBarModule,
254
+ MatTableModule,
255
+ MatSortModule,
256
+ MatPaginatorModule,
257
+ PortalModule] }); }
258
+ static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.0.5", ngImport: i0, type: MaterialModule, imports: [MatCheckboxModule,
259
+ MatCheckboxModule,
260
+ MatButtonModule,
261
+ MatInputModule,
262
+ MatAutocompleteModule,
263
+ MatDatepickerModule,
264
+ MatFormFieldModule,
265
+ MatRadioModule,
266
+ MatSelectModule,
267
+ MatSliderModule,
268
+ MatSlideToggleModule,
269
+ MatMenuModule,
270
+ MatSidenavModule,
271
+ MatToolbarModule,
272
+ MatListModule,
273
+ MatGridListModule,
274
+ MatCardModule,
275
+ MatStepperModule,
276
+ MatTabsModule,
277
+ MatExpansionModule,
278
+ MatButtonToggleModule,
279
+ MatChipsModule,
280
+ MatIconModule,
281
+ MatProgressSpinnerModule,
282
+ MatProgressBarModule,
283
+ MatRippleModule,
284
+ MatDialogModule,
285
+ MatTooltipModule,
286
+ MatSnackBarModule,
287
+ MatTableModule,
288
+ MatSortModule,
289
+ MatPaginatorModule,
290
+ PortalModule] }); }
291
+ }
292
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.5", ngImport: i0, type: MaterialModule, decorators: [{
293
+ type: NgModule,
294
+ args: [{
295
+ declarations: [],
296
+ exports: [
297
+ MatCheckboxModule,
298
+ MatCheckboxModule,
299
+ MatButtonModule,
300
+ MatInputModule,
301
+ MatAutocompleteModule,
302
+ MatDatepickerModule,
303
+ MatFormFieldModule,
304
+ MatRadioModule,
305
+ MatSelectModule,
306
+ MatSliderModule,
307
+ MatSlideToggleModule,
308
+ MatMenuModule,
309
+ MatSidenavModule,
310
+ MatToolbarModule,
311
+ MatListModule,
312
+ MatGridListModule,
313
+ MatCardModule,
314
+ MatStepperModule,
315
+ MatTabsModule,
316
+ MatExpansionModule,
317
+ MatButtonToggleModule,
318
+ MatChipsModule,
319
+ MatIconModule,
320
+ MatProgressSpinnerModule,
321
+ MatProgressBarModule,
322
+ MatRippleModule,
323
+ MatDialogModule,
324
+ MatTooltipModule,
325
+ MatSnackBarModule,
326
+ MatTableModule,
327
+ MatSortModule,
328
+ MatPaginatorModule,
329
+ PortalModule
330
+ ],
331
+ providers: [],
332
+ bootstrap: []
333
+ }]
334
+ }] });
335
+
336
+ class SharedModule {
337
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.5", ngImport: i0, type: SharedModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
338
+ static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.0.5", ngImport: i0, type: SharedModule, imports: [CommonModule,
339
+ FormsModule,
340
+ MaterialModule], exports: [CommonModule,
341
+ FormsModule,
342
+ MaterialModule] }); }
343
+ static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.0.5", ngImport: i0, type: SharedModule, imports: [CommonModule,
344
+ FormsModule,
345
+ MaterialModule, CommonModule,
346
+ FormsModule,
347
+ MaterialModule] }); }
348
+ }
349
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.5", ngImport: i0, type: SharedModule, decorators: [{
350
+ type: NgModule,
351
+ args: [{
352
+ imports: [
353
+ CommonModule,
354
+ FormsModule,
355
+ MaterialModule
356
+ ],
357
+ exports: [
358
+ CommonModule,
359
+ FormsModule,
360
+ MaterialModule
361
+ ]
362
+ }]
363
+ }] });
364
+
365
+ class InputComponent {
366
+ constructor() {
367
+ this.dialogRef = inject(MatDialogRef, { optional: true });
368
+ this.config = inject(MAT_DIALOG_DATA, { optional: true });
369
+ this.cd = inject(ChangeDetectorRef);
370
+ this.inputConfig = {};
371
+ this.isMobile = false;
372
+ this.inputSubmitEvent = new EventEmitter();
373
+ this.inputChangeEvent = new EventEmitter();
374
+ this.inputPrefixActionEvent = new EventEmitter();
375
+ this.input = null;
376
+ this.inputValue = '';
377
+ }
378
+ ngOnInit() {
379
+ if (this.config) {
380
+ this.inputConfig = this.config;
381
+ }
382
+ }
383
+ ngAfterViewInit() {
384
+ if (this.input && this.inputConfig.autoFocus) {
385
+ this.input.nativeElement.focus();
386
+ this.cd.detectChanges();
387
+ }
388
+ }
389
+ ngOnDestroy() {
390
+ this.inputValue = '';
391
+ this.inputChangeEvent.emit(this.inputValue);
392
+ }
393
+ inputSubmitted(value) {
394
+ this.inputSubmitEvent.emit(value);
395
+ if (this.dialogRef) {
396
+ this.dialogRef.close(value);
397
+ }
398
+ }
399
+ inputChanged(value) {
400
+ this.inputChangeEvent.emit(value);
401
+ }
402
+ inputPrefixAction() {
403
+ this.inputPrefixActionEvent.emit();
404
+ if (this.dialogRef) {
405
+ this.dialogRef.close();
406
+ }
407
+ }
408
+ clearInput() {
409
+ this.inputValue = '';
410
+ this.inputChangeEvent.emit(this.inputValue);
411
+ }
412
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.5", ngImport: i0, type: InputComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
413
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.0.5", type: InputComponent, isStandalone: true, selector: "lf-input", inputs: { inputConfig: "inputConfig", isMobile: "isMobile" }, outputs: { inputSubmitEvent: "inputSubmitEvent", inputChangeEvent: "inputChangeEvent", inputPrefixActionEvent: "inputPrefixActionEvent" }, viewQueries: [{ propertyName: "input", first: true, predicate: ["input"], descendants: true }], ngImport: i0, template: "@if (inputConfig) {\r\n <mat-form-field class=\"lf-input\" appearance=\"fill\" [class.lf-hide-hint]=\"!inputConfig.hint\">\r\n <mat-label>{{ inputConfig.label || \"Search\" }}</mat-label>\r\n @if (inputConfig.hint) {\r\n <mat-hint>{{ inputConfig.hint }}</mat-hint>\r\n }\r\n <input\r\n matInput\r\n type=\"text\"\r\n [(ngModel)]=\"inputValue\"\r\n [disabled]=\"inputConfig.disabled!\"\r\n (keyup.enter)=\"inputSubmitted(inputValue)\"\r\n (ngModelChange)=\"inputChanged($event)\"\r\n #input />\r\n @if (isMobile) {\r\n <button mat-icon-button matPrefix color=\"accent\" (click)=\"inputPrefixAction()\">\r\n <mat-icon>arrow_back</mat-icon>\r\n </button>\r\n }\r\n @if (inputValue) {\r\n <button class=\"lf-input-close-button\" mat-icon-button matSuffix (click)=\"clearInput()\">\r\n <mat-icon>close</mat-icon>\r\n </button>\r\n }\r\n @if (inputConfig.matIconSubmit) {\r\n <button\r\n mat-icon-button\r\n matSuffix\r\n color=\"accent\"\r\n type=\"submit\"\r\n (click)=\"inputSubmitted(inputValue)\">\r\n <mat-icon>\r\n {{ inputConfig.matIconSubmit }}\r\n </mat-icon>\r\n </button>\r\n }\r\n </mat-form-field>\r\n}\r\n", styles: [".lf-input{width:100%}.lf-input ::ng-deep .mdc-text-field{border-radius:28px!important}.lf-input ::ng-deep .mdc-line-ripple:after{border-bottom-width:0!important}.lf-input ::ng-deep .mdc-line-ripple:before{border-bottom-width:0!important}.lf-input .lf-input-close-button{color:#808080cc}.lf-input.lf-hide-hint ::ng-deep .mat-mdc-form-field-subscript-wrapper{display:none!important}\n"], dependencies: [{ kind: "ngmodule", type: SharedModule }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i2.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "directive", type: i3$2.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "component", type: i3$2.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i3$2.MatLabel, selector: "mat-label" }, { kind: "directive", type: i3$2.MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "directive", type: i3$2.MatPrefix, selector: "[matPrefix], [matIconPrefix], [matTextPrefix]", inputs: ["matTextPrefix"] }, { kind: "directive", type: i3$2.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "component", type: i4.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }] }); }
414
+ }
415
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.5", ngImport: i0, type: InputComponent, decorators: [{
416
+ type: Component,
417
+ args: [{ selector: 'lf-input', standalone: true, imports: [SharedModule], template: "@if (inputConfig) {\r\n <mat-form-field class=\"lf-input\" appearance=\"fill\" [class.lf-hide-hint]=\"!inputConfig.hint\">\r\n <mat-label>{{ inputConfig.label || \"Search\" }}</mat-label>\r\n @if (inputConfig.hint) {\r\n <mat-hint>{{ inputConfig.hint }}</mat-hint>\r\n }\r\n <input\r\n matInput\r\n type=\"text\"\r\n [(ngModel)]=\"inputValue\"\r\n [disabled]=\"inputConfig.disabled!\"\r\n (keyup.enter)=\"inputSubmitted(inputValue)\"\r\n (ngModelChange)=\"inputChanged($event)\"\r\n #input />\r\n @if (isMobile) {\r\n <button mat-icon-button matPrefix color=\"accent\" (click)=\"inputPrefixAction()\">\r\n <mat-icon>arrow_back</mat-icon>\r\n </button>\r\n }\r\n @if (inputValue) {\r\n <button class=\"lf-input-close-button\" mat-icon-button matSuffix (click)=\"clearInput()\">\r\n <mat-icon>close</mat-icon>\r\n </button>\r\n }\r\n @if (inputConfig.matIconSubmit) {\r\n <button\r\n mat-icon-button\r\n matSuffix\r\n color=\"accent\"\r\n type=\"submit\"\r\n (click)=\"inputSubmitted(inputValue)\">\r\n <mat-icon>\r\n {{ inputConfig.matIconSubmit }}\r\n </mat-icon>\r\n </button>\r\n }\r\n </mat-form-field>\r\n}\r\n", styles: [".lf-input{width:100%}.lf-input ::ng-deep .mdc-text-field{border-radius:28px!important}.lf-input ::ng-deep .mdc-line-ripple:after{border-bottom-width:0!important}.lf-input ::ng-deep .mdc-line-ripple:before{border-bottom-width:0!important}.lf-input .lf-input-close-button{color:#808080cc}.lf-input.lf-hide-hint ::ng-deep .mat-mdc-form-field-subscript-wrapper{display:none!important}\n"] }]
418
+ }], propDecorators: { inputConfig: [{
419
+ type: Input
420
+ }], isMobile: [{
421
+ type: Input
422
+ }], inputSubmitEvent: [{
423
+ type: Output
424
+ }], inputChangeEvent: [{
425
+ type: Output
426
+ }], inputPrefixActionEvent: [{
427
+ type: Output
428
+ }], input: [{
429
+ type: ViewChild,
430
+ args: ['input']
431
+ }] } });
432
+
433
+ class IconComponent {
434
+ constructor() {
435
+ this.outlineIcon = false;
436
+ this.alignMiddle = false;
437
+ }
438
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.5", ngImport: i0, type: IconComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
439
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.0.5", type: IconComponent, isStandalone: true, selector: "lf-icon", inputs: { matIcon: "matIcon", svgIcon: "svgIcon", outlineIcon: "outlineIcon", alignMiddle: "alignMiddle" }, ngImport: i0, template: "<!-- mat icon -->\r\n@if (matIcon) {\r\n <mat-icon\r\n class=\"lf-icon\"\r\n [class.material-icons-outlined]=\"outlineIcon\"\r\n [class.lf-icon-align-middle]=\"alignMiddle\">\r\n {{ matIcon }}\r\n </mat-icon>\r\n} @else {\r\n @if (svgIcon) {\r\n <mat-icon\r\n class=\"lf-icon\"\r\n [svgIcon]=\"svgIcon\"\r\n [class.lf-icon-align-middle]=\"alignMiddle\"></mat-icon>\r\n }\r\n}\r\n<!-- svg icon -->\r\n", styles: [":host{display:contents}.lf-icon-align-middle{vertical-align:bottom}\n"], dependencies: [{ kind: "ngmodule", type: SharedModule }, { kind: "component", type: i4.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }] }); }
440
+ }
441
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.5", ngImport: i0, type: IconComponent, decorators: [{
442
+ type: Component,
443
+ args: [{ selector: 'lf-icon', standalone: true, imports: [SharedModule], template: "<!-- mat icon -->\r\n@if (matIcon) {\r\n <mat-icon\r\n class=\"lf-icon\"\r\n [class.material-icons-outlined]=\"outlineIcon\"\r\n [class.lf-icon-align-middle]=\"alignMiddle\">\r\n {{ matIcon }}\r\n </mat-icon>\r\n} @else {\r\n @if (svgIcon) {\r\n <mat-icon\r\n class=\"lf-icon\"\r\n [svgIcon]=\"svgIcon\"\r\n [class.lf-icon-align-middle]=\"alignMiddle\"></mat-icon>\r\n }\r\n}\r\n<!-- svg icon -->\r\n", styles: [":host{display:contents}.lf-icon-align-middle{vertical-align:bottom}\n"] }]
444
+ }], propDecorators: { matIcon: [{
445
+ type: Input
446
+ }], svgIcon: [{
447
+ type: Input
448
+ }], outlineIcon: [{
449
+ type: Input
450
+ }], alignMiddle: [{
451
+ type: Input
452
+ }] } });
453
+
454
+ class HeaderComponent {
455
+ constructor() {
456
+ this.headerConfig = null;
457
+ this.isMobile = false;
458
+ this.routeLoading = false;
459
+ this.headerButtonClickEvent = new EventEmitter();
460
+ this.headerInputSubmitEvent = new EventEmitter();
461
+ this.headerInputChangeEvent = new EventEmitter();
462
+ }
463
+ ngOnInit() {
464
+ // Avoid initializing the header with an open input field on mobile
465
+ if (this.isMobile && this.headerConfig?.inputConfig?.enable) {
466
+ this.headerConfig.inputConfig.enable = false;
467
+ }
468
+ }
469
+ buttonClicked(id) {
470
+ if (!id) {
471
+ return;
472
+ }
473
+ this.headerButtonClickEvent.emit(id);
474
+ }
475
+ inputSubmitted(value) {
476
+ this.headerInputSubmitEvent.emit(value);
477
+ }
478
+ inputChanged(value) {
479
+ this.headerInputChangeEvent.emit(value);
480
+ }
481
+ isActive(id) {
482
+ if (!id || !this.currentRoute) {
483
+ return false;
484
+ }
485
+ const route = this.currentRoute.substring(this.currentRoute.indexOf('/') + 1);
486
+ return route === id;
487
+ }
488
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.5", ngImport: i0, type: HeaderComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
489
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.0.5", type: HeaderComponent, isStandalone: false, selector: "lf-header", inputs: { headerConfig: "headerConfig", isMobile: "isMobile", routeLoading: "routeLoading", currentRoute: "currentRoute" }, outputs: { headerButtonClickEvent: "headerButtonClickEvent", headerInputSubmitEvent: "headerInputSubmitEvent", headerInputChangeEvent: "headerInputChangeEvent" }, ngImport: i0, template: "@if (headerConfig && headerConfig.enable) {\r\n <mat-toolbar\r\n class=\"lf-header mat-elevation-z3\"\r\n [class.px-4]=\"!isMobile\"\r\n [class.px-1]=\"isMobile\"\r\n [ngClass]=\"headerConfig.class\"\r\n color=\"primary\">\r\n <!-- left menu button -->\r\n <ng-container\r\n [ngTemplateOutlet]=\"menuButtonTemplate\"\r\n [ngTemplateOutletContext]=\"{\r\n menuButton: headerConfig.leftMenuButton!,\r\n hideLabel: true,\r\n }\"></ng-container>\r\n <!-- logo & title -->\r\n <div\r\n class=\"lf-header-logo-title-wrapper ml-1 mr-2\"\r\n [class.ml-10]=\"headerConfig.leftMenuButton && !isMobile\">\r\n <!-- link wrapper -->\r\n <div\r\n class=\"lf-header-logo-title-wrapper-link\"\r\n [class.lf-clickable]=\"headerConfig.titleRouterLink\"\r\n [routerLink]=\"headerConfig.titleRouterLink ? [headerConfig.titleRouterLink] : null\">\r\n <!-- svg logo -->\r\n @if (headerConfig.svgLogo) {\r\n <mat-icon\r\n class=\"lf-header-logo\"\r\n [class.mr-3]=\"headerConfig.title\"\r\n [svgIcon]=\"headerConfig.svgLogo!\"></mat-icon>\r\n } @else {\r\n @if (headerConfig.imgLogo) {\r\n <img\r\n class=\"lf-header-logo\"\r\n [class.mr-3]=\"headerConfig.title\"\r\n [src]=\"headerConfig.imgLogo\"\r\n alt=\"Logo\" />\r\n }\r\n }\r\n <!-- img logo -->\r\n <!-- title -->\r\n @if (headerConfig.title) {\r\n <div class=\"lf-header-title-wrapper\">\r\n @if (headerConfig.title) {\r\n <span class=\"lf-header-title\">\r\n {{ headerConfig.title }}\r\n </span>\r\n }\r\n @if (headerConfig.subtitle) {\r\n <span class=\"lf-header-subtitle\">\r\n {{ headerConfig.subtitle }}\r\n </span>\r\n }\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n <!-- input -->\r\n @if (headerConfig.inputConfig?.enable) {\r\n <div class=\"spacer\"></div>\r\n <lf-input\r\n [class.lf-header-input-mobile]=\"isMobile\"\r\n [class.mx-3]=\"!isMobile\"\r\n [inputConfig]=\"headerConfig.inputConfig!\"\r\n [isMobile]=\"isMobile\"\r\n (inputSubmitEvent)=\"inputSubmitted($event)\"\r\n (inputChangeEvent)=\"inputChanged($event)\"\r\n (inputPrefixActionEvent)=\"headerConfig.inputConfig!.enable = false\"></lf-input>\r\n }\r\n <!-- spacer -->\r\n <div class=\"spacer\"></div>\r\n <!-- right menu buttons -->\r\n @for (button of headerConfig.rightMenuButtons; track button) {\r\n <ng-container\r\n [ngTemplateOutlet]=\"menuButtonTemplate\"\r\n [ngTemplateOutletContext]=\"{\r\n menuButton: button,\r\n }\"></ng-container>\r\n }\r\n </mat-toolbar>\r\n <!-- loading bar -->\r\n @if (headerConfig.loading || (headerConfig.showRouteLoading && routeLoading)) {\r\n <mat-progress-bar\r\n class=\"lf-header-progress-bar\"\r\n color=\"accent\"\r\n mode=\"indeterminate\"></mat-progress-bar>\r\n }\r\n}\r\n\r\n<!-- header menu button -->\r\n<ng-template #menuButtonTemplate let-menuButton=\"menuButton\" let-hideLabel=\"hideLabel\">\r\n @if (menuButton) {\r\n <!-- icon button -->\r\n @if ((menuButton.matIcon || menuButton.svgIcon) && (!menuButton.label || hideLabel)) {\r\n <button\r\n mat-icon-button\r\n class=\"lf-header-menu-button\"\r\n [ngClass]=\"menuButton.class\"\r\n (click)=\"buttonClicked(menuButton.id)\"\r\n [matMenuTriggerFor]=\"menuButton.menuButtons ? menu : null\"\r\n [matTooltip]=\"menuButton.tooltip\"\r\n [attr.aria-label]=\"menuButton.id\">\r\n <!-- icon -->\r\n <lf-icon\r\n [matIcon]=\"menuButton.matIcon\"\r\n [svgIcon]=\"menuButton.svgIcon\"\r\n [outlineIcon]=\"menuButton.outlineIcon\"></lf-icon>\r\n </button>\r\n } @else {\r\n @if (!hideLabel) {\r\n <button\r\n mat-button\r\n class=\"lf-header-menu-button\"\r\n [class.lf-header-menu-button-active]=\"isActive(menuButton.id)\"\r\n [ngClass]=\"menuButton.class\"\r\n (click)=\"buttonClicked(menuButton.id)\"\r\n [matMenuTriggerFor]=\"menuButton.menuButtons ? menu : null\"\r\n [matTooltip]=\"menuButton.tooltip\">\r\n {{ menuButton.label }}\r\n </button>\r\n }\r\n }\r\n <!-- text button -->\r\n <!-- menu -->\r\n <mat-menu #menu=\"matMenu\">\r\n <!-- label menu buttons -->\r\n @for (button of menuButton.menuButtons; track button) {\r\n <!-- menu button -->\r\n @if (button.label) {\r\n <button\r\n mat-menu-item\r\n [class.lf-header-menu-button-active]=\"isActive(button.id)\"\r\n [ngClass]=\"button.class\"\r\n (click)=\"buttonClicked(button.id)\">\r\n <!-- icon -->\r\n <lf-icon\r\n [matIcon]=\"button.matIcon\"\r\n [svgIcon]=\"button.svgIcon\"\r\n [outlineIcon]=\"button.outlineIcon\"\r\n [alignMiddle]=\"true\"></lf-icon>\r\n <!-- label -->\r\n @if (button.label) {\r\n <span>{{ button.label }}</span>\r\n }\r\n </button>\r\n }\r\n }\r\n <!-- icon menu buttons -->\r\n <div class=\"lf-menu-icons px-1\">\r\n @for (button of menuButton.menuButtons; track button) {\r\n <!-- icon button -->\r\n @if (!button.label && (button.matIcon || button.svgIcon)) {\r\n <button\r\n mat-button\r\n class=\"lf-menu-icon-button\"\r\n [ngClass]=\"button.class\"\r\n (click)=\"buttonClicked(button.id)\"\r\n [matTooltip]=\"button.tooltip\">\r\n <!-- icon -->\r\n <lf-icon\r\n [matIcon]=\"button.matIcon\"\r\n [svgIcon]=\"button.svgIcon\"\r\n [outlineIcon]=\"button.outlineIcon\"\r\n [alignMiddle]=\"true\"></lf-icon>\r\n </button>\r\n }\r\n }\r\n </div>\r\n </mat-menu>\r\n }\r\n</ng-template>\r\n", styles: [".lf-header{transition:top .3s;z-index:100;position:fixed;top:0;height:64px}.lf-header .lf-header-menu-button{flex-shrink:0;max-width:144px}.lf-header .lf-header-menu-button ::ng-deep .mdc-button__label{overflow:hidden;text-overflow:ellipsis}.lf-header .lf-header-menu-button.lf-header-menu-button-active{background-color:#fff}.lf-header .lf-header-logo-title-wrapper{flex:0 0 auto;max-width:480px;overflow:hidden;display:flex}.lf-header .lf-header-logo-title-wrapper .lf-header-logo-title-wrapper-link{display:flex;flex-flow:row nowrap;align-items:center;flex:0}.lf-header .lf-header-logo-title-wrapper .lf-header-logo-title-wrapper-link.lf-clickable{cursor:pointer}.lf-header .lf-header-logo-title-wrapper .lf-header-logo{width:40px;height:40px;min-width:40px;min-height:40px}.lf-header .lf-header-logo-title-wrapper .lf-header-title-wrapper{display:flex;flex-flow:column}.lf-header .lf-header-logo-title-wrapper .lf-header-title-wrapper .lf-header-title{font-size:20px;line-height:28px}.lf-header .lf-header-logo-title-wrapper .lf-header-title-wrapper .lf-header-subtitle{font-size:12px;line-height:12px}.lf-header lf-input{z-index:100;flex:1 1 480px}.lf-header lf-input.lf-header-input-mobile{position:fixed!important;left:4px!important;right:4px!important;width:unset!important;max-width:unset!important}.lf-header .spacer{flex:1 0 auto}.lf-menu-icons{display:flex;flex-flow:row wrap;align-items:center;justify-content:flex-start}.lf-menu-icons .lf-menu-icon-button{width:48px;min-width:unset;height:48px;margin:0;padding:0;border-radius:50%}.lf-header-progress-bar{z-index:100;position:fixed;top:64px}\n"], dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i2$2.RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "component", type: i2.MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i2.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i4$2.MatMenu, selector: "mat-menu", inputs: ["backdropClass", "aria-label", "aria-labelledby", "aria-describedby", "xPosition", "yPosition", "overlapTrigger", "hasBackdrop", "class", "classList"], outputs: ["closed", "close"], exportAs: ["matMenu"] }, { kind: "component", type: i4$2.MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i4$2.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }, { kind: "component", type: i5.MatToolbar, selector: "mat-toolbar", inputs: ["color"], exportAs: ["matToolbar"] }, { kind: "component", type: i4.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i7.MatProgressBar, selector: "mat-progress-bar", inputs: ["color", "value", "bufferValue", "mode"], outputs: ["animationEnd"], exportAs: ["matProgressBar"] }, { kind: "directive", type: i4$1.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: InputComponent, selector: "lf-input", inputs: ["inputConfig", "isMobile"], outputs: ["inputSubmitEvent", "inputChangeEvent", "inputPrefixActionEvent"] }, { kind: "component", type: IconComponent, selector: "lf-icon", inputs: ["matIcon", "svgIcon", "outlineIcon", "alignMiddle"] }] }); }
490
+ }
491
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.5", ngImport: i0, type: HeaderComponent, decorators: [{
492
+ type: Component,
493
+ args: [{ selector: 'lf-header', standalone: false, template: "@if (headerConfig && headerConfig.enable) {\r\n <mat-toolbar\r\n class=\"lf-header mat-elevation-z3\"\r\n [class.px-4]=\"!isMobile\"\r\n [class.px-1]=\"isMobile\"\r\n [ngClass]=\"headerConfig.class\"\r\n color=\"primary\">\r\n <!-- left menu button -->\r\n <ng-container\r\n [ngTemplateOutlet]=\"menuButtonTemplate\"\r\n [ngTemplateOutletContext]=\"{\r\n menuButton: headerConfig.leftMenuButton!,\r\n hideLabel: true,\r\n }\"></ng-container>\r\n <!-- logo & title -->\r\n <div\r\n class=\"lf-header-logo-title-wrapper ml-1 mr-2\"\r\n [class.ml-10]=\"headerConfig.leftMenuButton && !isMobile\">\r\n <!-- link wrapper -->\r\n <div\r\n class=\"lf-header-logo-title-wrapper-link\"\r\n [class.lf-clickable]=\"headerConfig.titleRouterLink\"\r\n [routerLink]=\"headerConfig.titleRouterLink ? [headerConfig.titleRouterLink] : null\">\r\n <!-- svg logo -->\r\n @if (headerConfig.svgLogo) {\r\n <mat-icon\r\n class=\"lf-header-logo\"\r\n [class.mr-3]=\"headerConfig.title\"\r\n [svgIcon]=\"headerConfig.svgLogo!\"></mat-icon>\r\n } @else {\r\n @if (headerConfig.imgLogo) {\r\n <img\r\n class=\"lf-header-logo\"\r\n [class.mr-3]=\"headerConfig.title\"\r\n [src]=\"headerConfig.imgLogo\"\r\n alt=\"Logo\" />\r\n }\r\n }\r\n <!-- img logo -->\r\n <!-- title -->\r\n @if (headerConfig.title) {\r\n <div class=\"lf-header-title-wrapper\">\r\n @if (headerConfig.title) {\r\n <span class=\"lf-header-title\">\r\n {{ headerConfig.title }}\r\n </span>\r\n }\r\n @if (headerConfig.subtitle) {\r\n <span class=\"lf-header-subtitle\">\r\n {{ headerConfig.subtitle }}\r\n </span>\r\n }\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n <!-- input -->\r\n @if (headerConfig.inputConfig?.enable) {\r\n <div class=\"spacer\"></div>\r\n <lf-input\r\n [class.lf-header-input-mobile]=\"isMobile\"\r\n [class.mx-3]=\"!isMobile\"\r\n [inputConfig]=\"headerConfig.inputConfig!\"\r\n [isMobile]=\"isMobile\"\r\n (inputSubmitEvent)=\"inputSubmitted($event)\"\r\n (inputChangeEvent)=\"inputChanged($event)\"\r\n (inputPrefixActionEvent)=\"headerConfig.inputConfig!.enable = false\"></lf-input>\r\n }\r\n <!-- spacer -->\r\n <div class=\"spacer\"></div>\r\n <!-- right menu buttons -->\r\n @for (button of headerConfig.rightMenuButtons; track button) {\r\n <ng-container\r\n [ngTemplateOutlet]=\"menuButtonTemplate\"\r\n [ngTemplateOutletContext]=\"{\r\n menuButton: button,\r\n }\"></ng-container>\r\n }\r\n </mat-toolbar>\r\n <!-- loading bar -->\r\n @if (headerConfig.loading || (headerConfig.showRouteLoading && routeLoading)) {\r\n <mat-progress-bar\r\n class=\"lf-header-progress-bar\"\r\n color=\"accent\"\r\n mode=\"indeterminate\"></mat-progress-bar>\r\n }\r\n}\r\n\r\n<!-- header menu button -->\r\n<ng-template #menuButtonTemplate let-menuButton=\"menuButton\" let-hideLabel=\"hideLabel\">\r\n @if (menuButton) {\r\n <!-- icon button -->\r\n @if ((menuButton.matIcon || menuButton.svgIcon) && (!menuButton.label || hideLabel)) {\r\n <button\r\n mat-icon-button\r\n class=\"lf-header-menu-button\"\r\n [ngClass]=\"menuButton.class\"\r\n (click)=\"buttonClicked(menuButton.id)\"\r\n [matMenuTriggerFor]=\"menuButton.menuButtons ? menu : null\"\r\n [matTooltip]=\"menuButton.tooltip\"\r\n [attr.aria-label]=\"menuButton.id\">\r\n <!-- icon -->\r\n <lf-icon\r\n [matIcon]=\"menuButton.matIcon\"\r\n [svgIcon]=\"menuButton.svgIcon\"\r\n [outlineIcon]=\"menuButton.outlineIcon\"></lf-icon>\r\n </button>\r\n } @else {\r\n @if (!hideLabel) {\r\n <button\r\n mat-button\r\n class=\"lf-header-menu-button\"\r\n [class.lf-header-menu-button-active]=\"isActive(menuButton.id)\"\r\n [ngClass]=\"menuButton.class\"\r\n (click)=\"buttonClicked(menuButton.id)\"\r\n [matMenuTriggerFor]=\"menuButton.menuButtons ? menu : null\"\r\n [matTooltip]=\"menuButton.tooltip\">\r\n {{ menuButton.label }}\r\n </button>\r\n }\r\n }\r\n <!-- text button -->\r\n <!-- menu -->\r\n <mat-menu #menu=\"matMenu\">\r\n <!-- label menu buttons -->\r\n @for (button of menuButton.menuButtons; track button) {\r\n <!-- menu button -->\r\n @if (button.label) {\r\n <button\r\n mat-menu-item\r\n [class.lf-header-menu-button-active]=\"isActive(button.id)\"\r\n [ngClass]=\"button.class\"\r\n (click)=\"buttonClicked(button.id)\">\r\n <!-- icon -->\r\n <lf-icon\r\n [matIcon]=\"button.matIcon\"\r\n [svgIcon]=\"button.svgIcon\"\r\n [outlineIcon]=\"button.outlineIcon\"\r\n [alignMiddle]=\"true\"></lf-icon>\r\n <!-- label -->\r\n @if (button.label) {\r\n <span>{{ button.label }}</span>\r\n }\r\n </button>\r\n }\r\n }\r\n <!-- icon menu buttons -->\r\n <div class=\"lf-menu-icons px-1\">\r\n @for (button of menuButton.menuButtons; track button) {\r\n <!-- icon button -->\r\n @if (!button.label && (button.matIcon || button.svgIcon)) {\r\n <button\r\n mat-button\r\n class=\"lf-menu-icon-button\"\r\n [ngClass]=\"button.class\"\r\n (click)=\"buttonClicked(button.id)\"\r\n [matTooltip]=\"button.tooltip\">\r\n <!-- icon -->\r\n <lf-icon\r\n [matIcon]=\"button.matIcon\"\r\n [svgIcon]=\"button.svgIcon\"\r\n [outlineIcon]=\"button.outlineIcon\"\r\n [alignMiddle]=\"true\"></lf-icon>\r\n </button>\r\n }\r\n }\r\n </div>\r\n </mat-menu>\r\n }\r\n</ng-template>\r\n", styles: [".lf-header{transition:top .3s;z-index:100;position:fixed;top:0;height:64px}.lf-header .lf-header-menu-button{flex-shrink:0;max-width:144px}.lf-header .lf-header-menu-button ::ng-deep .mdc-button__label{overflow:hidden;text-overflow:ellipsis}.lf-header .lf-header-menu-button.lf-header-menu-button-active{background-color:#fff}.lf-header .lf-header-logo-title-wrapper{flex:0 0 auto;max-width:480px;overflow:hidden;display:flex}.lf-header .lf-header-logo-title-wrapper .lf-header-logo-title-wrapper-link{display:flex;flex-flow:row nowrap;align-items:center;flex:0}.lf-header .lf-header-logo-title-wrapper .lf-header-logo-title-wrapper-link.lf-clickable{cursor:pointer}.lf-header .lf-header-logo-title-wrapper .lf-header-logo{width:40px;height:40px;min-width:40px;min-height:40px}.lf-header .lf-header-logo-title-wrapper .lf-header-title-wrapper{display:flex;flex-flow:column}.lf-header .lf-header-logo-title-wrapper .lf-header-title-wrapper .lf-header-title{font-size:20px;line-height:28px}.lf-header .lf-header-logo-title-wrapper .lf-header-title-wrapper .lf-header-subtitle{font-size:12px;line-height:12px}.lf-header lf-input{z-index:100;flex:1 1 480px}.lf-header lf-input.lf-header-input-mobile{position:fixed!important;left:4px!important;right:4px!important;width:unset!important;max-width:unset!important}.lf-header .spacer{flex:1 0 auto}.lf-menu-icons{display:flex;flex-flow:row wrap;align-items:center;justify-content:flex-start}.lf-menu-icons .lf-menu-icon-button{width:48px;min-width:unset;height:48px;margin:0;padding:0;border-radius:50%}.lf-header-progress-bar{z-index:100;position:fixed;top:64px}\n"] }]
494
+ }], propDecorators: { headerConfig: [{
495
+ type: Input
496
+ }], isMobile: [{
497
+ type: Input
498
+ }], routeLoading: [{
499
+ type: Input
500
+ }], currentRoute: [{
501
+ type: Input
502
+ }], headerButtonClickEvent: [{
503
+ type: Output
504
+ }], headerInputSubmitEvent: [{
505
+ type: Output
506
+ }], headerInputChangeEvent: [{
507
+ type: Output
508
+ }] } });
509
+
510
+ class LoadingOverlayComponent {
511
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.5", ngImport: i0, type: LoadingOverlayComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
512
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.0.5", type: LoadingOverlayComponent, isStandalone: false, selector: "lf-loading-overlay", ngImport: i0, template: "<div class=\"lf-loading-overlay\">\r\n <mat-spinner class=\"lf-loading-spinner\" color=\"accent\" mode=\"indeterminate\"></mat-spinner>\r\n</div>\r\n", styles: [".lf-loading-overlay{position:fixed;z-index:101;inset:0;height:100%;width:100%;display:flex;align-items:center;justify-content:center;background-color:#00000029}\n"], dependencies: [{ kind: "component", type: i1$2.MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }] }); }
513
+ }
514
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.5", ngImport: i0, type: LoadingOverlayComponent, decorators: [{
515
+ type: Component,
516
+ args: [{ selector: 'lf-loading-overlay', standalone: false, template: "<div class=\"lf-loading-overlay\">\r\n <mat-spinner class=\"lf-loading-spinner\" color=\"accent\" mode=\"indeterminate\"></mat-spinner>\r\n</div>\r\n", styles: [".lf-loading-overlay{position:fixed;z-index:101;inset:0;height:100%;width:100%;display:flex;align-items:center;justify-content:center;background-color:#00000029}\n"] }]
517
+ }] });
518
+
519
+ class NavbarComponent {
520
+ constructor() {
521
+ this.navbarConfig = null;
522
+ this.isMobile = false;
523
+ this.navbarButtonClickEvent = new EventEmitter();
524
+ }
525
+ buttonClicked(id) {
526
+ if (!id) {
527
+ return;
528
+ }
529
+ this.navbarButtonClickEvent.emit(id);
530
+ }
531
+ isActive(id) {
532
+ if (!id || !this.currentRoute) {
533
+ return false;
534
+ }
535
+ const route = this.currentRoute.substring(this.currentRoute.indexOf('/') + 1);
536
+ return route === id;
537
+ }
538
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.5", ngImport: i0, type: NavbarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
539
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.0.5", type: NavbarComponent, isStandalone: false, selector: "lf-navbar", inputs: { navbarConfig: "navbarConfig", isMobile: "isMobile", currentRoute: "currentRoute" }, outputs: { navbarButtonClickEvent: "navbarButtonClickEvent" }, ngImport: i0, template: "@if (navbarConfig && navbarConfig.enable) {\r\n <div\r\n class=\"mat-app-background mat-elevation-z3\"\r\n [class.lf-navbar]=\"!isMobile\"\r\n [class.lf-navbar-mobile]=\"isMobile\"\r\n [ngClass]=\"navbarConfig.class\">\r\n <!-- items -->\r\n <div [class.lf-navbar-items]=\"!isMobile\" [class.lf-navbar-mobile-items]=\"isMobile\">\r\n <!-- item -->\r\n @for (button of navbarConfig.menuButtons; track button; let i = $index) {\r\n @if (i < 5) {\r\n <div\r\n class=\"lf-navbar-item\"\r\n [class.lf-navbar-item-active]=\"isActive(button.id)\"\r\n [ngClass]=\"button.class\"\r\n (click)=\"buttonClicked(button.id)\"\r\n tabindex=\"0\"\r\n role=\"button\"\r\n [matTooltip]=\"button.tooltip\">\r\n <!-- icon -->\r\n <lf-icon\r\n [matIcon]=\"button.matIcon!\"\r\n [svgIcon]=\"button.svgIcon!\"\r\n [outlineIcon]=\"button.outlineIcon!\"></lf-icon>\r\n <!-- label -->\r\n <!-- show a protected space on desktop so the icon doesn't move up and down -->\r\n @if (button?.label) {\r\n <span class=\"lf-navbar-item-label\">\r\n {{\r\n isActive(button.id) || navbarConfig.showAllLabels\r\n ? button.label\r\n : isMobile\r\n ? \"\"\r\n : \"&nbsp;\"\r\n }}\r\n </span>\r\n }\r\n </div>\r\n }\r\n }\r\n </div>\r\n </div>\r\n}\r\n", styles: [".lf-navbar{z-index:99;position:fixed;left:0;top:0;height:100vh;padding:80px 4px 0;border-right:solid 1px rgba(0,0,0,.12)}.lf-navbar .lf-navbar-items{display:flex;flex-flow:column;align-items:center}.lf-navbar-mobile{z-index:99;position:fixed;left:0;bottom:0;width:100vw;padding:4px 0;box-sizing:border-box;border-top:solid 1px rgba(0,0,0,.12)}.lf-navbar-mobile .lf-navbar-mobile-items{display:flex;flex-flow:row nowrap;align-items:center;justify-content:space-evenly}.lf-navbar-mobile .lf-navbar-mobile-items .lf-navbar-item{height:56px!important}.lf-navbar-item{width:72px;height:72px;display:flex;align-items:center;justify-content:center;flex-flow:column;border-radius:16px;cursor:pointer}.lf-navbar-item.lf-navbar-item-active{color:var(--color-primary)}.lf-navbar-item .lf-navbar-item-icon{width:24px;height:24px;overflow:visible!important}.lf-navbar-item .lf-navbar-item-label{max-width:72px;white-space:nowrap!important;overflow:hidden;text-overflow:ellipsis;text-transform:none;vertical-align:top;font-size:12px;font-weight:500}\n"], dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i4$1.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: IconComponent, selector: "lf-icon", inputs: ["matIcon", "svgIcon", "outlineIcon", "alignMiddle"] }] }); }
540
+ }
541
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.5", ngImport: i0, type: NavbarComponent, decorators: [{
542
+ type: Component,
543
+ args: [{ selector: 'lf-navbar', standalone: false, template: "@if (navbarConfig && navbarConfig.enable) {\r\n <div\r\n class=\"mat-app-background mat-elevation-z3\"\r\n [class.lf-navbar]=\"!isMobile\"\r\n [class.lf-navbar-mobile]=\"isMobile\"\r\n [ngClass]=\"navbarConfig.class\">\r\n <!-- items -->\r\n <div [class.lf-navbar-items]=\"!isMobile\" [class.lf-navbar-mobile-items]=\"isMobile\">\r\n <!-- item -->\r\n @for (button of navbarConfig.menuButtons; track button; let i = $index) {\r\n @if (i < 5) {\r\n <div\r\n class=\"lf-navbar-item\"\r\n [class.lf-navbar-item-active]=\"isActive(button.id)\"\r\n [ngClass]=\"button.class\"\r\n (click)=\"buttonClicked(button.id)\"\r\n tabindex=\"0\"\r\n role=\"button\"\r\n [matTooltip]=\"button.tooltip\">\r\n <!-- icon -->\r\n <lf-icon\r\n [matIcon]=\"button.matIcon!\"\r\n [svgIcon]=\"button.svgIcon!\"\r\n [outlineIcon]=\"button.outlineIcon!\"></lf-icon>\r\n <!-- label -->\r\n <!-- show a protected space on desktop so the icon doesn't move up and down -->\r\n @if (button?.label) {\r\n <span class=\"lf-navbar-item-label\">\r\n {{\r\n isActive(button.id) || navbarConfig.showAllLabels\r\n ? button.label\r\n : isMobile\r\n ? \"\"\r\n : \"&nbsp;\"\r\n }}\r\n </span>\r\n }\r\n </div>\r\n }\r\n }\r\n </div>\r\n </div>\r\n}\r\n", styles: [".lf-navbar{z-index:99;position:fixed;left:0;top:0;height:100vh;padding:80px 4px 0;border-right:solid 1px rgba(0,0,0,.12)}.lf-navbar .lf-navbar-items{display:flex;flex-flow:column;align-items:center}.lf-navbar-mobile{z-index:99;position:fixed;left:0;bottom:0;width:100vw;padding:4px 0;box-sizing:border-box;border-top:solid 1px rgba(0,0,0,.12)}.lf-navbar-mobile .lf-navbar-mobile-items{display:flex;flex-flow:row nowrap;align-items:center;justify-content:space-evenly}.lf-navbar-mobile .lf-navbar-mobile-items .lf-navbar-item{height:56px!important}.lf-navbar-item{width:72px;height:72px;display:flex;align-items:center;justify-content:center;flex-flow:column;border-radius:16px;cursor:pointer}.lf-navbar-item.lf-navbar-item-active{color:var(--color-primary)}.lf-navbar-item .lf-navbar-item-icon{width:24px;height:24px;overflow:visible!important}.lf-navbar-item .lf-navbar-item-label{max-width:72px;white-space:nowrap!important;overflow:hidden;text-overflow:ellipsis;text-transform:none;vertical-align:top;font-size:12px;font-weight:500}\n"] }]
544
+ }], propDecorators: { navbarConfig: [{
545
+ type: Input
546
+ }], isMobile: [{
547
+ type: Input
548
+ }], currentRoute: [{
549
+ type: Input
550
+ }], navbarButtonClickEvent: [{
551
+ type: Output
552
+ }] } });
553
+
554
+ class BreakpointService {
555
+ constructor() {
556
+ this.breakpointObserver = inject(BreakpointObserver);
557
+ this.breakpoint$ = this.breakpointObserver
558
+ .observe([Breakpoints.Large, Breakpoints.Medium, Breakpoints.Small, Breakpoints.XSmall])
559
+ .pipe(distinctUntilChanged());
560
+ }
561
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.5", ngImport: i0, type: BreakpointService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
562
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.0.5", ngImport: i0, type: BreakpointService, providedIn: 'root' }); }
563
+ }
564
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.5", ngImport: i0, type: BreakpointService, decorators: [{
565
+ type: Injectable,
566
+ args: [{ providedIn: 'root' }]
567
+ }] });
568
+
569
+ class ConfirmDialogComponent {
570
+ constructor() {
571
+ this.config = inject(MAT_DIALOG_DATA);
572
+ }
573
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.5", ngImport: i0, type: ConfirmDialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
574
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.0.5", type: ConfirmDialogComponent, isStandalone: false, selector: "lf-confirm-dialog", ngImport: i0, template: "@if (config) {\r\n @if (config.title) {\r\n <h2 mat-dialog-title>{{ config.title }}</h2>\r\n }\r\n\r\n <mat-dialog-content>\r\n @if (config.message) {\r\n <p>{{ config.message }}</p>\r\n }\r\n </mat-dialog-content>\r\n\r\n <mat-dialog-actions align=\"end\">\r\n @if (config.closeLabel) {\r\n <button mat-button [mat-dialog-close]=\"false\">\r\n {{ config.closeLabel }}\r\n </button>\r\n }\r\n @if (config.confirmLabel) {\r\n <button mat-button color=\"primary\" [mat-dialog-close]=\"true\">\r\n {{ config.confirmLabel }}\r\n </button>\r\n }\r\n </mat-dialog-actions>\r\n}\r\n", styles: [""], dependencies: [{ kind: "component", type: i2.MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "directive", type: i2$3.MatDialogClose, selector: "[mat-dialog-close], [matDialogClose]", inputs: ["aria-label", "type", "mat-dialog-close", "matDialogClose"], exportAs: ["matDialogClose"] }, { kind: "directive", type: i2$3.MatDialogTitle, selector: "[mat-dialog-title], [matDialogTitle]", inputs: ["id"], exportAs: ["matDialogTitle"] }, { kind: "directive", type: i2$3.MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]", inputs: ["align"] }, { kind: "directive", type: i2$3.MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }] }); }
575
+ }
576
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.5", ngImport: i0, type: ConfirmDialogComponent, decorators: [{
577
+ type: Component,
578
+ args: [{ selector: 'lf-confirm-dialog', standalone: false, template: "@if (config) {\r\n @if (config.title) {\r\n <h2 mat-dialog-title>{{ config.title }}</h2>\r\n }\r\n\r\n <mat-dialog-content>\r\n @if (config.message) {\r\n <p>{{ config.message }}</p>\r\n }\r\n </mat-dialog-content>\r\n\r\n <mat-dialog-actions align=\"end\">\r\n @if (config.closeLabel) {\r\n <button mat-button [mat-dialog-close]=\"false\">\r\n {{ config.closeLabel }}\r\n </button>\r\n }\r\n @if (config.confirmLabel) {\r\n <button mat-button color=\"primary\" [mat-dialog-close]=\"true\">\r\n {{ config.confirmLabel }}\r\n </button>\r\n }\r\n </mat-dialog-actions>\r\n}\r\n" }]
579
+ }] });
580
+
581
+ class DialogService {
582
+ constructor() {
583
+ this.matDialog = inject(MatDialog);
584
+ }
585
+ /**
586
+ * Opens a dialog with custom template and custom config
587
+ *
588
+ * @param templateRef reference to the component or template
589
+ * @param config of the dialog
590
+ * @returns an asynchronous any response
591
+ */
592
+ openCustomDialog(templateRef, config) {
593
+ const dialogRef = this.matDialog.open(templateRef, config);
594
+ return firstValueFrom(dialogRef.afterClosed());
595
+ }
596
+ /**
597
+ * Opens a simple pre-made confirm dialog
598
+ *
599
+ * @param config of the dialog
600
+ * @returns an asynchronous boolean response
601
+ */
602
+ openConfirmDialog(config) {
603
+ const dialogRef = this.matDialog.open(ConfirmDialogComponent, {
604
+ autoFocus: false,
605
+ maxWidth: '368px',
606
+ data: config
607
+ });
608
+ return firstValueFrom(dialogRef.afterClosed());
609
+ }
610
+ /**
611
+ * Opens a simple pre-made input dialog
612
+ *
613
+ * @param config of the dialog
614
+ * @returns an asynchronous string response
615
+ */
616
+ openInputDialog(config) {
617
+ const dialogRef = this.matDialog.open(InputComponent, {
618
+ autoFocus: false,
619
+ width: '100vw',
620
+ data: config,
621
+ panelClass: 'lf-input-dialog'
622
+ });
623
+ return firstValueFrom(dialogRef.afterClosed());
624
+ }
625
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.5", ngImport: i0, type: DialogService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
626
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.0.5", ngImport: i0, type: DialogService, providedIn: 'root' }); }
627
+ }
628
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.5", ngImport: i0, type: DialogService, decorators: [{
629
+ type: Injectable,
630
+ args: [{
631
+ providedIn: 'root'
632
+ }]
633
+ }] });
634
+
635
+ class Logger {
636
+ constructor() {
637
+ this.config = inject(CONFIG, { optional: true });
638
+ }
639
+ /**
640
+ * Uses the regular console log but can be automatically disabled during production by using the ScaffoldLibraryConfig in the ScaffoldModule.forRoot
641
+ *
642
+ * @param message message of the log
643
+ * @param args arguments of the log
644
+ */
645
+ log(message, ...args) {
646
+ if (this.config?.production === false) {
647
+ console.log(message, ...args); // eslint-disable-line no-console
648
+ }
649
+ }
650
+ /**
651
+ * Uses the regular console warn but can be automatically disabled during production by using the ScaffoldLibraryConfig in the ScaffoldModule.forRoot
652
+ *
653
+ * @param message message of the warn
654
+ * @param args arguments of the warn
655
+ */
656
+ warn(message, ...args) {
657
+ if (this.config?.production === false) {
658
+ console.warn(message, ...args); // eslint-disable-line no-console
659
+ }
660
+ }
661
+ /**
662
+ * Uses the regular console error but can be automatically disabled during production by using the ScaffoldLibraryConfig in the ScaffoldModule.forRoot
663
+ *
664
+ * @param message message of the error
665
+ * @param args arguments of the error
666
+ */
667
+ error(message, ...args) {
668
+ if (this.config?.production === false) {
669
+ console.error(message, ...args); // eslint-disable-line no-console
670
+ }
671
+ }
672
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.5", ngImport: i0, type: Logger, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
673
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.0.5", ngImport: i0, type: Logger, providedIn: 'root' }); }
674
+ }
675
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.5", ngImport: i0, type: Logger, decorators: [{
676
+ type: Injectable,
677
+ args: [{ providedIn: 'root' }]
678
+ }] });
679
+
680
+ class LocalStorageService {
681
+ constructor() {
682
+ this.logger = inject(Logger);
683
+ this.config = inject(CONFIG, { optional: true });
684
+ }
685
+ /**
686
+ * Set an item into the browser's local storage
687
+ *
688
+ * @param key key of the item
689
+ * @param value value of the item
690
+ */
691
+ setItem(key, value) {
692
+ try {
693
+ const stringValue = JSON.stringify(value);
694
+ if (this.config?.debugging)
695
+ this.logger.log(`[SET ITEM] ${key} with value:`, stringValue);
696
+ localStorage.setItem(key, stringValue);
697
+ }
698
+ catch (error) {
699
+ this.logger.error(`[ERROR SET ITEM] ${key}: ${error}`);
700
+ }
701
+ }
702
+ /**
703
+ * Set an item encoded into the browser's local storage
704
+ *
705
+ * @param key key of the item
706
+ * @param value value of the item
707
+ */
708
+ setItemEncoded(key, value) {
709
+ try {
710
+ const encodedValue = btoa(JSON.stringify(value));
711
+ if (this.config?.debugging)
712
+ this.logger.log(`[SET ITEM] ${key} with value:`, encodedValue);
713
+ localStorage.setItem(key, encodedValue);
714
+ }
715
+ catch (error) {
716
+ this.logger.error(`[ERROR SET ITEM] ${key}: ${error}`);
717
+ }
718
+ }
719
+ /**
720
+ * Get an item from the browser's local storage by key
721
+ *
722
+ * @param key key of the item
723
+ * @returns value of the item
724
+ */
725
+ getItem(key) {
726
+ try {
727
+ const item = localStorage.getItem(key);
728
+ if (this.config?.debugging)
729
+ this.logger.log(`[GET ITEM] ${key} with value:`, item);
730
+ return item ? JSON.parse(item, this.dateReviver) : null;
731
+ }
732
+ catch (error) {
733
+ this.logger.error(`[ERROR GET ITEM] ${key}: ${error}`);
734
+ return null;
735
+ }
736
+ }
737
+ /**
738
+ * Get an item and decode it from the browser's local storage by key
739
+ *
740
+ * @param key key of the item
741
+ * @returns value of the item
742
+ */
743
+ getItemDecoded(key) {
744
+ try {
745
+ const item = localStorage.getItem(key);
746
+ if (this.config?.debugging)
747
+ this.logger.log(`[GET ITEM] ${key} with value:`, item);
748
+ return item ? JSON.parse(atob(item), this.dateReviver) : null;
749
+ }
750
+ catch (error) {
751
+ this.logger.error(`[ERROR GET ITEM] ${key}: ${error}`);
752
+ return null;
753
+ }
754
+ }
755
+ /**
756
+ * Get an unparsed string item from the browser's local storage by key
757
+ *
758
+ * @param key key of the item
759
+ */
760
+ getItemUnparsed(key) {
761
+ try {
762
+ const item = localStorage.getItem(key);
763
+ if (this.config?.debugging)
764
+ this.logger.log(`[GET ITEM] ${key} with value:`, item);
765
+ return item || null;
766
+ }
767
+ catch (error) {
768
+ this.logger.error(`[ERROR GET ITEM] ${key}: ${error}`);
769
+ return null;
770
+ }
771
+ }
772
+ /**
773
+ * Remove an item from the browser's local storage by key
774
+ *
775
+ * @param key key of the item
776
+ * @returns value of the item
777
+ */
778
+ removeItem(key) {
779
+ try {
780
+ if (this.config?.debugging)
781
+ this.logger.log(`[REMOVE ITEM] ${key}`);
782
+ localStorage.removeItem(key);
783
+ }
784
+ catch (error) {
785
+ this.logger.error(`[ERROR REMOVE ITEM] ${key}: ${error}`);
786
+ }
787
+ }
788
+ /**
789
+ * Clear the browser's local storage for this application
790
+ *
791
+ */
792
+ clear() {
793
+ localStorage.clear();
794
+ }
795
+ dateReviver(key, value) {
796
+ if (typeof value === 'string' && /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}.\d{3}Z$/.test(value)) {
797
+ return new Date(value);
798
+ }
799
+ return value;
800
+ }
801
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.5", ngImport: i0, type: LocalStorageService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
802
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.0.5", ngImport: i0, type: LocalStorageService, providedIn: 'root' }); }
803
+ }
804
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.5", ngImport: i0, type: LocalStorageService, decorators: [{
805
+ type: Injectable,
806
+ args: [{
807
+ providedIn: 'root'
808
+ }]
809
+ }] });
810
+
811
+ class RouterService {
812
+ get loading$() {
813
+ return this._loading$.asObservable();
814
+ }
815
+ get routeHistory$() {
816
+ return this._routeHistory$.asObservable();
817
+ }
818
+ get currentRoute$() {
819
+ return this._currentRoute$.asObservable();
820
+ }
821
+ get currentRoute() {
822
+ return this._currentRoute$.value;
823
+ }
824
+ get previousRoute$() {
825
+ return this._previousRoute$.asObservable();
826
+ }
827
+ get previousRoute() {
828
+ return this._previousRoute$.value;
829
+ }
830
+ constructor() {
831
+ this.router = inject(Router);
832
+ this._loading$ = new BehaviorSubject(false);
833
+ this._routeHistory$ = new BehaviorSubject([]);
834
+ this._currentRoute$ = new BehaviorSubject('');
835
+ this._previousRoute$ = new BehaviorSubject('');
836
+ this.router.events.subscribe(event => {
837
+ let asyncLoadCount = 0;
838
+ if (event instanceof RouteConfigLoadStart) {
839
+ asyncLoadCount++;
840
+ }
841
+ if (event instanceof RouteConfigLoadEnd) {
842
+ asyncLoadCount--;
843
+ }
844
+ if (event instanceof NavigationEnd) {
845
+ const previousRoute = this._currentRoute$.value;
846
+ this._previousRoute$.next(previousRoute);
847
+ const currentRoute = event.urlAfterRedirects;
848
+ this._currentRoute$.next(currentRoute);
849
+ if (!this.router.getCurrentNavigation()?.extras?.state?.['back']) {
850
+ const routeHistory = this._routeHistory$.value;
851
+ routeHistory.push(currentRoute);
852
+ this._routeHistory$.next(routeHistory);
853
+ }
854
+ }
855
+ this._loading$.next(!!asyncLoadCount);
856
+ });
857
+ }
858
+ /**
859
+ * Navigates to the previous route found in the routeHistory Observable
860
+ *
861
+ * @param fallbackRoute fallback in case there is no previous route
862
+ */
863
+ navigateBack(fallbackRoute) {
864
+ this._routeHistory$.pipe(take(1)).subscribe(routeHistory => {
865
+ if (routeHistory.length > 1) {
866
+ const previousRoute = routeHistory[routeHistory.length - 2];
867
+ if (previousRoute) {
868
+ this.router.navigateByUrl(previousRoute, { state: { back: true } }).then(result => {
869
+ if (result) {
870
+ routeHistory.pop();
871
+ }
872
+ });
873
+ }
874
+ else if (fallbackRoute) {
875
+ this.router.navigate([fallbackRoute]);
876
+ }
877
+ }
878
+ });
879
+ }
880
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.5", ngImport: i0, type: RouterService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
881
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.0.5", ngImport: i0, type: RouterService, providedIn: 'root' }); }
882
+ }
883
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.5", ngImport: i0, type: RouterService, decorators: [{
884
+ type: Injectable,
885
+ args: [{ providedIn: 'root' }]
886
+ }], ctorParameters: () => [] });
887
+
888
+ class ScaffoldService {
889
+ constructor() {
890
+ this.logger = inject(Logger);
891
+ this.config = inject(CONFIG, { optional: true });
892
+ // Scaffold Config
893
+ this._scaffoldConfig$ = new BehaviorSubject({});
894
+ // Header Input Change
895
+ this._headerInputChangeValue$ = new BehaviorSubject('');
896
+ // Button Click Event
897
+ this._buttonClickEventValue$ = new BehaviorSubject('');
898
+ // Drawer component
899
+ this._drawerPortal$ = new BehaviorSubject(null);
900
+ }
901
+ get scaffoldConfig$() {
902
+ return this._scaffoldConfig$.asObservable();
903
+ }
904
+ set scaffoldConfig(value) {
905
+ this._scaffoldConfig$.next(value);
906
+ }
907
+ get scaffoldConfig() {
908
+ return this._scaffoldConfig$.value;
909
+ }
910
+ get headerInputChangeValue$() {
911
+ return this._headerInputChangeValue$.asObservable();
912
+ }
913
+ set headerInputChangeValue(value) {
914
+ this._headerInputChangeValue$.next(value);
915
+ }
916
+ get buttonClickEventValue$() {
917
+ return this._buttonClickEventValue$.asObservable();
918
+ }
919
+ set buttonClickEventValue(value) {
920
+ this._buttonClickEventValue$.next(value);
921
+ this._buttonClickEventValue$.next('');
922
+ }
923
+ get drawerPortal$() {
924
+ return this._drawerPortal$.asObservable();
925
+ }
926
+ set drawerPortal(value) {
927
+ const componentPortal = new ComponentPortal(value);
928
+ this._drawerPortal$.next(value ? componentPortal : null);
929
+ }
930
+ // Update a specific property in the ScaffoldConfig
931
+ updateScaffoldProperty(property, value) {
932
+ const currentState = this._scaffoldConfig$.getValue();
933
+ if (currentState[property] === value) {
934
+ return;
935
+ }
936
+ const updatedState = { ...currentState, [property]: value };
937
+ if (this.config?.debugging)
938
+ this.logger.log(`[UPDATE] ScaffoldConfig.${property}`, value);
939
+ this._scaffoldConfig$.next(updatedState);
940
+ }
941
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.5", ngImport: i0, type: ScaffoldService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
942
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.0.5", ngImport: i0, type: ScaffoldService, providedIn: 'root' }); }
943
+ }
944
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.5", ngImport: i0, type: ScaffoldService, decorators: [{
945
+ type: Injectable,
946
+ args: [{ providedIn: 'root' }]
947
+ }] });
948
+
949
+ class SeoService {
950
+ constructor() {
951
+ this.metaTitle = inject(Title);
952
+ this.metaTags = inject(Meta);
953
+ this.document = inject(DOCUMENT);
954
+ this.logger = inject(Logger);
955
+ }
956
+ /**
957
+ * Pass a configuration to set meta tags such as title, description and image for search results and social media
958
+ *
959
+ * @param seoConfig config that contains all the meta information
960
+ *
961
+ */
962
+ setMetaTags(seoConfig) {
963
+ const autoTrim = seoConfig.autoTrim || false;
964
+ const title = seoConfig.metaPageTitle || '';
965
+ const description = seoConfig.metaPageDescription || '';
966
+ const imagePath = seoConfig.metaImagePath || '';
967
+ const titleLimit = 60;
968
+ const descriptionLimit = 160;
969
+ // Set meta title
970
+ if (title) {
971
+ if (autoTrim && title.length > titleLimit) {
972
+ this.logger.error(`[SeoService] The set meta title is too long. Recommended length is ${titleLimit}. The title will be trimmed.`);
973
+ }
974
+ const titleTrim = (title.length > titleLimit) ? title.substring(0, titleLimit - 3) + '...' : title;
975
+ this._setMetaTitle(autoTrim ? titleTrim : title);
976
+ }
977
+ // Set meta description
978
+ if (description) {
979
+ if (autoTrim && description.length > descriptionLimit) {
980
+ this.logger.error(`[SeoService] The set meta description is too long. Recommended length is ${descriptionLimit}. The description will be trimmed.`);
981
+ }
982
+ const descriptionTrim = (description.length > descriptionLimit) ? description.substring(0, descriptionLimit - 3) + '...' : description;
983
+ this._setMetaDescription(autoTrim ? descriptionTrim : description);
984
+ }
985
+ // Set meta image
986
+ const host = this.document.location.origin;
987
+ if (imagePath) {
988
+ this._setMetaImage(`${host}/${imagePath}`);
989
+ }
990
+ }
991
+ // Set all meta titles
992
+ _setMetaTitle(title) {
993
+ this.metaTitle.setTitle(title);
994
+ this.metaTags.updateTag({ property: 'og:title', content: title });
995
+ this.metaTags.updateTag({ name: 'twitter:title', content: title });
996
+ }
997
+ // Set all meta descriptions
998
+ _setMetaDescription(description) {
999
+ this.metaTags.updateTag({ name: 'description', content: description });
1000
+ this.metaTags.updateTag({ property: 'og:description', content: description });
1001
+ this.metaTags.updateTag({ name: 'twitter:description', content: description });
1002
+ }
1003
+ // Set all meta images
1004
+ _setMetaImage(image) {
1005
+ this.metaTags.updateTag({ property: 'og:image', content: image });
1006
+ this.metaTags.updateTag({ name: 'twitter:image', content: image });
1007
+ }
1008
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.5", ngImport: i0, type: SeoService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
1009
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.0.5", ngImport: i0, type: SeoService, providedIn: 'root' }); }
1010
+ }
1011
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.5", ngImport: i0, type: SeoService, decorators: [{
1012
+ type: Injectable,
1013
+ args: [{
1014
+ providedIn: 'root'
1015
+ }]
1016
+ }] });
1017
+
1018
+ class SnackbarService {
1019
+ constructor() {
1020
+ this.snackbar = inject(MatSnackBar);
1021
+ this.SNACKBAR_DURATION = 5000;
1022
+ this.SNACKBAR_POSITION_HORIZONTAL = 'center';
1023
+ this.SNACKBAR_POSITION_VERTICAL = 'bottom';
1024
+ this.actionConfig = {
1025
+ horizontalPosition: this.SNACKBAR_POSITION_HORIZONTAL,
1026
+ verticalPosition: this.SNACKBAR_POSITION_VERTICAL
1027
+ };
1028
+ this.defaultConfig = {
1029
+ duration: this.SNACKBAR_DURATION,
1030
+ horizontalPosition: this.SNACKBAR_POSITION_HORIZONTAL,
1031
+ verticalPosition: this.SNACKBAR_POSITION_VERTICAL
1032
+ };
1033
+ }
1034
+ // Opens a snackbar with an action to wait for
1035
+ openSnackbarWithAction(message, action, config) {
1036
+ const snackbarRef = this.snackbar.open(message, action, config ? config : this.actionConfig);
1037
+ return firstValueFrom(snackbarRef.onAction());
1038
+ }
1039
+ // Opens a generic snackbar with a message
1040
+ openSnackbar(message, config) {
1041
+ this.snackbar.open(message, '', config ? config : this.defaultConfig);
1042
+ }
1043
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.5", ngImport: i0, type: SnackbarService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
1044
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.0.5", ngImport: i0, type: SnackbarService, providedIn: 'root' }); }
1045
+ }
1046
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.5", ngImport: i0, type: SnackbarService, decorators: [{
1047
+ type: Injectable,
1048
+ args: [{
1049
+ providedIn: 'root'
1050
+ }]
1051
+ }] });
1052
+
1053
+ class ThemeService {
1054
+ get currentTheme$() {
1055
+ return this._currentTheme$.asObservable();
1056
+ }
1057
+ constructor() {
1058
+ this.storageService = inject(LocalStorageService);
1059
+ this.document = inject(DOCUMENT);
1060
+ this.THEME_KEY = 'THEME';
1061
+ this._currentTheme$ = new BehaviorSubject('');
1062
+ this.loadTheme();
1063
+ }
1064
+ /**
1065
+ * Set one of the defined themes by passing its class name
1066
+ *
1067
+ * @param newTheme class name of the theme (pass empty string for default theme)
1068
+ * @param useLocalStorage persist the current theme in the LocalStorage
1069
+ */
1070
+ setTheme(newTheme, useLocalStorage) {
1071
+ const currentTheme = this._currentTheme$.value;
1072
+ if (newTheme === currentTheme) {
1073
+ return;
1074
+ }
1075
+ if (currentTheme) {
1076
+ this.document.body.classList.remove(currentTheme);
1077
+ }
1078
+ this._currentTheme$.next(newTheme);
1079
+ if (newTheme) {
1080
+ this.document.body.classList.add(newTheme);
1081
+ if (useLocalStorage) {
1082
+ this.storageService.setItem(this.THEME_KEY, JSON.stringify(newTheme));
1083
+ }
1084
+ }
1085
+ else {
1086
+ if (useLocalStorage) {
1087
+ this.storageService.removeItem(this.THEME_KEY);
1088
+ }
1089
+ }
1090
+ }
1091
+ /**
1092
+ * Loads the current theme stored in the local storage if available
1093
+ *
1094
+ */
1095
+ loadTheme() {
1096
+ const theme = this.storageService.getItem(this.THEME_KEY);
1097
+ if (!theme) {
1098
+ return;
1099
+ }
1100
+ this.setTheme(theme.replace(/"/g, ''));
1101
+ }
1102
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.5", ngImport: i0, type: ThemeService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
1103
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.0.5", ngImport: i0, type: ThemeService, providedIn: 'root' }); }
1104
+ }
1105
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.5", ngImport: i0, type: ThemeService, decorators: [{
1106
+ type: Injectable,
1107
+ args: [{
1108
+ providedIn: 'root'
1109
+ }]
1110
+ }], ctorParameters: () => [] });
1111
+
1112
+ class ScaffoldComponent {
1113
+ constructor() {
1114
+ this.scaffoldService = inject(ScaffoldService);
1115
+ this.breakpointService = inject(BreakpointService);
1116
+ this.routerService = inject(RouterService);
1117
+ this.logger = inject(Logger);
1118
+ this.route = inject(ActivatedRoute);
1119
+ this.document = inject(DOCUMENT);
1120
+ this.config = inject(CONFIG, { optional: true });
1121
+ this.headerButtonClickEvent = new EventEmitter();
1122
+ this.headerInputSubmitEvent = new EventEmitter();
1123
+ this.headerInputChangeEvent = new EventEmitter();
1124
+ this.navbarButtonClickEvent = new EventEmitter();
1125
+ this.floatingButtonClickEvent = new EventEmitter();
1126
+ this.bottomBarButtonClickEvent = new EventEmitter();
1127
+ this.scaffoldConfig = null;
1128
+ this.headerConfig = null;
1129
+ this.navbarConfig = null;
1130
+ this.drawerConfig = null;
1131
+ this.footerConfig = null;
1132
+ this.contentTitleCardConfig = null;
1133
+ this.floatingButtonConfig = null;
1134
+ this.bottomBarConfig = null;
1135
+ this.routeHistory = [];
1136
+ this.isMobile = false;
1137
+ this.routeLoading = false;
1138
+ this.scrollTopPosition = 0;
1139
+ this._subscription = new Subscription;
1140
+ }
1141
+ ngOnInit() {
1142
+ // Listen for config changes
1143
+ this._subscription.add(this.scaffoldService.scaffoldConfig$.subscribe((scaffoldConfig) => {
1144
+ if (this.config?.debugging)
1145
+ this.logger.log('[ScaffoldConfig]', scaffoldConfig);
1146
+ this.scaffoldConfig = scaffoldConfig;
1147
+ this.headerConfig = this.scaffoldConfig.headerConfig;
1148
+ this.navbarConfig = this.scaffoldConfig.navbarConfig;
1149
+ this.drawerConfig = this.scaffoldConfig.drawerConfig;
1150
+ this.footerConfig = this.scaffoldConfig.footerConfig;
1151
+ this.contentTitleCardConfig = this.scaffoldConfig.contentTitleCardConfig;
1152
+ this.floatingButtonConfig = this.scaffoldConfig.floatingButtonConfig;
1153
+ this.bottomBarConfig = this.scaffoldConfig.bottomBarConfig;
1154
+ }));
1155
+ // Listen for drawer portal changes
1156
+ this._subscription.add(this.scaffoldService.drawerPortal$.subscribe((drawerPortal) => {
1157
+ if (this.config?.debugging)
1158
+ this.logger.log('[DrawerPortal]', drawerPortal);
1159
+ this.drawerPortal = drawerPortal;
1160
+ }));
1161
+ // Listen for breakpoint changes
1162
+ this._subscription.add(this.breakpointService.breakpoint$.subscribe((breakpointState) => {
1163
+ if (this.config?.debugging)
1164
+ this.logger.log('[BreakpointState]', breakpointState);
1165
+ if (breakpointState.breakpoints[Breakpoints.XSmall]) {
1166
+ this.isMobile = true;
1167
+ }
1168
+ else if (breakpointState.breakpoints[Breakpoints.Small]) {
1169
+ this.isMobile = true;
1170
+ }
1171
+ else if (breakpointState.breakpoints[Breakpoints.Medium]) {
1172
+ this.isMobile = false;
1173
+ }
1174
+ else if (breakpointState.breakpoints[Breakpoints.Large]) {
1175
+ this.isMobile = false;
1176
+ }
1177
+ }));
1178
+ // Listen for route changes
1179
+ this._subscription.add(this.routerService.routeHistory$.subscribe((routeHistory) => {
1180
+ if (this.config?.debugging)
1181
+ this.logger.log('[RouteHistory]', routeHistory);
1182
+ if (routeHistory) {
1183
+ this.routeHistory = routeHistory;
1184
+ }
1185
+ if (this.scrollContainer && this.scaffoldConfig?.scrollPositionRestoration) {
1186
+ this.scrollContainer.nativeElement.scrollTop = 0;
1187
+ }
1188
+ }));
1189
+ // Listen for current route changes
1190
+ this._subscription.add(this.routerService.currentRoute$.subscribe((currentRout) => {
1191
+ this.currentRoute = currentRout;
1192
+ }));
1193
+ // Listen for route loading
1194
+ this._subscription.add(this.routerService.loading$.subscribe((routeLoading) => {
1195
+ this.routeLoading = routeLoading;
1196
+ }));
1197
+ // Listen to scroll events
1198
+ if (this.scrollContainer) {
1199
+ const element = this.scrollContainer.nativeElement;
1200
+ this._subscription.add(fromEvent(element, 'scroll').pipe(distinctUntilChanged(), debounceTime(100)).subscribe((e) => {
1201
+ const target = e.target;
1202
+ this.scrollTopPosition = target.scrollTop;
1203
+ }));
1204
+ }
1205
+ // Listen for fragments in the current route
1206
+ if (this.scaffoldConfig?.anchorScrolling) {
1207
+ this._subscription.add(this.route.fragment.subscribe((fragment) => {
1208
+ if (fragment) {
1209
+ if (this.config?.debugging)
1210
+ this.logger.log('[RouteFragment]', fragment);
1211
+ setTimeout(() => {
1212
+ const element = this.document.querySelector(`#${fragment}`);
1213
+ if (element) {
1214
+ element.scrollIntoView({ behavior: 'auto', block: 'start', inline: 'nearest' });
1215
+ }
1216
+ }, 100);
1217
+ }
1218
+ }));
1219
+ }
1220
+ }
1221
+ ngOnDestroy() {
1222
+ if (this._subscription) {
1223
+ this._subscription.unsubscribe();
1224
+ }
1225
+ }
1226
+ headerButtonClicked(id) {
1227
+ this.scaffoldService.buttonClickEventValue = id;
1228
+ this.headerButtonClickEvent.emit(id);
1229
+ }
1230
+ headerInputSubmitted(value) {
1231
+ this.headerInputSubmitEvent.emit(value);
1232
+ }
1233
+ headerInputChanged(value) {
1234
+ this.scaffoldService.headerInputChangeValue = value;
1235
+ this.headerInputChangeEvent.emit(value);
1236
+ }
1237
+ navbarButtonClicked(id) {
1238
+ this.scaffoldService.buttonClickEventValue = id;
1239
+ this.navbarButtonClickEvent.emit(id);
1240
+ }
1241
+ backButtonClicked() {
1242
+ this.routerService.navigateBack();
1243
+ }
1244
+ floatingButtonClicked(id) {
1245
+ if (!id && this.scrollContainer) {
1246
+ this.scrollContainer.nativeElement.scrollTop = 0;
1247
+ }
1248
+ else {
1249
+ this.scaffoldService.buttonClickEventValue = id;
1250
+ this.floatingButtonClickEvent.emit(id);
1251
+ }
1252
+ }
1253
+ bottomBarCloseClicked(id) {
1254
+ this.scaffoldService.buttonClickEventValue = id;
1255
+ this.bottomBarButtonClickEvent.emit(id);
1256
+ }
1257
+ bottomBarButtonClicked(id) {
1258
+ this.scaffoldService.buttonClickEventValue = id;
1259
+ this.bottomBarButtonClickEvent.emit(id);
1260
+ }
1261
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.5", ngImport: i0, type: ScaffoldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1262
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.0.5", type: ScaffoldComponent, isStandalone: false, selector: "lf-scaffold", outputs: { headerButtonClickEvent: "headerButtonClickEvent", headerInputSubmitEvent: "headerInputSubmitEvent", headerInputChangeEvent: "headerInputChangeEvent", navbarButtonClickEvent: "navbarButtonClickEvent", floatingButtonClickEvent: "floatingButtonClickEvent", bottomBarButtonClickEvent: "bottomBarButtonClickEvent" }, viewQueries: [{ propertyName: "scrollContainer", first: true, predicate: ["scrollContainer"], descendants: true, static: true }, { propertyName: "content", first: true, predicate: ["content"], descendants: true, static: true }], ngImport: i0, template: "<!-- header-height: 64px; navbar-size: 80px; floating-button-bottom: 24px -->\r\n\r\n<div class=\"lf-scaffold mat-app-background mat-typography\" [ngClass]=\"scaffoldConfig?.class\">\r\n <!-- loading overlay -->\r\n @if (scaffoldConfig?.loading) {\r\n <lf-loading-overlay></lf-loading-overlay>\r\n }\r\n <!-- header -->\r\n <lf-header\r\n [headerConfig]=\"headerConfig\"\r\n [isMobile]=\"isMobile\"\r\n [routeLoading]=\"routeLoading\"\r\n [currentRoute]=\"currentRoute\"\r\n (headerButtonClickEvent)=\"headerButtonClicked($event)\"\r\n (headerInputSubmitEvent)=\"headerInputSubmitted($event)\"\r\n (headerInputChangeEvent)=\"headerInputChanged($event)\"></lf-header>\r\n <!-- navbar -->\r\n <lf-navbar\r\n [navbarConfig]=\"navbarConfig\"\r\n [isMobile]=\"isMobile\"\r\n [currentRoute]=\"currentRoute\"\r\n (navbarButtonClickEvent)=\"navbarButtonClicked($event)\"></lf-navbar>\r\n <!-- content wrapper -->\r\n <div\r\n class=\"lf-content-wrapper\"\r\n [class.lf-show-navbar]=\"navbarConfig?.enable && !isMobile\"\r\n [class.lf-show-header]=\"headerConfig?.enable && !(navbarConfig?.enable && isMobile)\"\r\n [class.lf-show-navbar-mobile]=\"navbarConfig?.enable && isMobile && !headerConfig?.enable\"\r\n [class.lf-show-header-and-navbar-mobile]=\"\r\n headerConfig?.enable && navbarConfig?.enable && isMobile\r\n \"\r\n #scrollContainer\r\n cdkScrollable>\r\n <!-- drawer -->\r\n <lf-drawer\r\n [drawerConfig]=\"drawerConfig\"\r\n [drawerPortal]=\"drawerPortal\"\r\n [isMobile]=\"isMobile\"\r\n [fixedOffset]=\"headerConfig?.enable ? 64 : 0\">\r\n <!-- drawer content -->\r\n <ng-content select=\"[drawerContent]\" drawerContent></ng-content>\r\n <!-- content title card -->\r\n <lf-content-title-card\r\n [contentTitleCardConfig]=\"contentTitleCardConfig\"\r\n [isMobile]=\"isMobile\"\r\n [routeHistory]=\"routeHistory\"\r\n (backButtonClickEvent)=\"backButtonClicked()\"></lf-content-title-card>\r\n <!-- main content -->\r\n <div\r\n class=\"lf-content\"\r\n [class.lf-content-mobile]=\"isMobile\"\r\n [class.lf-show-footer]=\"footerConfig?.enable\"\r\n #content>\r\n <ng-content></ng-content>\r\n </div>\r\n <!-- footer -->\r\n <lf-footer [footerConfig]=\"footerConfig\"></lf-footer>\r\n </lf-drawer>\r\n </div>\r\n <!-- to top button -->\r\n <lf-floating-button\r\n [floatingButtonConfig]=\"floatingButtonConfig\"\r\n [onTop]=\"scrollTopPosition <= 0\"\r\n [isMobile]=\"isMobile && navbarConfig?.enable!\"\r\n [bottomBarEnabled]=\"bottomBarConfig?.enable!\"\r\n (floatingButtonClickEvent)=\"floatingButtonClicked($event)\"></lf-floating-button>\r\n <!-- bottom bar -->\r\n <lf-bottom-bar\r\n [bottomBarConfig]=\"bottomBarConfig\"\r\n [isMobile]=\"isMobile && navbarConfig?.enable!\"\r\n [navbarEnabled]=\"navbarConfig?.enable!\"\r\n (bottomBarCloseClickEvent)=\"bottomBarCloseClicked($event)\"\r\n (bottomBarButtonClickEvent)=\"bottomBarButtonClicked($event)\"></lf-bottom-bar>\r\n</div>\r\n", styles: [".lf-scaffold{height:100vh}.lf-scaffold .lf-content-wrapper{transition:height .3s;position:absolute;inset:0;overflow-y:auto}.lf-scaffold .lf-content-wrapper.lf-show-navbar{left:80px}.lf-scaffold .lf-content-wrapper.lf-show-header{top:64px;height:calc(100vh - 64px)}.lf-scaffold .lf-content-wrapper.lf-show-navbar-mobile{height:calc(100vh - 56px)}.lf-scaffold .lf-content-wrapper.lf-show-header-and-navbar-mobile{top:64px;height:calc(100vh - 120px)}.lf-scaffold .lf-content-wrapper .lf-content{padding-left:24px;padding-right:24px}.lf-scaffold .lf-content-wrapper .lf-content.lf-content-mobile{padding-left:16px;padding-right:16px}.lf-scaffold .lf-content-wrapper .lf-content.lf-show-footer{min-height:100%}\n"], dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i2$4.CdkScrollable, selector: "[cdk-scrollable], [cdkScrollable]" }, { kind: "component", type: LoadingOverlayComponent, selector: "lf-loading-overlay" }, { kind: "component", type: HeaderComponent, selector: "lf-header", inputs: ["headerConfig", "isMobile", "routeLoading", "currentRoute"], outputs: ["headerButtonClickEvent", "headerInputSubmitEvent", "headerInputChangeEvent"] }, { kind: "component", type: NavbarComponent, selector: "lf-navbar", inputs: ["navbarConfig", "isMobile", "currentRoute"], outputs: ["navbarButtonClickEvent"] }, { kind: "component", type: DrawerComponent, selector: "lf-drawer", inputs: ["drawerConfig", "isMobile", "fixedOffset", "drawerPortal"] }, { kind: "component", type: FooterComponent, selector: "lf-footer", inputs: ["footerConfig"] }, { kind: "component", type: ContentTitleCardComponent, selector: "lf-content-title-card", inputs: ["contentTitleCardConfig", "isMobile", "routeHistory"], outputs: ["backButtonClickEvent"] }, { kind: "component", type: FloatingButtonComponent, selector: "lf-floating-button", inputs: ["floatingButtonConfig", "onTop", "isMobile", "bottomBarEnabled"], outputs: ["floatingButtonClickEvent"] }, { kind: "component", type: BottomBarComponent, selector: "lf-bottom-bar", inputs: ["bottomBarConfig", "isMobile", "navbarEnabled"], outputs: ["bottomBarCloseClickEvent", "bottomBarButtonClickEvent"] }] }); }
1263
+ }
1264
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.5", ngImport: i0, type: ScaffoldComponent, decorators: [{
1265
+ type: Component,
1266
+ args: [{ selector: 'lf-scaffold', standalone: false, template: "<!-- header-height: 64px; navbar-size: 80px; floating-button-bottom: 24px -->\r\n\r\n<div class=\"lf-scaffold mat-app-background mat-typography\" [ngClass]=\"scaffoldConfig?.class\">\r\n <!-- loading overlay -->\r\n @if (scaffoldConfig?.loading) {\r\n <lf-loading-overlay></lf-loading-overlay>\r\n }\r\n <!-- header -->\r\n <lf-header\r\n [headerConfig]=\"headerConfig\"\r\n [isMobile]=\"isMobile\"\r\n [routeLoading]=\"routeLoading\"\r\n [currentRoute]=\"currentRoute\"\r\n (headerButtonClickEvent)=\"headerButtonClicked($event)\"\r\n (headerInputSubmitEvent)=\"headerInputSubmitted($event)\"\r\n (headerInputChangeEvent)=\"headerInputChanged($event)\"></lf-header>\r\n <!-- navbar -->\r\n <lf-navbar\r\n [navbarConfig]=\"navbarConfig\"\r\n [isMobile]=\"isMobile\"\r\n [currentRoute]=\"currentRoute\"\r\n (navbarButtonClickEvent)=\"navbarButtonClicked($event)\"></lf-navbar>\r\n <!-- content wrapper -->\r\n <div\r\n class=\"lf-content-wrapper\"\r\n [class.lf-show-navbar]=\"navbarConfig?.enable && !isMobile\"\r\n [class.lf-show-header]=\"headerConfig?.enable && !(navbarConfig?.enable && isMobile)\"\r\n [class.lf-show-navbar-mobile]=\"navbarConfig?.enable && isMobile && !headerConfig?.enable\"\r\n [class.lf-show-header-and-navbar-mobile]=\"\r\n headerConfig?.enable && navbarConfig?.enable && isMobile\r\n \"\r\n #scrollContainer\r\n cdkScrollable>\r\n <!-- drawer -->\r\n <lf-drawer\r\n [drawerConfig]=\"drawerConfig\"\r\n [drawerPortal]=\"drawerPortal\"\r\n [isMobile]=\"isMobile\"\r\n [fixedOffset]=\"headerConfig?.enable ? 64 : 0\">\r\n <!-- drawer content -->\r\n <ng-content select=\"[drawerContent]\" drawerContent></ng-content>\r\n <!-- content title card -->\r\n <lf-content-title-card\r\n [contentTitleCardConfig]=\"contentTitleCardConfig\"\r\n [isMobile]=\"isMobile\"\r\n [routeHistory]=\"routeHistory\"\r\n (backButtonClickEvent)=\"backButtonClicked()\"></lf-content-title-card>\r\n <!-- main content -->\r\n <div\r\n class=\"lf-content\"\r\n [class.lf-content-mobile]=\"isMobile\"\r\n [class.lf-show-footer]=\"footerConfig?.enable\"\r\n #content>\r\n <ng-content></ng-content>\r\n </div>\r\n <!-- footer -->\r\n <lf-footer [footerConfig]=\"footerConfig\"></lf-footer>\r\n </lf-drawer>\r\n </div>\r\n <!-- to top button -->\r\n <lf-floating-button\r\n [floatingButtonConfig]=\"floatingButtonConfig\"\r\n [onTop]=\"scrollTopPosition <= 0\"\r\n [isMobile]=\"isMobile && navbarConfig?.enable!\"\r\n [bottomBarEnabled]=\"bottomBarConfig?.enable!\"\r\n (floatingButtonClickEvent)=\"floatingButtonClicked($event)\"></lf-floating-button>\r\n <!-- bottom bar -->\r\n <lf-bottom-bar\r\n [bottomBarConfig]=\"bottomBarConfig\"\r\n [isMobile]=\"isMobile && navbarConfig?.enable!\"\r\n [navbarEnabled]=\"navbarConfig?.enable!\"\r\n (bottomBarCloseClickEvent)=\"bottomBarCloseClicked($event)\"\r\n (bottomBarButtonClickEvent)=\"bottomBarButtonClicked($event)\"></lf-bottom-bar>\r\n</div>\r\n", styles: [".lf-scaffold{height:100vh}.lf-scaffold .lf-content-wrapper{transition:height .3s;position:absolute;inset:0;overflow-y:auto}.lf-scaffold .lf-content-wrapper.lf-show-navbar{left:80px}.lf-scaffold .lf-content-wrapper.lf-show-header{top:64px;height:calc(100vh - 64px)}.lf-scaffold .lf-content-wrapper.lf-show-navbar-mobile{height:calc(100vh - 56px)}.lf-scaffold .lf-content-wrapper.lf-show-header-and-navbar-mobile{top:64px;height:calc(100vh - 120px)}.lf-scaffold .lf-content-wrapper .lf-content{padding-left:24px;padding-right:24px}.lf-scaffold .lf-content-wrapper .lf-content.lf-content-mobile{padding-left:16px;padding-right:16px}.lf-scaffold .lf-content-wrapper .lf-content.lf-show-footer{min-height:100%}\n"] }]
1267
+ }], propDecorators: { scrollContainer: [{
1268
+ type: ViewChild,
1269
+ args: ['scrollContainer', { static: true }]
1270
+ }], content: [{
1271
+ type: ViewChild,
1272
+ args: ['content', { static: true }]
1273
+ }], headerButtonClickEvent: [{
1274
+ type: Output
1275
+ }], headerInputSubmitEvent: [{
1276
+ type: Output
1277
+ }], headerInputChangeEvent: [{
1278
+ type: Output
1279
+ }], navbarButtonClickEvent: [{
1280
+ type: Output
1281
+ }], floatingButtonClickEvent: [{
1282
+ type: Output
1283
+ }], bottomBarButtonClickEvent: [{
1284
+ type: Output
1285
+ }] } });
1286
+
1287
+ const CONFIG = new InjectionToken('config');
1288
+ class ScaffoldModule {
1289
+ static forRoot(config) {
1290
+ return {
1291
+ ngModule: ScaffoldModule,
1292
+ providers: [
1293
+ { provide: CONFIG, useValue: config }
1294
+ ]
1295
+ };
1296
+ }
1297
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.5", ngImport: i0, type: ScaffoldModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
1298
+ static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.0.5", ngImport: i0, type: ScaffoldModule, declarations: [ScaffoldComponent,
1299
+ LoadingOverlayComponent,
1300
+ HeaderComponent,
1301
+ NavbarComponent,
1302
+ DrawerComponent,
1303
+ FooterComponent,
1304
+ ContentTitleCardComponent,
1305
+ FloatingButtonComponent,
1306
+ ConfirmDialogComponent,
1307
+ BottomBarComponent], imports: [BrowserAnimationsModule,
1308
+ RouterModule,
1309
+ SharedModule,
1310
+ InputComponent,
1311
+ IconComponent], exports: [ScaffoldComponent] }); }
1312
+ static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.0.5", ngImport: i0, type: ScaffoldModule, imports: [BrowserAnimationsModule,
1313
+ RouterModule,
1314
+ SharedModule,
1315
+ InputComponent,
1316
+ IconComponent] }); }
1317
+ }
1318
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.5", ngImport: i0, type: ScaffoldModule, decorators: [{
1319
+ type: NgModule,
1320
+ args: [{
1321
+ declarations: [
1322
+ ScaffoldComponent,
1323
+ LoadingOverlayComponent,
1324
+ HeaderComponent,
1325
+ NavbarComponent,
1326
+ DrawerComponent,
1327
+ FooterComponent,
1328
+ ContentTitleCardComponent,
1329
+ FloatingButtonComponent,
1330
+ ConfirmDialogComponent,
1331
+ BottomBarComponent
1332
+ ],
1333
+ imports: [
1334
+ BrowserAnimationsModule,
1335
+ RouterModule,
1336
+ SharedModule,
1337
+ InputComponent,
1338
+ IconComponent
1339
+ ],
1340
+ exports: [
1341
+ ScaffoldComponent
1342
+ ]
1343
+ }]
1344
+ }] });
1345
+
1346
+ class PlaceholderComponent {
1347
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.5", ngImport: i0, type: PlaceholderComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1348
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.0.5", type: PlaceholderComponent, isStandalone: true, selector: "lf-placeholder", inputs: { placeholderConfig: "placeholderConfig" }, ngImport: i0, template: "@if (placeholderConfig) {\r\n <div class=\"lf-placeholder px-6 pt-2 pb-6\">\r\n <!-- icon -->\r\n <lf-icon\r\n [matIcon]=\"placeholderConfig.matIcon!\"\r\n [svgIcon]=\"placeholderConfig.svgIcon!\"\r\n [outlineIcon]=\"placeholderConfig.outlineIcon!\"></lf-icon>\r\n <!-- heading -->\r\n @if (placeholderConfig.heading) {\r\n <p class=\"lf-placeholder-heading\">\r\n {{ placeholderConfig.heading }}\r\n </p>\r\n }\r\n <!-- message -->\r\n @if (placeholderConfig.message) {\r\n <p class=\"lf-placeholder-message\" [class.mt-6]=\"placeholderConfig.heading\">\r\n {{ placeholderConfig.message }}\r\n </p>\r\n }\r\n </div>\r\n}\r\n", styles: [".lf-placeholder{display:flex;flex-flow:column;align-items:center;justify-content:center;text-align:center}.lf-placeholder ::ng-deep .lf-icon{width:128px;height:128px;font-size:128px;color:#808080cc}.lf-placeholder .lf-placeholder-heading{margin:0;font-size:48px;color:#808080cc}.lf-placeholder .lf-placeholder-message{margin:0;font-size:18px;color:#808080cc}\n"], dependencies: [{ kind: "ngmodule", type: SharedModule }, { kind: "component", type: IconComponent, selector: "lf-icon", inputs: ["matIcon", "svgIcon", "outlineIcon", "alignMiddle"] }] }); }
1349
+ }
1350
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.5", ngImport: i0, type: PlaceholderComponent, decorators: [{
1351
+ type: Component,
1352
+ args: [{ selector: 'lf-placeholder', standalone: true, imports: [SharedModule, IconComponent], template: "@if (placeholderConfig) {\r\n <div class=\"lf-placeholder px-6 pt-2 pb-6\">\r\n <!-- icon -->\r\n <lf-icon\r\n [matIcon]=\"placeholderConfig.matIcon!\"\r\n [svgIcon]=\"placeholderConfig.svgIcon!\"\r\n [outlineIcon]=\"placeholderConfig.outlineIcon!\"></lf-icon>\r\n <!-- heading -->\r\n @if (placeholderConfig.heading) {\r\n <p class=\"lf-placeholder-heading\">\r\n {{ placeholderConfig.heading }}\r\n </p>\r\n }\r\n <!-- message -->\r\n @if (placeholderConfig.message) {\r\n <p class=\"lf-placeholder-message\" [class.mt-6]=\"placeholderConfig.heading\">\r\n {{ placeholderConfig.message }}\r\n </p>\r\n }\r\n </div>\r\n}\r\n", styles: [".lf-placeholder{display:flex;flex-flow:column;align-items:center;justify-content:center;text-align:center}.lf-placeholder ::ng-deep .lf-icon{width:128px;height:128px;font-size:128px;color:#808080cc}.lf-placeholder .lf-placeholder-heading{margin:0;font-size:48px;color:#808080cc}.lf-placeholder .lf-placeholder-message{margin:0;font-size:18px;color:#808080cc}\n"] }]
1353
+ }], propDecorators: { placeholderConfig: [{
1354
+ type: Input
1355
+ }] } });
1356
+
1357
+ class FileUploadComponent {
1358
+ constructor() {
1359
+ this.logger = inject(Logger);
1360
+ this.color = 'primary';
1361
+ this.disabled = false;
1362
+ this.fileChange = new EventEmitter();
1363
+ }
1364
+ selectFile(event) {
1365
+ const input = event.target;
1366
+ if (!input || !input.files)
1367
+ return;
1368
+ const file = input.files[0];
1369
+ if (!file)
1370
+ return;
1371
+ this.logger.log('[FileUploadComponent]', file);
1372
+ this.fileChange.emit(file);
1373
+ }
1374
+ triggerInput() {
1375
+ this.fileElement.nativeElement.click();
1376
+ }
1377
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.5", ngImport: i0, type: FileUploadComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1378
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.0.5", type: FileUploadComponent, isStandalone: true, selector: "lf-file-upload", inputs: { color: "color", label: "label", matIcon: "matIcon", disabled: "disabled", accept: "accept", tooltip: "tooltip" }, outputs: { fileChange: "fileChange" }, viewQueries: [{ propertyName: "fileElement", first: true, predicate: ["file"], descendants: true }], ngImport: i0, template: "<input\r\n hidden\r\n #file\r\n type=\"file\"\r\n [accept]=\"accept\"\r\n onclick=\"this.value=null\"\r\n (change)=\"selectFile($event)\" />\r\n\r\n<button\r\n mat-flat-button\r\n class=\"lf-button\"\r\n type=\"button\"\r\n [color]=\"color\"\r\n [disabled]=\"disabled\"\r\n (click)=\"triggerInput()\"\r\n [matTooltip]=\"tooltip\">\r\n @if (matIcon) {\r\n <mat-icon>{{ matIcon }}</mat-icon>\r\n }\r\n {{ label }}\r\n</button>\r\n", styles: [".lf-button{width:inherit}\n"], dependencies: [{ kind: "ngmodule", type: SharedModule }, { kind: "component", type: i2.MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i4.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: i4$1.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }] }); }
1379
+ }
1380
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.5", ngImport: i0, type: FileUploadComponent, decorators: [{
1381
+ type: Component,
1382
+ args: [{ selector: 'lf-file-upload', standalone: true, imports: [SharedModule], template: "<input\r\n hidden\r\n #file\r\n type=\"file\"\r\n [accept]=\"accept\"\r\n onclick=\"this.value=null\"\r\n (change)=\"selectFile($event)\" />\r\n\r\n<button\r\n mat-flat-button\r\n class=\"lf-button\"\r\n type=\"button\"\r\n [color]=\"color\"\r\n [disabled]=\"disabled\"\r\n (click)=\"triggerInput()\"\r\n [matTooltip]=\"tooltip\">\r\n @if (matIcon) {\r\n <mat-icon>{{ matIcon }}</mat-icon>\r\n }\r\n {{ label }}\r\n</button>\r\n", styles: [".lf-button{width:inherit}\n"] }]
1383
+ }], propDecorators: { fileElement: [{
1384
+ type: ViewChild,
1385
+ args: ['file']
1386
+ }], color: [{
1387
+ type: Input
1388
+ }], label: [{
1389
+ type: Input
1390
+ }], matIcon: [{
1391
+ type: Input
1392
+ }], disabled: [{
1393
+ type: Input
1394
+ }], accept: [{
1395
+ type: Input
1396
+ }], tooltip: [{
1397
+ type: Input
1398
+ }], fileChange: [{
1399
+ type: Output
1400
+ }] } });
1401
+
1402
+ class LoadingInterceptor {
1403
+ constructor() {
1404
+ this.scaffoldService = inject(ScaffoldService);
1405
+ this.activeRequests = 0;
1406
+ this.loadingDelay = 100; // milliseconds
1407
+ }
1408
+ intercept(req, next) {
1409
+ this.activeRequests++;
1410
+ // Set a delayed spinner timeout
1411
+ if (this.activeRequests === 1) {
1412
+ this.spinnerTimeout = setTimeout(() => {
1413
+ this.scaffoldService.updateScaffoldProperty('loading', true);
1414
+ }, this.loadingDelay);
1415
+ }
1416
+ return next.handle(req).pipe(
1417
+ // tap({
1418
+ // next: (event) => {
1419
+ // if (event instanceof HttpResponse) {
1420
+ // // Successful response
1421
+ // }
1422
+ // },
1423
+ // error: (error: HttpErrorResponse) => {
1424
+ // // Handle error if needed
1425
+ // }
1426
+ // }),
1427
+ finalize(() => {
1428
+ this.activeRequests--;
1429
+ if (this.activeRequests === 0) {
1430
+ // Clear any pending spinner timeout
1431
+ clearTimeout(this.spinnerTimeout);
1432
+ this.scaffoldService.updateScaffoldProperty('loading', false);
1433
+ }
1434
+ }));
1435
+ }
1436
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.5", ngImport: i0, type: LoadingInterceptor, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
1437
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.0.5", ngImport: i0, type: LoadingInterceptor }); }
1438
+ }
1439
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.5", ngImport: i0, type: LoadingInterceptor, decorators: [{
1440
+ type: Injectable
1441
+ }] });
1442
+
1443
+ /*
1444
+ * Public API Surface of components
1445
+ */
1446
+ /* MODELS */
1447
+
1448
+ /**
1449
+ * Generated bundle index. Do not edit.
1450
+ */
1451
+
1452
+ export { BreakpointService, CONFIG, DialogService, FileUploadComponent, LoadingInterceptor, LocalStorageService, Logger, PlaceholderComponent, RouterService, ScaffoldComponent, ScaffoldModule, ScaffoldService, SeoService, SnackbarService, ThemeService };
1453
+ //# sourceMappingURL=lukfel-ng-scaffold.mjs.map