@flusys/ng-shared 5.1.3 → 5.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,64 +1,75 @@
1
1
  import * as i0 from '@angular/core';
2
- import { inject, PLATFORM_ID, Injectable, DOCUMENT, REQUEST, signal, computed, ElementRef, input, effect, Directive, TemplateRef, ViewContainerRef, output, Pipe, Injector, isDevMode, NgModule, resource, model, runInInjectionContext, untracked, forwardRef, InjectionToken, Component, DestroyRef, ApplicationRef, viewChild, afterNextRender, ViewEncapsulation } from '@angular/core';
3
- import { isPlatformServer, isPlatformBrowser, CommonModule, NgOptimizedImage, NgComponentOutlet, DatePipe, DOCUMENT as DOCUMENT$1 } from '@angular/common';
2
+ import { inject, PLATFORM_ID, Injectable, DOCUMENT, REQUEST, signal, computed, ElementRef, input, effect, Directive, TemplateRef, ViewContainerRef, output, Pipe, Injector, isDevMode, NgModule, resource, model, runInInjectionContext, untracked, forwardRef, contentChildren, Component, ViewEncapsulation, InjectionToken, DestroyRef, ApplicationRef, viewChild, afterNextRender } from '@angular/core';
3
+ import * as i1 from '@angular/common';
4
+ import { isPlatformServer, DOCUMENT as DOCUMENT$1, isPlatformBrowser, CommonModule, NgOptimizedImage, NgComponentOutlet, DatePipe } from '@angular/common';
4
5
  import { HttpClient, HttpContextToken, HttpHeaders, HttpParams } from '@angular/common/http';
5
6
  import { APP_CONFIG, getServiceUrl, LOCALIZATION_STATE_SERVICE, FALLBACK_MESSAGES_REGISTRY, LOCALIZATION_API_SERVICE } from '@flusys/ng-core';
6
- import { of, catchError as catchError$1, throwError, firstValueFrom, map as map$1, from } from 'rxjs';
7
+ import { of, catchError as catchError$1, throwError, firstValueFrom, map as map$1 } from 'rxjs';
7
8
  import { map, tap, catchError } from 'rxjs/operators';
8
- import * as i1$1 from '@angular/forms';
9
+ import * as i2 from '@angular/forms';
9
10
  import { NgControl, FormsModule, ReactiveFormsModule, NG_VALUE_ACCESSOR } from '@angular/forms';
10
- import * as i3 from 'primeng/api';
11
+ import * as i3$1 from 'primeng/api';
11
12
  import { MessageService, ConfirmationService } from 'primeng/api';
12
- import { RouterOutlet, RouterLink, RouterLinkActive, Router, ActivatedRoute } from '@angular/router';
13
+ import { RouterOutlet, RouterLink, RouterLinkActive, Router } from '@angular/router';
13
14
  import { AutoCompleteModule } from 'primeng/autocomplete';
14
15
  import { AvatarModule } from 'primeng/avatar';
15
- import * as i1 from 'primeng/button';
16
+ import * as i3 from 'primeng/button';
16
17
  import { ButtonModule } from 'primeng/button';
18
+ import * as i4 from 'primeng/card';
17
19
  import { CardModule } from 'primeng/card';
18
- import * as i1$2 from 'primeng/checkbox';
20
+ import * as i5$1 from 'primeng/checkbox';
19
21
  import { CheckboxModule } from 'primeng/checkbox';
20
22
  import { ConfirmDialogModule } from 'primeng/confirmdialog';
23
+ import * as i6$1 from 'primeng/datepicker';
21
24
  import { DatePickerModule } from 'primeng/datepicker';
22
- import * as i5 from 'primeng/dialog';
25
+ import * as i5$2 from 'primeng/dialog';
23
26
  import { DialogModule } from 'primeng/dialog';
24
27
  import { DividerModule } from 'primeng/divider';
25
28
  import { FileUploadModule } from 'primeng/fileupload';
26
- import * as i6 from 'primeng/iconfield';
29
+ import * as i5 from 'primeng/iconfield';
27
30
  import { IconFieldModule } from 'primeng/iconfield';
28
31
  import { ImageModule } from 'primeng/image';
29
- import * as i7 from 'primeng/inputicon';
32
+ import * as i6 from 'primeng/inputicon';
30
33
  import { InputIconModule } from 'primeng/inputicon';
34
+ import * as i7 from 'primeng/inputnumber';
31
35
  import { InputNumberModule } from 'primeng/inputnumber';
32
- import * as i2$1 from 'primeng/inputtext';
36
+ import * as i8 from 'primeng/inputtext';
33
37
  import { InputTextModule } from 'primeng/inputtext';
34
38
  import { ListboxModule } from 'primeng/listbox';
39
+ import * as i9$1 from 'primeng/multiselect';
35
40
  import { MultiSelectModule } from 'primeng/multiselect';
36
41
  import { PaginatorModule } from 'primeng/paginator';
37
42
  import { PanelModule } from 'primeng/panel';
43
+ import * as i10$1 from 'primeng/password';
38
44
  import { PasswordModule } from 'primeng/password';
39
45
  import { PopoverModule } from 'primeng/popover';
40
- import * as i2 from 'primeng/progressbar';
46
+ import * as i2$1 from 'primeng/progressbar';
41
47
  import { ProgressBarModule } from 'primeng/progressbar';
42
48
  import { RadioButtonModule } from 'primeng/radiobutton';
43
49
  import { RippleModule } from 'primeng/ripple';
44
- import * as i9 from 'primeng/select';
50
+ import * as i11 from 'primeng/select';
45
51
  import { SelectModule } from 'primeng/select';
46
52
  import { SelectButtonModule } from 'primeng/selectbutton';
47
53
  import { SkeletonModule } from 'primeng/skeleton';
48
54
  import { SplitButtonModule } from 'primeng/splitbutton';
49
55
  import { StepsModule } from 'primeng/steps';
56
+ import * as i8$1 from 'primeng/table';
50
57
  import { TableModule } from 'primeng/table';
51
58
  import { TabsModule } from 'primeng/tabs';
59
+ import * as i9 from 'primeng/tag';
52
60
  import { TagModule } from 'primeng/tag';
61
+ import * as i12 from 'primeng/textarea';
53
62
  import { TextareaModule } from 'primeng/textarea';
54
63
  import { ToastModule } from 'primeng/toast';
55
64
  import { ToggleButtonModule } from 'primeng/togglebutton';
65
+ import * as i13 from 'primeng/toggleswitch';
56
66
  import { ToggleSwitchModule } from 'primeng/toggleswitch';
67
+ import * as i10 from 'primeng/tooltip';
57
68
  import { TooltipModule } from 'primeng/tooltip';
58
69
  import { TreeTableModule } from 'primeng/treetable';
59
70
  import { ProgressSpinnerModule } from 'primeng/progressspinner';
60
71
  import { ColorPickerModule } from 'primeng/colorpicker';
61
- import { toSignal, takeUntilDestroyed } from '@angular/core/rxjs-interop';
72
+ import { DomSanitizer } from '@angular/platform-browser';
62
73
 
63
74
  const SHARED_MESSAGES = {
64
75
  // Backend shared auth key (used by exception filters)
@@ -97,15 +108,19 @@ const SHARED_MESSAGES = {
97
108
  'system.sdk.not.installed': 'Required SDK "{{sdk}}" not installed. Run: npm install {{sdk}}',
98
109
  'system.path.traversal.detected': 'Path traversal detected',
99
110
  'system.invalid.file.key': 'Invalid file key',
100
- // utils/base-list-page.ts
111
+ // shared feedback & confirmation keys (used across all list/form components)
101
112
  'shared.success': 'Success',
102
113
  'shared.error': 'Error',
103
114
  'shared.info': 'Info',
104
115
  'shared.warning': 'Warning',
105
116
  'shared.confirm.delete.header': 'Confirm Delete',
106
- // utils/base-form-page.ts
107
117
  'shared.validation.error': 'Validation Error',
108
118
  'shared.fill.required.fields': 'Please fill in all required fields',
119
+ // components/base-list/base-list.component.ts
120
+ 'shared.no.data': 'No data found',
121
+ 'shared.pagination.report': 'Showing {first} to {last} of {totalRecords} records',
122
+ // components/base-form/base-form.component.ts
123
+ 'shared.required': 'is required',
109
124
  // components/file-selector-dialog/file-selector-dialog.component.ts
110
125
  'shared.file.selector.provider.not.configured': 'File selection not configured.',
111
126
  'shared.file.selector.add.provider': 'Add',
@@ -755,6 +770,44 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
755
770
  args: [{ providedIn: 'root' }]
756
771
  }] });
757
772
 
773
+ class FaviconService {
774
+ http = inject(HttpClient);
775
+ platformService = inject(PlatformService);
776
+ document = inject(DOCUMENT$1);
777
+ svgTemplate = null;
778
+ apply() {
779
+ if (this.platformService.isServer)
780
+ return;
781
+ if (this.svgTemplate) {
782
+ this.render(this.svgTemplate);
783
+ return;
784
+ }
785
+ this.http
786
+ .get('/favicon.svg', { responseType: 'text' })
787
+ .subscribe((text) => {
788
+ this.svgTemplate = text;
789
+ this.render(text);
790
+ });
791
+ }
792
+ render(svgText) {
793
+ const style = getComputedStyle(this.document.documentElement);
794
+ const resolved = svgText.replace(/var\(\s*(--[^,)]+?)\s*(?:,\s*([^)]+?))?\s*\)/g, (_, varName, fallback = '') => {
795
+ const value = style.getPropertyValue(varName).trim();
796
+ return value || fallback;
797
+ });
798
+ const link = this.document.querySelector('link[rel="icon"]');
799
+ if (link) {
800
+ link.href = `data:image/svg+xml,${encodeURIComponent(resolved)}`;
801
+ }
802
+ }
803
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: FaviconService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
804
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: FaviconService, providedIn: 'root' });
805
+ }
806
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: FaviconService, decorators: [{
807
+ type: Injectable,
808
+ args: [{ providedIn: 'root' }]
809
+ }] });
810
+
758
811
  class EditModeElementChangerDirective {
759
812
  el = inject(ElementRef);
760
813
  ngControl = inject(NgControl, { optional: true });
@@ -1681,6 +1734,393 @@ function provideValueAccessor(component) {
1681
1734
  };
1682
1735
  }
1683
1736
 
1737
+ class BaseListTemplateDirective {
1738
+ key = input.required({ ...(ngDevMode ? { debugName: "key" } : {}), alias: 'baseListTemplate' });
1739
+ templateRef = inject((TemplateRef));
1740
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: BaseListTemplateDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
1741
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.1.5", type: BaseListTemplateDirective, isStandalone: true, selector: "ng-template[baseListTemplate]", inputs: { key: { classPropertyName: "key", publicName: "baseListTemplate", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0 });
1742
+ }
1743
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: BaseListTemplateDirective, decorators: [{
1744
+ type: Directive,
1745
+ args: [{ selector: 'ng-template[baseListTemplate]' }]
1746
+ }], propDecorators: { key: [{ type: i0.Input, args: [{ isSignal: true, alias: "baseListTemplate", required: true }] }] } });
1747
+
1748
+ class BaseListComponent {
1749
+ translateAdapter = inject(TranslateService, { optional: true });
1750
+ router = inject(Router, { optional: true });
1751
+ messageService = inject(MessageService, { optional: true });
1752
+ confirmationService = inject(ConfirmationService, { optional: true });
1753
+ columns = input.required(...(ngDevMode ? [{ debugName: "columns" }] : []));
1754
+ actions = input([], ...(ngDevMode ? [{ debugName: "actions" }] : []));
1755
+ title = input('', ...(ngDevMode ? [{ debugName: "title" }] : []));
1756
+ showCreateButton = input(true, ...(ngDevMode ? [{ debugName: "showCreateButton" }] : []));
1757
+ searchable = input(false, ...(ngDevMode ? [{ debugName: "searchable" }] : []));
1758
+ pageSize = input(10, ...(ngDevMode ? [{ debugName: "pageSize" }] : []));
1759
+ emptyMessage = input('', ...(ngDevMode ? [{ debugName: "emptyMessage" }] : []));
1760
+ createButtonLabel = input('', ...(ngDevMode ? [{ debugName: "createButtonLabel" }] : []));
1761
+ createButtonIcon = input('pi pi-plus', ...(ngDevMode ? [{ debugName: "createButtonIcon" }] : []));
1762
+ data = input([], ...(ngDevMode ? [{ debugName: "data" }] : []));
1763
+ total = input(0, ...(ngDevMode ? [{ debugName: "total" }] : []));
1764
+ isLoading = input(false, ...(ngDevMode ? [{ debugName: "isLoading" }] : []));
1765
+ service = input(null, ...(ngDevMode ? [{ debugName: "service" }] : []));
1766
+ filter = input({}, ...(ngDevMode ? [{ debugName: "filter" }] : []));
1767
+ createRoute = input(null, ...(ngDevMode ? [{ debugName: "createRoute" }] : []));
1768
+ editRoute = input(null, ...(ngDevMode ? [{ debugName: "editRoute" }] : []));
1769
+ deleteConfirmField = input(null, ...(ngDevMode ? [{ debugName: "deleteConfirmField" }] : []));
1770
+ idField = input('id', ...(ngDevMode ? [{ debugName: "idField" }] : []));
1771
+ canEdit = input(null, ...(ngDevMode ? [{ debugName: "canEdit" }] : []));
1772
+ canDelete = input(null, ...(ngDevMode ? [{ debugName: "canDelete" }] : []));
1773
+ onCreate = output();
1774
+ onLazyLoad = output();
1775
+ onSearch = output();
1776
+ columnTemplates = contentChildren(BaseListTemplateDirective, ...(ngDevMode ? [{ debugName: "columnTemplates" }] : []));
1777
+ _first = signal(0, ...(ngDevMode ? [{ debugName: "_first" }] : []));
1778
+ _searchTerm = signal('', ...(ngDevMode ? [{ debugName: "_searchTerm" }] : []));
1779
+ first = this._first.asReadonly();
1780
+ searchTerm = this._searchTerm.asReadonly();
1781
+ effectiveData = computed(() => this.service()?.data() ?? this.data(), ...(ngDevMode ? [{ debugName: "effectiveData" }] : []));
1782
+ effectiveTotal = computed(() => this.service()?.total() ?? this.total(), ...(ngDevMode ? [{ debugName: "effectiveTotal" }] : []));
1783
+ effectiveIsLoading = computed(() => this.service()?.isLoading() ?? this.isLoading(), ...(ngDevMode ? [{ debugName: "effectiveIsLoading" }] : []));
1784
+ effectiveActions = computed(() => {
1785
+ const editRoute = this.editRoute();
1786
+ const deleteField = this.deleteConfirmField();
1787
+ const editAction = editRoute
1788
+ ? [{ icon: 'pi pi-pencil', tooltip: 'shared.edit', severity: 'info',
1789
+ show: this.canEdit() ?? undefined, handler: (item) => this.handleEditItem(item) }]
1790
+ : [];
1791
+ const deleteAction = deleteField
1792
+ ? [{ icon: 'pi pi-trash', tooltip: 'shared.delete', severity: 'danger',
1793
+ show: this.canDelete() ?? undefined, handler: (item) => this.handleDeleteItem(item) }]
1794
+ : [];
1795
+ return [...editAction, ...this.actions(), ...deleteAction];
1796
+ }, ...(ngDevMode ? [{ debugName: "effectiveActions" }] : []));
1797
+ visibleColumns = computed(() => this.columns().filter((c) => !c.hidden), ...(ngDevMode ? [{ debugName: "visibleColumns" }] : []));
1798
+ columnCount = computed(() => this.visibleColumns().length + (this.effectiveActions().length > 0 ? 1 : 0), ...(ngDevMode ? [{ debugName: "columnCount" }] : []));
1799
+ resolvedEmptyMessage = computed(() => this.emptyMessage() || this.t('shared.no.data'), ...(ngDevMode ? [{ debugName: "resolvedEmptyMessage" }] : []));
1800
+ resolvedCreateLabel = computed(() => this.createButtonLabel() || this.t('shared.create'), ...(ngDevMode ? [{ debugName: "resolvedCreateLabel" }] : []));
1801
+ handleLazyLoad(event) {
1802
+ const first = event.first ?? 0;
1803
+ const rows = event.rows ?? this.pageSize();
1804
+ this._first.set(first);
1805
+ const service = this.service();
1806
+ if (service) {
1807
+ service.fetchList(this.searchTerm(), {
1808
+ pagination: { currentPage: Math.floor(first / rows), pageSize: rows },
1809
+ filter: this.filter(),
1810
+ });
1811
+ }
1812
+ this.onLazyLoad.emit({ first, rows });
1813
+ }
1814
+ onSearchChange(value) {
1815
+ this._first.set(0);
1816
+ this._searchTerm.set(value);
1817
+ const service = this.service();
1818
+ if (service) {
1819
+ service.fetchList(value, {
1820
+ pagination: { currentPage: 0, pageSize: this.pageSize() },
1821
+ filter: this.filter(),
1822
+ });
1823
+ }
1824
+ this.onSearch.emit(value);
1825
+ }
1826
+ handleCreate() {
1827
+ const route = this.createRoute();
1828
+ if (route && this.router)
1829
+ this.router.navigate([route]);
1830
+ this.onCreate.emit();
1831
+ }
1832
+ handleEditItem(item) {
1833
+ const route = this.editRoute();
1834
+ const id = this.getFieldValueAsString(item, this.idField());
1835
+ if (route && id && this.router)
1836
+ this.router.navigate([route, id]);
1837
+ }
1838
+ handleDeleteItem(item) {
1839
+ const nameField = this.deleteConfirmField();
1840
+ const name = this.getFieldValueAsString(item, nameField);
1841
+ const id = this.getFieldValueAsString(item, this.idField());
1842
+ this.confirmationService?.confirm({
1843
+ message: this.t('shared.confirm.delete.item', { name }),
1844
+ header: this.t('shared.confirm.delete'),
1845
+ icon: 'pi pi-exclamation-triangle',
1846
+ acceptButtonStyleClass: 'p-button-danger',
1847
+ accept: async () => {
1848
+ try {
1849
+ const response = await this.service()?.delete({ id, type: 'delete' });
1850
+ this.messageService?.add({
1851
+ severity: 'success',
1852
+ summary: this.t('shared.success'),
1853
+ detail: response?.messageKey
1854
+ ? this.t(response.messageKey, response.messageVariables)
1855
+ : (response?.message ?? ''),
1856
+ });
1857
+ this.service()?.reload();
1858
+ }
1859
+ catch {
1860
+ // handled by global interceptor
1861
+ }
1862
+ },
1863
+ });
1864
+ }
1865
+ getFieldValue(item, field) {
1866
+ return field
1867
+ .split('.')
1868
+ .reduce((obj, key) => (obj != null ? obj[key] : null), item);
1869
+ }
1870
+ getFieldValueAsString(item, field) {
1871
+ return String(this.getFieldValue(item, field) ?? '');
1872
+ }
1873
+ getTagConfig(col, value) {
1874
+ return col.tagMap?.[String(value)] ?? null;
1875
+ }
1876
+ getColumnTemplate(field) {
1877
+ return this.columnTemplates().find((t) => t.key() === field)?.templateRef ?? null;
1878
+ }
1879
+ truncateText(value, limit) {
1880
+ const str = String(value ?? '');
1881
+ return limit && str.length > limit ? `${str.slice(0, limit)}…` : str;
1882
+ }
1883
+ getCellClass(col) {
1884
+ switch (col.align) {
1885
+ case 'center': return 'text-center';
1886
+ case 'right': return 'text-right';
1887
+ default: return '';
1888
+ }
1889
+ }
1890
+ t(key, vars) {
1891
+ return this.translateAdapter?.translate(key, vars) ?? key;
1892
+ }
1893
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: BaseListComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1894
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.5", type: BaseListComponent, isStandalone: true, selector: "lib-base-list", inputs: { columns: { classPropertyName: "columns", publicName: "columns", isSignal: true, isRequired: true, transformFunction: null }, actions: { classPropertyName: "actions", publicName: "actions", isSignal: true, isRequired: false, transformFunction: null }, title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, showCreateButton: { classPropertyName: "showCreateButton", publicName: "showCreateButton", isSignal: true, isRequired: false, transformFunction: null }, searchable: { classPropertyName: "searchable", publicName: "searchable", isSignal: true, isRequired: false, transformFunction: null }, pageSize: { classPropertyName: "pageSize", publicName: "pageSize", isSignal: true, isRequired: false, transformFunction: null }, emptyMessage: { classPropertyName: "emptyMessage", publicName: "emptyMessage", isSignal: true, isRequired: false, transformFunction: null }, createButtonLabel: { classPropertyName: "createButtonLabel", publicName: "createButtonLabel", isSignal: true, isRequired: false, transformFunction: null }, createButtonIcon: { classPropertyName: "createButtonIcon", publicName: "createButtonIcon", isSignal: true, isRequired: false, transformFunction: null }, data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: false, transformFunction: null }, total: { classPropertyName: "total", publicName: "total", isSignal: true, isRequired: false, transformFunction: null }, isLoading: { classPropertyName: "isLoading", publicName: "isLoading", isSignal: true, isRequired: false, transformFunction: null }, service: { classPropertyName: "service", publicName: "service", isSignal: true, isRequired: false, transformFunction: null }, filter: { classPropertyName: "filter", publicName: "filter", isSignal: true, isRequired: false, transformFunction: null }, createRoute: { classPropertyName: "createRoute", publicName: "createRoute", isSignal: true, isRequired: false, transformFunction: null }, editRoute: { classPropertyName: "editRoute", publicName: "editRoute", isSignal: true, isRequired: false, transformFunction: null }, deleteConfirmField: { classPropertyName: "deleteConfirmField", publicName: "deleteConfirmField", isSignal: true, isRequired: false, transformFunction: null }, idField: { classPropertyName: "idField", publicName: "idField", isSignal: true, isRequired: false, transformFunction: null }, canEdit: { classPropertyName: "canEdit", publicName: "canEdit", isSignal: true, isRequired: false, transformFunction: null }, canDelete: { classPropertyName: "canDelete", publicName: "canDelete", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { onCreate: "onCreate", onLazyLoad: "onLazyLoad", onSearch: "onSearch" }, queries: [{ propertyName: "columnTemplates", predicate: BaseListTemplateDirective, isSignal: true }], ngImport: i0, template: "<p-card>\n <ng-template #header>\n @if (title() || searchable() || showCreateButton()) {\n <div class=\"flex flex-col sm:flex-row justify-between items-start sm:items-center gap-3 p-4\">\n @if (title()) {\n <h2 class=\"text-xl font-semibold m-0\">{{ title() }}</h2>\n }\n <div class=\"flex items-center gap-2\" [class.ml-auto]=\"!!title()\">\n @if (searchable()) {\n <p-iconfield>\n <p-inputicon class=\"pi pi-search\" />\n <input\n pInputText\n type=\"text\"\n [ngModel]=\"searchTerm()\"\n (ngModelChange)=\"onSearchChange($event)\"\n [placeholder]=\"t('shared.search')\"\n />\n </p-iconfield>\n }\n @if (showCreateButton()) {\n <p-button\n [icon]=\"createButtonIcon()\"\n [label]=\"resolvedCreateLabel()\"\n (onClick)=\"handleCreate()\"\n />\n }\n </div>\n </div>\n }\n </ng-template>\n\n <div class=\"overflow-x-auto\">\n <p-table\n [value]=\"effectiveData()\"\n [loading]=\"effectiveIsLoading()\"\n [lazy]=\"true\"\n [scrollable]=\"true\"\n [paginator]=\"effectiveTotal() > pageSize()\"\n [rows]=\"pageSize()\"\n [totalRecords]=\"effectiveTotal()\"\n [first]=\"first()\"\n (onLazyLoad)=\"handleLazyLoad($event)\"\n [showCurrentPageReport]=\"true\"\n [currentPageReportTemplate]=\"t('shared.pagination.report')\"\n class=\"p-datatable-striped\"\n >\n <ng-template #header>\n <tr>\n @for (col of visibleColumns(); track col.field) {\n <th [style.width]=\"col.width\" [style.min-width]=\"col.minWidth\" [class]=\"getCellClass(col)\">\n {{ col.header }}\n </th>\n }\n @if (effectiveActions().length > 0) {\n <th style=\"width: 120px; text-align: center;\">{{ t('shared.actions') }}</th>\n }\n </tr>\n </ng-template>\n\n <ng-template #body let-item>\n <tr>\n @for (col of visibleColumns(); track col.field) {\n <td [class]=\"getCellClass(col)\">\n @switch (col.type ?? 'text') {\n @case ('tag') {\n @if (getTagConfig(col, getFieldValue(item, col.field)); as tagCfg) {\n <p-tag [severity]=\"tagCfg.severity\" [value]=\"tagCfg.label ?? getFieldValueAsString(item, col.field)\" />\n } @else {\n {{ getFieldValueAsString(item, col.field) }}\n }\n }\n @case ('boolean') {\n <p-tag\n [severity]=\"getFieldValue(item, col.field) ? 'success' : 'danger'\"\n [value]=\"getFieldValue(item, col.field) ? t('shared.yes') : t('shared.no')\"\n />\n }\n @case ('date') {\n {{ getFieldValueAsString(item, col.field) | date: (col.dateFormat ?? 'dd/MM/yyyy') }}\n }\n @case ('number') {\n {{ getFieldValueAsString(item, col.field) | number }}\n }\n @case ('custom') {\n <ng-container\n *ngTemplateOutlet=\"getColumnTemplate(col.field); context: { $implicit: item, field: col.field }\"\n />\n }\n @default {\n {{ truncateText(getFieldValue(item, col.field), col.truncate) }}\n }\n }\n </td>\n }\n @if (effectiveActions().length > 0) {\n <td>\n <div class=\"flex items-center justify-center gap-2\">\n @for (action of effectiveActions(); track $index) {\n @if (!action.show || action.show(item)) {\n <p-button\n [icon]=\"action.icon\"\n [severity]=\"action.severity\"\n [pTooltip]=\"action.tooltip ? t(action.tooltip) : ''\"\n [disabled]=\"action.disabled ? action.disabled(item) : false\"\n (onClick)=\"action.handler(item)\"\n [rounded]=\"true\"\n [text]=\"true\"\n />\n }\n }\n </div>\n </td>\n }\n </tr>\n </ng-template>\n\n <ng-template #emptymessage>\n <tr>\n <td [attr.colspan]=\"columnCount()\">\n <div class=\"flex flex-col items-center justify-center py-12 text-surface-400\">\n <i class=\"pi pi-inbox text-5xl mb-3\"></i>\n <span>{{ resolvedEmptyMessage() }}</span>\n </div>\n </td>\n </tr>\n </ng-template>\n </p-table>\n </div>\n</p-card>\n", dependencies: [{ kind: "ngmodule", type: AngularModule }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: PrimeModule }, { kind: "component", type: i3.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: i4.Card, selector: "p-card", inputs: ["header", "subheader", "style", "styleClass"] }, { kind: "component", type: i5.IconField, selector: "p-iconfield, p-iconField, p-icon-field", inputs: ["hostName", "iconPosition", "styleClass"] }, { kind: "component", type: i6.InputIcon, selector: "p-inputicon, p-inputIcon", inputs: ["hostName", "styleClass"] }, { kind: "directive", type: i8.InputText, selector: "[pInputText]", inputs: ["hostName", "ptInputText", "pInputTextPT", "pInputTextUnstyled", "pSize", "variant", "fluid", "invalid"] }, { kind: "component", type: i8$1.Table, selector: "p-table", inputs: ["frozenColumns", "frozenValue", "styleClass", "tableStyle", "tableStyleClass", "paginator", "pageLinks", "rowsPerPageOptions", "alwaysShowPaginator", "paginatorPosition", "paginatorStyleClass", "paginatorDropdownAppendTo", "paginatorDropdownScrollHeight", "currentPageReportTemplate", "showCurrentPageReport", "showJumpToPageDropdown", "showJumpToPageInput", "showFirstLastIcon", "showPageLinks", "defaultSortOrder", "sortMode", "resetPageOnSort", "selectionMode", "selectionPageOnly", "contextMenuSelection", "contextMenuSelectionMode", "dataKey", "metaKeySelection", "rowSelectable", "rowTrackBy", "lazy", "lazyLoadOnInit", "compareSelectionBy", "csvSeparator", "exportFilename", "filters", "globalFilterFields", "filterDelay", "filterLocale", "expandedRowKeys", "editingRowKeys", "rowExpandMode", "scrollable", "rowGroupMode", "scrollHeight", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "virtualScrollDelay", "frozenWidth", "contextMenu", "resizableColumns", "columnResizeMode", "reorderableColumns", "loading", "loadingIcon", "showLoader", "rowHover", "customSort", "showInitialSortBadge", "exportFunction", "exportHeader", "stateKey", "stateStorage", "editMode", "groupRowsBy", "size", "showGridlines", "stripedRows", "groupRowsByOrder", "responsiveLayout", "breakpoint", "paginatorLocale", "value", "columns", "first", "rows", "totalRecords", "sortField", "sortOrder", "multiSortMeta", "selection", "selectAll"], outputs: ["contextMenuSelectionChange", "selectAllChange", "selectionChange", "onRowSelect", "onRowUnselect", "onPage", "onSort", "onFilter", "onLazyLoad", "onRowExpand", "onRowCollapse", "onContextMenuSelect", "onColResize", "onColReorder", "onRowReorder", "onEditInit", "onEditComplete", "onEditCancel", "onHeaderCheckboxToggle", "sortFunction", "firstChange", "rowsChange", "onStateSave", "onStateRestore"] }, { kind: "component", type: i9.Tag, selector: "p-tag", inputs: ["styleClass", "severity", "value", "icon", "rounded"] }, { kind: "directive", type: i10.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "showOnEllipsis", "pTooltip", "tooltipDisabled", "tooltipOptions", "appendTo", "ptTooltip", "pTooltipPT", "pTooltipUnstyled"] }, { kind: "pipe", type: i1.DecimalPipe, name: "number" }, { kind: "pipe", type: i1.DatePipe, name: "date" }] });
1895
+ }
1896
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: BaseListComponent, decorators: [{
1897
+ type: Component,
1898
+ args: [{ selector: 'lib-base-list', imports: [AngularModule, PrimeModule], template: "<p-card>\n <ng-template #header>\n @if (title() || searchable() || showCreateButton()) {\n <div class=\"flex flex-col sm:flex-row justify-between items-start sm:items-center gap-3 p-4\">\n @if (title()) {\n <h2 class=\"text-xl font-semibold m-0\">{{ title() }}</h2>\n }\n <div class=\"flex items-center gap-2\" [class.ml-auto]=\"!!title()\">\n @if (searchable()) {\n <p-iconfield>\n <p-inputicon class=\"pi pi-search\" />\n <input\n pInputText\n type=\"text\"\n [ngModel]=\"searchTerm()\"\n (ngModelChange)=\"onSearchChange($event)\"\n [placeholder]=\"t('shared.search')\"\n />\n </p-iconfield>\n }\n @if (showCreateButton()) {\n <p-button\n [icon]=\"createButtonIcon()\"\n [label]=\"resolvedCreateLabel()\"\n (onClick)=\"handleCreate()\"\n />\n }\n </div>\n </div>\n }\n </ng-template>\n\n <div class=\"overflow-x-auto\">\n <p-table\n [value]=\"effectiveData()\"\n [loading]=\"effectiveIsLoading()\"\n [lazy]=\"true\"\n [scrollable]=\"true\"\n [paginator]=\"effectiveTotal() > pageSize()\"\n [rows]=\"pageSize()\"\n [totalRecords]=\"effectiveTotal()\"\n [first]=\"first()\"\n (onLazyLoad)=\"handleLazyLoad($event)\"\n [showCurrentPageReport]=\"true\"\n [currentPageReportTemplate]=\"t('shared.pagination.report')\"\n class=\"p-datatable-striped\"\n >\n <ng-template #header>\n <tr>\n @for (col of visibleColumns(); track col.field) {\n <th [style.width]=\"col.width\" [style.min-width]=\"col.minWidth\" [class]=\"getCellClass(col)\">\n {{ col.header }}\n </th>\n }\n @if (effectiveActions().length > 0) {\n <th style=\"width: 120px; text-align: center;\">{{ t('shared.actions') }}</th>\n }\n </tr>\n </ng-template>\n\n <ng-template #body let-item>\n <tr>\n @for (col of visibleColumns(); track col.field) {\n <td [class]=\"getCellClass(col)\">\n @switch (col.type ?? 'text') {\n @case ('tag') {\n @if (getTagConfig(col, getFieldValue(item, col.field)); as tagCfg) {\n <p-tag [severity]=\"tagCfg.severity\" [value]=\"tagCfg.label ?? getFieldValueAsString(item, col.field)\" />\n } @else {\n {{ getFieldValueAsString(item, col.field) }}\n }\n }\n @case ('boolean') {\n <p-tag\n [severity]=\"getFieldValue(item, col.field) ? 'success' : 'danger'\"\n [value]=\"getFieldValue(item, col.field) ? t('shared.yes') : t('shared.no')\"\n />\n }\n @case ('date') {\n {{ getFieldValueAsString(item, col.field) | date: (col.dateFormat ?? 'dd/MM/yyyy') }}\n }\n @case ('number') {\n {{ getFieldValueAsString(item, col.field) | number }}\n }\n @case ('custom') {\n <ng-container\n *ngTemplateOutlet=\"getColumnTemplate(col.field); context: { $implicit: item, field: col.field }\"\n />\n }\n @default {\n {{ truncateText(getFieldValue(item, col.field), col.truncate) }}\n }\n }\n </td>\n }\n @if (effectiveActions().length > 0) {\n <td>\n <div class=\"flex items-center justify-center gap-2\">\n @for (action of effectiveActions(); track $index) {\n @if (!action.show || action.show(item)) {\n <p-button\n [icon]=\"action.icon\"\n [severity]=\"action.severity\"\n [pTooltip]=\"action.tooltip ? t(action.tooltip) : ''\"\n [disabled]=\"action.disabled ? action.disabled(item) : false\"\n (onClick)=\"action.handler(item)\"\n [rounded]=\"true\"\n [text]=\"true\"\n />\n }\n }\n </div>\n </td>\n }\n </tr>\n </ng-template>\n\n <ng-template #emptymessage>\n <tr>\n <td [attr.colspan]=\"columnCount()\">\n <div class=\"flex flex-col items-center justify-center py-12 text-surface-400\">\n <i class=\"pi pi-inbox text-5xl mb-3\"></i>\n <span>{{ resolvedEmptyMessage() }}</span>\n </div>\n </td>\n </tr>\n </ng-template>\n </p-table>\n </div>\n</p-card>\n" }]
1899
+ }], propDecorators: { columns: [{ type: i0.Input, args: [{ isSignal: true, alias: "columns", required: true }] }], actions: [{ type: i0.Input, args: [{ isSignal: true, alias: "actions", required: false }] }], title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: false }] }], showCreateButton: [{ type: i0.Input, args: [{ isSignal: true, alias: "showCreateButton", required: false }] }], searchable: [{ type: i0.Input, args: [{ isSignal: true, alias: "searchable", required: false }] }], pageSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "pageSize", required: false }] }], emptyMessage: [{ type: i0.Input, args: [{ isSignal: true, alias: "emptyMessage", required: false }] }], createButtonLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "createButtonLabel", required: false }] }], createButtonIcon: [{ type: i0.Input, args: [{ isSignal: true, alias: "createButtonIcon", required: false }] }], data: [{ type: i0.Input, args: [{ isSignal: true, alias: "data", required: false }] }], total: [{ type: i0.Input, args: [{ isSignal: true, alias: "total", required: false }] }], isLoading: [{ type: i0.Input, args: [{ isSignal: true, alias: "isLoading", required: false }] }], service: [{ type: i0.Input, args: [{ isSignal: true, alias: "service", required: false }] }], filter: [{ type: i0.Input, args: [{ isSignal: true, alias: "filter", required: false }] }], createRoute: [{ type: i0.Input, args: [{ isSignal: true, alias: "createRoute", required: false }] }], editRoute: [{ type: i0.Input, args: [{ isSignal: true, alias: "editRoute", required: false }] }], deleteConfirmField: [{ type: i0.Input, args: [{ isSignal: true, alias: "deleteConfirmField", required: false }] }], idField: [{ type: i0.Input, args: [{ isSignal: true, alias: "idField", required: false }] }], canEdit: [{ type: i0.Input, args: [{ isSignal: true, alias: "canEdit", required: false }] }], canDelete: [{ type: i0.Input, args: [{ isSignal: true, alias: "canDelete", required: false }] }], onCreate: [{ type: i0.Output, args: ["onCreate"] }], onLazyLoad: [{ type: i0.Output, args: ["onLazyLoad"] }], onSearch: [{ type: i0.Output, args: ["onSearch"] }], columnTemplates: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => BaseListTemplateDirective), { isSignal: true }] }] } });
1900
+
1901
+ class BaseFormTemplateDirective {
1902
+ key = input.required({ ...(ngDevMode ? { debugName: "key" } : {}), alias: 'baseFormTemplate' });
1903
+ templateRef = inject((TemplateRef));
1904
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: BaseFormTemplateDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
1905
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.1.5", type: BaseFormTemplateDirective, isStandalone: true, selector: "ng-template[baseFormTemplate]", inputs: { key: { classPropertyName: "key", publicName: "baseFormTemplate", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0 });
1906
+ }
1907
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: BaseFormTemplateDirective, decorators: [{
1908
+ type: Directive,
1909
+ args: [{ selector: 'ng-template[baseFormTemplate]' }]
1910
+ }], propDecorators: { key: [{ type: i0.Input, args: [{ isSignal: true, alias: "baseFormTemplate", required: true }] }] } });
1911
+
1912
+ class BaseFormComponent {
1913
+ translateAdapter = inject(TranslateService, { optional: true });
1914
+ router = inject(Router, { optional: true });
1915
+ messageService = inject(MessageService, { optional: true });
1916
+ fields = input.required(...(ngDevMode ? [{ debugName: "fields" }] : []));
1917
+ title = input('', ...(ngDevMode ? [{ debugName: "title" }] : []));
1918
+ createTitle = input('', ...(ngDevMode ? [{ debugName: "createTitle" }] : []));
1919
+ editTitle = input('', ...(ngDevMode ? [{ debugName: "editTitle" }] : []));
1920
+ columns = input(2, ...(ngDevMode ? [{ debugName: "columns" }] : []));
1921
+ submitLabel = input('', ...(ngDevMode ? [{ debugName: "submitLabel" }] : []));
1922
+ cancelLabel = input('', ...(ngDevMode ? [{ debugName: "cancelLabel" }] : []));
1923
+ isLoading = input(false, ...(ngDevMode ? [{ debugName: "isLoading" }] : []));
1924
+ isEditMode = input(false, ...(ngDevMode ? [{ debugName: "isEditMode" }] : []));
1925
+ initialValue = input({}, ...(ngDevMode ? [{ debugName: "initialValue" }] : []));
1926
+ service = input(null, ...(ngDevMode ? [{ debugName: "service" }] : []));
1927
+ editId = input(null, ...(ngDevMode ? [{ debugName: "editId" }] : []));
1928
+ cancelRoute = input(null, ...(ngDevMode ? [{ debugName: "cancelRoute" }] : []));
1929
+ navigateOnSuccess = input(null, ...(ngDevMode ? [{ debugName: "navigateOnSuccess" }] : []));
1930
+ mapToRequest = input(null, ...(ngDevMode ? [{ debugName: "mapToRequest" }] : []));
1931
+ mapFromEntity = input(null, ...(ngDevMode ? [{ debugName: "mapFromEntity" }] : []));
1932
+ onSubmit = output();
1933
+ onCancel = output();
1934
+ onValueChange = output();
1935
+ fieldTemplates = contentChildren(BaseFormTemplateDirective, ...(ngDevMode ? [{ debugName: "fieldTemplates" }] : []));
1936
+ _formData = signal({}, ...(ngDevMode ? [{ debugName: "_formData" }] : []));
1937
+ _submitted = signal(false, ...(ngDevMode ? [{ debugName: "_submitted" }] : []));
1938
+ _isLoadingInternal = signal(false, ...(ngDevMode ? [{ debugName: "_isLoadingInternal" }] : []));
1939
+ _touchedFields = signal(new Set(), ...(ngDevMode ? [{ debugName: "_touchedFields" }] : []));
1940
+ formData = this._formData.asReadonly();
1941
+ submitted = this._submitted.asReadonly();
1942
+ effectiveIsEditMode = computed(() => this.isEditMode() || !!this.editId(), ...(ngDevMode ? [{ debugName: "effectiveIsEditMode" }] : []));
1943
+ effectiveIsLoading = computed(() => this.isLoading() || this._isLoadingInternal(), ...(ngDevMode ? [{ debugName: "effectiveIsLoading" }] : []));
1944
+ isFormValid = computed(() => this.checkValidity(), ...(ngDevMode ? [{ debugName: "isFormValid" }] : []));
1945
+ resolvedTitle = computed(() => {
1946
+ if (this.effectiveIsEditMode())
1947
+ return this.editTitle() || this.title();
1948
+ return this.createTitle() || this.title();
1949
+ }, ...(ngDevMode ? [{ debugName: "resolvedTitle" }] : []));
1950
+ gridClass = computed(() => {
1951
+ switch (this.columns()) {
1952
+ case 1: return 'grid-cols-1';
1953
+ case 3: return 'grid-cols-1 md:grid-cols-3';
1954
+ default: return 'grid-cols-1 md:grid-cols-2';
1955
+ }
1956
+ }, ...(ngDevMode ? [{ debugName: "gridClass" }] : []));
1957
+ constructor() {
1958
+ effect(() => {
1959
+ const fields = this.fields();
1960
+ const initial = this.initialValue();
1961
+ const defaults = {};
1962
+ for (const f of fields)
1963
+ defaults[f.key] = this.getDefaultValue(f);
1964
+ this._formData.set({ ...defaults, ...initial });
1965
+ this._submitted.set(false);
1966
+ this._touchedFields.set(new Set());
1967
+ });
1968
+ effect(() => {
1969
+ const editId = this.editId();
1970
+ const service = this.service();
1971
+ const mapFn = this.mapFromEntity();
1972
+ if (editId && service && mapFn)
1973
+ this.loadEntity(editId, service, mapFn);
1974
+ });
1975
+ }
1976
+ async loadEntity(id, service, mapFn) {
1977
+ this._isLoadingInternal.set(true);
1978
+ try {
1979
+ const response = await service.findById(id);
1980
+ if (response.success && response.data) {
1981
+ this._formData.update((prev) => ({ ...prev, ...mapFn(response.data) }));
1982
+ this._submitted.set(false);
1983
+ }
1984
+ }
1985
+ catch {
1986
+ this.navigateTo(this.cancelRoute());
1987
+ }
1988
+ finally {
1989
+ this._isLoadingInternal.set(false);
1990
+ }
1991
+ }
1992
+ getFieldValue(key) {
1993
+ return this._formData()[key];
1994
+ }
1995
+ setFieldValue(key, value) {
1996
+ this._formData.update((data) => ({ ...data, [key]: value }));
1997
+ this._touchedFields.update((set) => new Set([...set, key]));
1998
+ this.onValueChange.emit(this._formData());
1999
+ }
2000
+ markFieldTouched(key) {
2001
+ this._touchedFields.update((set) => new Set([...set, key]));
2002
+ }
2003
+ isFieldInvalid(field) {
2004
+ const isActive = this._submitted() || this._touchedFields().has(field.key);
2005
+ if (!isActive || !field.required)
2006
+ return false;
2007
+ const value = this._formData()[field.key];
2008
+ if (Array.isArray(value))
2009
+ return value.length === 0;
2010
+ return value === null || value === undefined || value === '';
2011
+ }
2012
+ getFieldTemplate(key) {
2013
+ return this.fieldTemplates().find((t) => t.key() === key)?.templateRef ?? null;
2014
+ }
2015
+ async handleSubmit() {
2016
+ this._submitted.set(true);
2017
+ if (!this.isFormValid())
2018
+ return;
2019
+ const service = this.service();
2020
+ const mapFn = this.mapToRequest();
2021
+ if (service && mapFn) {
2022
+ await this.managedSubmit(service, mapFn);
2023
+ }
2024
+ else {
2025
+ this.onSubmit.emit({ ...this._formData() });
2026
+ }
2027
+ }
2028
+ handleCancel() {
2029
+ this.navigateTo(this.cancelRoute());
2030
+ this.onCancel.emit();
2031
+ }
2032
+ reset() {
2033
+ const defaults = {};
2034
+ for (const f of this.fields())
2035
+ defaults[f.key] = this.getDefaultValue(f);
2036
+ this._formData.set(defaults);
2037
+ this._submitted.set(false);
2038
+ this._touchedFields.set(new Set());
2039
+ }
2040
+ t(key, vars) {
2041
+ return this.translateAdapter?.translate(key, vars) ?? key;
2042
+ }
2043
+ async managedSubmit(service, mapFn) {
2044
+ this._isLoadingInternal.set(true);
2045
+ try {
2046
+ const editId = this.editId();
2047
+ const dto = mapFn(this._formData(), editId);
2048
+ const response = editId ? await service.update(dto) : await service.insert(dto);
2049
+ this.messageService?.add({
2050
+ severity: 'success',
2051
+ summary: this.t('shared.success'),
2052
+ detail: response.messageKey
2053
+ ? this.t(response.messageKey, response.messageVariables)
2054
+ : (response.message ?? ''),
2055
+ });
2056
+ this.onSubmit.emit({ ...this._formData() });
2057
+ this.navigateTo(this.navigateOnSuccess());
2058
+ }
2059
+ catch {
2060
+ // handled by global interceptor
2061
+ }
2062
+ finally {
2063
+ this._isLoadingInternal.set(false);
2064
+ }
2065
+ }
2066
+ checkValidity() {
2067
+ return this.fields().every((f) => {
2068
+ if (!f.required)
2069
+ return true;
2070
+ const value = this._formData()[f.key];
2071
+ if (Array.isArray(value))
2072
+ return value.length > 0;
2073
+ return value !== null && value !== undefined && value !== '';
2074
+ });
2075
+ }
2076
+ navigateTo(route) {
2077
+ if (!route || !this.router)
2078
+ return;
2079
+ this.router.navigate(Array.isArray(route) ? route : [route]);
2080
+ }
2081
+ getDefaultValue(field) {
2082
+ switch (field.type) {
2083
+ case 'checkbox':
2084
+ case 'toggle':
2085
+ return false;
2086
+ case 'multiselect':
2087
+ return [];
2088
+ case 'number':
2089
+ return null;
2090
+ default:
2091
+ return '';
2092
+ }
2093
+ }
2094
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: BaseFormComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
2095
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.5", type: BaseFormComponent, isStandalone: true, selector: "lib-base-form", inputs: { fields: { classPropertyName: "fields", publicName: "fields", isSignal: true, isRequired: true, transformFunction: null }, title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, createTitle: { classPropertyName: "createTitle", publicName: "createTitle", isSignal: true, isRequired: false, transformFunction: null }, editTitle: { classPropertyName: "editTitle", publicName: "editTitle", isSignal: true, isRequired: false, transformFunction: null }, columns: { classPropertyName: "columns", publicName: "columns", isSignal: true, isRequired: false, transformFunction: null }, submitLabel: { classPropertyName: "submitLabel", publicName: "submitLabel", isSignal: true, isRequired: false, transformFunction: null }, cancelLabel: { classPropertyName: "cancelLabel", publicName: "cancelLabel", isSignal: true, isRequired: false, transformFunction: null }, isLoading: { classPropertyName: "isLoading", publicName: "isLoading", isSignal: true, isRequired: false, transformFunction: null }, isEditMode: { classPropertyName: "isEditMode", publicName: "isEditMode", isSignal: true, isRequired: false, transformFunction: null }, initialValue: { classPropertyName: "initialValue", publicName: "initialValue", isSignal: true, isRequired: false, transformFunction: null }, service: { classPropertyName: "service", publicName: "service", isSignal: true, isRequired: false, transformFunction: null }, editId: { classPropertyName: "editId", publicName: "editId", isSignal: true, isRequired: false, transformFunction: null }, cancelRoute: { classPropertyName: "cancelRoute", publicName: "cancelRoute", isSignal: true, isRequired: false, transformFunction: null }, navigateOnSuccess: { classPropertyName: "navigateOnSuccess", publicName: "navigateOnSuccess", isSignal: true, isRequired: false, transformFunction: null }, mapToRequest: { classPropertyName: "mapToRequest", publicName: "mapToRequest", isSignal: true, isRequired: false, transformFunction: null }, mapFromEntity: { classPropertyName: "mapFromEntity", publicName: "mapFromEntity", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { onSubmit: "onSubmit", onCancel: "onCancel", onValueChange: "onValueChange" }, queries: [{ propertyName: "fieldTemplates", predicate: BaseFormTemplateDirective, isSignal: true }], ngImport: i0, template: "<p-card>\n <ng-template #header>\n @if (resolvedTitle()) {\n <div class=\"flex justify-between items-center p-4\">\n <h2 class=\"text-xl font-semibold m-0\">{{ resolvedTitle() }}</h2>\n </div>\n }\n </ng-template>\n\n <form (ngSubmit)=\"handleSubmit()\" novalidate>\n <div class=\"grid gap-4\" [class]=\"gridClass()\">\n @for (field of fields(); track field.key) {\n <div class=\"flex flex-col gap-2\" [class.col-span-full]=\"field.fullWidth\">\n @if (field.type !== 'checkbox' && field.type !== 'toggle') {\n <label [for]=\"field.key\" class=\"font-medium\">\n {{ field.label }}\n @if (field.required) {\n <span class=\"text-red-500 ml-1\">*</span>\n }\n </label>\n }\n\n @switch (field.type) {\n @case ('text') {\n <input\n pInputText\n [id]=\"field.key\"\n [name]=\"field.key\"\n [ngModel]=\"getFieldValue(field.key)\"\n (ngModelChange)=\"setFieldValue(field.key, $event)\"\n (blur)=\"markFieldTouched(field.key)\"\n [placeholder]=\"field.placeholder ?? ''\"\n [disabled]=\"field.disabled ?? false\"\n [class.ng-invalid]=\"isFieldInvalid(field)\"\n [class.ng-dirty]=\"isFieldInvalid(field)\"\n class=\"w-full\"\n />\n }\n\n @case ('email') {\n <input\n pInputText\n type=\"email\"\n [id]=\"field.key\"\n [name]=\"field.key\"\n [ngModel]=\"getFieldValue(field.key)\"\n (ngModelChange)=\"setFieldValue(field.key, $event)\"\n (blur)=\"markFieldTouched(field.key)\"\n [placeholder]=\"field.placeholder ?? ''\"\n [disabled]=\"field.disabled ?? false\"\n [class.ng-invalid]=\"isFieldInvalid(field)\"\n [class.ng-dirty]=\"isFieldInvalid(field)\"\n class=\"w-full\"\n />\n }\n\n @case ('password') {\n <p-password\n [inputId]=\"field.key\"\n [name]=\"field.key\"\n [ngModel]=\"getFieldValue(field.key)\"\n (ngModelChange)=\"setFieldValue(field.key, $event)\"\n (onBlur)=\"markFieldTouched(field.key)\"\n [placeholder]=\"field.placeholder ?? ''\"\n [disabled]=\"field.disabled ?? false\"\n [feedback]=\"false\"\n [toggleMask]=\"true\"\n [invalid]=\"isFieldInvalid(field)\"\n class=\"w-full\"\n inputStyleClass=\"w-full\"\n />\n }\n\n @case ('number') {\n <p-inputnumber\n [inputId]=\"field.key\"\n [name]=\"field.key\"\n [ngModel]=\"getFieldValue(field.key)\"\n (ngModelChange)=\"setFieldValue(field.key, $event)\"\n (onBlur)=\"markFieldTouched(field.key)\"\n [placeholder]=\"field.placeholder ?? ''\"\n [disabled]=\"field.disabled ?? false\"\n [min]=\"field.min ?? undefined\"\n [max]=\"field.max ?? undefined\"\n [invalid]=\"isFieldInvalid(field)\"\n class=\"w-full\"\n inputStyleClass=\"w-full\"\n />\n }\n\n @case ('textarea') {\n <textarea\n pTextarea\n [id]=\"field.key\"\n [name]=\"field.key\"\n [ngModel]=\"getFieldValue(field.key)\"\n (ngModelChange)=\"setFieldValue(field.key, $event)\"\n (blur)=\"markFieldTouched(field.key)\"\n [placeholder]=\"field.placeholder ?? ''\"\n [disabled]=\"field.disabled ?? false\"\n [rows]=\"field.rows ?? 3\"\n [class.ng-invalid]=\"isFieldInvalid(field)\"\n [class.ng-dirty]=\"isFieldInvalid(field)\"\n class=\"w-full\"\n ></textarea>\n }\n\n @case ('select') {\n <p-select\n [inputId]=\"field.key\"\n [name]=\"field.key\"\n [ngModel]=\"getFieldValue(field.key)\"\n (ngModelChange)=\"setFieldValue(field.key, $event)\"\n [options]=\"field.options ?? []\"\n optionLabel=\"label\"\n optionValue=\"value\"\n [placeholder]=\"field.placeholder ?? t('shared.select.placeholder')\"\n [disabled]=\"field.disabled ?? false\"\n [invalid]=\"isFieldInvalid(field)\"\n class=\"w-full\"\n />\n }\n\n @case ('multiselect') {\n <p-multiselect\n [inputId]=\"field.key\"\n [name]=\"field.key\"\n [ngModel]=\"getFieldValue(field.key)\"\n (ngModelChange)=\"setFieldValue(field.key, $event)\"\n [options]=\"field.options ?? []\"\n optionLabel=\"label\"\n optionValue=\"value\"\n [placeholder]=\"field.placeholder ?? t('shared.select.placeholder')\"\n [disabled]=\"field.disabled ?? false\"\n [invalid]=\"isFieldInvalid(field)\"\n class=\"w-full\"\n />\n }\n\n @case ('date') {\n <p-datepicker\n [inputId]=\"field.key\"\n [name]=\"field.key\"\n [ngModel]=\"getFieldValue(field.key)\"\n (ngModelChange)=\"setFieldValue(field.key, $event)\"\n (onBlur)=\"markFieldTouched(field.key)\"\n [placeholder]=\"field.placeholder ?? ''\"\n [disabled]=\"field.disabled ?? false\"\n [minDate]=\"field.minDate ?? undefined\"\n [maxDate]=\"field.maxDate ?? undefined\"\n [invalid]=\"isFieldInvalid(field)\"\n class=\"w-full\"\n inputStyleClass=\"w-full\"\n />\n }\n\n @case ('checkbox') {\n <div class=\"flex items-center gap-2 h-9\">\n <p-checkbox\n [inputId]=\"field.key\"\n [name]=\"field.key\"\n [ngModel]=\"getFieldValue(field.key)\"\n (ngModelChange)=\"setFieldValue(field.key, $event)\"\n [disabled]=\"field.disabled ?? false\"\n [binary]=\"true\"\n [invalid]=\"isFieldInvalid(field)\"\n />\n <label [for]=\"field.key\" class=\"font-medium cursor-pointer select-none\">\n {{ field.label }}\n @if (field.required) {\n <span class=\"text-red-500 ml-1\">*</span>\n }\n </label>\n </div>\n }\n\n @case ('toggle') {\n <div class=\"flex items-center gap-3 h-9\">\n <p-toggleswitch\n [inputId]=\"field.key\"\n [name]=\"field.key\"\n [ngModel]=\"getFieldValue(field.key)\"\n (ngModelChange)=\"setFieldValue(field.key, $event)\"\n [disabled]=\"field.disabled ?? false\"\n />\n <label [for]=\"field.key\" class=\"font-medium cursor-pointer select-none\">\n {{ field.label }}\n @if (field.required) {\n <span class=\"text-red-500 ml-1\">*</span>\n }\n </label>\n </div>\n }\n\n @case ('custom') {\n <ng-container\n *ngTemplateOutlet=\"getFieldTemplate(field.key); context: { $implicit: getFieldValue(field.key), field: field }\"\n />\n }\n }\n\n @if (isFieldInvalid(field)) {\n <small class=\"text-red-500\">{{ field.label }} {{ t('shared.required') }}</small>\n }\n\n @if (field.hint && !isFieldInvalid(field)) {\n <small class=\"text-surface-400\">{{ field.hint }}</small>\n }\n </div>\n }\n\n <div class=\"col-span-full flex justify-end gap-4 pt-4\">\n <p-button\n type=\"button\"\n [label]=\"cancelLabel() || t('shared.cancel')\"\n severity=\"secondary\"\n [outlined]=\"true\"\n [disabled]=\"effectiveIsLoading()\"\n (onClick)=\"handleCancel()\"\n />\n <p-button\n type=\"submit\"\n [label]=\"submitLabel() || (effectiveIsEditMode() ? t('shared.update') : t('shared.save'))\"\n [loading]=\"effectiveIsLoading()\"\n [disabled]=\"!isFormValid() || effectiveIsLoading()\"\n />\n </div>\n </div>\n </form>\n</p-card>\n", dependencies: [{ kind: "ngmodule", type: AngularModule }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i2.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i2.NgForm, selector: "form:not([ngNoForm]):not([formGroup]):not([formArray]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: PrimeModule }, { kind: "component", type: i3.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: i4.Card, selector: "p-card", inputs: ["header", "subheader", "style", "styleClass"] }, { kind: "component", type: i5$1.Checkbox, selector: "p-checkbox, p-checkBox, p-check-box", inputs: ["hostName", "value", "binary", "ariaLabelledBy", "ariaLabel", "tabindex", "inputId", "inputStyle", "styleClass", "inputClass", "indeterminate", "formControl", "checkboxIcon", "readonly", "autofocus", "trueValue", "falseValue", "variant", "size"], outputs: ["onChange", "onFocus", "onBlur"] }, { kind: "component", type: i6$1.DatePicker, selector: "p-datePicker, p-datepicker, p-date-picker", inputs: ["iconDisplay", "styleClass", "inputStyle", "inputId", "inputStyleClass", "placeholder", "ariaLabelledBy", "ariaLabel", "iconAriaLabel", "dateFormat", "multipleSeparator", "rangeSeparator", "inline", "showOtherMonths", "selectOtherMonths", "showIcon", "icon", "readonlyInput", "shortYearCutoff", "hourFormat", "timeOnly", "stepHour", "stepMinute", "stepSecond", "showSeconds", "showOnFocus", "showWeek", "startWeekFromFirstDayOfYear", "showClear", "dataType", "selectionMode", "maxDateCount", "showButtonBar", "todayButtonStyleClass", "clearButtonStyleClass", "autofocus", "autoZIndex", "baseZIndex", "panelStyleClass", "panelStyle", "keepInvalid", "hideOnDateTimeSelect", "touchUI", "timeSeparator", "focusTrap", "showTransitionOptions", "hideTransitionOptions", "tabindex", "minDate", "maxDate", "disabledDates", "disabledDays", "showTime", "responsiveOptions", "numberOfMonths", "firstDayOfWeek", "view", "defaultDate", "appendTo", "motionOptions"], outputs: ["onFocus", "onBlur", "onClose", "onSelect", "onClear", "onInput", "onTodayClick", "onClearClick", "onMonthChange", "onYearChange", "onClickOutside", "onShow"] }, { kind: "component", type: i7.InputNumber, selector: "p-inputNumber, p-inputnumber, p-input-number", inputs: ["showButtons", "format", "buttonLayout", "inputId", "styleClass", "placeholder", "tabindex", "title", "ariaLabelledBy", "ariaDescribedBy", "ariaLabel", "ariaRequired", "autocomplete", "incrementButtonClass", "decrementButtonClass", "incrementButtonIcon", "decrementButtonIcon", "readonly", "allowEmpty", "locale", "localeMatcher", "mode", "currency", "currencyDisplay", "useGrouping", "minFractionDigits", "maxFractionDigits", "prefix", "suffix", "inputStyle", "inputStyleClass", "showClear", "autofocus"], outputs: ["onInput", "onFocus", "onBlur", "onKeyDown", "onClear"] }, { kind: "directive", type: i8.InputText, selector: "[pInputText]", inputs: ["hostName", "ptInputText", "pInputTextPT", "pInputTextUnstyled", "pSize", "variant", "fluid", "invalid"] }, { kind: "component", type: i9$1.MultiSelect, selector: "p-multiSelect, p-multiselect, p-multi-select", inputs: ["id", "ariaLabel", "styleClass", "panelStyle", "panelStyleClass", "inputId", "readonly", "group", "filter", "filterPlaceHolder", "filterLocale", "overlayVisible", "tabindex", "dataKey", "ariaLabelledBy", "displaySelectedLabel", "maxSelectedLabels", "selectionLimit", "selectedItemsLabel", "showToggleAll", "emptyFilterMessage", "emptyMessage", "resetFilterOnHide", "dropdownIcon", "chipIcon", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "showHeader", "filterBy", "scrollHeight", "lazy", "virtualScroll", "loading", "virtualScrollItemSize", "loadingIcon", "virtualScrollOptions", "overlayOptions", "ariaFilterLabel", "filterMatchMode", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "autofocusFilter", "display", "autocomplete", "showClear", "autofocus", "placeholder", "options", "filterValue", "selectAll", "focusOnHover", "filterFields", "selectOnFocus", "autoOptionFocus", "highlightOnSelect", "size", "variant", "fluid", "appendTo", "motionOptions"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onClear", "onPanelShow", "onPanelHide", "onLazyLoad", "onRemove", "onSelectAllChange"] }, { kind: "component", type: i10$1.Password, selector: "p-password", inputs: ["ariaLabel", "ariaLabelledBy", "label", "promptLabel", "mediumRegex", "strongRegex", "weakLabel", "mediumLabel", "maxLength", "strongLabel", "inputId", "feedback", "toggleMask", "inputStyleClass", "styleClass", "inputStyle", "showTransitionOptions", "hideTransitionOptions", "autocomplete", "placeholder", "showClear", "autofocus", "tabindex", "appendTo", "motionOptions", "overlayOptions"], outputs: ["onFocus", "onBlur", "onClear"] }, { kind: "component", type: i11.Select, selector: "p-select", inputs: ["id", "scrollHeight", "filter", "panelStyle", "styleClass", "panelStyleClass", "readonly", "editable", "tabindex", "placeholder", "loadingIcon", "filterPlaceholder", "filterLocale", "inputId", "dataKey", "filterBy", "filterFields", "autofocus", "resetFilterOnHide", "checkmark", "dropdownIcon", "loading", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "group", "showClear", "emptyFilterMessage", "emptyMessage", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "overlayOptions", "ariaFilterLabel", "ariaLabel", "ariaLabelledBy", "filterMatchMode", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "focusOnHover", "selectOnFocus", "autoOptionFocus", "autofocusFilter", "filterValue", "options", "appendTo", "motionOptions"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }, { kind: "directive", type: i12.Textarea, selector: "[pTextarea], [pInputTextarea]", inputs: ["pTextareaPT", "pTextareaUnstyled", "autoResize", "pSize", "variant", "fluid", "invalid"], outputs: ["onResize"] }, { kind: "component", type: i13.ToggleSwitch, selector: "p-toggleswitch, p-toggleSwitch, p-toggle-switch", inputs: ["styleClass", "tabindex", "inputId", "readonly", "trueValue", "falseValue", "ariaLabel", "size", "ariaLabelledBy", "autofocus"], outputs: ["onChange"] }] });
2096
+ }
2097
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: BaseFormComponent, decorators: [{
2098
+ type: Component,
2099
+ args: [{ selector: 'lib-base-form', imports: [AngularModule, PrimeModule], template: "<p-card>\n <ng-template #header>\n @if (resolvedTitle()) {\n <div class=\"flex justify-between items-center p-4\">\n <h2 class=\"text-xl font-semibold m-0\">{{ resolvedTitle() }}</h2>\n </div>\n }\n </ng-template>\n\n <form (ngSubmit)=\"handleSubmit()\" novalidate>\n <div class=\"grid gap-4\" [class]=\"gridClass()\">\n @for (field of fields(); track field.key) {\n <div class=\"flex flex-col gap-2\" [class.col-span-full]=\"field.fullWidth\">\n @if (field.type !== 'checkbox' && field.type !== 'toggle') {\n <label [for]=\"field.key\" class=\"font-medium\">\n {{ field.label }}\n @if (field.required) {\n <span class=\"text-red-500 ml-1\">*</span>\n }\n </label>\n }\n\n @switch (field.type) {\n @case ('text') {\n <input\n pInputText\n [id]=\"field.key\"\n [name]=\"field.key\"\n [ngModel]=\"getFieldValue(field.key)\"\n (ngModelChange)=\"setFieldValue(field.key, $event)\"\n (blur)=\"markFieldTouched(field.key)\"\n [placeholder]=\"field.placeholder ?? ''\"\n [disabled]=\"field.disabled ?? false\"\n [class.ng-invalid]=\"isFieldInvalid(field)\"\n [class.ng-dirty]=\"isFieldInvalid(field)\"\n class=\"w-full\"\n />\n }\n\n @case ('email') {\n <input\n pInputText\n type=\"email\"\n [id]=\"field.key\"\n [name]=\"field.key\"\n [ngModel]=\"getFieldValue(field.key)\"\n (ngModelChange)=\"setFieldValue(field.key, $event)\"\n (blur)=\"markFieldTouched(field.key)\"\n [placeholder]=\"field.placeholder ?? ''\"\n [disabled]=\"field.disabled ?? false\"\n [class.ng-invalid]=\"isFieldInvalid(field)\"\n [class.ng-dirty]=\"isFieldInvalid(field)\"\n class=\"w-full\"\n />\n }\n\n @case ('password') {\n <p-password\n [inputId]=\"field.key\"\n [name]=\"field.key\"\n [ngModel]=\"getFieldValue(field.key)\"\n (ngModelChange)=\"setFieldValue(field.key, $event)\"\n (onBlur)=\"markFieldTouched(field.key)\"\n [placeholder]=\"field.placeholder ?? ''\"\n [disabled]=\"field.disabled ?? false\"\n [feedback]=\"false\"\n [toggleMask]=\"true\"\n [invalid]=\"isFieldInvalid(field)\"\n class=\"w-full\"\n inputStyleClass=\"w-full\"\n />\n }\n\n @case ('number') {\n <p-inputnumber\n [inputId]=\"field.key\"\n [name]=\"field.key\"\n [ngModel]=\"getFieldValue(field.key)\"\n (ngModelChange)=\"setFieldValue(field.key, $event)\"\n (onBlur)=\"markFieldTouched(field.key)\"\n [placeholder]=\"field.placeholder ?? ''\"\n [disabled]=\"field.disabled ?? false\"\n [min]=\"field.min ?? undefined\"\n [max]=\"field.max ?? undefined\"\n [invalid]=\"isFieldInvalid(field)\"\n class=\"w-full\"\n inputStyleClass=\"w-full\"\n />\n }\n\n @case ('textarea') {\n <textarea\n pTextarea\n [id]=\"field.key\"\n [name]=\"field.key\"\n [ngModel]=\"getFieldValue(field.key)\"\n (ngModelChange)=\"setFieldValue(field.key, $event)\"\n (blur)=\"markFieldTouched(field.key)\"\n [placeholder]=\"field.placeholder ?? ''\"\n [disabled]=\"field.disabled ?? false\"\n [rows]=\"field.rows ?? 3\"\n [class.ng-invalid]=\"isFieldInvalid(field)\"\n [class.ng-dirty]=\"isFieldInvalid(field)\"\n class=\"w-full\"\n ></textarea>\n }\n\n @case ('select') {\n <p-select\n [inputId]=\"field.key\"\n [name]=\"field.key\"\n [ngModel]=\"getFieldValue(field.key)\"\n (ngModelChange)=\"setFieldValue(field.key, $event)\"\n [options]=\"field.options ?? []\"\n optionLabel=\"label\"\n optionValue=\"value\"\n [placeholder]=\"field.placeholder ?? t('shared.select.placeholder')\"\n [disabled]=\"field.disabled ?? false\"\n [invalid]=\"isFieldInvalid(field)\"\n class=\"w-full\"\n />\n }\n\n @case ('multiselect') {\n <p-multiselect\n [inputId]=\"field.key\"\n [name]=\"field.key\"\n [ngModel]=\"getFieldValue(field.key)\"\n (ngModelChange)=\"setFieldValue(field.key, $event)\"\n [options]=\"field.options ?? []\"\n optionLabel=\"label\"\n optionValue=\"value\"\n [placeholder]=\"field.placeholder ?? t('shared.select.placeholder')\"\n [disabled]=\"field.disabled ?? false\"\n [invalid]=\"isFieldInvalid(field)\"\n class=\"w-full\"\n />\n }\n\n @case ('date') {\n <p-datepicker\n [inputId]=\"field.key\"\n [name]=\"field.key\"\n [ngModel]=\"getFieldValue(field.key)\"\n (ngModelChange)=\"setFieldValue(field.key, $event)\"\n (onBlur)=\"markFieldTouched(field.key)\"\n [placeholder]=\"field.placeholder ?? ''\"\n [disabled]=\"field.disabled ?? false\"\n [minDate]=\"field.minDate ?? undefined\"\n [maxDate]=\"field.maxDate ?? undefined\"\n [invalid]=\"isFieldInvalid(field)\"\n class=\"w-full\"\n inputStyleClass=\"w-full\"\n />\n }\n\n @case ('checkbox') {\n <div class=\"flex items-center gap-2 h-9\">\n <p-checkbox\n [inputId]=\"field.key\"\n [name]=\"field.key\"\n [ngModel]=\"getFieldValue(field.key)\"\n (ngModelChange)=\"setFieldValue(field.key, $event)\"\n [disabled]=\"field.disabled ?? false\"\n [binary]=\"true\"\n [invalid]=\"isFieldInvalid(field)\"\n />\n <label [for]=\"field.key\" class=\"font-medium cursor-pointer select-none\">\n {{ field.label }}\n @if (field.required) {\n <span class=\"text-red-500 ml-1\">*</span>\n }\n </label>\n </div>\n }\n\n @case ('toggle') {\n <div class=\"flex items-center gap-3 h-9\">\n <p-toggleswitch\n [inputId]=\"field.key\"\n [name]=\"field.key\"\n [ngModel]=\"getFieldValue(field.key)\"\n (ngModelChange)=\"setFieldValue(field.key, $event)\"\n [disabled]=\"field.disabled ?? false\"\n />\n <label [for]=\"field.key\" class=\"font-medium cursor-pointer select-none\">\n {{ field.label }}\n @if (field.required) {\n <span class=\"text-red-500 ml-1\">*</span>\n }\n </label>\n </div>\n }\n\n @case ('custom') {\n <ng-container\n *ngTemplateOutlet=\"getFieldTemplate(field.key); context: { $implicit: getFieldValue(field.key), field: field }\"\n />\n }\n }\n\n @if (isFieldInvalid(field)) {\n <small class=\"text-red-500\">{{ field.label }} {{ t('shared.required') }}</small>\n }\n\n @if (field.hint && !isFieldInvalid(field)) {\n <small class=\"text-surface-400\">{{ field.hint }}</small>\n }\n </div>\n }\n\n <div class=\"col-span-full flex justify-end gap-4 pt-4\">\n <p-button\n type=\"button\"\n [label]=\"cancelLabel() || t('shared.cancel')\"\n severity=\"secondary\"\n [outlined]=\"true\"\n [disabled]=\"effectiveIsLoading()\"\n (onClick)=\"handleCancel()\"\n />\n <p-button\n type=\"submit\"\n [label]=\"submitLabel() || (effectiveIsEditMode() ? t('shared.update') : t('shared.save'))\"\n [loading]=\"effectiveIsLoading()\"\n [disabled]=\"!isFormValid() || effectiveIsLoading()\"\n />\n </div>\n </div>\n </form>\n</p-card>\n" }]
2100
+ }], ctorParameters: () => [], propDecorators: { fields: [{ type: i0.Input, args: [{ isSignal: true, alias: "fields", required: true }] }], title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: false }] }], createTitle: [{ type: i0.Input, args: [{ isSignal: true, alias: "createTitle", required: false }] }], editTitle: [{ type: i0.Input, args: [{ isSignal: true, alias: "editTitle", required: false }] }], columns: [{ type: i0.Input, args: [{ isSignal: true, alias: "columns", required: false }] }], submitLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "submitLabel", required: false }] }], cancelLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "cancelLabel", required: false }] }], isLoading: [{ type: i0.Input, args: [{ isSignal: true, alias: "isLoading", required: false }] }], isEditMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "isEditMode", required: false }] }], initialValue: [{ type: i0.Input, args: [{ isSignal: true, alias: "initialValue", required: false }] }], service: [{ type: i0.Input, args: [{ isSignal: true, alias: "service", required: false }] }], editId: [{ type: i0.Input, args: [{ isSignal: true, alias: "editId", required: false }] }], cancelRoute: [{ type: i0.Input, args: [{ isSignal: true, alias: "cancelRoute", required: false }] }], navigateOnSuccess: [{ type: i0.Input, args: [{ isSignal: true, alias: "navigateOnSuccess", required: false }] }], mapToRequest: [{ type: i0.Input, args: [{ isSignal: true, alias: "mapToRequest", required: false }] }], mapFromEntity: [{ type: i0.Input, args: [{ isSignal: true, alias: "mapFromEntity", required: false }] }], onSubmit: [{ type: i0.Output, args: ["onSubmit"] }], onCancel: [{ type: i0.Output, args: ["onCancel"] }], onValueChange: [{ type: i0.Output, args: ["onValueChange"] }], fieldTemplates: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => BaseFormTemplateDirective), { isSignal: true }] }] } });
2101
+
2102
+ class InlineSvgComponent {
2103
+ src = input.required(...(ngDevMode ? [{ debugName: "src" }] : []));
2104
+ http = inject(HttpClient);
2105
+ sanitizer = inject(DomSanitizer);
2106
+ svg = resource({ ...(ngDevMode ? { debugName: "svg" } : {}), params: this.src,
2107
+ loader: ({ params: url }) => firstValueFrom(this.http.get(url, { responseType: 'text' })).then((text) => this.sanitizer.bypassSecurityTrustHtml(text)) });
2108
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: InlineSvgComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
2109
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.5", type: InlineSvgComponent, isStandalone: true, selector: "inline-svg", inputs: { src: { classPropertyName: "src", publicName: "src", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: `
2110
+ @if (svg.hasValue()) {
2111
+ <span [innerHTML]="svg.value()"></span>
2112
+ }
2113
+ `, isInline: true, styles: ["inline-svg{display:inline-flex;align-items:center}inline-svg span{display:inline-flex;align-items:center;height:100%;width:100%}inline-svg svg{height:100%;width:auto}\n"], encapsulation: i0.ViewEncapsulation.None });
2114
+ }
2115
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: InlineSvgComponent, decorators: [{
2116
+ type: Component,
2117
+ args: [{ selector: 'inline-svg', encapsulation: ViewEncapsulation.None, template: `
2118
+ @if (svg.hasValue()) {
2119
+ <span [innerHTML]="svg.value()"></span>
2120
+ }
2121
+ `, styles: ["inline-svg{display:inline-flex;align-items:center}inline-svg span{display:inline-flex;align-items:center;height:100%;width:100%}inline-svg svg{height:100%;width:auto}\n"] }]
2122
+ }], propDecorators: { src: [{ type: i0.Input, args: [{ isSignal: true, alias: "src", required: true }] }] } });
2123
+
1684
2124
  /**
1685
2125
  * Injection Tokens for Provider Interfaces
1686
2126
  *
@@ -2137,7 +2577,7 @@ class FileUploaderComponent {
2137
2577
  }
2138
2578
  </div>
2139
2579
  }
2140
- `, isInline: true, styles: [".upload-zone{border-color:var(--p-surface-300);background:var(--p-surface-50)}.upload-zone:hover:not(.cursor-not-allowed){border-color:var(--p-primary-color);background:var(--p-surface-100)}.upload-zone.drag-over{border-color:var(--p-primary-color);background:var(--p-primary-50)}:host-context(.p-dark) .upload-zone,.dark .upload-zone{border-color:var(--p-surface-600);background:var(--p-surface-800)}:host-context(.p-dark) .upload-zone:hover:not(.cursor-not-allowed),.dark .upload-zone:hover:not(.cursor-not-allowed){border-color:var(--p-primary-color);background:var(--p-surface-700)}:host-context(.p-dark) .upload-zone.drag-over,.dark .upload-zone.drag-over{border-color:var(--p-primary-color);background:var(--p-primary-900)}.file-preview-item{border:1px solid var(--p-surface-200);background:var(--p-surface-0)}:host-context(.p-dark) .file-preview-item,.dark .file-preview-item{border-color:var(--p-surface-600);background:var(--p-surface-800)}\n"], dependencies: [{ kind: "ngmodule", type: AngularModule }, { kind: "ngmodule", type: PrimeModule }, { kind: "component", type: i1.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: i2.ProgressBar, selector: "p-progressBar, p-progressbar, p-progress-bar", inputs: ["value", "showValue", "styleClass", "valueStyleClass", "unit", "mode", "color"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }] });
2580
+ `, isInline: true, styles: [".upload-zone{border-color:var(--p-surface-300);background:var(--p-surface-50)}.upload-zone:hover:not(.cursor-not-allowed){border-color:var(--p-primary-color);background:var(--p-surface-100)}.upload-zone.drag-over{border-color:var(--p-primary-color);background:var(--p-primary-50)}:host-context(.p-dark) .upload-zone,.dark .upload-zone{border-color:var(--p-surface-600);background:var(--p-surface-800)}:host-context(.p-dark) .upload-zone:hover:not(.cursor-not-allowed),.dark .upload-zone:hover:not(.cursor-not-allowed){border-color:var(--p-primary-color);background:var(--p-surface-700)}:host-context(.p-dark) .upload-zone.drag-over,.dark .upload-zone.drag-over{border-color:var(--p-primary-color);background:var(--p-primary-900)}.file-preview-item{border:1px solid var(--p-surface-200);background:var(--p-surface-0)}:host-context(.p-dark) .file-preview-item,.dark .file-preview-item{border-color:var(--p-surface-600);background:var(--p-surface-800)}\n"], dependencies: [{ kind: "ngmodule", type: AngularModule }, { kind: "ngmodule", type: PrimeModule }, { kind: "component", type: i3.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: i2$1.ProgressBar, selector: "p-progressBar, p-progressbar, p-progress-bar", inputs: ["value", "showValue", "styleClass", "valueStyleClass", "unit", "mode", "color"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }] });
2141
2581
  }
2142
2582
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: FileUploaderComponent, decorators: [{
2143
2583
  type: Component,
@@ -2860,7 +3300,7 @@ class FileSelectorDialogComponent {
2860
3300
  </ng-template>
2861
3301
  }
2862
3302
  </p-dialog>
2863
- `, isInline: true, styles: [".file-grid{display:grid;grid-template-columns:repeat(2,1fr);gap:.75rem;max-height:300px;overflow-y:auto;padding:.5rem}@media(min-width:480px){.file-grid{grid-template-columns:repeat(3,1fr);max-height:350px}}@media(min-width:640px){.file-grid{grid-template-columns:repeat(auto-fill,minmax(140px,1fr));gap:1rem;max-height:400px}}.file-card{border:2px solid var(--p-surface-300);border-radius:var(--p-border-radius);cursor:pointer;transition:all .2s ease;overflow:hidden;background:var(--p-surface-0)}:host-context(.p-dark) .file-card,.dark .file-card{border-color:var(--p-surface-600);background:var(--p-surface-800)}.file-card:hover:not(.disabled){border-color:var(--p-primary-color);transform:translateY(-2px);box-shadow:var(--p-overlay-shadow)}.file-card.selected{border-color:var(--p-primary-color);background:var(--p-primary-50)}:host-context(.p-dark) .file-card.selected,.dark .file-card.selected{background:var(--p-primary-900)}.file-card.disabled{opacity:.5;cursor:not-allowed}.file-preview{position:relative;height:80px;display:flex;align-items:center;justify-content:center;background:var(--p-surface-100)}@media(min-width:640px){.file-preview{height:100px}}:host-context(.p-dark) .file-preview,.dark .file-preview{background:var(--p-surface-700)}.selected-overlay{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;background:rgba(var(--p-primary-500-rgb, 59, 130, 246),.3)}.selected-overlay i{color:var(--p-primary-color);background:var(--p-surface-0);border-radius:50%;padding:.5rem}:host-context(.p-dark) .selected-overlay i,.dark .selected-overlay i{background:var(--p-surface-900)}\n"], dependencies: [{ kind: "ngmodule", type: AngularModule }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: IsEmptyImageDirective, selector: "img", inputs: ["src"] }, { kind: "ngmodule", type: PrimeModule }, { kind: "directive", type: i3.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "directive", type: i1.ButtonDirective, selector: "[pButton]", inputs: ["ptButtonDirective", "pButtonPT", "pButtonUnstyled", "hostName", "text", "plain", "raised", "size", "outlined", "rounded", "iconPos", "loadingIcon", "fluid", "label", "icon", "loading", "buttonProps", "severity"] }, { kind: "component", type: i5.Dialog, selector: "p-dialog", inputs: ["hostName", "header", "draggable", "resizable", "contentStyle", "contentStyleClass", "modal", "closeOnEscape", "dismissableMask", "rtl", "closable", "breakpoints", "styleClass", "maskStyleClass", "maskStyle", "showHeader", "blockScroll", "autoZIndex", "baseZIndex", "minX", "minY", "focusOnShow", "maximizable", "keepInViewport", "focusTrap", "transitionOptions", "maskMotionOptions", "motionOptions", "closeIcon", "closeAriaLabel", "closeTabindex", "minimizeIcon", "maximizeIcon", "closeButtonProps", "maximizeButtonProps", "visible", "style", "position", "role", "appendTo", "content", "contentTemplate", "footerTemplate", "closeIconTemplate", "maximizeIconTemplate", "minimizeIconTemplate", "headlessTemplate"], outputs: ["onShow", "onHide", "visibleChange", "onResizeInit", "onResizeEnd", "onDragEnd", "onMaximize"] }, { kind: "component", type: i6.IconField, selector: "p-iconfield, p-iconField, p-icon-field", inputs: ["hostName", "iconPosition", "styleClass"] }, { kind: "component", type: i7.InputIcon, selector: "p-inputicon, p-inputIcon", inputs: ["hostName", "styleClass"] }, { kind: "directive", type: i2$1.InputText, selector: "[pInputText]", inputs: ["hostName", "ptInputText", "pInputTextPT", "pInputTextUnstyled", "pSize", "variant", "fluid", "invalid"] }, { kind: "component", type: i9.Select, selector: "p-select", inputs: ["id", "scrollHeight", "filter", "panelStyle", "styleClass", "panelStyleClass", "readonly", "editable", "tabindex", "placeholder", "loadingIcon", "filterPlaceholder", "filterLocale", "inputId", "dataKey", "filterBy", "filterFields", "autofocus", "resetFilterOnHide", "checkmark", "dropdownIcon", "loading", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "group", "showClear", "emptyFilterMessage", "emptyMessage", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "overlayOptions", "ariaFilterLabel", "ariaLabel", "ariaLabelledBy", "filterMatchMode", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "focusOnHover", "selectOnFocus", "autoOptionFocus", "autofocusFilter", "filterValue", "options", "appendTo", "motionOptions"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }, { kind: "component", type: FileUploaderComponent, selector: "lib-file-uploader", inputs: ["uploadFile", "uploadMultipleFiles", "acceptTypes", "multiple", "maxFiles", "maxSizeMb", "uploadOptions", "disabled", "showPreview", "autoUpload"], outputs: ["fileUploaded", "filesUploaded", "onError", "fileSelected"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }] });
3303
+ `, isInline: true, styles: [".file-grid{display:grid;grid-template-columns:repeat(2,1fr);gap:.75rem;max-height:300px;overflow-y:auto;padding:.5rem}@media(min-width:480px){.file-grid{grid-template-columns:repeat(3,1fr);max-height:350px}}@media(min-width:640px){.file-grid{grid-template-columns:repeat(auto-fill,minmax(140px,1fr));gap:1rem;max-height:400px}}.file-card{border:2px solid var(--p-surface-300);border-radius:var(--p-border-radius);cursor:pointer;transition:all .2s ease;overflow:hidden;background:var(--p-surface-0)}:host-context(.p-dark) .file-card,.dark .file-card{border-color:var(--p-surface-600);background:var(--p-surface-800)}.file-card:hover:not(.disabled){border-color:var(--p-primary-color);transform:translateY(-2px);box-shadow:var(--p-overlay-shadow)}.file-card.selected{border-color:var(--p-primary-color);background:var(--p-primary-50)}:host-context(.p-dark) .file-card.selected,.dark .file-card.selected{background:var(--p-primary-900)}.file-card.disabled{opacity:.5;cursor:not-allowed}.file-preview{position:relative;height:80px;display:flex;align-items:center;justify-content:center;background:var(--p-surface-100)}@media(min-width:640px){.file-preview{height:100px}}:host-context(.p-dark) .file-preview,.dark .file-preview{background:var(--p-surface-700)}.selected-overlay{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;background:rgba(var(--p-primary-500-rgb, 59, 130, 246),.3)}.selected-overlay i{color:var(--p-primary-color);background:var(--p-surface-0);border-radius:50%;padding:.5rem}:host-context(.p-dark) .selected-overlay i,.dark .selected-overlay i{background:var(--p-surface-900)}\n"], dependencies: [{ kind: "ngmodule", type: AngularModule }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: IsEmptyImageDirective, selector: "img", inputs: ["src"] }, { kind: "ngmodule", type: PrimeModule }, { kind: "directive", type: i3$1.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "directive", type: i3.ButtonDirective, selector: "[pButton]", inputs: ["ptButtonDirective", "pButtonPT", "pButtonUnstyled", "hostName", "text", "plain", "raised", "size", "outlined", "rounded", "iconPos", "loadingIcon", "fluid", "label", "icon", "loading", "buttonProps", "severity"] }, { kind: "component", type: i5$2.Dialog, selector: "p-dialog", inputs: ["hostName", "header", "draggable", "resizable", "contentStyle", "contentStyleClass", "modal", "closeOnEscape", "dismissableMask", "rtl", "closable", "breakpoints", "styleClass", "maskStyleClass", "maskStyle", "showHeader", "blockScroll", "autoZIndex", "baseZIndex", "minX", "minY", "focusOnShow", "maximizable", "keepInViewport", "focusTrap", "transitionOptions", "maskMotionOptions", "motionOptions", "closeIcon", "closeAriaLabel", "closeTabindex", "minimizeIcon", "maximizeIcon", "closeButtonProps", "maximizeButtonProps", "visible", "style", "position", "role", "appendTo", "content", "contentTemplate", "footerTemplate", "closeIconTemplate", "maximizeIconTemplate", "minimizeIconTemplate", "headlessTemplate"], outputs: ["onShow", "onHide", "visibleChange", "onResizeInit", "onResizeEnd", "onDragEnd", "onMaximize"] }, { kind: "component", type: i5.IconField, selector: "p-iconfield, p-iconField, p-icon-field", inputs: ["hostName", "iconPosition", "styleClass"] }, { kind: "component", type: i6.InputIcon, selector: "p-inputicon, p-inputIcon", inputs: ["hostName", "styleClass"] }, { kind: "directive", type: i8.InputText, selector: "[pInputText]", inputs: ["hostName", "ptInputText", "pInputTextPT", "pInputTextUnstyled", "pSize", "variant", "fluid", "invalid"] }, { kind: "component", type: i11.Select, selector: "p-select", inputs: ["id", "scrollHeight", "filter", "panelStyle", "styleClass", "panelStyleClass", "readonly", "editable", "tabindex", "placeholder", "loadingIcon", "filterPlaceholder", "filterLocale", "inputId", "dataKey", "filterBy", "filterFields", "autofocus", "resetFilterOnHide", "checkmark", "dropdownIcon", "loading", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "group", "showClear", "emptyFilterMessage", "emptyMessage", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "overlayOptions", "ariaFilterLabel", "ariaLabel", "ariaLabelledBy", "filterMatchMode", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "focusOnHover", "selectOnFocus", "autoOptionFocus", "autofocusFilter", "filterValue", "options", "appendTo", "motionOptions"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }, { kind: "component", type: FileUploaderComponent, selector: "lib-file-uploader", inputs: ["uploadFile", "uploadMultipleFiles", "acceptTypes", "multiple", "maxFiles", "maxSizeMb", "uploadOptions", "disabled", "showPreview", "autoUpload"], outputs: ["fileUploaded", "filesUploaded", "onError", "fileSelected"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }] });
2864
3304
  }
2865
3305
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: FileSelectorDialogComponent, decorators: [{
2866
3306
  type: Component,
@@ -3352,7 +3792,7 @@ class LazyMultiSelectComponent extends BaseFormControl {
3352
3792
  return key;
3353
3793
  }
3354
3794
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: LazyMultiSelectComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
3355
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.5", type: LazyMultiSelectComponent, isStandalone: true, selector: "lib-lazy-multi-select", inputs: { placeHolder: { classPropertyName: "placeHolder", publicName: "placeHolder", isSignal: true, isRequired: false, transformFunction: null }, showClear: { classPropertyName: "showClear", publicName: "showClear", isSignal: true, isRequired: false, transformFunction: null }, isEditMode: { classPropertyName: "isEditMode", publicName: "isEditMode", isSignal: true, isRequired: true, transformFunction: null }, isLoading: { classPropertyName: "isLoading", publicName: "isLoading", isSignal: true, isRequired: true, transformFunction: null }, total: { classPropertyName: "total", publicName: "total", isSignal: true, isRequired: true, transformFunction: null }, pagination: { classPropertyName: "pagination", publicName: "pagination", isSignal: true, isRequired: true, transformFunction: null }, selectDataList: { classPropertyName: "selectDataList", publicName: "selectDataList", isSignal: true, isRequired: true, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange", onSearch: "onSearch", onPagination: "onPagination" }, providers: [provideValueAccessor(LazyMultiSelectComponent)], viewQueries: [{ propertyName: "pSelectRef", first: true, predicate: ["pSelect"], descendants: true, isSignal: true }, { propertyName: "overlayTemplate", first: true, predicate: ["overlayTpl"], descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: "<div\n class=\"p-select w-full\"\n #pSelect\n (click)=\"onSelectClick()\"\n [class.p-disabled]=\"disabled()\"\n [class.edit-mode-element-css]=\"!isEditMode()\"\n [class.overflow-hidden]=\"!isEditMode()\"\n>\n @if (selectedValueDisplay()) {\n <span class=\"p-select-label\" [class.edit-mode-element-css]=\"!isEditMode()\">\n {{ selectedValueDisplay() }}\n </span>\n } @else {\n <span class=\"p-select-label p-placeholder\">{{ displayPlaceholder() }}</span>\n }\n\n @if (showClear() && hasSelectedValues()) {\n <span class=\"p-select-clear-icon\" (click)=\"clear($event)\">\n <i class=\"pi pi-times\"></i>\n </span>\n }\n\n @if (isEditMode()) {\n <div class=\"p-select-dropdown\">\n <span class=\"p-select-dropdown-icon flex items-center\">\n <svg\n width=\"14\"\n height=\"14\"\n viewBox=\"0 0 14 14\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n class=\"p-multiselect-dropdown-icon p-icon\"\n aria-hidden=\"true\"\n >\n <path\n d=\"M7.01744 10.398C6.91269 10.3985 6.8089 10.378 6.71215 10.3379C6.61541 10.2977 6.52766 10.2386 6.45405 10.1641L1.13907 4.84913C1.03306 4.69404 0.985221 4.5065 1.00399 4.31958C1.02276 4.13266 1.10693 3.95838 1.24166 3.82747C1.37639 3.69655 1.55301 3.61742 1.74039 3.60402C1.92777 3.59062 2.11386 3.64382 2.26584 3.75424L7.01744 8.47394L11.769 3.75424C11.9189 3.65709 12.097 3.61306 12.2748 3.62921C12.4527 3.64535 12.6199 3.72073 12.7498 3.84328C12.8797 3.96582 12.9647 4.12842 12.9912 4.30502C13.0177 4.48162 12.9841 4.662 12.8958 4.81724L7.58083 10.1322C7.50996 10.2125 7.42344 10.2775 7.32656 10.3232C7.22968 10.3689 7.12449 10.3944 7.01744 10.398Z\"\n fill=\"currentColor\"\n />\n </svg>\n </span>\n </div>\n }\n</div>\n\n<ng-template #overlayTpl>\n <div class=\"p-select-overlay\" (click)=\"onOverlayClick($event)\">\n <div class=\"p-select-header flex flex-row gap-2 items-center\">\n <p-checkbox\n [binary]=\"true\"\n [ngModel]=\"isSelectAll()\"\n [disabled]=\"disabled()\"\n (onChange)=\"changeSelectAll($event)\"\n />\n <input\n type=\"text\"\n pInputText\n class=\"w-full\"\n [placeholder]=\"'shared.search' | translate\"\n [ngModel]=\"searchTerm()\"\n (ngModelChange)=\"searchTerm.set($event)\"\n />\n </div>\n <div class=\"p-select-list-container\" (scroll)=\"onScroll($event)\">\n <ul class=\"p-select-list\">\n @for (data of selectDataList(); track data.value) {\n @let isItemSelected = isSelected(data);\n <li\n class=\"p-select-option flex flex-row gap-2 items-center\"\n [class.p-select-option-selected]=\"isItemSelected\"\n >\n <p-checkbox\n [binary]=\"true\"\n [ngModel]=\"isItemSelected\"\n [disabled]=\"disabled()\"\n (onChange)=\"selectValue($event, data)\"\n />\n <span>{{ data.label }}</span>\n </li>\n }\n </ul>\n </div>\n </div>\n</ng-template>\n", styles: [".p-select-overlay{display:flex;flex-direction:column;max-height:250px;overflow:hidden}.p-select-header{padding:.75rem;border-bottom:1px solid var(--p-surface-border);background:var(--p-content-hover-background);flex-shrink:0;width:100%;box-sizing:border-box}.p-select-header input{background:var(--p-form-field-background);border-color:var(--p-form-field-border-color);color:var(--p-text-color)}.p-select-header input::placeholder{color:var(--p-text-muted-color)}.p-select-list-container{flex:1;overflow-y:auto;min-height:0;width:100%}.p-select-list{margin:0;padding:.25rem 0;list-style:none;background:var(--p-surface-overlay);color:var(--p-text-color);width:100%}.p-select-option{padding:.5rem .75rem;cursor:pointer;transition:background-color .2s ease;color:var(--p-text-color)}.p-select-option:hover{background:var(--p-content-hover-background)}.p-select-option.p-select-option-selected{background:var(--p-highlight-background);color:var(--p-highlight-color)}.p-select-option.p-select-option-selected:hover{background:var(--p-highlight-focus-background);color:var(--p-highlight-focus-color)}.p-select-clear-icon{display:flex;align-items:center;padding:0 .5rem;color:var(--p-text-muted-color);cursor:pointer;transition:color .2s ease}.p-select-clear-icon:hover{color:var(--p-text-color)}\n"], dependencies: [{ kind: "ngmodule", type: PrimeModule }, { kind: "component", type: i1$2.Checkbox, selector: "p-checkbox, p-checkBox, p-check-box", inputs: ["hostName", "value", "binary", "ariaLabelledBy", "ariaLabel", "tabindex", "inputId", "inputStyle", "styleClass", "inputClass", "indeterminate", "formControl", "checkboxIcon", "readonly", "autofocus", "trueValue", "falseValue", "variant", "size"], outputs: ["onChange", "onFocus", "onBlur"] }, { kind: "directive", type: i2$1.InputText, selector: "[pInputText]", inputs: ["hostName", "ptInputText", "pInputTextPT", "pInputTextUnstyled", "pSize", "variant", "fluid", "invalid"] }, { kind: "ngmodule", type: AngularModule }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }], encapsulation: i0.ViewEncapsulation.None });
3795
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.5", type: LazyMultiSelectComponent, isStandalone: true, selector: "lib-lazy-multi-select", inputs: { placeHolder: { classPropertyName: "placeHolder", publicName: "placeHolder", isSignal: true, isRequired: false, transformFunction: null }, showClear: { classPropertyName: "showClear", publicName: "showClear", isSignal: true, isRequired: false, transformFunction: null }, isEditMode: { classPropertyName: "isEditMode", publicName: "isEditMode", isSignal: true, isRequired: true, transformFunction: null }, isLoading: { classPropertyName: "isLoading", publicName: "isLoading", isSignal: true, isRequired: true, transformFunction: null }, total: { classPropertyName: "total", publicName: "total", isSignal: true, isRequired: true, transformFunction: null }, pagination: { classPropertyName: "pagination", publicName: "pagination", isSignal: true, isRequired: true, transformFunction: null }, selectDataList: { classPropertyName: "selectDataList", publicName: "selectDataList", isSignal: true, isRequired: true, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange", onSearch: "onSearch", onPagination: "onPagination" }, providers: [provideValueAccessor(LazyMultiSelectComponent)], viewQueries: [{ propertyName: "pSelectRef", first: true, predicate: ["pSelect"], descendants: true, isSignal: true }, { propertyName: "overlayTemplate", first: true, predicate: ["overlayTpl"], descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: "<div\n class=\"p-select w-full\"\n #pSelect\n (click)=\"onSelectClick()\"\n [class.p-disabled]=\"disabled()\"\n [class.edit-mode-element-css]=\"!isEditMode()\"\n [class.overflow-hidden]=\"!isEditMode()\"\n>\n @if (selectedValueDisplay()) {\n <span class=\"p-select-label\" [class.edit-mode-element-css]=\"!isEditMode()\">\n {{ selectedValueDisplay() }}\n </span>\n } @else {\n <span class=\"p-select-label p-placeholder\">{{ displayPlaceholder() }}</span>\n }\n\n @if (showClear() && hasSelectedValues()) {\n <span class=\"p-select-clear-icon\" (click)=\"clear($event)\">\n <i class=\"pi pi-times\"></i>\n </span>\n }\n\n @if (isEditMode()) {\n <div class=\"p-select-dropdown\">\n <span class=\"p-select-dropdown-icon flex items-center\">\n <svg\n width=\"14\"\n height=\"14\"\n viewBox=\"0 0 14 14\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n class=\"p-multiselect-dropdown-icon p-icon\"\n aria-hidden=\"true\"\n >\n <path\n d=\"M7.01744 10.398C6.91269 10.3985 6.8089 10.378 6.71215 10.3379C6.61541 10.2977 6.52766 10.2386 6.45405 10.1641L1.13907 4.84913C1.03306 4.69404 0.985221 4.5065 1.00399 4.31958C1.02276 4.13266 1.10693 3.95838 1.24166 3.82747C1.37639 3.69655 1.55301 3.61742 1.74039 3.60402C1.92777 3.59062 2.11386 3.64382 2.26584 3.75424L7.01744 8.47394L11.769 3.75424C11.9189 3.65709 12.097 3.61306 12.2748 3.62921C12.4527 3.64535 12.6199 3.72073 12.7498 3.84328C12.8797 3.96582 12.9647 4.12842 12.9912 4.30502C13.0177 4.48162 12.9841 4.662 12.8958 4.81724L7.58083 10.1322C7.50996 10.2125 7.42344 10.2775 7.32656 10.3232C7.22968 10.3689 7.12449 10.3944 7.01744 10.398Z\"\n fill=\"currentColor\"\n />\n </svg>\n </span>\n </div>\n }\n</div>\n\n<ng-template #overlayTpl>\n <div class=\"p-select-overlay\" (click)=\"onOverlayClick($event)\">\n <div class=\"p-select-header flex flex-row gap-2 items-center\">\n <p-checkbox\n [binary]=\"true\"\n [ngModel]=\"isSelectAll()\"\n [disabled]=\"disabled()\"\n (onChange)=\"changeSelectAll($event)\"\n />\n <input\n type=\"text\"\n pInputText\n class=\"w-full\"\n [placeholder]=\"'shared.search' | translate\"\n [ngModel]=\"searchTerm()\"\n (ngModelChange)=\"searchTerm.set($event)\"\n />\n </div>\n <div class=\"p-select-list-container\" (scroll)=\"onScroll($event)\">\n <ul class=\"p-select-list\">\n @for (data of selectDataList(); track data.value) {\n @let isItemSelected = isSelected(data);\n <li\n class=\"p-select-option flex flex-row gap-2 items-center\"\n [class.p-select-option-selected]=\"isItemSelected\"\n >\n <p-checkbox\n [binary]=\"true\"\n [ngModel]=\"isItemSelected\"\n [disabled]=\"disabled()\"\n (onChange)=\"selectValue($event, data)\"\n />\n <span>{{ data.label }}</span>\n </li>\n }\n </ul>\n </div>\n </div>\n</ng-template>\n", styles: [".p-select-overlay{display:flex;flex-direction:column;max-height:250px;overflow:hidden}.p-select-header{padding:.75rem;border-bottom:1px solid var(--p-surface-border);background:var(--p-content-hover-background);flex-shrink:0;width:100%;box-sizing:border-box}.p-select-header input{background:var(--p-form-field-background);border-color:var(--p-form-field-border-color);color:var(--p-text-color)}.p-select-header input::placeholder{color:var(--p-text-muted-color)}.p-select-list-container{flex:1;overflow-y:auto;min-height:0;width:100%}.p-select-list{margin:0;padding:.25rem 0;list-style:none;background:var(--p-surface-overlay);color:var(--p-text-color);width:100%}.p-select-option{padding:.5rem .75rem;cursor:pointer;transition:background-color .2s ease;color:var(--p-text-color)}.p-select-option:hover{background:var(--p-content-hover-background)}.p-select-option.p-select-option-selected{background:var(--p-highlight-background);color:var(--p-highlight-color)}.p-select-option.p-select-option-selected:hover{background:var(--p-highlight-focus-background);color:var(--p-highlight-focus-color)}.p-select-clear-icon{display:flex;align-items:center;padding:0 .5rem;color:var(--p-text-muted-color);cursor:pointer;transition:color .2s ease}.p-select-clear-icon:hover{color:var(--p-text-color)}\n"], dependencies: [{ kind: "ngmodule", type: PrimeModule }, { kind: "component", type: i5$1.Checkbox, selector: "p-checkbox, p-checkBox, p-check-box", inputs: ["hostName", "value", "binary", "ariaLabelledBy", "ariaLabel", "tabindex", "inputId", "inputStyle", "styleClass", "inputClass", "indeterminate", "formControl", "checkboxIcon", "readonly", "autofocus", "trueValue", "falseValue", "variant", "size"], outputs: ["onChange", "onFocus", "onBlur"] }, { kind: "directive", type: i8.InputText, selector: "[pInputText]", inputs: ["hostName", "ptInputText", "pInputTextPT", "pInputTextUnstyled", "pSize", "variant", "fluid", "invalid"] }, { kind: "ngmodule", type: AngularModule }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }], encapsulation: i0.ViewEncapsulation.None });
3356
3796
  }
3357
3797
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: LazyMultiSelectComponent, decorators: [{
3358
3798
  type: Component,
@@ -3476,7 +3916,7 @@ class LazySelectComponent extends BaseFormControl {
3476
3916
  return key;
3477
3917
  }
3478
3918
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: LazySelectComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
3479
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "21.1.5", type: LazySelectComponent, isStandalone: true, selector: "lib-lazy-select", inputs: { placeHolder: { classPropertyName: "placeHolder", publicName: "placeHolder", isSignal: true, isRequired: false, transformFunction: null }, showClear: { classPropertyName: "showClear", publicName: "showClear", isSignal: true, isRequired: false, transformFunction: null }, optionLabel: { classPropertyName: "optionLabel", publicName: "optionLabel", isSignal: true, isRequired: true, transformFunction: null }, optionValue: { classPropertyName: "optionValue", publicName: "optionValue", isSignal: true, isRequired: true, transformFunction: null }, isEditMode: { classPropertyName: "isEditMode", publicName: "isEditMode", isSignal: true, isRequired: true, transformFunction: null }, isLoading: { classPropertyName: "isLoading", publicName: "isLoading", isSignal: true, isRequired: true, transformFunction: null }, total: { classPropertyName: "total", publicName: "total", isSignal: true, isRequired: true, transformFunction: null }, pagination: { classPropertyName: "pagination", publicName: "pagination", isSignal: true, isRequired: true, transformFunction: null }, selectDataList: { classPropertyName: "selectDataList", publicName: "selectDataList", isSignal: true, isRequired: true, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange", onSearch: "onSearch", onPagination: "onPagination" }, providers: [provideValueAccessor(LazySelectComponent)], viewQueries: [{ propertyName: "scrollContainer", first: true, predicate: ["scrollContainer"], descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: "<div #scrollContainer class=\"lib-scroll-container\">\n <p-select\n class=\"w-full\"\n [options]=\"selectDataList()\"\n [optionLabel]=\"optionLabel()\"\n [optionValue]=\"optionValue()\"\n [filter]=\"true\"\n [showClear]=\"showClear()\"\n [placeholder]=\"displayPlaceholder()\"\n [disabled]=\"disabled()\"\n [(ngModel)]=\"value\"\n appEditModeElementChanger\n [isEditMode]=\"isEditMode()\"\n (click)=\"showPanel()\"\n (onBlur)=\"onBlur()\"\n >\n <ng-template #filter let-filter>\n <input\n pInputText\n class=\"w-full\"\n [ngModel]=\"searchTerm()\"\n [ngModelOptions]=\"{ standalone: true }\"\n (ngModelChange)=\"searchTerm.set($event)\"\n />\n </ng-template>\n <ng-template #selectedItem let-selectedOption>\n {{ selectedOption[optionLabel()] }}\n </ng-template>\n <ng-template #item let-item>\n {{ item[optionLabel()] }}\n </ng-template>\n </p-select>\n</div>\n", styles: [""], dependencies: [{ kind: "ngmodule", type: AngularModule }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: PrimeModule }, { kind: "directive", type: i2$1.InputText, selector: "[pInputText]", inputs: ["hostName", "ptInputText", "pInputTextPT", "pInputTextUnstyled", "pSize", "variant", "fluid", "invalid"] }, { kind: "component", type: i9.Select, selector: "p-select", inputs: ["id", "scrollHeight", "filter", "panelStyle", "styleClass", "panelStyleClass", "readonly", "editable", "tabindex", "placeholder", "loadingIcon", "filterPlaceholder", "filterLocale", "inputId", "dataKey", "filterBy", "filterFields", "autofocus", "resetFilterOnHide", "checkmark", "dropdownIcon", "loading", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "group", "showClear", "emptyFilterMessage", "emptyMessage", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "overlayOptions", "ariaFilterLabel", "ariaLabel", "ariaLabelledBy", "filterMatchMode", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "focusOnHover", "selectOnFocus", "autoOptionFocus", "autofocusFilter", "filterValue", "options", "appendTo", "motionOptions"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }, { kind: "directive", type: EditModeElementChangerDirective, selector: "[appEditModeElementChanger]", inputs: ["isEditMode"] }] });
3919
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "21.1.5", type: LazySelectComponent, isStandalone: true, selector: "lib-lazy-select", inputs: { placeHolder: { classPropertyName: "placeHolder", publicName: "placeHolder", isSignal: true, isRequired: false, transformFunction: null }, showClear: { classPropertyName: "showClear", publicName: "showClear", isSignal: true, isRequired: false, transformFunction: null }, optionLabel: { classPropertyName: "optionLabel", publicName: "optionLabel", isSignal: true, isRequired: true, transformFunction: null }, optionValue: { classPropertyName: "optionValue", publicName: "optionValue", isSignal: true, isRequired: true, transformFunction: null }, isEditMode: { classPropertyName: "isEditMode", publicName: "isEditMode", isSignal: true, isRequired: true, transformFunction: null }, isLoading: { classPropertyName: "isLoading", publicName: "isLoading", isSignal: true, isRequired: true, transformFunction: null }, total: { classPropertyName: "total", publicName: "total", isSignal: true, isRequired: true, transformFunction: null }, pagination: { classPropertyName: "pagination", publicName: "pagination", isSignal: true, isRequired: true, transformFunction: null }, selectDataList: { classPropertyName: "selectDataList", publicName: "selectDataList", isSignal: true, isRequired: true, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange", onSearch: "onSearch", onPagination: "onPagination" }, providers: [provideValueAccessor(LazySelectComponent)], viewQueries: [{ propertyName: "scrollContainer", first: true, predicate: ["scrollContainer"], descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: "<div #scrollContainer class=\"lib-scroll-container\">\n <p-select\n class=\"w-full\"\n [options]=\"selectDataList()\"\n [optionLabel]=\"optionLabel()\"\n [optionValue]=\"optionValue()\"\n [filter]=\"true\"\n [showClear]=\"showClear()\"\n [placeholder]=\"displayPlaceholder()\"\n [disabled]=\"disabled()\"\n [(ngModel)]=\"value\"\n appEditModeElementChanger\n [isEditMode]=\"isEditMode()\"\n (click)=\"showPanel()\"\n (onBlur)=\"onBlur()\"\n >\n <ng-template #filter let-filter>\n <input\n pInputText\n class=\"w-full\"\n [ngModel]=\"searchTerm()\"\n [ngModelOptions]=\"{ standalone: true }\"\n (ngModelChange)=\"searchTerm.set($event)\"\n />\n </ng-template>\n <ng-template #selectedItem let-selectedOption>\n {{ selectedOption[optionLabel()] }}\n </ng-template>\n <ng-template #item let-item>\n {{ item[optionLabel()] }}\n </ng-template>\n </p-select>\n</div>\n", styles: [""], dependencies: [{ kind: "ngmodule", type: AngularModule }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: PrimeModule }, { kind: "directive", type: i8.InputText, selector: "[pInputText]", inputs: ["hostName", "ptInputText", "pInputTextPT", "pInputTextUnstyled", "pSize", "variant", "fluid", "invalid"] }, { kind: "component", type: i11.Select, selector: "p-select", inputs: ["id", "scrollHeight", "filter", "panelStyle", "styleClass", "panelStyleClass", "readonly", "editable", "tabindex", "placeholder", "loadingIcon", "filterPlaceholder", "filterLocale", "inputId", "dataKey", "filterBy", "filterFields", "autofocus", "resetFilterOnHide", "checkmark", "dropdownIcon", "loading", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "group", "showClear", "emptyFilterMessage", "emptyMessage", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "overlayOptions", "ariaFilterLabel", "ariaLabel", "ariaLabelledBy", "filterMatchMode", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "focusOnHover", "selectOnFocus", "autoOptionFocus", "autofocusFilter", "filterValue", "options", "appendTo", "motionOptions"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }, { kind: "directive", type: EditModeElementChangerDirective, selector: "[appEditModeElementChanger]", inputs: ["isEditMode"] }] });
3480
3920
  }
3481
3921
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: LazySelectComponent, decorators: [{
3482
3922
  type: Component,
@@ -3883,390 +4323,6 @@ function allPermissionsGuard(permissions, redirectTo = '/') {
3883
4323
  return createGuard('allPermissionsGuard', redirectTo, (perms) => hasAllPermissions(permissions, perms), () => `Access denied - missing all of: ${permissions.join(', ')}`);
3884
4324
  }
3885
4325
 
3886
- /**
3887
- * Base class for form page components that handle create/edit operations.
3888
- * Provides common functionality for loading existing items, form submission,
3889
- * navigation, and toast notifications.
3890
- *
3891
- * ## Features
3892
- * - Automatic route parameter handling (loads item when ID is present)
3893
- * - Edit mode detection based on existing item
3894
- * - Unified submit handler for create/update operations
3895
- * - Cancel navigation
3896
- * - Toast messages for success/validation errors
3897
- *
3898
- * ## Usage
3899
- *
3900
- * ```typescript
3901
- * interface IProductFormModel {
3902
- * name: string;
3903
- * price: number;
3904
- * }
3905
- *
3906
- * @Component({
3907
- * selector: 'app-product-form',
3908
- * standalone: true,
3909
- * * template: `...`
3910
- * })
3911
- * export class ProductFormComponent extends BaseFormPage<IProduct, IProductFormModel> {
3912
- * private readonly productService = inject(ProductApiService);
3913
- *
3914
- * // Form model signal (private writable, public readonly)
3915
- * private readonly _formModel = signal<IProductFormModel>({ name: '', price: 0 });
3916
- * readonly formModel = this._formModel.asReadonly();
3917
- *
3918
- * // Required abstract implementations
3919
- * getFormModel(): Signal<IProductFormModel> {
3920
- * return this.formModel;
3921
- * }
3922
- *
3923
- * getResourceRoute(): string {
3924
- * return '/products';
3925
- * }
3926
- *
3927
- * getResourceName(): string {
3928
- * return 'Product';
3929
- * }
3930
- *
3931
- * isFormValid(): boolean {
3932
- * const model = this.formModel();
3933
- * return model.name.trim().length > 0 && model.price > 0;
3934
- * }
3935
- *
3936
- * loadItem(id: string): void {
3937
- * this.isLoading.set(true);
3938
- * this.productService.findById(id)
3939
- * .pipe(takeUntilDestroyed(this.destroyRef))
3940
- * .subscribe({
3941
- * next: (response) => {
3942
- * if (response.success && response.data) {
3943
- * this.existingItem.set(response.data);
3944
- * this._formModel.set({
3945
- * name: response.data.name,
3946
- * price: response.data.price,
3947
- * });
3948
- * }
3949
- * this.isLoading.set(false);
3950
- * },
3951
- * error: () => {
3952
- * this.router.navigate([this.getResourceRoute()]);
3953
- * this.isLoading.set(false);
3954
- * },
3955
- * });
3956
- * }
3957
- *
3958
- * createItem(model: IProductFormModel): Observable<ISingleResponse<IProduct>> {
3959
- * return this.productService.insert(model);
3960
- * }
3961
- *
3962
- * updateItem(model: IProductFormModel): Observable<ISingleResponse<IProduct>> {
3963
- * return this.productService.update({ id: this.existingItem()!.id, ...model });
3964
- * }
3965
- * }
3966
- * ```
3967
- *
3968
- * @template T The entity/interface type being edited
3969
- * @template TFormModel The form model interface
3970
- */
3971
- class BaseFormPage {
3972
- router = inject(Router);
3973
- route = inject(ActivatedRoute);
3974
- messageService = inject(MessageService);
3975
- destroyRef = inject(DestroyRef);
3976
- translateAdapter = inject(TranslateService, {
3977
- optional: true,
3978
- });
3979
- routeParams = toSignal(this.route.paramMap);
3980
- initialized = false;
3981
- /** Loading state for async operations */
3982
- isLoading = signal(false, ...(ngDevMode ? [{ debugName: "isLoading" }] : []));
3983
- /** The existing item when in edit mode, null when creating */
3984
- existingItem = signal(null, ...(ngDevMode ? [{ debugName: "existingItem" }] : []));
3985
- /** Whether the form is in edit mode (has existing item) */
3986
- isEditMode = computed(() => !!this.existingItem(), ...(ngDevMode ? [{ debugName: "isEditMode" }] : []));
3987
- constructor() {
3988
- effect(() => {
3989
- const params = this.routeParams();
3990
- if (!params || this.initialized)
3991
- return;
3992
- this.initialized = true;
3993
- const id = params.get('id');
3994
- if (id && id !== 'new') {
3995
- this.loadItem(id);
3996
- }
3997
- });
3998
- }
3999
- /**
4000
- * Handle form submission.
4001
- * Validates the form, then calls createItem or updateItem based on mode.
4002
- * Shows appropriate toast messages and navigates back on success.
4003
- */
4004
- onSubmit() {
4005
- if (!this.isFormValid()) {
4006
- this.showValidationError();
4007
- return;
4008
- }
4009
- this.isLoading.set(true);
4010
- const model = this.getFormModel()();
4011
- const operation$ = this.isEditMode()
4012
- ? this.updateItem(model)
4013
- : this.createItem(model);
4014
- operation$.pipe(takeUntilDestroyed(this.destroyRef)).subscribe({
4015
- next: (res) => {
4016
- const r = res;
4017
- this.showSuccess(r?.messageKey
4018
- ? this.t(r.messageKey, r.messageVariables)
4019
- : (r?.message ?? ''));
4020
- this.router.navigate([this.getResourceRoute()]);
4021
- },
4022
- error: () => {
4023
- this.isLoading.set(false);
4024
- },
4025
- complete: () => {
4026
- this.isLoading.set(false);
4027
- },
4028
- });
4029
- }
4030
- /**
4031
- * Handle cancel action.
4032
- * Navigates back to the resource list.
4033
- */
4034
- onCancel() {
4035
- this.router.navigate([this.getResourceRoute()]);
4036
- }
4037
- /**
4038
- * Show validation error toast.
4039
- * Override to customize the validation error message.
4040
- */
4041
- showValidationError() {
4042
- this.messageService.add({
4043
- severity: 'error',
4044
- summary: this.t('shared.validation.error'),
4045
- detail: this.t('shared.fill.required.fields'),
4046
- });
4047
- }
4048
- /**
4049
- * Show success toast.
4050
- * @param detail The success message to display
4051
- */
4052
- showSuccess(detail) {
4053
- this.messageService.add({
4054
- severity: 'success',
4055
- summary: this.t('shared.success'),
4056
- detail,
4057
- });
4058
- }
4059
- /**
4060
- * Show error toast.
4061
- * @param detail The error message to display
4062
- */
4063
- showError(detail) {
4064
- this.messageService.add({
4065
- severity: 'error',
4066
- summary: this.t('shared.error'),
4067
- detail,
4068
- });
4069
- }
4070
- /**
4071
- * Translate a key using the adapter, fallback to key if not available.
4072
- */
4073
- t(key, variables) {
4074
- return this.translateAdapter?.translate(key, variables) ?? key;
4075
- }
4076
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: BaseFormPage, deps: [], target: i0.ɵɵFactoryTarget.Directive });
4077
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.1.5", type: BaseFormPage, isStandalone: true, ngImport: i0 });
4078
- }
4079
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: BaseFormPage, decorators: [{
4080
- type: Directive
4081
- }], ctorParameters: () => [] });
4082
-
4083
- /**
4084
- * Base List Page
4085
- * Abstract directive providing common signals, computed values, and utilities
4086
- * for list page components across all feature packages.
4087
- *
4088
- * Features:
4089
- * - Pagination state management (pageSize, currentPage, total)
4090
- * - Loading state
4091
- * - CRUD navigation helpers
4092
- * - Message display utilities
4093
- * - Delete confirmation with API integration
4094
- * - Company feature flag support
4095
- *
4096
- * Usage:
4097
- * ```typescript
4098
- * @Component({ ... })
4099
- * export class UserListComponent extends BaseListPage<IUser> {
4100
- * getResourceRoute(): string { return '/users'; }
4101
- * getDeleteConfirmMessage(user: IUser): string { return `Delete "${user.name}"?`; }
4102
- * async loadData(): Promise<void> { ... }
4103
- * }
4104
- * ```
4105
- */
4106
- class BaseListPage {
4107
- router = inject(Router);
4108
- messageService = inject(MessageService);
4109
- appConfig = inject(APP_CONFIG);
4110
- confirmationService = inject(ConfirmationService);
4111
- destroyRef = inject(DestroyRef);
4112
- translateAdapter = inject(TranslateService, {
4113
- optional: true,
4114
- });
4115
- /** Items list */
4116
- items = signal([], ...(ngDevMode ? [{ debugName: "items" }] : []));
4117
- /** Loading state */
4118
- isLoading = signal(false, ...(ngDevMode ? [{ debugName: "isLoading" }] : []));
4119
- /** Total records for pagination */
4120
- total = signal(0, ...(ngDevMode ? [{ debugName: "total" }] : []));
4121
- /** Page size */
4122
- pageSize = signal(10, ...(ngDevMode ? [{ debugName: "pageSize" }] : []));
4123
- /** First record index (for p-table lazy load) */
4124
- first = signal(0, ...(ngDevMode ? [{ debugName: "first" }] : []));
4125
- /** Current page (0-based for API, derived from first/pageSize) */
4126
- currentPage = computed(() => Math.floor(this.first() / this.pageSize()), ...(ngDevMode ? [{ debugName: "currentPage" }] : []));
4127
- /** Show company info if company feature enabled */
4128
- showCompanyInfo = computed(() => this.appConfig.enableCompanyFeature, ...(ngDevMode ? [{ debugName: "showCompanyInfo" }] : []));
4129
- /**
4130
- * Navigate to create page
4131
- */
4132
- onCreate() {
4133
- this.router.navigate([this.getResourceRoute(), 'new']);
4134
- }
4135
- /**
4136
- * Navigate to edit page
4137
- * @param id The ID of the item to edit
4138
- */
4139
- onEdit(id) {
4140
- this.router.navigate([this.getResourceRoute(), id]);
4141
- }
4142
- /**
4143
- * Handle page change from p-table lazy load
4144
- */
4145
- onPageChange(event) {
4146
- this.first.set(event.first ?? 0);
4147
- this.pageSize.set(event.rows ?? 10);
4148
- this.loadData();
4149
- }
4150
- /**
4151
- * Get pagination params for API call
4152
- * Returns 0-based page for backend API
4153
- */
4154
- getPaginationParams() {
4155
- return {
4156
- currentPage: this.currentPage(),
4157
- pageSize: this.pageSize(),
4158
- };
4159
- }
4160
- /**
4161
- * Show success toast message
4162
- */
4163
- showSuccess(detail, summary) {
4164
- this.messageService.add({
4165
- severity: 'success',
4166
- summary: summary ?? this.t('shared.success'),
4167
- detail,
4168
- });
4169
- }
4170
- /**
4171
- * Show error toast message
4172
- */
4173
- showError(detail, summary) {
4174
- this.messageService.add({
4175
- severity: 'error',
4176
- summary: summary ?? this.t('shared.error'),
4177
- detail,
4178
- });
4179
- }
4180
- /**
4181
- * Show info toast message
4182
- */
4183
- showInfo(detail, summary) {
4184
- this.messageService.add({
4185
- severity: 'info',
4186
- summary: summary ?? this.t('shared.info'),
4187
- detail,
4188
- });
4189
- }
4190
- /**
4191
- * Show warning toast message
4192
- */
4193
- showWarn(detail, summary) {
4194
- this.messageService.add({
4195
- severity: 'warn',
4196
- summary: summary ?? this.t('shared.warning'),
4197
- detail,
4198
- });
4199
- }
4200
- /**
4201
- * Translate a key using the adapter, fallback to key if not available.
4202
- */
4203
- t(key, variables) {
4204
- return this.translateAdapter?.translate(key, variables) ?? key;
4205
- }
4206
- /**
4207
- * Delete an item with confirmation dialog
4208
- * @param item The item to delete
4209
- * @param idGetter Function to extract ID from item
4210
- * @param deleteApiCall Function that returns Observable for delete API call
4211
- * @param options Optional configuration
4212
- */
4213
- onDelete(item, idGetter, deleteApiCall, options) {
4214
- this.confirmationService.confirm({
4215
- message: this.getDeleteConfirmMessage(item),
4216
- header: options?.header ?? this.t('shared.confirm.delete.header'),
4217
- icon: 'pi pi-exclamation-triangle',
4218
- acceptButtonStyleClass: 'p-button-danger',
4219
- accept: () => {
4220
- from(deleteApiCall(idGetter(item)))
4221
- .pipe(takeUntilDestroyed(this.destroyRef))
4222
- .subscribe({
4223
- next: (res) => {
4224
- const r = res;
4225
- this.showSuccess(r?.messageKey
4226
- ? this.t(r.messageKey, r.messageVariables)
4227
- : (r?.message ?? ''));
4228
- this.loadData();
4229
- },
4230
- });
4231
- },
4232
- });
4233
- }
4234
- /**
4235
- * Delete an item with confirmation dialog using async/await
4236
- * @param item The item to delete
4237
- * @param idGetter Function to extract ID from item
4238
- * @param deleteApiCall Async function for delete API call
4239
- * @param options Optional configuration
4240
- */
4241
- async onDeleteAsync(item, idGetter, deleteApiCall, options) {
4242
- this.confirmationService.confirm({
4243
- message: this.getDeleteConfirmMessage(item),
4244
- header: options?.header ?? this.t('shared.confirm.delete.header'),
4245
- icon: 'pi pi-exclamation-triangle',
4246
- acceptButtonStyleClass: 'p-button-danger',
4247
- accept: async () => {
4248
- const res = await deleteApiCall(idGetter(item));
4249
- const r = res;
4250
- this.showSuccess(r?.messageKey
4251
- ? this.t(r.messageKey, r.messageVariables)
4252
- : (r?.message ?? ''));
4253
- await this.loadData();
4254
- },
4255
- });
4256
- }
4257
- /**
4258
- * Navigate to a route
4259
- */
4260
- navigateTo(path) {
4261
- this.router.navigate(path);
4262
- }
4263
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: BaseListPage, deps: [], target: i0.ɵɵFactoryTarget.Directive });
4264
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.1.5", type: BaseListPage, isStandalone: true, ngImport: i0 });
4265
- }
4266
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: BaseListPage, decorators: [{
4267
- type: Directive
4268
- }] });
4269
-
4270
4326
  function getOffsetMinutes(utcDate, timezone) {
4271
4327
  const extract = (tz) => {
4272
4328
  const parts = new Intl.DateTimeFormat('en-US', {
@@ -4334,5 +4390,5 @@ function getUserTimezone() {
4334
4390
  * Generated bundle index. Do not edit.
4335
4391
  */
4336
4392
 
4337
- export { ACTION_PERMISSIONS, AUTH_STATE_PROVIDER, AngularModule, ApiResourceService, ApiResourceService as ApiService, BRANCH_PERMISSIONS, BaseFormControl, BaseFormPage, BaseListPage, BaseUserSelectComponent, COMPANY_ACTION_PERMISSIONS, COMPANY_API_PROVIDER, COMPANY_PERMISSIONS, CookieService, EMAIL_CONFIG_PERMISSIONS, EMAIL_TEMPLATE_PERMISSIONS, EVENT_PERMISSIONS, EditModeElementChangerDirective, FILE_PERMISSIONS, FILE_PROVIDER, FILE_TYPE_FILTERS, FOLDER_PERMISSIONS, FORM_PERMISSIONS, FORM_RESULT_PERMISSIONS, FileSelectorDialogComponent, FileUploaderComponent, FileUrlService, HasPermissionDirective, IconComponent, IconTypeEnum, IsEmptyImageDirective, LANGUAGE_PERMISSIONS, LazyMultiSelectComponent, LazySelectComponent, NOTIFICATION_PERMISSIONS, PERMISSIONS, PROFILE_PERMISSION_PROVIDER, PermissionValidatorService, PlatformService, PreventDefaultDirective, PrimeModule, ROLE_ACTION_PERMISSIONS, ROLE_PERMISSIONS, SHARED_MESSAGES, SKIP_ERROR_TOAST, STORAGE_CONFIG_PERMISSIONS, TRANSLATION_KEY_PERMISSIONS, TRANSLATION_PERMISSIONS, TranslatePipe, TranslateService, UPLOAD_CONFIG_PERMISSIONS, USER_ACTION_PERMISSIONS, USER_PERMISSIONS, USER_PERMISSION_PROVIDER, USER_PROVIDER, USER_ROLE_PERMISSIONS, UserMultiSelectComponent, UserSelectComponent, allPermissionsGuard, anyPermissionGuard, checkScrollPagination, errorCatchingInterceptor, evaluateLogicNode, evaluatePermission, formatFileSize, formatInTimezone, getAcceptString, getFileIconClass, getUserTimezone, hasAllPermissions, hasAnyPermission, hasPermission, isFileTypeAllowed, localToUtc, permissionGuard, provideValueAccessor, resolveTranslationModule, utcToLocal };
4393
+ export { ACTION_PERMISSIONS, AUTH_STATE_PROVIDER, AngularModule, ApiResourceService, ApiResourceService as ApiService, BRANCH_PERMISSIONS, BaseFormComponent, BaseFormControl, BaseFormTemplateDirective, BaseListComponent, BaseListTemplateDirective, BaseUserSelectComponent, COMPANY_ACTION_PERMISSIONS, COMPANY_API_PROVIDER, COMPANY_PERMISSIONS, CookieService, EMAIL_CONFIG_PERMISSIONS, EMAIL_TEMPLATE_PERMISSIONS, EVENT_PERMISSIONS, EditModeElementChangerDirective, FILE_PERMISSIONS, FILE_PROVIDER, FILE_TYPE_FILTERS, FOLDER_PERMISSIONS, FORM_PERMISSIONS, FORM_RESULT_PERMISSIONS, FaviconService, FileSelectorDialogComponent, FileUploaderComponent, FileUrlService, HasPermissionDirective, IconComponent, IconTypeEnum, InlineSvgComponent, IsEmptyImageDirective, LANGUAGE_PERMISSIONS, LazyMultiSelectComponent, LazySelectComponent, NOTIFICATION_PERMISSIONS, PERMISSIONS, PROFILE_PERMISSION_PROVIDER, PermissionValidatorService, PlatformService, PreventDefaultDirective, PrimeModule, ROLE_ACTION_PERMISSIONS, ROLE_PERMISSIONS, SHARED_MESSAGES, SKIP_ERROR_TOAST, STORAGE_CONFIG_PERMISSIONS, TRANSLATION_KEY_PERMISSIONS, TRANSLATION_PERMISSIONS, TranslatePipe, TranslateService, UPLOAD_CONFIG_PERMISSIONS, USER_ACTION_PERMISSIONS, USER_PERMISSIONS, USER_PERMISSION_PROVIDER, USER_PROVIDER, USER_ROLE_PERMISSIONS, UserMultiSelectComponent, UserSelectComponent, allPermissionsGuard, anyPermissionGuard, checkScrollPagination, errorCatchingInterceptor, evaluateLogicNode, evaluatePermission, formatFileSize, formatInTimezone, getAcceptString, getFileIconClass, getUserTimezone, hasAllPermissions, hasAnyPermission, hasPermission, isFileTypeAllowed, localToUtc, permissionGuard, provideValueAccessor, resolveTranslationModule, utcToLocal };
4338
4394
  //# sourceMappingURL=flusys-ng-shared.mjs.map