@sftech/ng-shared 0.0.1 → 0.0.2

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 (32) hide show
  1. package/fesm2022/sftech-ng-shared.mjs +663 -15
  2. package/fesm2022/sftech-ng-shared.mjs.map +1 -1
  3. package/index.d.ts +26 -4
  4. package/lib/components/pages/base-display/base-display-modal/base-display-modal.component.d.ts +7 -0
  5. package/lib/components/pages/base-display/base-display.component.d.ts +46 -0
  6. package/lib/components/pages/base-list.component.d.ts +30 -0
  7. package/lib/components/paginator/paginator.component.d.ts +11 -0
  8. package/lib/core/dtos/api-response.dto.d.ts +9 -0
  9. package/lib/core/dtos/base-db-create.dto.d.ts +2 -0
  10. package/lib/core/dtos/base-db-response.dto.d.ts +5 -0
  11. package/lib/core/dtos/base-db-update.dto.d.ts +2 -0
  12. package/lib/core/dtos/base-response.dto.d.ts +1 -0
  13. package/lib/core/dtos/odata-response.dto.d.ts +13 -0
  14. package/lib/core/models/base-db.model.d.ts +24 -0
  15. package/lib/core/models/mapped-api-response.model.d.ts +13 -0
  16. package/lib/core/models/mapped-odata-response.model.d.ts +12 -0
  17. package/lib/core/models/odata/filter/filter.enums.d.ts +16 -0
  18. package/lib/core/models/odata/odata-expands.model.d.ts +7 -0
  19. package/lib/core/models/odata/odata-filter-collection.model.d.ts +14 -0
  20. package/lib/core/models/odata/odata-filter.model.d.ts +13 -0
  21. package/lib/core/models/odata/odata-order.model.d.ts +10 -0
  22. package/lib/core/models/odata/odata-pagination.model.d.ts +10 -0
  23. package/lib/core/models/odata/odata.interface.d.ts +3 -0
  24. package/lib/core/models/odata/odata.model.d.ts +12 -0
  25. package/lib/core/services/base-db-api.service.d.ts +27 -0
  26. package/lib/providers/icon.provider.d.ts +2 -0
  27. package/lib/ui/layouts/base-dialog/base-dialog.component.d.ts +18 -0
  28. package/lib/{layouts → ui/layouts}/head-main-footer-with-canvas/head-main-footer-with-canvas.component.d.ts +1 -2
  29. package/package.json +1 -1
  30. /package/lib/{configuration → core/configuration}/app-config.interface.d.ts +0 -0
  31. /package/lib/{configuration → core/configuration}/app-config.loader.d.ts +0 -0
  32. /package/lib/{styles → ui/styles}/themes/sftech.preset.d.ts +0 -0
@@ -1,12 +1,19 @@
1
1
  import { definePreset } from '@primeng/themes';
2
2
  import Aura from '@primeng/themes/aura';
3
- import * as i0 from '@angular/core';
4
- import { ViewChild, ContentChild, Input, Component } from '@angular/core';
5
3
  import { NgTemplateOutlet } from '@angular/common';
4
+ import * as i0 from '@angular/core';
5
+ import { ViewChild, ContentChild, Input, Component, input, EventEmitter, Output, model, signal, inject, effect } from '@angular/core';
6
+ import { FaIconComponent } from '@fortawesome/angular-fontawesome';
6
7
  import { Button } from 'primeng/button';
7
8
  import { Drawer } from 'primeng/drawer';
8
- import { FaIconComponent } from '@fortawesome/angular-fontawesome';
9
- import { faBars } from '@fortawesome/free-solid-svg-icons';
9
+ import { Toast } from 'primeng/toast';
10
+ import { faClose, faTrash, faBars } from '@fortawesome/free-solid-svg-icons';
11
+ import { Router, ActivatedRoute } from '@angular/router';
12
+ import { DialogService, DynamicDialogRef } from 'primeng/dynamicdialog';
13
+ import { MessageService } from 'primeng/api';
14
+ import { switchMap, map, of, catchError } from 'rxjs';
15
+ import * as i1 from 'primeng/paginator';
16
+ import { PaginatorModule } from 'primeng/paginator';
10
17
 
11
18
  const SfTechPreset = definePreset(Aura, {
12
19
  semantic: {
@@ -25,7 +32,10 @@ const SfTechPreset = definePreset(Aura, {
25
32
  }
26
33
  });
27
34
 
35
+ // biome-ignore lint/complexity/noStaticOnlyClass: <explanation>
28
36
  class IconProvider {
37
+ static close = faClose;
38
+ static delete = faTrash;
29
39
  static menu = faBars;
30
40
  }
31
41
 
@@ -39,20 +49,12 @@ class HeadMainFooterWithCanvasComponent {
39
49
  drawerRef;
40
50
  drawerVisible = false;
41
51
  iconProvider = IconProvider;
42
- closeCallback(e) {
43
- this.drawerRef.close(e);
44
- }
45
52
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.9", ngImport: i0, type: HeadMainFooterWithCanvasComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
46
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.9", type: HeadMainFooterWithCanvasComponent, isStandalone: true, selector: "sftech-head-main-footer-with-canvas", inputs: { title: "title", maxWidth: "maxWidth" }, 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 }, { propertyName: "drawers", first: true, predicate: ["drawers"], descendants: true }], viewQueries: [{ propertyName: "drawerRef", first: true, predicate: ["drawerRef"], descendants: true }], ngImport: i0, template: "<div class=\"min-h-screen flex flex-col justify-between\">\r\n <header class=\"p-2 bg-primary-600\">\r\n <div [style.max-width]=\"maxWidth\" class=\"mx-auto\">\r\n @if (drawers) {\r\n <div class=\"flex items-center\">\r\n <div class=\"flex-shrink\">\r\n <p-button (click)=\"drawerVisible = !drawerVisible\"><fa-icon [icon]=\"iconProvider.menu\"></fa-icon></p-button>\r\n </div>\r\n <div class=\"ms-2\">\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=\"p-2 h-full flex-grow\">\r\n <div [style.max-width]=\"maxWidth\" class=\"mx-auto\">\r\n <ng-container [ngTemplateOutlet]=\"main\"></ng-container>\r\n </div>\r\n </main>\r\n\r\n <footer class=\"p-2 bg-primary-600\">\r\n <div [style.max-width]=\"maxWidth\" class=\"mx-auto\">\r\n <ng-container [ngTemplateOutlet]=\"footer\"></ng-container>\r\n </div>\r\n </footer>\r\n</div>\r\n\r\n@if (drawers) {\r\n <p-drawer #drawerRef [(visible)]=\"drawerVisible\">\r\n <ng-template #headless>\r\n <ng-container *ngTemplateOutlet=\"drawers\"></ng-container>\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"] }] });
53
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.9", type: HeadMainFooterWithCanvasComponent, isStandalone: true, selector: "sftech-head-main-footer-with-canvas", inputs: { title: "title", maxWidth: "maxWidth" }, 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 }, { propertyName: "drawers", first: true, predicate: ["drawers"], descendants: true }], viewQueries: [{ propertyName: "drawerRef", first: true, predicate: ["drawerRef"], descendants: true }], ngImport: i0, template: "<div class=\"min-h-screen flex flex-col justify-between\">\r\n <p-toast />\r\n <header class=\"p-2 bg-primary-600\">\r\n <div [style.max-width]=\"maxWidth\" class=\"mx-auto\">\r\n @if (drawers) {\r\n <div class=\"flex items-center\">\r\n <div class=\"flex-shrink\">\r\n <p-button (click)=\"drawerVisible = !drawerVisible\"><fa-icon [icon]=\"iconProvider.menu\"></fa-icon></p-button>\r\n </div>\r\n <div class=\"ms-2\">\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=\"p-2 h-full flex-grow\">\r\n <div [style.max-width]=\"maxWidth\" class=\"mx-auto\">\r\n <ng-container [ngTemplateOutlet]=\"main\"></ng-container>\r\n </div>\r\n </main>\r\n\r\n <footer class=\"p-2 bg-primary-600\">\r\n <div [style.max-width]=\"maxWidth\" class=\"mx-auto\">\r\n <ng-container [ngTemplateOutlet]=\"footer\"></ng-container>\r\n </div>\r\n </footer>\r\n</div>\r\n\r\n@if (drawers) {\r\n <p-drawer #drawerRef [(visible)]=\"drawerVisible\">\r\n <ng-template #headless>\r\n <ng-container *ngTemplateOutlet=\"drawers\"></ng-container>\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"] }] });
47
54
  }
48
55
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.9", ngImport: i0, type: HeadMainFooterWithCanvasComponent, decorators: [{
49
56
  type: Component,
50
- args: [{ selector: 'sftech-head-main-footer-with-canvas', imports: [
51
- NgTemplateOutlet,
52
- Button,
53
- Drawer,
54
- FaIconComponent
55
- ], template: "<div class=\"min-h-screen flex flex-col justify-between\">\r\n <header class=\"p-2 bg-primary-600\">\r\n <div [style.max-width]=\"maxWidth\" class=\"mx-auto\">\r\n @if (drawers) {\r\n <div class=\"flex items-center\">\r\n <div class=\"flex-shrink\">\r\n <p-button (click)=\"drawerVisible = !drawerVisible\"><fa-icon [icon]=\"iconProvider.menu\"></fa-icon></p-button>\r\n </div>\r\n <div class=\"ms-2\">\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=\"p-2 h-full flex-grow\">\r\n <div [style.max-width]=\"maxWidth\" class=\"mx-auto\">\r\n <ng-container [ngTemplateOutlet]=\"main\"></ng-container>\r\n </div>\r\n </main>\r\n\r\n <footer class=\"p-2 bg-primary-600\">\r\n <div [style.max-width]=\"maxWidth\" class=\"mx-auto\">\r\n <ng-container [ngTemplateOutlet]=\"footer\"></ng-container>\r\n </div>\r\n </footer>\r\n</div>\r\n\r\n@if (drawers) {\r\n <p-drawer #drawerRef [(visible)]=\"drawerVisible\">\r\n <ng-template #headless>\r\n <ng-container *ngTemplateOutlet=\"drawers\"></ng-container>\r\n </ng-template>\r\n </p-drawer>\r\n}" }]
57
+ args: [{ selector: 'sftech-head-main-footer-with-canvas', imports: [NgTemplateOutlet, Button, Drawer, FaIconComponent, Toast], template: "<div class=\"min-h-screen flex flex-col justify-between\">\r\n <p-toast />\r\n <header class=\"p-2 bg-primary-600\">\r\n <div [style.max-width]=\"maxWidth\" class=\"mx-auto\">\r\n @if (drawers) {\r\n <div class=\"flex items-center\">\r\n <div class=\"flex-shrink\">\r\n <p-button (click)=\"drawerVisible = !drawerVisible\"><fa-icon [icon]=\"iconProvider.menu\"></fa-icon></p-button>\r\n </div>\r\n <div class=\"ms-2\">\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=\"p-2 h-full flex-grow\">\r\n <div [style.max-width]=\"maxWidth\" class=\"mx-auto\">\r\n <ng-container [ngTemplateOutlet]=\"main\"></ng-container>\r\n </div>\r\n </main>\r\n\r\n <footer class=\"p-2 bg-primary-600\">\r\n <div [style.max-width]=\"maxWidth\" class=\"mx-auto\">\r\n <ng-container [ngTemplateOutlet]=\"footer\"></ng-container>\r\n </div>\r\n </footer>\r\n</div>\r\n\r\n@if (drawers) {\r\n <p-drawer #drawerRef [(visible)]=\"drawerVisible\">\r\n <ng-template #headless>\r\n <ng-container *ngTemplateOutlet=\"drawers\"></ng-container>\r\n </ng-template>\r\n </p-drawer>\r\n}" }]
56
58
  }], propDecorators: { title: [{
57
59
  type: Input
58
60
  }], maxWidth: [{
@@ -74,6 +76,39 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.9", ngImpor
74
76
  args: ['drawerRef']
75
77
  }] } });
76
78
 
79
+ class BaseDialogComponent {
80
+ hasHeader = input(true);
81
+ hasFooter = input(true);
82
+ showButtons = input(true);
83
+ headerText = input(undefined);
84
+ closed = new EventEmitter();
85
+ header = null;
86
+ body = null;
87
+ footer = null;
88
+ iconProvider = IconProvider;
89
+ constructor() { }
90
+ close() {
91
+ this.closed.emit();
92
+ }
93
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.9", ngImport: i0, type: BaseDialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
94
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.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@if (hasHeader()) {\r\n <div id=\"dialog-header\" class=\"flex justify-between mb-5\">\r\n <div class=\"header-content\">\r\n @if (headerText()) {\r\n <h1>{{ headerText() }}</h1>\r\n } @else {\r\n <ng-container [ngTemplateOutlet]=\"header\"></ng-container>\r\n }\r\n </div>\r\n <div class=\"header-actions\">\r\n <p-button (onClick)=\"close()\">\r\n <fa-icon [icon]=\"iconProvider.close\"></fa-icon>\r\n </p-button>\r\n </div>\r\n </div>\r\n}\r\n<div id=\"dialog-body\">\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}", styles: [""], dependencies: [{ 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: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: FaIconComponent, selector: "fa-icon", inputs: ["icon", "title", "animation", "mask", "flip", "size", "pull", "border", "inverse", "symbol", "rotate", "fixedWidth", "transform", "a11yRole"] }] });
95
+ }
96
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.9", ngImport: i0, type: BaseDialogComponent, decorators: [{
97
+ type: Component,
98
+ args: [{ selector: 'sftech-base-dialog', imports: [Button, NgTemplateOutlet, FaIconComponent], 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@if (hasHeader()) {\r\n <div id=\"dialog-header\" class=\"flex justify-between mb-5\">\r\n <div class=\"header-content\">\r\n @if (headerText()) {\r\n <h1>{{ headerText() }}</h1>\r\n } @else {\r\n <ng-container [ngTemplateOutlet]=\"header\"></ng-container>\r\n }\r\n </div>\r\n <div class=\"header-actions\">\r\n <p-button (onClick)=\"close()\">\r\n <fa-icon [icon]=\"iconProvider.close\"></fa-icon>\r\n </p-button>\r\n </div>\r\n </div>\r\n}\r\n<div id=\"dialog-body\">\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}" }]
99
+ }], ctorParameters: () => [], propDecorators: { closed: [{
100
+ type: Output
101
+ }], header: [{
102
+ type: ContentChild,
103
+ args: ['header']
104
+ }], body: [{
105
+ type: ContentChild,
106
+ args: ['body']
107
+ }], footer: [{
108
+ type: ContentChild,
109
+ args: ['footer']
110
+ }] } });
111
+
77
112
  async function loadConfig(configPath) {
78
113
  return fetch(configPath)
79
114
  .then((res) => {
@@ -83,9 +118,622 @@ async function loadConfig(configPath) {
83
118
  });
84
119
  }
85
120
 
121
+ class BaseDbModel {
122
+ id;
123
+ createdAt;
124
+ propertiesToShow = [];
125
+ propertyFilterType = new Map();
126
+ propertyUINames = new Map();
127
+ getUiNameForProperty(propertyName) {
128
+ return this.propertyUINames.get(propertyName) || propertyName;
129
+ }
130
+ getFilterTypeForProperty(propertyName) {
131
+ return this.propertyFilterType.get(propertyName);
132
+ }
133
+ getPropertyValue(propertyName) {
134
+ return this[propertyName];
135
+ }
136
+ static fromDto(dto) {
137
+ const model = new this();
138
+ return model.fromDto(dto);
139
+ }
140
+ static fromDtos(dtos) {
141
+ return dtos.map((dto) => this.fromDto(dto));
142
+ }
143
+ fromDto(dto) {
144
+ this.id = dto.id;
145
+ this.createdAt = dto.createdAt;
146
+ return this;
147
+ }
148
+ fromDtos(dtos) {
149
+ return dtos.map((dto) => this.fromDto(dto));
150
+ }
151
+ }
152
+
153
+ class OdataExpands {
154
+ expands = [];
155
+ constructor(expands = []) {
156
+ this.expands = expands;
157
+ }
158
+ addField(field) {
159
+ this.expands.push(field);
160
+ }
161
+ toGetParameter() {
162
+ return this.expands.length > 0 ? `$expand=${this.expands.join(',')}` : '';
163
+ }
164
+ }
165
+
166
+ var FilterConcatenation;
167
+ (function (FilterConcatenation) {
168
+ FilterConcatenation["OR"] = " or ";
169
+ FilterConcatenation["AND"] = " and ";
170
+ })(FilterConcatenation || (FilterConcatenation = {}));
171
+ class OdataFilterCollection {
172
+ andFilters = [];
173
+ // public orFilters: OdataFilter[] = [];
174
+ toGetParameter() {
175
+ let odataString = '$filter=';
176
+ const filters = this.andFilters.filter((x) => this._isFilterValid(x));
177
+ if (filters.length === 0) {
178
+ return '';
179
+ }
180
+ odataString += filters.map((x) => x.toGetParameter()).join(FilterConcatenation.AND);
181
+ return odataString;
182
+ }
183
+ addAnd(andFilter) {
184
+ this.andFilters.push(andFilter);
185
+ }
186
+ remove(field) {
187
+ const idx = this.andFilters.findIndex((f) => f.field === field);
188
+ if (idx >= 0) {
189
+ this.andFilters.splice(idx, 1);
190
+ }
191
+ }
192
+ hasValidFilters() {
193
+ return this.andFilters.filter((f) => this._isFilterValid(f)).length > 0;
194
+ }
195
+ _isFilterValid(filter) {
196
+ return !(!filter.type || !filter.field || !filter.operator);
197
+ }
198
+ }
199
+
200
+ var ESortDirection;
201
+ (function (ESortDirection) {
202
+ ESortDirection["ASC"] = "asc";
203
+ ESortDirection["DESC"] = "desc";
204
+ })(ESortDirection || (ESortDirection = {}));
205
+ class ODataOrder {
206
+ column = 'id';
207
+ direction = ESortDirection.ASC;
208
+ toGetParameter() {
209
+ return `$orderby=${this.column} ${this.direction}`;
210
+ }
211
+ }
212
+
213
+ class ODataPagination {
214
+ pageSize = 20;
215
+ totalPages = 0;
216
+ totalElements = 0;
217
+ page = 1;
218
+ static fromDto(dto) {
219
+ const obj = new ODataPagination();
220
+ obj.pageSize = dto.pageSize;
221
+ obj.totalPages = dto.totalPages;
222
+ obj.totalElements = dto.totalElements;
223
+ obj.page = dto.page;
224
+ return obj;
225
+ }
226
+ toGetParameter() {
227
+ let odataString = `$top=${this.pageSize}`;
228
+ odataString += `&$skip=${(this.page - 1) * this.pageSize}`;
229
+ return odataString;
230
+ }
231
+ }
232
+
233
+ class OData {
234
+ pagination = new ODataPagination();
235
+ filter = new OdataFilterCollection();
236
+ expands = new OdataExpands();
237
+ order = new ODataOrder();
238
+ toGetParameter() {
239
+ let odataString = `odata?${this.pagination.toGetParameter()}`;
240
+ if (this.filter.hasValidFilters()) {
241
+ odataString += `&${this.filter.toGetParameter()}`;
242
+ }
243
+ if (this.order) {
244
+ odataString += `&${this.order.toGetParameter()}`;
245
+ }
246
+ if (this.expands) {
247
+ odataString += `&${this.expands.toGetParameter()}`;
248
+ }
249
+ return odataString;
250
+ }
251
+ }
252
+
253
+ var EFilterTypes;
254
+ (function (EFilterTypes) {
255
+ EFilterTypes["NUMERIC"] = "numeric";
256
+ EFilterTypes["STRING"] = "string";
257
+ EFilterTypes["DATE"] = "date";
258
+ EFilterTypes["TIME"] = "time";
259
+ EFilterTypes["PACE"] = "pace";
260
+ })(EFilterTypes || (EFilterTypes = {}));
261
+ var EFilterOperator;
262
+ (function (EFilterOperator) {
263
+ EFilterOperator["EQUALS"] = "=";
264
+ EFilterOperator["GREATER"] = ">";
265
+ EFilterOperator["LESS"] = "<";
266
+ EFilterOperator["GREATEREQUALS"] = ">=";
267
+ EFilterOperator["LESSEQUALS"] = "<=";
268
+ EFilterOperator["BETWEEN"] = "zwischen";
269
+ EFilterOperator["CONTAINS"] = "enth\u00E4lt";
270
+ })(EFilterOperator || (EFilterOperator = {}));
271
+
272
+ class OdataFilter {
273
+ field;
274
+ value;
275
+ operator;
276
+ type;
277
+ constructor(field, value, operator, type) {
278
+ this.field = field;
279
+ this.value = value;
280
+ this.operator = operator;
281
+ this.type = type;
282
+ }
283
+ toGetParameter() {
284
+ if (!this.field || !this.operator || !this.type || !this.value) {
285
+ return '';
286
+ }
287
+ switch (this.operator) {
288
+ case EFilterOperator.CONTAINS:
289
+ return `contains(${this.field},'${this.value}')`;
290
+ default:
291
+ return `${this.field} ${this._getODataOperator()} ${this._getTypeDependentValue()}`;
292
+ }
293
+ }
294
+ static availableOperators(type) {
295
+ switch (type) {
296
+ case EFilterTypes.NUMERIC:
297
+ return [EFilterOperator.GREATER, EFilterOperator.GREATEREQUALS, EFilterOperator.BETWEEN, EFilterOperator.LESS, EFilterOperator.LESSEQUALS, EFilterOperator.EQUALS];
298
+ case EFilterTypes.STRING:
299
+ return [EFilterOperator.CONTAINS];
300
+ case EFilterTypes.DATE:
301
+ return [EFilterOperator.GREATER, EFilterOperator.GREATEREQUALS, EFilterOperator.BETWEEN, EFilterOperator.LESS, EFilterOperator.LESSEQUALS, EFilterOperator.EQUALS];
302
+ case EFilterTypes.TIME:
303
+ case EFilterTypes.PACE:
304
+ return [EFilterOperator.GREATER, EFilterOperator.GREATEREQUALS, EFilterOperator.BETWEEN, EFilterOperator.LESS, EFilterOperator.LESSEQUALS, EFilterOperator.EQUALS];
305
+ default:
306
+ return [EFilterOperator.GREATER, EFilterOperator.GREATEREQUALS, EFilterOperator.BETWEEN, EFilterOperator.LESS, EFilterOperator.LESSEQUALS, EFilterOperator.EQUALS];
307
+ }
308
+ }
309
+ _getTypeDependentValue() {
310
+ if (this.type === EFilterTypes.STRING) {
311
+ return `'${this.value}'`;
312
+ }
313
+ if (this.type === EFilterTypes.TIME) {
314
+ if (!this.value.includes(':')) {
315
+ console.warn(this.value, 'not a valid time');
316
+ return 0;
317
+ }
318
+ const minutesSeconds = this.value.split(':');
319
+ return parseInt(minutesSeconds[0], 10) * 60 + parseInt(minutesSeconds[1], 10);
320
+ }
321
+ return this.value;
322
+ }
323
+ _getODataOperator() {
324
+ switch (this.operator) {
325
+ case EFilterOperator.EQUALS:
326
+ return 'eq';
327
+ case EFilterOperator.LESS:
328
+ return 'lt';
329
+ case EFilterOperator.LESSEQUALS:
330
+ return 'le';
331
+ case EFilterOperator.GREATER:
332
+ return 'gt';
333
+ case EFilterOperator.GREATEREQUALS:
334
+ return 'ge';
335
+ case EFilterOperator.BETWEEN:
336
+ return 'between';
337
+ case EFilterOperator.CONTAINS:
338
+ return 'contains';
339
+ default:
340
+ return 'eq';
341
+ }
342
+ }
343
+ }
344
+
345
+ class MappedApiResponse {
346
+ status;
347
+ data;
348
+ messages = [];
349
+ isError = false;
350
+ }
351
+ class MappedApiError {
352
+ status;
353
+ data;
354
+ messages = [];
355
+ isError = true;
356
+ }
357
+
358
+ class BaseListComponent {
359
+ odata = model(new OData());
360
+ showPageTitle = input(true);
361
+ canEdit = input(true);
362
+ openDisplayAsModal = input(true);
363
+ data = signal(undefined);
364
+ router = inject(Router);
365
+ modalService = inject(DialogService);
366
+ constructor() { }
367
+ ngOnInit() {
368
+ this._loadData();
369
+ }
370
+ updatePagination($event) {
371
+ this.odata.update((odata) => {
372
+ const odataNew = new OData();
373
+ odataNew.pagination = $event;
374
+ odataNew.filter = odata.filter;
375
+ odataNew.order = odata.order;
376
+ odataNew.expands = odata.expands;
377
+ return odataNew;
378
+ });
379
+ this._loadData();
380
+ }
381
+ openDisplay(id) {
382
+ if (id === undefined) {
383
+ return;
384
+ }
385
+ if (this.openDisplayAsModal()) {
386
+ const modalRef = this.modalService.open(this._modalComponent, { inputValues: { id, canEdit: this.canEdit(), openedAsModal: true }, focusOnShow: false, modal: true, dismissableMask: true, width: '70%', contentStyle: { overflow: 'auto' } });
387
+ modalRef.onClose.subscribe((result) => {
388
+ if (result) {
389
+ this.data.update((data) => {
390
+ const index = data?.findIndex((item) => item.id === result.id);
391
+ if (index !== undefined && index >= 0) {
392
+ data[index] = result.data;
393
+ }
394
+ return data;
395
+ });
396
+ }
397
+ });
398
+ return;
399
+ }
400
+ this.router.navigate([this._route, id]);
401
+ }
402
+ _loadData() {
403
+ this._repo.odata(this.odata()).subscribe((response) => {
404
+ if (response instanceof MappedApiError) {
405
+ console.error(response);
406
+ return;
407
+ }
408
+ this.data.set(response.data.items);
409
+ if (!response.data) {
410
+ return;
411
+ }
412
+ this.odata.update((odata) => {
413
+ const odataNew = new OData();
414
+ odataNew.pagination = response.data.pagination;
415
+ odataNew.filter = odata.filter;
416
+ odataNew.order = odata.order;
417
+ odataNew.expands = odata.expands;
418
+ return odataNew;
419
+ });
420
+ });
421
+ }
422
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.9", ngImport: i0, type: BaseListComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
423
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "19.2.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: [""] });
424
+ }
425
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.9", ngImport: i0, type: BaseListComponent, decorators: [{
426
+ type: Component,
427
+ args: [{ selector: 'sftech-pages-base-list', standalone: true, imports: [], template: '<div></div>' }]
428
+ }], ctorParameters: () => [] });
429
+
430
+ class BaseDisplayComponent {
431
+ id;
432
+ openedAsModal = false;
433
+ canEdit = true;
434
+ redirectAfterSave = false;
435
+ ref = inject(DynamicDialogRef);
436
+ form;
437
+ model = signal(this.getNewModel());
438
+ iconProvider = IconProvider;
439
+ router = inject(Router);
440
+ activatedRoute = inject(ActivatedRoute);
441
+ toastr = inject(MessageService);
442
+ constructor() {
443
+ effect(() => {
444
+ if (this.model()) {
445
+ this.form = this.initializeForm();
446
+ if (!this.canEdit) {
447
+ for (const control in this.form.controls) {
448
+ this.form.controls[control].disable();
449
+ }
450
+ }
451
+ }
452
+ });
453
+ }
454
+ ngOnInit() {
455
+ let obs;
456
+ if (this.id) {
457
+ obs = this._loadData(this.id);
458
+ }
459
+ else {
460
+ obs = this.activatedRoute.params.pipe(switchMap((params) => {
461
+ const id = parseInt(params['id']);
462
+ this.id = id;
463
+ return this._loadData(id);
464
+ }));
465
+ }
466
+ obs.subscribe((res) => {
467
+ if (res instanceof MappedApiError) {
468
+ this.toastr.add({ severity: 'error', detail: 'Beim Laden der Daten ist ein Fehler aufgetreten' });
469
+ throw new Error(res.messages ? res.messages.join(' | ') : 'Beim Laden der Daten ist ein Fehler aufgetreten');
470
+ }
471
+ this.model.set(res.data);
472
+ if (this.form) {
473
+ this.form.patchValue(this.model());
474
+ this.form.markAsUntouched();
475
+ }
476
+ });
477
+ }
478
+ async submitForm() {
479
+ let obs;
480
+ if (!this.form.valid) {
481
+ return;
482
+ }
483
+ if (this.model().id) {
484
+ const dto = this.mapFormToUpdateDto();
485
+ obs = this._repo.update(this.model().id, dto);
486
+ }
487
+ else {
488
+ const dto = this.mapFormToCreateDto();
489
+ obs = this._repo.insert(dto);
490
+ }
491
+ obs.subscribe((res) => {
492
+ if (res.isError) {
493
+ this.toastr.add({ severity: 'error', detail: 'Beim Speichern der Daten ist ein Fehler aufgetreten' });
494
+ throw new Error(res.messages ? res.messages.join(' | ') : 'Beim Speichern der Daten ist ein Fehler aufgetreten');
495
+ }
496
+ this.model.set(res.data);
497
+ this.toastr.add({ severity: 'success', detail: `Datensatz mit der Id '${this.model().id}' erfolgreich gespeichert` });
498
+ if (this.redirectAfterSave) {
499
+ this.goBack({ operation: this.model().id ? 'update' : 'create', id: this.model().id, data: res.data });
500
+ }
501
+ });
502
+ }
503
+ deleteData() {
504
+ if (!this.model().id) {
505
+ this.model.set(this.getNewModel());
506
+ this.form.patchValue(this.model);
507
+ return;
508
+ }
509
+ this._repo.delete(this.model().id).subscribe((res) => {
510
+ if (res.isError) {
511
+ this.toastr.add({ severity: 'error', detail: 'Beim Löschen der Daten ist ein Fehler aufgetreten' });
512
+ throw new Error(res.messages ? res.messages.join(' | ') : 'Beim Löschen der Daten ist ein Fehler aufgetreten');
513
+ }
514
+ this.toastr.add({ severity: 'success', detail: `Datensatz mit der Id '${this.model().id}' erfolgreich gelöscht` });
515
+ this.goBack({ operation: 'delete', id: this.model().id });
516
+ });
517
+ }
518
+ getFormControl(property) {
519
+ return this.form.get(property);
520
+ }
521
+ goBack(retVal = { operation: 'aborted' }) {
522
+ if (this.openedAsModal) {
523
+ this.close(retVal);
524
+ return;
525
+ }
526
+ this.router.navigate([this._route]);
527
+ }
528
+ _loadData(id) {
529
+ if (id) {
530
+ return this._repo.get(id, true).pipe(map((res) => {
531
+ if (res instanceof MappedApiError) {
532
+ this.toastr.add({ severity: 'error', detail: 'Beim Laden der Daten ist ein Fehler aufgetreten' });
533
+ throw new Error(res.messages ? res.messages.join(' | ') : 'Beim Laden der Daten ist ein Fehler aufgetreten');
534
+ }
535
+ return res;
536
+ }));
537
+ }
538
+ const mappedApiResponse = new MappedApiResponse();
539
+ mappedApiResponse.data = this.model();
540
+ return of(mappedApiResponse);
541
+ }
542
+ close(retVal = { operation: 'aborted' }) {
543
+ this.ref.close(retVal);
544
+ }
545
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.9", ngImport: i0, type: BaseDisplayComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
546
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.9", type: BaseDisplayComponent, isStandalone: true, selector: "lib-core-base-display", inputs: { id: "id", openedAsModal: "openedAsModal", canEdit: "canEdit" }, ngImport: i0, template: '<div></div>', isInline: true, styles: [""] });
547
+ }
548
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.9", ngImport: i0, type: BaseDisplayComponent, decorators: [{
549
+ type: Component,
550
+ args: [{ selector: 'lib-core-base-display', standalone: true, imports: [], template: '<div></div>' }]
551
+ }], ctorParameters: () => [], propDecorators: { id: [{
552
+ type: Input
553
+ }], openedAsModal: [{
554
+ type: Input
555
+ }], canEdit: [{
556
+ type: Input
557
+ }] } });
558
+
559
+ class BaseDisplayModalComponent {
560
+ id;
561
+ canEdit = true;
562
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.9", ngImport: i0, type: BaseDisplayModalComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
563
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.9", type: BaseDisplayModalComponent, isStandalone: true, selector: "lib-prompt-display-modal", ngImport: i0, template: '', isInline: true, styles: [""] });
564
+ }
565
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.9", ngImport: i0, type: BaseDisplayModalComponent, decorators: [{
566
+ type: Component,
567
+ args: [{ selector: 'lib-prompt-display-modal', standalone: true, imports: [], template: '' }]
568
+ }] });
569
+
570
+ class PaginatorComponent {
571
+ pagination;
572
+ odataChanged = new EventEmitter();
573
+ // public amountOfPageNumbersToShow = 5;
574
+ // public pageNumbers = computed(() => {
575
+ // const currentPage = this.pagination!.page;
576
+ // const totalPages = this.pagination!.totalPages;
577
+ //
578
+ // if (totalPages <= this.amountOfPageNumbersToShow) {
579
+ // // Wenn die Gesamtseiten kleiner als oder gleich der sichtbaren Seiten sind
580
+ // return Array.from({ length: totalPages }, (_, i) => i + 1);
581
+ // }
582
+ //
583
+ // const pagination: number[] = []; // Immer mit 1 starten
584
+ //
585
+ // // Bereich in der Mitte berechnen
586
+ // const middleCount = this.amountOfPageNumbersToShow - 2; // Plätze für Mitte (ohne 1 und x)
587
+ // const half = Math.floor(middleCount / 2);
588
+ //
589
+ // let start = Math.max(2, currentPage - half); // Startpunkt der Mitte
590
+ // let end = Math.min(totalPages - 1, currentPage + half); // Endpunkt der Mitte
591
+ //
592
+ // // Anpassen, falls die Mitte den Anfang oder das Ende überschreitet
593
+ // if (end - start < middleCount - 1) {
594
+ // if (start === 2) {
595
+ // end = start + middleCount - 1;
596
+ // } else if (end === totalPages - 1) {
597
+ // start = end - middleCount + 1;
598
+ // }
599
+ // }
600
+ //
601
+ // // Mittlere Zahlen hinzufügen
602
+ // for (let i = start; i <= end; i++) {
603
+ // pagination.push(i);
604
+ // }
605
+ //
606
+ // return pagination;
607
+ // });
608
+ //
609
+ // public changePage(pageNumber: number) {
610
+ // this.pagination.page = pageNumber;
611
+ // this.odataChanged.emit(this.pagination);
612
+ // }
613
+ onPageChange(event) {
614
+ if (event.page !== undefined) {
615
+ this.pagination.page = event.page + 1;
616
+ }
617
+ this.pagination.pageSize = event.rows ?? 10;
618
+ this.odataChanged.emit(this.pagination);
619
+ }
620
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.9", ngImport: i0, type: PaginatorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
621
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.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", "style", "styleClass", "alwaysShow", "dropdownAppendTo", "templateLeft", "templateRight", "appendTo", "dropdownScrollHeight", "currentPageReportTemplate", "showCurrentPageReport", "showFirstLastIcon", "totalRecords", "rows", "rowsPerPageOptions", "showJumpToPageDropdown", "showJumpToPageInput", "jumpToPageItemTemplate", "showPageLinks", "locale", "dropdownItemTemplate", "first"], outputs: ["onPageChange"] }] });
622
+ }
623
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.9", ngImport: i0, type: PaginatorComponent, decorators: [{
624
+ type: Component,
625
+ 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>" }]
626
+ }], propDecorators: { pagination: [{
627
+ type: Input
628
+ }], odataChanged: [{
629
+ type: Output
630
+ }] } });
631
+
632
+ class MappedOdataResponse {
633
+ status;
634
+ data = new MappedOdataResponseData();
635
+ messages = [];
636
+ isError;
637
+ }
638
+ class MappedOdataResponseData {
639
+ items;
640
+ pagination = new ODataPagination();
641
+ }
642
+
643
+ class BaseDbApiService {
644
+ http;
645
+ config;
646
+ url;
647
+ constructor(http, config) {
648
+ this.http = http;
649
+ this.config = config;
650
+ }
651
+ get(id, detailed = false) {
652
+ let url = `${this.url}/${id}`;
653
+ console.log(url);
654
+ if (detailed) {
655
+ url = `${url}/?detailed=${detailed}`;
656
+ }
657
+ return this.http.get(url).pipe(map((response) => this._responseMapping(response)), catchError((error) => {
658
+ return this._httpErrorToApiResponse(error);
659
+ }));
660
+ }
661
+ getAll() {
662
+ const odata = new OData();
663
+ return this.odata(odata);
664
+ }
665
+ odata(odataQuery) {
666
+ return this.http.get(`${this.url}/${odataQuery.toGetParameter()}`).pipe(map((response) => this._responseOdataMapping(response)), catchError((error) => {
667
+ return this._httpErrorToApiResponse(error);
668
+ }));
669
+ }
670
+ insert(dto) {
671
+ return this.http.post(this.url, dto).pipe(map((response) => this._responseMapping(response)), catchError((error) => {
672
+ return this._httpErrorToApiResponse(error);
673
+ }));
674
+ }
675
+ update(id, dto) {
676
+ return this.http.put(`${this.url}/${id}`, dto).pipe(map((response) => this._responseMapping(response)), catchError((error) => {
677
+ return this._httpErrorToApiResponse(error);
678
+ }));
679
+ }
680
+ delete(id) {
681
+ return this.http.delete(`${this.url}/${id}`).pipe(map((response) => {
682
+ const apiReponse = new MappedApiResponse();
683
+ apiReponse.status = response.status;
684
+ apiReponse.messages = response.messages ? response.messages : [];
685
+ apiReponse.isError = false;
686
+ return apiReponse;
687
+ }), catchError((error) => {
688
+ return this._httpErrorToApiResponse(error);
689
+ }));
690
+ }
691
+ _responseOdataMapping(response) {
692
+ const odataResponse = new MappedOdataResponse();
693
+ odataResponse.data.items = this.getNewModel().fromDtos(response.data?.items);
694
+ odataResponse.data.pagination = ODataPagination.fromDto(response.data.pagination);
695
+ return odataResponse;
696
+ }
697
+ _responseMapping(response) {
698
+ if (![200, 201, 202].includes(response.status)) {
699
+ return this._errorHandling(response.status, response.messages);
700
+ }
701
+ const apiResponse = new MappedApiResponse();
702
+ apiResponse.status = response.status;
703
+ apiResponse.messages = response.messages ? response.messages : [];
704
+ apiResponse.isError = false;
705
+ let mappedData;
706
+ if (Array.isArray(response.data)) {
707
+ mappedData = this.getNewModel().fromDtos(response.data);
708
+ }
709
+ else {
710
+ mappedData = this.getNewModel().fromDto(response.data);
711
+ }
712
+ apiResponse.data = mappedData;
713
+ return apiResponse;
714
+ }
715
+ _errorHandling(statusCode, messages) {
716
+ const apiResponse = new MappedApiError();
717
+ apiResponse.status = statusCode;
718
+ apiResponse.messages = messages ? messages : [];
719
+ apiResponse.isError = true;
720
+ return apiResponse;
721
+ }
722
+ _httpErrorToApiResponse(error) {
723
+ const messages = [];
724
+ if (error.message) {
725
+ messages.push(error.message);
726
+ }
727
+ if (error.error?.messages) {
728
+ messages.push(...error.error.messages);
729
+ }
730
+ return of(this._errorHandling(error.status, messages));
731
+ }
732
+ }
733
+
86
734
  /**
87
735
  * Generated bundle index. Do not edit.
88
736
  */
89
737
 
90
- export { HeadMainFooterWithCanvasComponent, SfTechPreset, loadConfig };
738
+ export { BaseDbApiService, BaseDbModel, BaseDialogComponent, BaseDisplayComponent, BaseDisplayModalComponent, BaseListComponent, EFilterOperator, EFilterTypes, ESortDirection, FilterConcatenation, HeadMainFooterWithCanvasComponent, IconProvider, OData, ODataOrder, ODataPagination, OdataExpands, OdataFilter, OdataFilterCollection, PaginatorComponent, SfTechPreset, loadConfig };
91
739
  //# sourceMappingURL=sftech-ng-shared.mjs.map