@sftech/ng-shared 0.0.22 → 0.0.23

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 (35) hide show
  1. package/fesm2022/sftech-ng-shared.mjs +134 -71
  2. package/fesm2022/sftech-ng-shared.mjs.map +1 -1
  3. package/index.d.ts +408 -31
  4. package/package.json +8 -8
  5. package/lib/components/forms/form-error-display/form-error-display.component.d.ts +0 -8
  6. package/lib/components/pages/base-display/base-display-modal/base-display-modal.component.d.ts +0 -7
  7. package/lib/components/pages/base-display/base-display.component.d.ts +0 -43
  8. package/lib/components/pages/base-list.component.d.ts +0 -32
  9. package/lib/components/paginator/paginator.component.d.ts +0 -11
  10. package/lib/core/configuration/app-config.interface.d.ts +0 -3
  11. package/lib/core/configuration/app-config.loader.d.ts +0 -2
  12. package/lib/core/dtos/api-response.dto.d.ts +0 -9
  13. package/lib/core/dtos/base-db-create.dto.d.ts +0 -2
  14. package/lib/core/dtos/base-db-response.dto.d.ts +0 -5
  15. package/lib/core/dtos/base-db-update.dto.d.ts +0 -2
  16. package/lib/core/dtos/base-response.dto.d.ts +0 -1
  17. package/lib/core/dtos/odata-response.dto.d.ts +0 -13
  18. package/lib/core/models/base-db.model.d.ts +0 -24
  19. package/lib/core/models/mapped-api-response.model.d.ts +0 -19
  20. package/lib/core/models/mapped-odata-response.model.d.ts +0 -12
  21. package/lib/core/models/odata/filter/filter.enums.d.ts +0 -16
  22. package/lib/core/models/odata/odata-expands.model.d.ts +0 -7
  23. package/lib/core/models/odata/odata-filter-collection.model.d.ts +0 -14
  24. package/lib/core/models/odata/odata-filter.model.d.ts +0 -13
  25. package/lib/core/models/odata/odata-order.model.d.ts +0 -10
  26. package/lib/core/models/odata/odata-pagination.model.d.ts +0 -10
  27. package/lib/core/models/odata/odata.interface.d.ts +0 -3
  28. package/lib/core/models/odata/odata.model.d.ts +0 -12
  29. package/lib/core/services/base-db-api.service.d.ts +0 -29
  30. package/lib/providers/icon.provider.d.ts +0 -27
  31. package/lib/ui/layouts/base-dialog/base-dialog.component.d.ts +0 -20
  32. package/lib/ui/layouts/head-main-footer-with-canvas/head-main-footer-with-canvas.component.d.ts +0 -20
  33. package/lib/ui/layouts/sidebar-navigation/sidebar-navigation.component.d.ts +0 -18
  34. package/lib/ui/pages/not-permitted/not-permitted.component.d.ts +0 -5
  35. package/lib/ui/styles/themes/sftech.preset.d.ts +0 -1
@@ -1,13 +1,13 @@
1
1
  import { definePreset } from '@primeng/themes';
2
2
  import Aura from '@primeng/themes/aura';
3
- import { NgTemplateOutlet, CommonModule } from '@angular/common';
3
+ import { NgTemplateOutlet } from '@angular/common';
4
4
  import * as i0 from '@angular/core';
5
5
  import { EventEmitter, input, Output, Component, ViewChild, ContentChild, Input, inject, model, signal, effect } from '@angular/core';
6
6
  import { FaIconComponent } from '@fortawesome/angular-fontawesome';
7
7
  import { Button } from 'primeng/button';
8
8
  import { Drawer } from 'primeng/drawer';
9
9
  import { Toast } from 'primeng/toast';
10
- import { faPlus, faHexagonNodes, faArrowRight, faArrowLeft, faBrain, faComments, faClose, faCloud, faTrash, faDatabase, faFileArrowUp, faExchange, faQuestion, faSpinner, faBars, faComment, faRocket, faSearch, faShield, faHandSparkles, faScrewdriverWrench, faUpload, faLaptop } from '@fortawesome/free-solid-svg-icons';
10
+ import { faPlus, faHexagonNodes, faArrowRight, faArrowLeft, faBolt, faBrain, faCalendarDays, faComments, faClose, faCloud, faTrash, faDatabase, faFileLines, faFileArrowUp, faExchange, faArrowUpRightFromSquare, faFilter, faSliders, faGlobe, faChevronDown, faChevronUp, faQuestion, faInbox, faCircleInfo, faLightbulb, faSpinner, faBars, faComment, faCircleExclamation, faRocket, faSearch, faShield, faHandSparkles, faTag, faScrewdriverWrench, faUpload, faLaptop } from '@fortawesome/free-solid-svg-icons';
11
11
  import { Ripple } from 'primeng/ripple';
12
12
  import { StyleClass } from 'primeng/styleclass';
13
13
  import { RouterLink, Router, ActivatedRoute } from '@angular/router';
@@ -50,23 +50,37 @@ class IconProvider {
50
50
  static agent = faHexagonNodes;
51
51
  static arrowRight = faArrowRight;
52
52
  static back = faArrowLeft;
53
+ static bolt = faBolt;
53
54
  static brain = faBrain;
55
+ static calendar = faCalendarDays;
54
56
  static chat = faComments;
55
57
  static close = faClose;
56
58
  static cloud = faCloud;
57
59
  static delete = faTrash;
58
60
  static database = faDatabase;
61
+ static document = faFileLines;
59
62
  static documentAdd = faFileArrowUp;
60
63
  static exchange = faExchange;
64
+ static externalLink = faArrowUpRightFromSquare;
65
+ static filter = faFilter;
66
+ static filterSettings = faSliders;
67
+ static globe = faGlobe;
68
+ static chevronDown = faChevronDown;
69
+ static chevronUp = faChevronUp;
61
70
  static help = faQuestion;
71
+ static inbox = faInbox;
72
+ static info = faCircleInfo;
73
+ static lightbulb = faLightbulb;
62
74
  static loading = faSpinner;
63
75
  static menu = faBars;
64
76
  static message = faComment;
77
+ static notFound = faCircleExclamation;
65
78
  static robot = faHexagonNodes;
66
79
  static rocket = faRocket;
67
80
  static search = faSearch;
68
81
  static shield = faShield;
69
82
  static sparkles = faHandSparkles;
83
+ static tag = faTag;
70
84
  static tools = faScrewdriverWrench;
71
85
  static unknown = faQuestion;
72
86
  static upload = faUpload;
@@ -75,11 +89,11 @@ class IconProvider {
75
89
 
76
90
  class SidebarNavigationComponent {
77
91
  closeDrawer = new EventEmitter();
78
- navigation = input([]);
79
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: SidebarNavigationComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
80
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.14", type: SidebarNavigationComponent, isStandalone: true, selector: "sftech-sidebar-navigation", inputs: { navigation: { classPropertyName: "navigation", publicName: "navigation", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { closeDrawer: "closeDrawer" }, ngImport: i0, template: "<ul class=\"list-none p-4 m-0\">\r\n @for (category of navigation(); track category) {\r\n <li>\r\n <div\r\n pRipple\r\n pStyleClass=\"@next\"\r\n enterFromClass=\"hidden\"\r\n enterActiveClass=\"animate-slidedown\"\r\n leaveToClass=\"hidden\"\r\n leaveActiveClass=\"animate-slideup\"\r\n class=\"py-2 flex items-center justify-between cursor-pointer p-ripple\"\r\n >\r\n @if (category.icon) {\r\n <fa-icon [icon]=\"category.icon\"></fa-icon>\r\n }\r\n <span class=\"font-bold\">{{ category.categoryName }}</span>\r\n </div>\r\n <ul class=\"list-none p-0 m-0 overflow-hidden\">\r\n @for (link of category.links; track link) {\r\n <li class=\"py-1\">\r\n <a [routerLink]=\"[link.routerLink]\" (click)=\"closeDrawer.emit()\" pRipple class=\"flex items-center cursor-pointer px-4 py-2.5 rounded-border hover:bg-primary-50 duration-150 transition-colors p-ripple\">\r\n @if (link.icon) {\r\n <fa-icon [icon]=\"link.icon\"></fa-icon>\r\n }\r\n <span class=\"font-medium\">{{ link.name}}</span>\r\n </a>\r\n </li>\r\n }\r\n </ul>\r\n </li>\r\n }\r\n</ul>", styles: [""], dependencies: [{ kind: "directive", type: Ripple, selector: "[pRipple]" }, { kind: "directive", type: StyleClass, selector: "[pStyleClass]", inputs: ["pStyleClass", "enterClass", "enterFromClass", "enterActiveClass", "enterToClass", "leaveClass", "leaveFromClass", "leaveActiveClass", "leaveToClass", "hideOnOutsideClick", "toggleClass", "hideOnEscape"] }, { kind: "component", type: FaIconComponent, selector: "fa-icon", inputs: ["icon", "title", "animation", "mask", "flip", "size", "pull", "border", "inverse", "symbol", "rotate", "fixedWidth", "transform", "a11yRole"] }, { kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }] });
92
+ navigation = input([], ...(ngDevMode ? [{ debugName: "navigation" }] : []));
93
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: SidebarNavigationComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
94
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.9", type: SidebarNavigationComponent, isStandalone: true, selector: "sftech-sidebar-navigation", inputs: { navigation: { classPropertyName: "navigation", publicName: "navigation", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { closeDrawer: "closeDrawer" }, ngImport: i0, template: "<ul class=\"list-none p-4 m-0\">\r\n @for (category of navigation(); track category) {\r\n <li>\r\n <div\r\n pRipple\r\n pStyleClass=\"@next\"\r\n enterFromClass=\"hidden\"\r\n enterActiveClass=\"animate-slidedown\"\r\n leaveToClass=\"hidden\"\r\n leaveActiveClass=\"animate-slideup\"\r\n class=\"py-2 flex items-center justify-between cursor-pointer p-ripple\"\r\n >\r\n @if (category.icon) {\r\n <fa-icon [icon]=\"category.icon\"></fa-icon>\r\n }\r\n <span class=\"font-bold\">{{ category.categoryName }}</span>\r\n </div>\r\n <ul class=\"list-none p-0 m-0 overflow-hidden\">\r\n @for (link of category.links; track link) {\r\n <li class=\"py-1\">\r\n <a [routerLink]=\"[link.routerLink]\" (click)=\"closeDrawer.emit()\" pRipple class=\"flex items-center cursor-pointer px-4 py-2.5 rounded-border hover:bg-primary-50 duration-150 transition-colors p-ripple\">\r\n @if (link.icon) {\r\n <fa-icon [icon]=\"link.icon\"></fa-icon>\r\n }\r\n <span class=\"font-medium\">{{ link.name}}</span>\r\n </a>\r\n </li>\r\n }\r\n </ul>\r\n </li>\r\n }\r\n</ul>", styles: [""], dependencies: [{ kind: "directive", type: Ripple, selector: "[pRipple]" }, { kind: "directive", type: StyleClass, selector: "[pStyleClass]", inputs: ["pStyleClass", "enterFromClass", "enterActiveClass", "enterToClass", "leaveFromClass", "leaveActiveClass", "leaveToClass", "hideOnOutsideClick", "toggleClass", "hideOnEscape", "hideOnResize", "resizeSelector"] }, { kind: "component", type: FaIconComponent, selector: "fa-icon", inputs: ["icon", "title", "animation", "mask", "flip", "size", "pull", "border", "inverse", "symbol", "rotate", "fixedWidth", "transform", "a11yRole"], outputs: ["iconChange", "titleChange", "animationChange", "maskChange", "flipChange", "sizeChange", "pullChange", "borderChange", "inverseChange", "symbolChange", "rotateChange", "fixedWidthChange", "transformChange", "a11yRoleChange"] }, { kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }] });
81
95
  }
82
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: SidebarNavigationComponent, decorators: [{
96
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: SidebarNavigationComponent, decorators: [{
83
97
  type: Component,
84
98
  args: [{ selector: 'sftech-sidebar-navigation', imports: [
85
99
  Ripple,
@@ -89,7 +103,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImpo
89
103
  ], template: "<ul class=\"list-none p-4 m-0\">\r\n @for (category of navigation(); track category) {\r\n <li>\r\n <div\r\n pRipple\r\n pStyleClass=\"@next\"\r\n enterFromClass=\"hidden\"\r\n enterActiveClass=\"animate-slidedown\"\r\n leaveToClass=\"hidden\"\r\n leaveActiveClass=\"animate-slideup\"\r\n class=\"py-2 flex items-center justify-between cursor-pointer p-ripple\"\r\n >\r\n @if (category.icon) {\r\n <fa-icon [icon]=\"category.icon\"></fa-icon>\r\n }\r\n <span class=\"font-bold\">{{ category.categoryName }}</span>\r\n </div>\r\n <ul class=\"list-none p-0 m-0 overflow-hidden\">\r\n @for (link of category.links; track link) {\r\n <li class=\"py-1\">\r\n <a [routerLink]=\"[link.routerLink]\" (click)=\"closeDrawer.emit()\" pRipple class=\"flex items-center cursor-pointer px-4 py-2.5 rounded-border hover:bg-primary-50 duration-150 transition-colors p-ripple\">\r\n @if (link.icon) {\r\n <fa-icon [icon]=\"link.icon\"></fa-icon>\r\n }\r\n <span class=\"font-medium\">{{ link.name}}</span>\r\n </a>\r\n </li>\r\n }\r\n </ul>\r\n </li>\r\n }\r\n</ul>" }]
90
104
  }], propDecorators: { closeDrawer: [{
91
105
  type: Output
92
- }] } });
106
+ }], navigation: [{ type: i0.Input, args: [{ isSignal: true, alias: "navigation", required: false }] }] } });
93
107
 
94
108
  class HeadMainFooterWithCanvasComponent {
95
109
  title = 'demo';
@@ -105,10 +119,10 @@ class HeadMainFooterWithCanvasComponent {
105
119
  closeCallback(e) {
106
120
  this.drawerRef.close(e);
107
121
  }
108
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: HeadMainFooterWithCanvasComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
109
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.14", type: HeadMainFooterWithCanvasComponent, isStandalone: true, selector: "sftech-head-main-footer-with-canvas", inputs: { title: "title", maxWidth: "maxWidth", navigationItems: "navigationItems", hasDrawer: "hasDrawer" }, queries: [{ propertyName: "header", first: true, predicate: ["header"], descendants: true }, { propertyName: "main", first: true, predicate: ["main"], descendants: true }, { propertyName: "footer", first: true, predicate: ["footer"], descendants: true }], viewQueries: [{ propertyName: "drawerRef", first: true, predicate: ["drawerRef"], descendants: true }], ngImport: i0, template: "<div class=\"h-screen flex flex-col justify-between bg-gradient-to-b from-primary-50/40 via-white to-primary-50/40\">\r\n <p-toast/>\r\n <header class=\"shrink-0 p-3 bg-gradient-to-r from-primary-500 to-primary-900 text-white\">\r\n <div [style.max-width]=\"maxWidth\" class=\"w-full mx-auto\">\r\n @if (hasDrawer) {\r\n <div class=\"flex items-center w-full\">\r\n <div class=\"flex-shrink\">\r\n <p-button (click)=\"drawerVisible = !drawerVisible\">\r\n <fa-icon [icon]=\"iconProvider.menu\"></fa-icon>\r\n </p-button>\r\n </div>\r\n <div class=\"ms-2 w-full\">\r\n <ng-container [ngTemplateOutlet]=\"header\"></ng-container>\r\n </div>\r\n </div>\r\n } @else {\r\n <ng-container [ngTemplateOutlet]=\"header\"></ng-container>\r\n }\r\n </div>\r\n </header>\r\n\r\n <main class=\"flex-grow min-h-0 flex flex-col\">\r\n <div [style.max-width]=\"maxWidth\" class=\"mx-auto bg-white shadow-xl flex-grow overflow-auto w-full\">\r\n <ng-container [ngTemplateOutlet]=\"main\"></ng-container>\r\n </div>\r\n </main>\r\n\r\n <footer class=\"shrink-0 p-3 bg-gradient-to-r from-primary-900 to-primary-500 text-white text-sm\">\r\n <div [style.max-width]=\"maxWidth\" class=\"w-full mx-auto\">\r\n <ng-container [ngTemplateOutlet]=\"footer\"></ng-container>\r\n </div>\r\n </footer>\r\n</div>\r\n\r\n@if (hasDrawer) {\r\n <p-drawer #drawerRef [(visible)]=\"drawerVisible\">\r\n <ng-template #headless>\r\n <div class=\"flex flex-col h-full bg-white shadow-lg\">\r\n <div class=\"flex items-center justify-between px-4 pt-5 pb-5 border-b border-gray-200\">\r\n <span class=\"font-semibold text-2xl text-primary\">Menu</span>\r\n <span>\r\n <p-button type=\"button\" (click)=\"drawerVisible = false\" rounded=\"true\" outlined=\"true\"\r\n styleClass=\"h-9 w-9\"><fa-icon [icon]=\"iconProvider.close\"></fa-icon></p-button>\r\n </span>\r\n </div>\r\n <div class=\"overflow-y-auto px-4 mt-4\">\r\n <sftech-sidebar-navigation [navigation]=\"navigationItems\" (closeDrawer)=\"drawerVisible = false\"></sftech-sidebar-navigation>\r\n </div>\r\n </div>\r\n </ng-template>\r\n </p-drawer>\r\n}", styles: [""], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: Button, selector: "p-button", inputs: ["type", "iconPos", "icon", "badge", "label", "disabled", "loading", "loadingIcon", "raised", "rounded", "text", "plain", "severity", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "fluid", "buttonProps"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "component", type: Drawer, selector: "p-drawer", inputs: ["appendTo", "blockScroll", "style", "styleClass", "ariaCloseLabel", "autoZIndex", "baseZIndex", "modal", "closeButtonProps", "dismissible", "showCloseIcon", "closeOnEscape", "transitionOptions", "visible", "position", "fullScreen", "header", "maskStyle", "closable"], outputs: ["onShow", "onHide", "visibleChange"] }, { kind: "component", type: FaIconComponent, selector: "fa-icon", inputs: ["icon", "title", "animation", "mask", "flip", "size", "pull", "border", "inverse", "symbol", "rotate", "fixedWidth", "transform", "a11yRole"] }, { kind: "component", type: Toast, selector: "p-toast", inputs: ["key", "autoZIndex", "baseZIndex", "life", "style", "styleClass", "position", "preventOpenDuplicates", "preventDuplicates", "showTransformOptions", "hideTransformOptions", "showTransitionOptions", "hideTransitionOptions", "breakpoints"], outputs: ["onClose"] }, { kind: "component", type: SidebarNavigationComponent, selector: "sftech-sidebar-navigation", inputs: ["navigation"], outputs: ["closeDrawer"] }] });
122
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: HeadMainFooterWithCanvasComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
123
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.9", type: HeadMainFooterWithCanvasComponent, isStandalone: true, selector: "sftech-head-main-footer-with-canvas", inputs: { title: "title", maxWidth: "maxWidth", navigationItems: "navigationItems", hasDrawer: "hasDrawer" }, queries: [{ propertyName: "header", first: true, predicate: ["header"], descendants: true }, { propertyName: "main", first: true, predicate: ["main"], descendants: true }, { propertyName: "footer", first: true, predicate: ["footer"], descendants: true }], viewQueries: [{ propertyName: "drawerRef", first: true, predicate: ["drawerRef"], descendants: true }], ngImport: i0, template: "<div class=\"h-screen flex flex-col justify-between bg-gradient-to-b from-primary-50/40 via-white to-primary-50/40\">\r\n <p-toast/>\r\n <header class=\"shrink-0 p-3 bg-gradient-to-r from-primary-500 to-primary-900 text-white\">\r\n <div [style.max-width]=\"maxWidth\" class=\"w-full mx-auto\">\r\n @if (hasDrawer) {\r\n <div class=\"flex items-center w-full\">\r\n <div class=\"flex-shrink\">\r\n <p-button (click)=\"drawerVisible = !drawerVisible\">\r\n <fa-icon [icon]=\"iconProvider.menu\"></fa-icon>\r\n </p-button>\r\n </div>\r\n <div class=\"ms-2 w-full\">\r\n <ng-container [ngTemplateOutlet]=\"header\"></ng-container>\r\n </div>\r\n </div>\r\n } @else {\r\n <ng-container [ngTemplateOutlet]=\"header\"></ng-container>\r\n }\r\n </div>\r\n </header>\r\n\r\n <main class=\"flex-grow min-h-0 flex flex-col\">\r\n <div [style.max-width]=\"maxWidth\" class=\"mx-auto bg-white shadow-xl flex-grow overflow-auto w-full\">\r\n <ng-container [ngTemplateOutlet]=\"main\"></ng-container>\r\n </div>\r\n </main>\r\n\r\n <footer class=\"shrink-0 p-3 bg-gradient-to-r from-primary-900 to-primary-500 text-white text-sm\">\r\n <div [style.max-width]=\"maxWidth\" class=\"w-full mx-auto\">\r\n <ng-container [ngTemplateOutlet]=\"footer\"></ng-container>\r\n </div>\r\n </footer>\r\n</div>\r\n\r\n@if (hasDrawer) {\r\n <p-drawer #drawerRef [(visible)]=\"drawerVisible\">\r\n <ng-template #headless>\r\n <div class=\"flex flex-col h-full bg-white shadow-lg\">\r\n <div class=\"flex items-center justify-between px-4 pt-5 pb-5 border-b border-gray-200\">\r\n <span class=\"font-semibold text-2xl text-primary\">Menu</span>\r\n <span>\r\n <p-button type=\"button\" (click)=\"drawerVisible = false\" rounded=\"true\" outlined=\"true\"\r\n styleClass=\"h-9 w-9\"><fa-icon [icon]=\"iconProvider.close\"></fa-icon></p-button>\r\n </span>\r\n </div>\r\n <div class=\"overflow-y-auto px-4 mt-4\">\r\n <sftech-sidebar-navigation [navigation]=\"navigationItems\" (closeDrawer)=\"drawerVisible = false\"></sftech-sidebar-navigation>\r\n </div>\r\n </div>\r\n </ng-template>\r\n </p-drawer>\r\n}", styles: [""], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: Button, selector: "p-button", inputs: ["hostName", "type", "badge", "disabled", "raised", "rounded", "text", "plain", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "iconPos", "icon", "label", "loading", "loadingIcon", "severity", "buttonProps", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "component", type: Drawer, selector: "p-drawer", inputs: ["appendTo", "blockScroll", "style", "styleClass", "ariaCloseLabel", "autoZIndex", "baseZIndex", "modal", "closeButtonProps", "dismissible", "showCloseIcon", "closeOnEscape", "transitionOptions", "visible", "position", "fullScreen", "header", "maskStyle", "closable"], outputs: ["onShow", "onHide", "visibleChange"] }, { kind: "component", type: FaIconComponent, selector: "fa-icon", inputs: ["icon", "title", "animation", "mask", "flip", "size", "pull", "border", "inverse", "symbol", "rotate", "fixedWidth", "transform", "a11yRole"], outputs: ["iconChange", "titleChange", "animationChange", "maskChange", "flipChange", "sizeChange", "pullChange", "borderChange", "inverseChange", "symbolChange", "rotateChange", "fixedWidthChange", "transformChange", "a11yRoleChange"] }, { kind: "component", type: Toast, selector: "p-toast", inputs: ["key", "autoZIndex", "baseZIndex", "life", "styleClass", "position", "preventOpenDuplicates", "preventDuplicates", "showTransformOptions", "hideTransformOptions", "showTransitionOptions", "hideTransitionOptions", "breakpoints"], outputs: ["onClose"] }, { kind: "component", type: SidebarNavigationComponent, selector: "sftech-sidebar-navigation", inputs: ["navigation"], outputs: ["closeDrawer"] }] });
110
124
  }
111
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: HeadMainFooterWithCanvasComponent, decorators: [{
125
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: HeadMainFooterWithCanvasComponent, decorators: [{
112
126
  type: Component,
113
127
  args: [{ selector: 'sftech-head-main-footer-with-canvas', imports: [NgTemplateOutlet, Button, Drawer, FaIconComponent, Toast, SidebarNavigationComponent], template: "<div class=\"h-screen flex flex-col justify-between bg-gradient-to-b from-primary-50/40 via-white to-primary-50/40\">\r\n <p-toast/>\r\n <header class=\"shrink-0 p-3 bg-gradient-to-r from-primary-500 to-primary-900 text-white\">\r\n <div [style.max-width]=\"maxWidth\" class=\"w-full mx-auto\">\r\n @if (hasDrawer) {\r\n <div class=\"flex items-center w-full\">\r\n <div class=\"flex-shrink\">\r\n <p-button (click)=\"drawerVisible = !drawerVisible\">\r\n <fa-icon [icon]=\"iconProvider.menu\"></fa-icon>\r\n </p-button>\r\n </div>\r\n <div class=\"ms-2 w-full\">\r\n <ng-container [ngTemplateOutlet]=\"header\"></ng-container>\r\n </div>\r\n </div>\r\n } @else {\r\n <ng-container [ngTemplateOutlet]=\"header\"></ng-container>\r\n }\r\n </div>\r\n </header>\r\n\r\n <main class=\"flex-grow min-h-0 flex flex-col\">\r\n <div [style.max-width]=\"maxWidth\" class=\"mx-auto bg-white shadow-xl flex-grow overflow-auto w-full\">\r\n <ng-container [ngTemplateOutlet]=\"main\"></ng-container>\r\n </div>\r\n </main>\r\n\r\n <footer class=\"shrink-0 p-3 bg-gradient-to-r from-primary-900 to-primary-500 text-white text-sm\">\r\n <div [style.max-width]=\"maxWidth\" class=\"w-full mx-auto\">\r\n <ng-container [ngTemplateOutlet]=\"footer\"></ng-container>\r\n </div>\r\n </footer>\r\n</div>\r\n\r\n@if (hasDrawer) {\r\n <p-drawer #drawerRef [(visible)]=\"drawerVisible\">\r\n <ng-template #headless>\r\n <div class=\"flex flex-col h-full bg-white shadow-lg\">\r\n <div class=\"flex items-center justify-between px-4 pt-5 pb-5 border-b border-gray-200\">\r\n <span class=\"font-semibold text-2xl text-primary\">Menu</span>\r\n <span>\r\n <p-button type=\"button\" (click)=\"drawerVisible = false\" rounded=\"true\" outlined=\"true\"\r\n styleClass=\"h-9 w-9\"><fa-icon [icon]=\"iconProvider.close\"></fa-icon></p-button>\r\n </span>\r\n </div>\r\n <div class=\"overflow-y-auto px-4 mt-4\">\r\n <sftech-sidebar-navigation [navigation]=\"navigationItems\" (closeDrawer)=\"drawerVisible = false\"></sftech-sidebar-navigation>\r\n </div>\r\n </div>\r\n </ng-template>\r\n </p-drawer>\r\n}" }]
114
128
  }], propDecorators: { title: [{
@@ -134,10 +148,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImpo
134
148
  }] } });
135
149
 
136
150
  class BaseDialogComponent {
137
- hasHeader = input(true);
138
- hasFooter = input(true);
139
- showButtons = input(true);
140
- headerText = input(undefined);
151
+ hasHeader = input(true, ...(ngDevMode ? [{ debugName: "hasHeader" }] : []));
152
+ hasFooter = input(true, ...(ngDevMode ? [{ debugName: "hasFooter" }] : []));
153
+ showButtons = input(true, ...(ngDevMode ? [{ debugName: "showButtons" }] : []));
154
+ headerText = input(undefined, ...(ngDevMode ? [{ debugName: "headerText" }] : []));
141
155
  closed = new EventEmitter();
142
156
  header = null;
143
157
  body = null;
@@ -149,13 +163,13 @@ class BaseDialogComponent {
149
163
  this.ref.close(retVal);
150
164
  this.closed.emit();
151
165
  }
152
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: BaseDialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
153
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.14", type: BaseDialogComponent, isStandalone: true, selector: "sftech-base-dialog", inputs: { hasHeader: { classPropertyName: "hasHeader", publicName: "hasHeader", isSignal: true, isRequired: false, transformFunction: null }, hasFooter: { classPropertyName: "hasFooter", publicName: "hasFooter", isSignal: true, isRequired: false, transformFunction: null }, showButtons: { classPropertyName: "showButtons", publicName: "showButtons", isSignal: true, isRequired: false, transformFunction: null }, headerText: { classPropertyName: "headerText", publicName: "headerText", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { closed: "closed" }, queries: [{ propertyName: "header", first: true, predicate: ["header"], descendants: true }, { propertyName: "body", first: true, predicate: ["body"], descendants: true }, { propertyName: "footer", first: true, predicate: ["footer"], descendants: true }], ngImport: i0, template: "<!--<p-dialog [(visible)]=\"visible\" [modal]=\"true\" [style]=\"{ width: '25rem' }\">-->\r\n<!-- <ng-template #header>-->\r\n<!-- <div class=\"inline-flex items-center justify-center gap-2\">-->\r\n<!-- <span class=\"font-bold whitespace-nowrap\">Amy Elsner</span>-->\r\n<!-- </div>-->\r\n<!-- </ng-template>-->\r\n<!-- <span class=\"text-surface-500 dark:text-surface-400 block mb-8\">Update your information.</span>-->\r\n<!-- <div class=\"flex items-center gap-4 mb-4\">-->\r\n<!-- <label for=\"username\" class=\"font-semibold w-24\">Username</label>-->\r\n<!-- <input pInputText id=\"username\" class=\"flex-auto\" autocomplete=\"off\" />-->\r\n<!-- </div>-->\r\n<!-- <div class=\"flex items-center gap-4 mb-2\">-->\r\n<!-- <label for=\"email\" class=\"font-semibold w-24\">Email</label>-->\r\n<!-- <input pInputText id=\"email\" class=\"flex-auto\" autocomplete=\"off\" />-->\r\n<!-- </div>-->\r\n<!-- <ng-template #footer>-->\r\n<!-- <p-button label=\"Cancel\" [text]=\"true\" severity=\"secondary\" (click)=\"visible = false\" />-->\r\n<!-- <p-button label=\"Save\" [outlined]=\"true\" severity=\"secondary\" (click)=\"visible = false\" />-->\r\n<!-- </ng-template>-->\r\n<!--</p-dialog>-->\r\n\r\n<div class=\"flex flex-col\">\r\n <div id=\"dialog-body\" class=\"flex-grow overflow-auto\">\r\n <ng-container [ngTemplateOutlet]=\"body\"></ng-container>\r\n </div>\r\n\r\n @if (hasFooter()) {\r\n <div id=\"dialog-footer\" class=\"flex justify-end mt-5\">\r\n <div id=\"footer-content\">\r\n <ng-container [ngTemplateOutlet]=\"footer\"></ng-container>\r\n </div>\r\n </div>\r\n }\r\n</div>\r\n", styles: [""], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }] });
166
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: BaseDialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
167
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.9", type: BaseDialogComponent, isStandalone: true, selector: "sftech-base-dialog", inputs: { hasHeader: { classPropertyName: "hasHeader", publicName: "hasHeader", isSignal: true, isRequired: false, transformFunction: null }, hasFooter: { classPropertyName: "hasFooter", publicName: "hasFooter", isSignal: true, isRequired: false, transformFunction: null }, showButtons: { classPropertyName: "showButtons", publicName: "showButtons", isSignal: true, isRequired: false, transformFunction: null }, headerText: { classPropertyName: "headerText", publicName: "headerText", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { closed: "closed" }, queries: [{ propertyName: "header", first: true, predicate: ["header"], descendants: true }, { propertyName: "body", first: true, predicate: ["body"], descendants: true }, { propertyName: "footer", first: true, predicate: ["footer"], descendants: true }], ngImport: i0, template: "<!--<p-dialog [(visible)]=\"visible\" [modal]=\"true\" [style]=\"{ width: '25rem' }\">-->\r\n<!-- <ng-template #header>-->\r\n<!-- <div class=\"inline-flex items-center justify-center gap-2\">-->\r\n<!-- <span class=\"font-bold whitespace-nowrap\">Amy Elsner</span>-->\r\n<!-- </div>-->\r\n<!-- </ng-template>-->\r\n<!-- <span class=\"text-surface-500 dark:text-surface-400 block mb-8\">Update your information.</span>-->\r\n<!-- <div class=\"flex items-center gap-4 mb-4\">-->\r\n<!-- <label for=\"username\" class=\"font-semibold w-24\">Username</label>-->\r\n<!-- <input pInputText id=\"username\" class=\"flex-auto\" autocomplete=\"off\" />-->\r\n<!-- </div>-->\r\n<!-- <div class=\"flex items-center gap-4 mb-2\">-->\r\n<!-- <label for=\"email\" class=\"font-semibold w-24\">Email</label>-->\r\n<!-- <input pInputText id=\"email\" class=\"flex-auto\" autocomplete=\"off\" />-->\r\n<!-- </div>-->\r\n<!-- <ng-template #footer>-->\r\n<!-- <p-button label=\"Cancel\" [text]=\"true\" severity=\"secondary\" (click)=\"visible = false\" />-->\r\n<!-- <p-button label=\"Save\" [outlined]=\"true\" severity=\"secondary\" (click)=\"visible = false\" />-->\r\n<!-- </ng-template>-->\r\n<!--</p-dialog>-->\r\n\r\n<div class=\"flex flex-col\">\r\n <div id=\"dialog-body\" class=\"flex-grow overflow-auto\">\r\n <ng-container [ngTemplateOutlet]=\"body\"></ng-container>\r\n </div>\r\n\r\n @if (hasFooter()) {\r\n <div id=\"dialog-footer\" class=\"flex justify-end mt-5\">\r\n <div id=\"footer-content\">\r\n <ng-container [ngTemplateOutlet]=\"footer\"></ng-container>\r\n </div>\r\n </div>\r\n }\r\n</div>\r\n", styles: [""], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }] });
154
168
  }
155
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: BaseDialogComponent, decorators: [{
169
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: BaseDialogComponent, decorators: [{
156
170
  type: Component,
157
171
  args: [{ selector: 'sftech-base-dialog', imports: [NgTemplateOutlet], template: "<!--<p-dialog [(visible)]=\"visible\" [modal]=\"true\" [style]=\"{ width: '25rem' }\">-->\r\n<!-- <ng-template #header>-->\r\n<!-- <div class=\"inline-flex items-center justify-center gap-2\">-->\r\n<!-- <span class=\"font-bold whitespace-nowrap\">Amy Elsner</span>-->\r\n<!-- </div>-->\r\n<!-- </ng-template>-->\r\n<!-- <span class=\"text-surface-500 dark:text-surface-400 block mb-8\">Update your information.</span>-->\r\n<!-- <div class=\"flex items-center gap-4 mb-4\">-->\r\n<!-- <label for=\"username\" class=\"font-semibold w-24\">Username</label>-->\r\n<!-- <input pInputText id=\"username\" class=\"flex-auto\" autocomplete=\"off\" />-->\r\n<!-- </div>-->\r\n<!-- <div class=\"flex items-center gap-4 mb-2\">-->\r\n<!-- <label for=\"email\" class=\"font-semibold w-24\">Email</label>-->\r\n<!-- <input pInputText id=\"email\" class=\"flex-auto\" autocomplete=\"off\" />-->\r\n<!-- </div>-->\r\n<!-- <ng-template #footer>-->\r\n<!-- <p-button label=\"Cancel\" [text]=\"true\" severity=\"secondary\" (click)=\"visible = false\" />-->\r\n<!-- <p-button label=\"Save\" [outlined]=\"true\" severity=\"secondary\" (click)=\"visible = false\" />-->\r\n<!-- </ng-template>-->\r\n<!--</p-dialog>-->\r\n\r\n<div class=\"flex flex-col\">\r\n <div id=\"dialog-body\" class=\"flex-grow overflow-auto\">\r\n <ng-container [ngTemplateOutlet]=\"body\"></ng-container>\r\n </div>\r\n\r\n @if (hasFooter()) {\r\n <div id=\"dialog-footer\" class=\"flex justify-end mt-5\">\r\n <div id=\"footer-content\">\r\n <ng-container [ngTemplateOutlet]=\"footer\"></ng-container>\r\n </div>\r\n </div>\r\n }\r\n</div>\r\n" }]
158
- }], ctorParameters: () => [], propDecorators: { closed: [{
172
+ }], ctorParameters: () => [], propDecorators: { hasHeader: [{ type: i0.Input, args: [{ isSignal: true, alias: "hasHeader", required: false }] }], hasFooter: [{ type: i0.Input, args: [{ isSignal: true, alias: "hasFooter", required: false }] }], showButtons: [{ type: i0.Input, args: [{ isSignal: true, alias: "showButtons", required: false }] }], headerText: [{ type: i0.Input, args: [{ isSignal: true, alias: "headerText", required: false }] }], closed: [{
159
173
  type: Output
160
174
  }], header: [{
161
175
  type: ContentChild,
@@ -279,19 +293,35 @@ var FilterConcatenation;
279
293
  })(FilterConcatenation || (FilterConcatenation = {}));
280
294
  class OdataFilterCollection {
281
295
  andFilters = [];
282
- // public orFilters: OdataFilter[] = [];
296
+ /**
297
+ * Raw filter strings that are added directly to the OData query.
298
+ * Useful for complex filters that can't be expressed with OdataFilter (e.g., OR conditions).
299
+ */
300
+ rawFilters = [];
283
301
  toGetParameter() {
284
302
  let odataString = '$filter=';
285
303
  const filters = this.andFilters.filter((x) => this._isFilterValid(x));
286
- if (filters.length === 0) {
304
+ const allFilterStrings = [
305
+ ...filters.map((x) => x.toGetParameter()),
306
+ ...this.rawFilters.filter((x) => x.trim().length > 0),
307
+ ];
308
+ if (allFilterStrings.length === 0) {
287
309
  return '';
288
310
  }
289
- odataString += filters.map((x) => x.toGetParameter()).join(FilterConcatenation.AND);
311
+ odataString += allFilterStrings.join(FilterConcatenation.AND);
290
312
  return odataString;
291
313
  }
292
314
  addAnd(andFilter) {
293
315
  this.andFilters.push(andFilter);
294
316
  }
317
+ /**
318
+ * Adds a raw OData filter string.
319
+ * Use this for complex filters like OR conditions.
320
+ * Example: "((publishedAt ne null and publishedAt ge '2024-01-01') or (publishedAt eq null and createdAt ge '2024-01-01'))"
321
+ */
322
+ addRaw(rawFilter) {
323
+ this.rawFilters.push(rawFilter);
324
+ }
295
325
  remove(field) {
296
326
  const idx = this.andFilters.findIndex((f) => f.field === field);
297
327
  if (idx >= 0) {
@@ -299,7 +329,7 @@ class OdataFilterCollection {
299
329
  }
300
330
  }
301
331
  hasValidFilters() {
302
- return this.andFilters.filter((f) => this._isFilterValid(f)).length > 0;
332
+ return this.andFilters.filter((f) => this._isFilterValid(f)).length > 0 || this.rawFilters.length > 0;
303
333
  }
304
334
  _isFilterValid(filter) {
305
335
  return !(!filter.type || !filter.field || !filter.operator);
@@ -314,6 +344,12 @@ var ESortDirection;
314
344
  class ODataOrder {
315
345
  column = 'id';
316
346
  direction = ESortDirection.ASC;
347
+ static create(column, direction) {
348
+ const order = new ODataOrder();
349
+ order.column = column;
350
+ order.direction = direction;
351
+ return order;
352
+ }
317
353
  toGetParameter() {
318
354
  return `$orderby=${this.column} ${this.direction}`;
319
355
  }
@@ -369,13 +405,24 @@ class OdataFilter {
369
405
  this.operator = operator;
370
406
  this.type = type;
371
407
  }
408
+ /**
409
+ * Escapes a string value for safe use in OData queries.
410
+ * Prevents OData injection attacks by escaping single quotes.
411
+ */
412
+ escapeODataString(value) {
413
+ if (typeof value !== 'string') {
414
+ return String(value);
415
+ }
416
+ // OData escaping: single quotes are escaped by doubling them
417
+ return value.replace(/'/g, "''");
418
+ }
372
419
  toGetParameter() {
373
420
  if (!this.field || !this.operator || !this.type || !this.value) {
374
421
  return '';
375
422
  }
376
423
  switch (this.operator) {
377
424
  case EFilterOperator.CONTAINS:
378
- return `contains(${this.field},'${this.value}')`;
425
+ return `contains(${this.field},'${this.escapeODataString(String(this.value))}')`;
379
426
  default:
380
427
  return `${this.field} ${this._getODataOperator()} ${this._getTypeDependentValue()}`;
381
428
  }
@@ -397,11 +444,10 @@ class OdataFilter {
397
444
  }
398
445
  _getTypeDependentValue() {
399
446
  if (this.type === EFilterTypes.STRING) {
400
- return `'${this.value}'`;
447
+ return `'${this.escapeODataString(String(this.value))}'`;
401
448
  }
402
449
  if (this.type === EFilterTypes.TIME) {
403
450
  if (!this.value.includes(':')) {
404
- console.warn(this.value, 'not a valid time');
405
451
  return 0;
406
452
  }
407
453
  const minutesSeconds = this.value.split(':');
@@ -432,12 +478,13 @@ class OdataFilter {
432
478
  }
433
479
 
434
480
  class BaseListComponent {
435
- odata = model(new OData());
436
- showPageTitle = input(true);
437
- canEdit = input(true);
438
- openDisplayAsModal = input(true);
481
+ odata = model(new OData(), ...(ngDevMode ? [{ debugName: "odata" }] : []));
482
+ showPageTitle = input(true, ...(ngDevMode ? [{ debugName: "showPageTitle" }] : []));
483
+ canEdit = input(true, ...(ngDevMode ? [{ debugName: "canEdit" }] : []));
484
+ openDisplayAsModal = input(true, ...(ngDevMode ? [{ debugName: "openDisplayAsModal" }] : []));
439
485
  modalWidth = '40%';
440
- data = signal(undefined);
486
+ data = signal(undefined, ...(ngDevMode ? [{ debugName: "data" }] : []));
487
+ loading = signal(false, ...(ngDevMode ? [{ debugName: "loading" }] : []));
441
488
  router = inject(Router);
442
489
  modalService = inject(DialogService);
443
490
  detailModalHeaderText = 'Details';
@@ -447,16 +494,29 @@ class BaseListComponent {
447
494
  this._loadData();
448
495
  }
449
496
  updatePagination($event) {
450
- this.odata.update((odata) => {
451
- const odataNew = new OData();
452
- odataNew.pagination = $event;
453
- odataNew.filter = odata.filter;
454
- odataNew.order = odata.order;
455
- odataNew.expands = odata.expands;
456
- return odataNew;
457
- });
497
+ this.updateOdata({ pagination: $event });
458
498
  this._loadData();
459
499
  }
500
+ updateOdata(changes) {
501
+ this.odata.update((current) => {
502
+ const newOdata = new OData();
503
+ newOdata.filter = changes.filter ?? current.filter;
504
+ newOdata.order = changes.order ?? current.order;
505
+ newOdata.expands = changes.expands ?? current.expands;
506
+ if (changes.resetPaginationToFirstPage) {
507
+ const newPag = new ODataPagination();
508
+ newPag.pageSize = current.pagination.pageSize;
509
+ newPag.totalPages = current.pagination.totalPages;
510
+ newPag.totalElements = current.pagination.totalElements;
511
+ newPag.page = 1;
512
+ newOdata.pagination = newPag;
513
+ }
514
+ else {
515
+ newOdata.pagination = changes.pagination ?? current.pagination;
516
+ }
517
+ return newOdata;
518
+ });
519
+ }
460
520
  openDisplay(id) {
461
521
  if (this.openDisplayAsModal()) {
462
522
  const modalRef = this.modalService.open(this._modalComponent, {
@@ -469,7 +529,7 @@ class BaseListComponent {
469
529
  closable: true,
470
530
  width: this.modalWidth,
471
531
  });
472
- modalRef.onClose.subscribe((result) => {
532
+ modalRef?.onClose.subscribe((result) => {
473
533
  if (result) {
474
534
  this.data.update((data) => {
475
535
  const index = data?.findIndex((item) => item.id === result.id);
@@ -488,9 +548,10 @@ class BaseListComponent {
488
548
  this.router.navigate([this._route, id]);
489
549
  }
490
550
  _loadData() {
551
+ this.loading.set(true);
491
552
  this._repo.odata(this.odata()).subscribe((response) => {
553
+ this.loading.set(false);
492
554
  if (response instanceof MappedApiError) {
493
- console.error(response);
494
555
  return;
495
556
  }
496
557
  this.data.set(response.data.items);
@@ -507,13 +568,13 @@ class BaseListComponent {
507
568
  });
508
569
  });
509
570
  }
510
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: BaseListComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
511
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "19.2.14", type: BaseListComponent, isStandalone: true, selector: "sftech-pages-base-list", inputs: { odata: { classPropertyName: "odata", publicName: "odata", isSignal: true, isRequired: false, transformFunction: null }, showPageTitle: { classPropertyName: "showPageTitle", publicName: "showPageTitle", isSignal: true, isRequired: false, transformFunction: null }, canEdit: { classPropertyName: "canEdit", publicName: "canEdit", isSignal: true, isRequired: false, transformFunction: null }, openDisplayAsModal: { classPropertyName: "openDisplayAsModal", publicName: "openDisplayAsModal", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { odata: "odataChange" }, ngImport: i0, template: '<div></div>', isInline: true, styles: [""] });
571
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: BaseListComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
572
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.3.9", type: BaseListComponent, isStandalone: true, selector: "sftech-pages-base-list", inputs: { odata: { classPropertyName: "odata", publicName: "odata", isSignal: true, isRequired: false, transformFunction: null }, showPageTitle: { classPropertyName: "showPageTitle", publicName: "showPageTitle", isSignal: true, isRequired: false, transformFunction: null }, canEdit: { classPropertyName: "canEdit", publicName: "canEdit", isSignal: true, isRequired: false, transformFunction: null }, openDisplayAsModal: { classPropertyName: "openDisplayAsModal", publicName: "openDisplayAsModal", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { odata: "odataChange" }, ngImport: i0, template: '<div></div>', isInline: true, styles: [""] });
512
573
  }
513
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: BaseListComponent, decorators: [{
574
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: BaseListComponent, decorators: [{
514
575
  type: Component,
515
576
  args: [{ selector: 'sftech-pages-base-list', standalone: true, imports: [], template: '<div></div>' }]
516
- }], ctorParameters: () => [] });
577
+ }], ctorParameters: () => [], propDecorators: { odata: [{ type: i0.Input, args: [{ isSignal: true, alias: "odata", required: false }] }, { type: i0.Output, args: ["odataChange"] }], showPageTitle: [{ type: i0.Input, args: [{ isSignal: true, alias: "showPageTitle", required: false }] }], canEdit: [{ type: i0.Input, args: [{ isSignal: true, alias: "canEdit", required: false }] }], openDisplayAsModal: [{ type: i0.Input, args: [{ isSignal: true, alias: "openDisplayAsModal", required: false }] }] } });
517
578
 
518
579
  class BaseDisplayComponent extends BaseDialogComponent {
519
580
  id;
@@ -521,8 +582,8 @@ class BaseDisplayComponent extends BaseDialogComponent {
521
582
  canEdit = true;
522
583
  redirectAfterSave = true;
523
584
  form;
524
- model = signal(undefined);
525
- isNew = signal(true);
585
+ model = signal(undefined, ...(ngDevMode ? [{ debugName: "model" }] : []));
586
+ isNew = signal(true, ...(ngDevMode ? [{ debugName: "isNew" }] : []));
526
587
  router = inject(Router);
527
588
  activatedRoute = inject(ActivatedRoute);
528
589
  toastr = inject(MessageService);
@@ -627,10 +688,10 @@ class BaseDisplayComponent extends BaseDialogComponent {
627
688
  mappedApiResponse.data = this.model();
628
689
  return of(mappedApiResponse);
629
690
  }
630
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: BaseDisplayComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
631
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.14", type: BaseDisplayComponent, isStandalone: true, selector: "lib-core-base-display", inputs: { id: "id", openedAsModal: "openedAsModal", canEdit: "canEdit" }, usesInheritance: true, ngImport: i0, template: '<div></div>', isInline: true, styles: [""] });
691
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: BaseDisplayComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
692
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.9", type: BaseDisplayComponent, isStandalone: true, selector: "lib-core-base-display", inputs: { id: "id", openedAsModal: "openedAsModal", canEdit: "canEdit" }, usesInheritance: true, ngImport: i0, template: '<div></div>', isInline: true, styles: [""] });
632
693
  }
633
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: BaseDisplayComponent, decorators: [{
694
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: BaseDisplayComponent, decorators: [{
634
695
  type: Component,
635
696
  args: [{ selector: 'lib-core-base-display', standalone: true, imports: [], template: '<div></div>' }]
636
697
  }], ctorParameters: () => [], propDecorators: { id: [{
@@ -644,24 +705,24 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImpo
644
705
  class BaseDisplayModalComponent {
645
706
  id;
646
707
  canEdit = true;
647
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: BaseDisplayModalComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
648
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.14", type: BaseDisplayModalComponent, isStandalone: true, selector: "lib-prompt-display-modal", ngImport: i0, template: '', isInline: true, styles: [""] });
708
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: BaseDisplayModalComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
709
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.9", type: BaseDisplayModalComponent, isStandalone: true, selector: "lib-prompt-display-modal", ngImport: i0, template: '', isInline: true, styles: [""] });
649
710
  }
650
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: BaseDisplayModalComponent, decorators: [{
711
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: BaseDisplayModalComponent, decorators: [{
651
712
  type: Component,
652
713
  args: [{ selector: 'lib-prompt-display-modal', standalone: true, imports: [], template: '' }]
653
714
  }] });
654
715
 
655
716
  class FormErrorDisplayComponent {
656
- control = input(undefined);
657
- label = input(undefined);
658
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: FormErrorDisplayComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
659
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.14", type: FormErrorDisplayComponent, isStandalone: true, selector: "sftech-form-error-display", inputs: { control: { classPropertyName: "control", publicName: "control", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "@if (control()?.errors) {\r\n <div class=\"p-1 text-xs text-red-500\">\r\n @if (control()?.errors?.['required']) {\r\n <div>{{ label() }} ist ein Pflichtfeld.</div>\r\n }\r\n </div>\r\n}\r\n", styles: [""] });
717
+ control = input(undefined, ...(ngDevMode ? [{ debugName: "control" }] : []));
718
+ label = input(undefined, ...(ngDevMode ? [{ debugName: "label" }] : []));
719
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: FormErrorDisplayComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
720
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.9", type: FormErrorDisplayComponent, isStandalone: true, selector: "sftech-form-error-display", inputs: { control: { classPropertyName: "control", publicName: "control", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "@if (control()?.errors) {\r\n <div class=\"p-1 text-xs text-red-500\">\r\n @if (control()?.errors?.['required']) {\r\n <div>{{ label() }} ist ein Pflichtfeld.</div>\r\n }\r\n </div>\r\n}\r\n", styles: [""] });
660
721
  }
661
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: FormErrorDisplayComponent, decorators: [{
722
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: FormErrorDisplayComponent, decorators: [{
662
723
  type: Component,
663
724
  args: [{ selector: 'sftech-form-error-display', standalone: true, imports: [], template: "@if (control()?.errors) {\r\n <div class=\"p-1 text-xs text-red-500\">\r\n @if (control()?.errors?.['required']) {\r\n <div>{{ label() }} ist ein Pflichtfeld.</div>\r\n }\r\n </div>\r\n}\r\n" }]
664
- }] });
725
+ }], propDecorators: { control: [{ type: i0.Input, args: [{ isSignal: true, alias: "control", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }] } });
665
726
 
666
727
  class PaginatorComponent {
667
728
  pagination;
@@ -707,16 +768,18 @@ class PaginatorComponent {
707
768
  // this.odataChanged.emit(this.pagination);
708
769
  // }
709
770
  onPageChange(event) {
710
- if (event.page !== undefined) {
711
- this.pagination.page = event.page + 1;
712
- }
713
- this.pagination.pageSize = event.rows ?? 10;
714
- this.odataChanged.emit(this.pagination);
715
- }
716
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: PaginatorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
717
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.14", type: PaginatorComponent, isStandalone: true, selector: "sftech-paginator", inputs: { pagination: "pagination" }, outputs: { odataChanged: "odataChanged" }, ngImport: i0, template: "<!--<nav aria-label=\"Table navigation\" class=\"flex items-center flex-wrap md:flex-row justify-between p-2 bg-gradient-to-b from-secondary_accent-500 to-secondary_accent-700\">-->\r\n<!-- <div-->\r\n<!-- class=\"font-normal text-white dark:text-gray-400 md:mb-0 block w-full md:inline md:w-auto\">Ergebnis-->\r\n<!-- <span class=\"font-semibold text-primary_accent-900 dark:text-white\">{{ ((pagination.page - 1) * pagination.pageSize) + 1 }} - {{ pagination.totalPages === pagination.page ? pagination.totalElements : pagination.pageSize * pagination.page}}</span>-->\r\n<!-- von-->\r\n<!-- <span class=\"font-semibold text-primary_accent-900 dark:text-white\">{{ pagination.totalElements }}</span></div>-->\r\n<!-- <ul class=\"inline-flex -space-x-px rtl:space-x-reverse text-sm h-8\">-->\r\n<!-- @for (pageNumber of pageNumbers(); track pageNumber) {-->\r\n<!-- <li>-->\r\n<!-- <a [class.rounded-s-lg]=\"pageNumber === 1\" [class.rounded-e-lg]=\"pageNumber === pagination.totalPages\"-->\r\n<!-- (click)=\"changePage(pageNumber)\"-->\r\n<!-- class=\"flex items-center justify-center px-3 h-8 leading-tight text-gray-500 bg-white border border-gray-300 hover:bg-gray-100 hover:text-gray-700 dark:bg-gray-800 dark:border-gray-700 dark:text-gray-400 dark:hover:bg-gray-700 dark:hover:text-white\">{{ pageNumber }}</a>-->\r\n<!-- </li>-->\r\n<!-- }-->\r\n<!-- </ul>-->\r\n<!--</nav>-->\r\n\r\n\r\n\r\n\r\n<div class=\"card flex justify-center\">\r\n <p-paginator (onPageChange)=\"onPageChange($event)\" [first]=\"pagination.page - 1 \" [rows]=\"pagination.pageSize\" [totalRecords]=\"pagination.totalElements\" [rowsPerPageOptions]=\"[10, 20, 30]\" />\r\n</div>", styles: [""], dependencies: [{ kind: "ngmodule", type: PaginatorModule }, { kind: "component", type: i1.Paginator, selector: "p-paginator", inputs: ["pageLinkSize", "style", "styleClass", "alwaysShow", "dropdownAppendTo", "templateLeft", "templateRight", "appendTo", "dropdownScrollHeight", "currentPageReportTemplate", "showCurrentPageReport", "showFirstLastIcon", "totalRecords", "rows", "rowsPerPageOptions", "showJumpToPageDropdown", "showJumpToPageInput", "jumpToPageItemTemplate", "showPageLinks", "locale", "dropdownItemTemplate", "first"], outputs: ["onPageChange"] }] });
771
+ // Create new instance instead of mutating
772
+ const newPagination = new ODataPagination();
773
+ newPagination.totalPages = this.pagination.totalPages;
774
+ newPagination.totalElements = this.pagination.totalElements;
775
+ newPagination.page = event.page !== undefined ? event.page + 1 : this.pagination.page;
776
+ newPagination.pageSize = event.rows ?? this.pagination.pageSize;
777
+ this.odataChanged.emit(newPagination);
778
+ }
779
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: PaginatorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
780
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.9", type: PaginatorComponent, isStandalone: true, selector: "sftech-paginator", inputs: { pagination: "pagination" }, outputs: { odataChanged: "odataChanged" }, ngImport: i0, template: "<!--<nav aria-label=\"Table navigation\" class=\"flex items-center flex-wrap md:flex-row justify-between p-2 bg-gradient-to-b from-secondary_accent-500 to-secondary_accent-700\">-->\r\n<!-- <div-->\r\n<!-- class=\"font-normal text-white dark:text-gray-400 md:mb-0 block w-full md:inline md:w-auto\">Ergebnis-->\r\n<!-- <span class=\"font-semibold text-primary_accent-900 dark:text-white\">{{ ((pagination.page - 1) * pagination.pageSize) + 1 }} - {{ pagination.totalPages === pagination.page ? pagination.totalElements : pagination.pageSize * pagination.page}}</span>-->\r\n<!-- von-->\r\n<!-- <span class=\"font-semibold text-primary_accent-900 dark:text-white\">{{ pagination.totalElements }}</span></div>-->\r\n<!-- <ul class=\"inline-flex -space-x-px rtl:space-x-reverse text-sm h-8\">-->\r\n<!-- @for (pageNumber of pageNumbers(); track pageNumber) {-->\r\n<!-- <li>-->\r\n<!-- <a [class.rounded-s-lg]=\"pageNumber === 1\" [class.rounded-e-lg]=\"pageNumber === pagination.totalPages\"-->\r\n<!-- (click)=\"changePage(pageNumber)\"-->\r\n<!-- class=\"flex items-center justify-center px-3 h-8 leading-tight text-gray-500 bg-white border border-gray-300 hover:bg-gray-100 hover:text-gray-700 dark:bg-gray-800 dark:border-gray-700 dark:text-gray-400 dark:hover:bg-gray-700 dark:hover:text-white\">{{ pageNumber }}</a>-->\r\n<!-- </li>-->\r\n<!-- }-->\r\n<!-- </ul>-->\r\n<!--</nav>-->\r\n\r\n\r\n\r\n\r\n<div class=\"card flex justify-center\">\r\n <p-paginator (onPageChange)=\"onPageChange($event)\" [first]=\"pagination.page - 1 \" [rows]=\"pagination.pageSize\" [totalRecords]=\"pagination.totalElements\" [rowsPerPageOptions]=\"[10, 20, 30]\" />\r\n</div>", styles: [""], dependencies: [{ kind: "ngmodule", type: PaginatorModule }, { kind: "component", type: i1.Paginator, selector: "p-paginator", inputs: ["pageLinkSize", "styleClass", "alwaysShow", "dropdownAppendTo", "templateLeft", "templateRight", "dropdownScrollHeight", "currentPageReportTemplate", "showCurrentPageReport", "showFirstLastIcon", "totalRecords", "rows", "rowsPerPageOptions", "showJumpToPageDropdown", "showJumpToPageInput", "jumpToPageItemTemplate", "showPageLinks", "locale", "dropdownItemTemplate", "first", "appendTo"], outputs: ["onPageChange"] }] });
718
781
  }
719
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: PaginatorComponent, decorators: [{
782
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: PaginatorComponent, decorators: [{
720
783
  type: Component,
721
784
  args: [{ selector: 'sftech-paginator', standalone: true, imports: [PaginatorModule], template: "<!--<nav aria-label=\"Table navigation\" class=\"flex items-center flex-wrap md:flex-row justify-between p-2 bg-gradient-to-b from-secondary_accent-500 to-secondary_accent-700\">-->\r\n<!-- <div-->\r\n<!-- class=\"font-normal text-white dark:text-gray-400 md:mb-0 block w-full md:inline md:w-auto\">Ergebnis-->\r\n<!-- <span class=\"font-semibold text-primary_accent-900 dark:text-white\">{{ ((pagination.page - 1) * pagination.pageSize) + 1 }} - {{ pagination.totalPages === pagination.page ? pagination.totalElements : pagination.pageSize * pagination.page}}</span>-->\r\n<!-- von-->\r\n<!-- <span class=\"font-semibold text-primary_accent-900 dark:text-white\">{{ pagination.totalElements }}</span></div>-->\r\n<!-- <ul class=\"inline-flex -space-x-px rtl:space-x-reverse text-sm h-8\">-->\r\n<!-- @for (pageNumber of pageNumbers(); track pageNumber) {-->\r\n<!-- <li>-->\r\n<!-- <a [class.rounded-s-lg]=\"pageNumber === 1\" [class.rounded-e-lg]=\"pageNumber === pagination.totalPages\"-->\r\n<!-- (click)=\"changePage(pageNumber)\"-->\r\n<!-- class=\"flex items-center justify-center px-3 h-8 leading-tight text-gray-500 bg-white border border-gray-300 hover:bg-gray-100 hover:text-gray-700 dark:bg-gray-800 dark:border-gray-700 dark:text-gray-400 dark:hover:bg-gray-700 dark:hover:text-white\">{{ pageNumber }}</a>-->\r\n<!-- </li>-->\r\n<!-- }-->\r\n<!-- </ul>-->\r\n<!--</nav>-->\r\n\r\n\r\n\r\n\r\n<div class=\"card flex justify-center\">\r\n <p-paginator (onPageChange)=\"onPageChange($event)\" [first]=\"pagination.page - 1 \" [rows]=\"pagination.pageSize\" [totalRecords]=\"pagination.totalElements\" [rowsPerPageOptions]=\"[10, 20, 30]\" />\r\n</div>" }]
722
785
  }], propDecorators: { pagination: [{
@@ -816,12 +879,12 @@ class BaseDbApiService {
816
879
  }
817
880
 
818
881
  class NotPermittedComponent {
819
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: NotPermittedComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
820
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.14", type: NotPermittedComponent, isStandalone: true, selector: "sftech-not-permitted", ngImport: i0, template: "<div class=\"min-h-screen flex flex-col items-center justify-center bg-gray-100\">\n <div class=\"bg-white shadow-md rounded-lg p-6 max-w-lg text-center border border-gray-200\">\n <h1 class=\"text-3xl font-semibold text-red-600 mb-4\">Zugriff verweigert</h1>\n <p class=\"text-lg text-gray-700 mb-6\">\n Du bist nicht berechtigt, auf diese Seite zuzugreifen.\n Bitte \u00FCberpr\u00FCfe deine Berechtigungen oder wende dich an den Administrator.\n </p>\n <a\n class=\"inline-block bg-blue-600 text-white font-medium px-6 py-2 rounded-md hover:bg-blue-700 transition\"\n href=\"/apps/frontend/public\"\n >\n Zur Startseite\n </a>\n </div>\n</div>\n", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }] });
882
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: NotPermittedComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
883
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.9", type: NotPermittedComponent, isStandalone: true, selector: "sftech-not-permitted", ngImport: i0, template: "<div class=\"min-h-screen flex flex-col items-center justify-center bg-gray-100\">\n <div class=\"bg-white shadow-md rounded-lg p-6 max-w-lg text-center border border-gray-200\">\n <h1 class=\"text-3xl font-semibold text-red-600 mb-4\">Zugriff verweigert</h1>\n <p class=\"text-lg text-gray-700 mb-6\">\n Du bist nicht berechtigt, auf diese Seite zuzugreifen.\n Bitte \u00FCberpr\u00FCfe deine Berechtigungen oder wende dich an den Administrator.\n </p>\n <a\n class=\"inline-block bg-blue-600 text-white font-medium px-6 py-2 rounded-md hover:bg-blue-700 transition\"\n href=\"/apps/frontend/public\"\n >\n Zur Startseite\n </a>\n </div>\n</div>\n", styles: [""] });
821
884
  }
822
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: NotPermittedComponent, decorators: [{
885
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: NotPermittedComponent, decorators: [{
823
886
  type: Component,
824
- args: [{ selector: 'sftech-not-permitted', imports: [CommonModule], template: "<div class=\"min-h-screen flex flex-col items-center justify-center bg-gray-100\">\n <div class=\"bg-white shadow-md rounded-lg p-6 max-w-lg text-center border border-gray-200\">\n <h1 class=\"text-3xl font-semibold text-red-600 mb-4\">Zugriff verweigert</h1>\n <p class=\"text-lg text-gray-700 mb-6\">\n Du bist nicht berechtigt, auf diese Seite zuzugreifen.\n Bitte \u00FCberpr\u00FCfe deine Berechtigungen oder wende dich an den Administrator.\n </p>\n <a\n class=\"inline-block bg-blue-600 text-white font-medium px-6 py-2 rounded-md hover:bg-blue-700 transition\"\n href=\"/apps/frontend/public\"\n >\n Zur Startseite\n </a>\n </div>\n</div>\n" }]
887
+ args: [{ selector: 'sftech-not-permitted', imports: [], template: "<div class=\"min-h-screen flex flex-col items-center justify-center bg-gray-100\">\n <div class=\"bg-white shadow-md rounded-lg p-6 max-w-lg text-center border border-gray-200\">\n <h1 class=\"text-3xl font-semibold text-red-600 mb-4\">Zugriff verweigert</h1>\n <p class=\"text-lg text-gray-700 mb-6\">\n Du bist nicht berechtigt, auf diese Seite zuzugreifen.\n Bitte \u00FCberpr\u00FCfe deine Berechtigungen oder wende dich an den Administrator.\n </p>\n <a\n class=\"inline-block bg-blue-600 text-white font-medium px-6 py-2 rounded-md hover:bg-blue-700 transition\"\n href=\"/apps/frontend/public\"\n >\n Zur Startseite\n </a>\n </div>\n</div>\n" }]
825
888
  }] });
826
889
 
827
890
  /**