@dmlibs/dm-cmps 0.0.4 → 0.1.1

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,34 +1,43 @@
1
1
  import * as i0 from '@angular/core';
2
- import { signal, input, booleanAttribute, model, computed, output, effect, Component, Injectable, numberAttribute } from '@angular/core';
2
+ import { signal, input, booleanAttribute, model, computed, output, effect, Component, Injectable, numberAttribute, Input, Directive, HostListener } from '@angular/core';
3
3
  import { toObservable } from '@angular/core/rxjs-interop';
4
4
  import { Subject, Subscription, switchMap, debounceTime, distinctUntilChanged } from 'rxjs';
5
- import * as i1 from '@angular/material/form-field';
6
- import { MatFormFieldModule, MatSuffix } from '@angular/material/form-field';
7
- import * as i2 from '@angular/material/select';
5
+ import * as i2 from '@angular/material/form-field';
6
+ import { MatFormFieldModule } from '@angular/material/form-field';
7
+ import * as i5 from '@angular/material/select';
8
8
  import { MatSelectModule } from '@angular/material/select';
9
- import * as i3 from '@angular/common';
9
+ import * as i11 from '@angular/common';
10
10
  import { CommonModule } from '@angular/common';
11
- import * as i4 from '@angular/forms';
12
- import { FormControl, FormsModule, ReactiveFormsModule } from '@angular/forms';
13
- import * as i5 from '@angular/material/input';
11
+ import * as i1 from '@angular/forms';
12
+ import { FormControl, ReactiveFormsModule, FormsModule } from '@angular/forms';
13
+ import * as i6 from '@angular/material/input';
14
14
  import { MatInputModule } from '@angular/material/input';
15
- import * as i6 from '@angular/material/checkbox';
15
+ import * as i3 from '@angular/material/checkbox';
16
16
  import { MatCheckboxModule } from '@angular/material/checkbox';
17
17
  import { MatIcon } from '@angular/material/icon';
18
- import * as i7 from '@angular/material/button';
18
+ import * as i8 from '@angular/material/button';
19
19
  import { MatButtonModule } from '@angular/material/button';
20
20
  import * as i2$1 from '@angular/material/tooltip';
21
21
  import { MatTooltip, MatTooltipModule } from '@angular/material/tooltip';
22
- import * as i1$1 from '@angular/material/menu';
22
+ import * as i10 from '@angular/material/menu';
23
23
  import { MatMenuModule } from '@angular/material/menu';
24
24
  import * as i3$1 from '@angular/material/slider';
25
25
  import { MatSliderModule } from '@angular/material/slider';
26
+ import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
27
+ import * as i2$2 from '@angular/material/progress-bar';
28
+ import { MatProgressBarModule } from '@angular/material/progress-bar';
29
+ import { A11yModule } from '@angular/cdk/a11y';
30
+ import { moveItemInArray, CdkDragHandle, CdkDropList, CdkDrag } from '@angular/cdk/drag-drop';
31
+ import * as i1$1 from '@angular/material/slide-toggle';
32
+ import { MatSlideToggleModule } from '@angular/material/slide-toggle';
33
+ import * as i6$1 from '@angular/cdk/scrolling';
26
34
 
27
35
  class DmCmpsDataSource {
28
36
  data;
29
37
  filteredData;
30
38
  _resultData;
31
39
  result = signal([], ...(ngDevMode ? [{ debugName: "result" }] : []));
40
+ resultVersion = signal(0, ...(ngDevMode ? [{ debugName: "resultVersion" }] : []));
32
41
  paginationEnabled = false;
33
42
  currentPageIndex = 0;
34
43
  pageSize = 10;
@@ -66,7 +75,8 @@ class DmCmpsDataSource {
66
75
  }
67
76
  return match(filter);
68
77
  };
69
- filterByObject = null;
78
+ isLoading = signal(false, ...(ngDevMode ? [{ debugName: "isLoading" }] : []));
79
+ objectToFilterBy = null;
70
80
  fieldsToSearchIn = [];
71
81
  sortMap = [];
72
82
  sortFn = null;
@@ -92,20 +102,11 @@ class DmCmpsDataSource {
92
102
  this.searchTerm = term;
93
103
  this.applySearch();
94
104
  }));
95
- // this.searchTerms$
96
- // .pipe(
97
- // debounceTime(this.searchDebounceTime),
98
- // distinctUntilChanged((p, c) => p === c && c != '')
99
- // )
100
- // .subscribe((term) => {
101
- // this.searchTerm = term;
102
- // this.applySearch();
103
- // });
104
- }
105
- updateResultData() {
105
+ }
106
+ async updateResultData() {
106
107
  this.applySorting();
107
- this.applySearch();
108
- this.updateResultSignal();
108
+ await this.applySearch();
109
+ await this.updateResultSignal();
109
110
  }
110
111
  disconnect() {
111
112
  this.subscription.unsubscribe();
@@ -137,9 +138,13 @@ class DmCmpsDataSource {
137
138
  this.pageSize = pageSize;
138
139
  this.updateResultSignal();
139
140
  }
141
+ getPageSize() {
142
+ return this.pageSize;
143
+ }
140
144
  disablePagination() {
141
145
  this.currentPageIndex = 0;
142
146
  this.paginationEnabled = false;
147
+ this.setAutoPaginationAboveItemsCount(-1);
143
148
  this.updateResultSignal();
144
149
  }
145
150
  nextPage() {
@@ -189,6 +194,22 @@ class DmCmpsDataSource {
189
194
  }
190
195
  return Math.ceil(this._resultData.length / this.pageSize);
191
196
  }
197
+ getFirstItemIndexInPage() {
198
+ return this.currentPageIndex * this.pageSize;
199
+ }
200
+ getLastItemIndexInPage() {
201
+ const lastIndex = (this.currentPageIndex + 1) * this.pageSize - 1;
202
+ return lastIndex >= this._resultData.length ? this._resultData.length - 1 : lastIndex;
203
+ }
204
+ getTotalResultElementsCount() {
205
+ return this._resultData.length;
206
+ }
207
+ isPaginationEnabled() {
208
+ return (this.pageSize > 0 &&
209
+ (this.paginationEnabled ||
210
+ (this.autoPaginationAboveItemsCount > 0 &&
211
+ this._resultData.length > this.autoPaginationAboveItemsCount)));
212
+ }
192
213
  setSearchDebounceTime(milliseconds) {
193
214
  this.searchDebounceTime.set(milliseconds);
194
215
  }
@@ -196,18 +217,24 @@ class DmCmpsDataSource {
196
217
  this.data = [...newData];
197
218
  this.applyObjectFilter();
198
219
  }
199
- updateResultSignal() {
200
- const res = (() => {
201
- if (this.pageSize > 0 &&
202
- (this.paginationEnabled ||
203
- (this.autoPaginationAboveItemsCount > 0 &&
204
- this._resultData.length > this.autoPaginationAboveItemsCount))) {
205
- const startIndex = this.currentPageIndex * this.pageSize;
206
- return this._resultData.slice(startIndex, startIndex + this.pageSize);
207
- }
208
- return this._resultData;
209
- })();
210
- this.result.set(res);
220
+ getDatasource() {
221
+ return this.data;
222
+ }
223
+ getResultData() {
224
+ return this._resultData;
225
+ }
226
+ async updateResultSignal() {
227
+ return new Promise((resolve) => {
228
+ const res = (() => {
229
+ if (this.isPaginationEnabled()) {
230
+ const startIndex = this.currentPageIndex * this.pageSize;
231
+ return this._resultData.slice(startIndex, startIndex + this.pageSize);
232
+ }
233
+ return this._resultData;
234
+ })();
235
+ this.result.set(res);
236
+ resolve();
237
+ });
211
238
  }
212
239
  // get resultData(): T[] {
213
240
  // if (
@@ -222,17 +249,23 @@ class DmCmpsDataSource {
222
249
  // return this.filteredData;
223
250
  // }
224
251
  search(filterTerm) {
252
+ this.isLoading.set(true);
225
253
  this.searchTerms$.next(filterTerm);
226
254
  }
227
- applySearch() {
228
- if (!this.searchTerm) {
229
- this._resultData = [...this.filteredData];
230
- }
231
- else {
232
- this.currentPageIndex = 0;
233
- this._resultData = this.filteredData.filter((item) => this.filterPredicate(item, this.searchTerm));
234
- }
235
- this.updateResultSignal();
255
+ async applySearch() {
256
+ return new Promise(async (resolve) => {
257
+ if (!this.searchTerm) {
258
+ this._resultData = [...this.filteredData];
259
+ }
260
+ else {
261
+ this.currentPageIndex = 0;
262
+ this._resultData = this.filteredData.filter((item) => this.filterPredicate(item, this.searchTerm));
263
+ }
264
+ await this.updateResultSignal();
265
+ this.resultVersion.update((v) => v + 1);
266
+ this.isLoading.set(false);
267
+ resolve();
268
+ });
236
269
  }
237
270
  setFilterPredicate(predicate) {
238
271
  this.filterPredicate = predicate;
@@ -326,16 +359,19 @@ class DmCmpsDataSource {
326
359
  this.applyObjectFilter();
327
360
  }
328
361
  setFilterByObjectFields(filterObj) {
329
- this.filterByObject = filterObj;
362
+ this.objectToFilterBy = filterObj;
330
363
  this.applyObjectFilter();
331
364
  }
365
+ getObjectToFilterBy() {
366
+ return this.objectToFilterBy;
367
+ }
332
368
  applyObjectFilter() {
333
- if (!this.filterByObject) {
369
+ if (!this.objectToFilterBy) {
334
370
  this.filteredData = [...this.data];
335
371
  }
336
372
  else {
337
373
  this.filteredData = this.data.filter((item) => {
338
- for (const [key, value] of Object.entries(this.filterByObject)) {
374
+ for (const [key, value] of Object.entries(this.objectToFilterBy)) {
339
375
  if (item[key] !== value) {
340
376
  return false;
341
377
  }
@@ -586,22 +622,21 @@ class DmMatSelect {
586
622
  }
587
623
  }
588
624
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: DmMatSelect, deps: [], target: i0.ɵɵFactoryTarget.Component });
589
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.3", type: DmMatSelect, isStandalone: true, selector: "dm-mat-select", inputs: { formFieldClass: { classPropertyName: "formFieldClass", publicName: "formFieldClass", isSignal: true, isRequired: false, transformFunction: null }, wrapperClass: { classPropertyName: "wrapperClass", publicName: "wrapperClass", isSignal: true, isRequired: false, transformFunction: null }, appearance: { classPropertyName: "appearance", publicName: "appearance", isSignal: true, isRequired: false, transformFunction: null }, multiple: { classPropertyName: "multiple", publicName: "multiple", isSignal: true, isRequired: false, transformFunction: null }, selectAllEnabled: { classPropertyName: "selectAllEnabled", publicName: "selectAllEnabled", isSignal: true, isRequired: false, transformFunction: null }, selectAllLabel: { classPropertyName: "selectAllLabel", publicName: "selectAllLabel", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: false, transformFunction: null }, optionValueKey: { classPropertyName: "optionValueKey", publicName: "optionValueKey", isSignal: true, isRequired: false, transformFunction: null }, optionLabelKey: { classPropertyName: "optionLabelKey", publicName: "optionLabelKey", isSignal: true, isRequired: false, transformFunction: null }, searchable: { classPropertyName: "searchable", publicName: "searchable", isSignal: true, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, error: { classPropertyName: "error", publicName: "error", isSignal: true, isRequired: false, transformFunction: null }, searchPlaceholder: { classPropertyName: "searchPlaceholder", publicName: "searchPlaceholder", isSignal: true, isRequired: false, transformFunction: null }, emptyOption: { classPropertyName: "emptyOption", publicName: "emptyOption", isSignal: true, isRequired: false, transformFunction: null }, emptyOptionLabel: { classPropertyName: "emptyOptionLabel", publicName: "emptyOptionLabel", isSignal: true, isRequired: false, transformFunction: null }, emptyOptionValue: { classPropertyName: "emptyOptionValue", publicName: "emptyOptionValue", isSignal: true, isRequired: false, transformFunction: null }, optionNameFormat: { classPropertyName: "optionNameFormat", publicName: "optionNameFormat", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, formControl: { classPropertyName: "formControl", publicName: "formControl", isSignal: true, isRequired: false, transformFunction: null }, panelWidth: { classPropertyName: "panelWidth", publicName: "panelWidth", isSignal: true, isRequired: false, transformFunction: null }, panelClass: { classPropertyName: "panelClass", publicName: "panelClass", isSignal: true, isRequired: false, transformFunction: null }, searchSectionBackgroundColor: { classPropertyName: "searchSectionBackgroundColor", publicName: "searchSectionBackgroundColor", isSignal: true, isRequired: false, transformFunction: null }, sortBySelectedOnTop: { classPropertyName: "sortBySelectedOnTop", publicName: "sortBySelectedOnTop", isSignal: true, isRequired: false, transformFunction: null }, icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: false, transformFunction: null }, noDataLabel: { classPropertyName: "noDataLabel", publicName: "noDataLabel", isSignal: true, isRequired: false, transformFunction: null }, clearSearchAfterSelect: { classPropertyName: "clearSearchAfterSelect", publicName: "clearSearchAfterSelect", isSignal: true, isRequired: false, transformFunction: null }, clearSearchButtonTooltip: { classPropertyName: "clearSearchButtonTooltip", publicName: "clearSearchButtonTooltip", isSignal: true, isRequired: false, transformFunction: null }, focusSearchInputOnPanelOpen: { classPropertyName: "focusSearchInputOnPanelOpen", publicName: "focusSearchInputOnPanelOpen", isSignal: true, isRequired: false, transformFunction: null }, filterPredicate: { classPropertyName: "filterPredicate", publicName: "filterPredicate", isSignal: true, isRequired: false, transformFunction: null }, propertiesToSkipInSearch: { classPropertyName: "propertiesToSkipInSearch", publicName: "propertiesToSkipInSearch", isSignal: true, isRequired: false, transformFunction: null }, filterText: { classPropertyName: "filterText", publicName: "filterText", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange", selectionChange: "selectionChange", filterText: "filterTextChange" }, ngImport: i0, template: "<div class=\"dm-mat-select-wrapper\" [class]=\"wrapperClass()\">\n <mat-form-field [appearance]=\"appearance()\" [class]=\"formFieldClass()\" style=\"width: 100%\">\n <mat-label>{{ label() }}</mat-label>\n <mat-select\n [multiple]=\"multiple()\"\n [formControl]=\"control()\"\n (selectionChange)=\"selectionChangeHandler($event)\"\n [disabled]=\"disabled()\"\n [panelWidth]=\"panelWidth()\"\n [panelClass]=\"panelClass()\"\n (opened)=\"onPanelOpened()\"\n >\n <div\n class=\"search-section\"\n [ngStyle]=\"{\n 'background-color': 'none'\n }\"\n >\n @if (searchable()) {\n <mat-form-field>\n <input\n id=\"dm-mat-select-search-input\"\n matInput\n [placeholder]=\"searchPlaceholder()\"\n [(ngModel)]=\"filterText\"\n (keyup)=\"applyFilter($event)\"\n (keyDown.Space)=\"$event.stopPropagation()\"\n />\n @if (filterText()) {\n <button\n mat-icon-button\n matSuffix\n (click)=\"resetSearch()\"\n [matTooltip]=\"clearSearchButtonTooltip() || ''\"\n >\n <mat-icon>close</mat-icon>\n </button>\n }\n </mat-form-field>\n } @if (selectAllEnabled() && multiple()) {\n <mat-checkbox [checked]=\"checkIfAllSelected()\" (change)=\"selectAllChange($event)\">{{\n selectAllLabel()\n }}</mat-checkbox>\n }\n </div>\n @if (emptyOption()) {\n <mat-option\n [value]=\"emptyOptionValue()\"\n (onSelectionChange)=\"onSelectionChangeHandler($event, emptyOptionValue())\"\n >{{ emptyOptionLabel() }}</mat-option\n >\n } @for (option of datasource().result(); track simpleArray() ? option :\n option[this.optionValueKey()]) {\n <mat-option\n [value]=\"simpleArray() ? option : option[optionValueKey()]\"\n (onSelectionChange)=\"onSelectionChangeHandler($event, option)\"\n >{{\n optionNameFormat()\n ? option.__dmMatSelectFormattedName\n : simpleArray()\n ? option\n : option[optionLabelKey()]\n }}</mat-option\n >\n } @if (datasource().result().length === 0) {\n <mat-option disabled>{{ noDataLabel() }}</mat-option>\n }\n </mat-select>\n\n @if (icon(); as icon) {\n <span matSuffix>\n @if (isBootstrapIcon()) {\n <span [innerHTML]=\"icon\"></span> } @else {\n <mat-icon matSuffix>{{ icon }}</mat-icon>\n }\n </span>\n }\n\n <span matSuffix>\n <ng-content select=\"[dm-mat-select-suffix]\"></ng-content>\n </span>\n\n <mat-error>{{ error() }}</mat-error>\n </mat-form-field>\n</div>\n", styles: [".dm-mat-select-wrapper{width:100%;position:relative}.dm-mat-select-wrapper .search-section{display:flex;flex-direction:column;position:sticky;top:0;z-index:1;background-color:var(--dm-mat-select-search-section-bg-color, #faf9fd)}.dm-mat-select-wrapper .search-section ::ng-deep mat-form-field>.mat-mdc-form-field-subscript-wrapper{display:none}.dm-mat-select-wrapper ::ng-deep mat-form-field>.mat-mdc-text-field-wrapper>.mat-mdc-form-field-flex>.mat-mdc-form-field-icon-suffix{padding:0 4px 0 8px}\n"], dependencies: [{ kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i1.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i1.MatLabel, selector: "mat-label" }, { kind: "directive", type: i1.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: i1.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i2.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth", "canSelectNullableOptions"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i2.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i3.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i4.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: i4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i4.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i4.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i5.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatCheckboxModule }, { kind: "component", type: i6.MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "aria-expanded", "aria-controls", "aria-owns", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "disabledInteractive", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i7.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "directive", type: MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }] });
625
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.3", type: DmMatSelect, isStandalone: true, selector: "dm-mat-select", inputs: { formFieldClass: { classPropertyName: "formFieldClass", publicName: "formFieldClass", isSignal: true, isRequired: false, transformFunction: null }, wrapperClass: { classPropertyName: "wrapperClass", publicName: "wrapperClass", isSignal: true, isRequired: false, transformFunction: null }, appearance: { classPropertyName: "appearance", publicName: "appearance", isSignal: true, isRequired: false, transformFunction: null }, multiple: { classPropertyName: "multiple", publicName: "multiple", isSignal: true, isRequired: false, transformFunction: null }, selectAllEnabled: { classPropertyName: "selectAllEnabled", publicName: "selectAllEnabled", isSignal: true, isRequired: false, transformFunction: null }, selectAllLabel: { classPropertyName: "selectAllLabel", publicName: "selectAllLabel", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: false, transformFunction: null }, optionValueKey: { classPropertyName: "optionValueKey", publicName: "optionValueKey", isSignal: true, isRequired: false, transformFunction: null }, optionLabelKey: { classPropertyName: "optionLabelKey", publicName: "optionLabelKey", isSignal: true, isRequired: false, transformFunction: null }, searchable: { classPropertyName: "searchable", publicName: "searchable", isSignal: true, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, error: { classPropertyName: "error", publicName: "error", isSignal: true, isRequired: false, transformFunction: null }, searchPlaceholder: { classPropertyName: "searchPlaceholder", publicName: "searchPlaceholder", isSignal: true, isRequired: false, transformFunction: null }, emptyOption: { classPropertyName: "emptyOption", publicName: "emptyOption", isSignal: true, isRequired: false, transformFunction: null }, emptyOptionLabel: { classPropertyName: "emptyOptionLabel", publicName: "emptyOptionLabel", isSignal: true, isRequired: false, transformFunction: null }, emptyOptionValue: { classPropertyName: "emptyOptionValue", publicName: "emptyOptionValue", isSignal: true, isRequired: false, transformFunction: null }, optionNameFormat: { classPropertyName: "optionNameFormat", publicName: "optionNameFormat", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, formControl: { classPropertyName: "formControl", publicName: "formControl", isSignal: true, isRequired: false, transformFunction: null }, panelWidth: { classPropertyName: "panelWidth", publicName: "panelWidth", isSignal: true, isRequired: false, transformFunction: null }, panelClass: { classPropertyName: "panelClass", publicName: "panelClass", isSignal: true, isRequired: false, transformFunction: null }, searchSectionBackgroundColor: { classPropertyName: "searchSectionBackgroundColor", publicName: "searchSectionBackgroundColor", isSignal: true, isRequired: false, transformFunction: null }, sortBySelectedOnTop: { classPropertyName: "sortBySelectedOnTop", publicName: "sortBySelectedOnTop", isSignal: true, isRequired: false, transformFunction: null }, icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: false, transformFunction: null }, noDataLabel: { classPropertyName: "noDataLabel", publicName: "noDataLabel", isSignal: true, isRequired: false, transformFunction: null }, clearSearchAfterSelect: { classPropertyName: "clearSearchAfterSelect", publicName: "clearSearchAfterSelect", isSignal: true, isRequired: false, transformFunction: null }, clearSearchButtonTooltip: { classPropertyName: "clearSearchButtonTooltip", publicName: "clearSearchButtonTooltip", isSignal: true, isRequired: false, transformFunction: null }, focusSearchInputOnPanelOpen: { classPropertyName: "focusSearchInputOnPanelOpen", publicName: "focusSearchInputOnPanelOpen", isSignal: true, isRequired: false, transformFunction: null }, filterPredicate: { classPropertyName: "filterPredicate", publicName: "filterPredicate", isSignal: true, isRequired: false, transformFunction: null }, propertiesToSkipInSearch: { classPropertyName: "propertiesToSkipInSearch", publicName: "propertiesToSkipInSearch", isSignal: true, isRequired: false, transformFunction: null }, filterText: { classPropertyName: "filterText", publicName: "filterText", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange", selectionChange: "selectionChange", filterText: "filterTextChange" }, ngImport: i0, template: "<div class=\"dm-mat-select-wrapper\" [class]=\"wrapperClass()\">\n <mat-form-field [appearance]=\"appearance()\" [class]=\"formFieldClass()\" style=\"width: 100%\">\n <mat-label>{{ label() }}</mat-label>\n <mat-select\n [multiple]=\"multiple()\"\n [formControl]=\"control()\"\n (selectionChange)=\"selectionChangeHandler($event)\"\n [disabled]=\"disabled()\"\n [panelWidth]=\"panelWidth()\"\n [panelClass]=\"panelClass()\"\n (opened)=\"onPanelOpened()\"\n >\n <div\n class=\"search-section\"\n [ngStyle]=\"{\n 'background-color': 'none'\n }\"\n >\n @if (searchable()) {\n <mat-form-field>\n <input\n id=\"dm-mat-select-search-input\"\n matInput\n [placeholder]=\"searchPlaceholder()\"\n [(ngModel)]=\"filterText\"\n (keyup)=\"applyFilter($event)\"\n (keyDown.Space)=\"$event.stopPropagation()\"\n />\n @if (filterText()) {\n <button\n mat-icon-button\n matSuffix\n (click)=\"resetSearch()\"\n [matTooltip]=\"clearSearchButtonTooltip() || ''\"\n >\n <mat-icon>close</mat-icon>\n </button>\n }\n </mat-form-field>\n } @if (selectAllEnabled() && multiple()) {\n <mat-checkbox [checked]=\"checkIfAllSelected()\" (change)=\"selectAllChange($event)\">{{\n selectAllLabel()\n }}</mat-checkbox>\n }\n </div>\n @if (emptyOption()) {\n <mat-option\n [value]=\"emptyOptionValue()\"\n (onSelectionChange)=\"onSelectionChangeHandler($event, emptyOptionValue())\"\n >{{ emptyOptionLabel() }}</mat-option\n >\n } @for (option of datasource().result(); track simpleArray() ? option :\n option[this.optionValueKey()]) {\n <mat-option\n [value]=\"simpleArray() ? option : option[optionValueKey()]\"\n (onSelectionChange)=\"onSelectionChangeHandler($event, option)\"\n >{{\n optionNameFormat()\n ? option.__dmMatSelectFormattedName\n : simpleArray()\n ? option\n : option[optionLabelKey()]\n }}</mat-option\n >\n } @if (datasource().result().length === 0) {\n <mat-option disabled>{{ noDataLabel() }}</mat-option>\n }\n </mat-select>\n\n @if (icon(); as icon) {\n <span matSuffix>\n @if (isBootstrapIcon()) {\n <span [innerHTML]=\"icon\"></span> } @else {\n <mat-icon matSuffix>{{ icon }}</mat-icon>\n }\n </span>\n }\n\n <span matSuffix>\n <ng-content select=\"[dm-mat-select-suffix]\"></ng-content>\n </span>\n\n <mat-error>{{ error() }}</mat-error>\n </mat-form-field>\n</div>\n", styles: [".dm-mat-select-wrapper{width:100%;position:relative}.dm-mat-select-wrapper .search-section{display:flex;flex-direction:column;position:sticky;top:0;z-index:1;background-color:var(--dm-mat-select-search-section-bg-color, #faf9fd)}.dm-mat-select-wrapper .search-section ::ng-deep mat-form-field>.mat-mdc-form-field-subscript-wrapper{display:none}.dm-mat-select-wrapper ::ng-deep mat-form-field>.mat-mdc-text-field-wrapper>.mat-mdc-form-field-flex>.mat-mdc-form-field-icon-suffix{padding:0 4px 0 8px}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.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.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i2.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i2.MatLabel, selector: "mat-label" }, { kind: "directive", type: i2.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: i2.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "ngmodule", type: MatCheckboxModule }, { kind: "component", type: i3.MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "aria-expanded", "aria-controls", "aria-owns", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "disabledInteractive", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i8.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i5.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth", "canSelectNullableOptions"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i5.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i6.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i11.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }] });
590
626
  }
591
627
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: DmMatSelect, decorators: [{
592
628
  type: Component,
593
629
  args: [{ selector: 'dm-mat-select', standalone: true, imports: [
630
+ ReactiveFormsModule,
594
631
  MatFormFieldModule,
632
+ MatCheckboxModule,
633
+ MatButtonModule,
595
634
  MatSelectModule,
635
+ MatInputModule,
596
636
  CommonModule,
597
637
  FormsModule,
598
- ReactiveFormsModule,
599
- MatInputModule,
600
- MatCheckboxModule,
601
- MatIcon,
602
- MatButtonModule,
603
638
  MatTooltip,
604
- MatSuffix,
639
+ MatIcon,
605
640
  ], template: "<div class=\"dm-mat-select-wrapper\" [class]=\"wrapperClass()\">\n <mat-form-field [appearance]=\"appearance()\" [class]=\"formFieldClass()\" style=\"width: 100%\">\n <mat-label>{{ label() }}</mat-label>\n <mat-select\n [multiple]=\"multiple()\"\n [formControl]=\"control()\"\n (selectionChange)=\"selectionChangeHandler($event)\"\n [disabled]=\"disabled()\"\n [panelWidth]=\"panelWidth()\"\n [panelClass]=\"panelClass()\"\n (opened)=\"onPanelOpened()\"\n >\n <div\n class=\"search-section\"\n [ngStyle]=\"{\n 'background-color': 'none'\n }\"\n >\n @if (searchable()) {\n <mat-form-field>\n <input\n id=\"dm-mat-select-search-input\"\n matInput\n [placeholder]=\"searchPlaceholder()\"\n [(ngModel)]=\"filterText\"\n (keyup)=\"applyFilter($event)\"\n (keyDown.Space)=\"$event.stopPropagation()\"\n />\n @if (filterText()) {\n <button\n mat-icon-button\n matSuffix\n (click)=\"resetSearch()\"\n [matTooltip]=\"clearSearchButtonTooltip() || ''\"\n >\n <mat-icon>close</mat-icon>\n </button>\n }\n </mat-form-field>\n } @if (selectAllEnabled() && multiple()) {\n <mat-checkbox [checked]=\"checkIfAllSelected()\" (change)=\"selectAllChange($event)\">{{\n selectAllLabel()\n }}</mat-checkbox>\n }\n </div>\n @if (emptyOption()) {\n <mat-option\n [value]=\"emptyOptionValue()\"\n (onSelectionChange)=\"onSelectionChangeHandler($event, emptyOptionValue())\"\n >{{ emptyOptionLabel() }}</mat-option\n >\n } @for (option of datasource().result(); track simpleArray() ? option :\n option[this.optionValueKey()]) {\n <mat-option\n [value]=\"simpleArray() ? option : option[optionValueKey()]\"\n (onSelectionChange)=\"onSelectionChangeHandler($event, option)\"\n >{{\n optionNameFormat()\n ? option.__dmMatSelectFormattedName\n : simpleArray()\n ? option\n : option[optionLabelKey()]\n }}</mat-option\n >\n } @if (datasource().result().length === 0) {\n <mat-option disabled>{{ noDataLabel() }}</mat-option>\n }\n </mat-select>\n\n @if (icon(); as icon) {\n <span matSuffix>\n @if (isBootstrapIcon()) {\n <span [innerHTML]=\"icon\"></span> } @else {\n <mat-icon matSuffix>{{ icon }}</mat-icon>\n }\n </span>\n }\n\n <span matSuffix>\n <ng-content select=\"[dm-mat-select-suffix]\"></ng-content>\n </span>\n\n <mat-error>{{ error() }}</mat-error>\n </mat-form-field>\n</div>\n", styles: [".dm-mat-select-wrapper{width:100%;position:relative}.dm-mat-select-wrapper .search-section{display:flex;flex-direction:column;position:sticky;top:0;z-index:1;background-color:var(--dm-mat-select-search-section-bg-color, #faf9fd)}.dm-mat-select-wrapper .search-section ::ng-deep mat-form-field>.mat-mdc-form-field-subscript-wrapper{display:none}.dm-mat-select-wrapper ::ng-deep mat-form-field>.mat-mdc-text-field-wrapper>.mat-mdc-form-field-flex>.mat-mdc-form-field-icon-suffix{padding:0 4px 0 8px}\n"] }]
606
641
  }], ctorParameters: () => [], propDecorators: { formFieldClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "formFieldClass", required: false }] }], wrapperClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "wrapperClass", required: false }] }], appearance: [{ type: i0.Input, args: [{ isSignal: true, alias: "appearance", required: false }] }], multiple: [{ type: i0.Input, args: [{ isSignal: true, alias: "multiple", required: false }] }], selectAllEnabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectAllEnabled", required: false }] }], selectAllLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectAllLabel", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: false }] }], optionValueKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "optionValueKey", required: false }] }], optionLabelKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "optionLabelKey", required: false }] }], searchable: [{ type: i0.Input, args: [{ isSignal: true, alias: "searchable", required: false }] }], required: [{ type: i0.Input, args: [{ isSignal: true, alias: "required", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], error: [{ type: i0.Input, args: [{ isSignal: true, alias: "error", required: false }] }], searchPlaceholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "searchPlaceholder", required: false }] }], emptyOption: [{ type: i0.Input, args: [{ isSignal: true, alias: "emptyOption", required: false }] }], emptyOptionLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "emptyOptionLabel", required: false }] }], emptyOptionValue: [{ type: i0.Input, args: [{ isSignal: true, alias: "emptyOptionValue", required: false }] }], optionNameFormat: [{ type: i0.Input, args: [{ isSignal: true, alias: "optionNameFormat", required: false }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }], formControl: [{ type: i0.Input, args: [{ isSignal: true, alias: "formControl", required: false }] }], panelWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "panelWidth", required: false }] }], panelClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "panelClass", required: false }] }], searchSectionBackgroundColor: [{ type: i0.Input, args: [{ isSignal: true, alias: "searchSectionBackgroundColor", required: false }] }], sortBySelectedOnTop: [{ type: i0.Input, args: [{ isSignal: true, alias: "sortBySelectedOnTop", required: false }] }], selectionChange: [{ type: i0.Output, args: ["selectionChange"] }], icon: [{ type: i0.Input, args: [{ isSignal: true, alias: "icon", required: false }] }], noDataLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "noDataLabel", required: false }] }], clearSearchAfterSelect: [{ type: i0.Input, args: [{ isSignal: true, alias: "clearSearchAfterSelect", required: false }] }], clearSearchButtonTooltip: [{ type: i0.Input, args: [{ isSignal: true, alias: "clearSearchButtonTooltip", required: false }] }], focusSearchInputOnPanelOpen: [{ type: i0.Input, args: [{ isSignal: true, alias: "focusSearchInputOnPanelOpen", required: false }] }], filterPredicate: [{ type: i0.Input, args: [{ isSignal: true, alias: "filterPredicate", required: false }] }], propertiesToSkipInSearch: [{ type: i0.Input, args: [{ isSignal: true, alias: "propertiesToSkipInSearch", required: false }] }], filterText: [{ type: i0.Input, args: [{ isSignal: true, alias: "filterText", required: false }] }, { type: i0.Output, args: ["filterTextChange"] }] } });
607
642
 
@@ -712,7 +747,7 @@ class DmColorPicker {
712
747
  registerOnChange(fn) { }
713
748
  registerOnTouched(fn) { }
714
749
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: DmColorPicker, deps: [], target: i0.ɵɵFactoryTarget.Component });
715
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.3", type: DmColorPicker, isStandalone: true, selector: "dm-color-picker", inputs: { colors: { classPropertyName: "colors", publicName: "colors", isSignal: true, isRequired: false, transformFunction: null }, formControl: { classPropertyName: "formControl", publicName: "formControl", isSignal: true, isRequired: false, transformFunction: null }, width: { classPropertyName: "width", publicName: "width", isSignal: true, isRequired: false, transformFunction: null }, height: { classPropertyName: "height", publicName: "height", isSignal: true, isRequired: false, transformFunction: null }, borderRadius: { classPropertyName: "borderRadius", publicName: "borderRadius", isSignal: true, isRequired: false, transformFunction: null }, tooltip: { classPropertyName: "tooltip", publicName: "tooltip", isSignal: true, isRequired: false, transformFunction: null }, tooltipPosition: { classPropertyName: "tooltipPosition", publicName: "tooltipPosition", isSignal: true, isRequired: false, transformFunction: null }, customColor: { classPropertyName: "customColor", publicName: "customColor", isSignal: true, isRequired: false, transformFunction: null }, opacitySlider: { classPropertyName: "opacitySlider", publicName: "opacitySlider", isSignal: true, isRequired: false, transformFunction: null }, opacitySliderLabel: { classPropertyName: "opacitySliderLabel", publicName: "opacitySliderLabel", isSignal: true, isRequired: false, transformFunction: null }, customColorTooltip: { classPropertyName: "customColorTooltip", publicName: "customColorTooltip", isSignal: true, isRequired: false, transformFunction: null }, wrapperClass: { classPropertyName: "wrapperClass", publicName: "wrapperClass", isSignal: true, isRequired: false, transformFunction: null }, wrapperStyle: { classPropertyName: "wrapperStyle", publicName: "wrapperStyle", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { onColorChange: "onColorChange", value: "valueChange" }, ngImport: i0, template: "<div class=\"dm-color-picker-wrapper\" [class]=\"wrapperClass()\" [style]=\"wrapperStyle()\">\n <div\n class=\"dm-color-picker\"\n [matMenuTriggerFor]=\"colorPicker\"\n [style.background-color]=\"selectedColor()\"\n [matTooltip]=\"tooltip()\"\n [matTooltipPosition]=\"tooltipPosition()\"\n [style.width.px]=\"width()\"\n [style.height.px]=\"height()\"\n [style.border-radius]=\"radius()\"\n ></div>\n @if (opacitySlider()){\n <div class=\"dm-color-picker-slider-wrapper\">\n {{ opacitySliderLabel() }}\n <mat-slider min=\"0\" max=\"100\" step=\"1\" discrete [displayWith]=\"formatLabel\">\n <input\n matSliderThumb\n [value]=\"getOpacity()\"\n (input)=\"onOpacityChange($event)\"\n #slider\n (change)=\"updateSelectedColor()\"\n />\n </mat-slider>\n </div>\n }\n</div>\n\n<mat-menu #colorPicker=\"matMenu\">\n <div class=\"dm-color-picker-menu\">\n @for (color of colors(); track color.color){\n <div\n (click)=\"onColorSelected(color.color)\"\n class=\"dm-color-div\"\n [matTooltip]=\"color.tooltip || ''\"\n matTooltipPosition=\"above\"\n [style.background-color]=\"color.color\"\n ></div>\n } @if (customColor()){<input\n (click)=\"$event.stopPropagation()\"\n [matTooltip]=\"customColorTooltip()\"\n [matTooltipPosition]=\"tooltipPosition()\"\n [value]=\"selectedColor()\"\n type=\"color\"\n class=\"pointer\"\n (change)=\"_onColorChange($event)\"\n />}\n </div>\n</mat-menu>\n", styles: [".dm-color-picker-wrapper{display:flex;flex-direction:column;align-items:start;width:fit-content}.dm-color-picker-wrapper .dm-color-picker{cursor:pointer;padding:3px;box-shadow:0 0 2.5px 1px #00000080}.dm-color-picker-wrapper .dm-color-picker-slider-wrapper{display:flex;align-items:center;gap:5px}.dm-color-picker-menu{display:flex;flex-direction:row;flex-wrap:wrap;align-items:center;justify-content:center;width:100%;height:100%}.dm-color-picker-menu .dm-color-div{width:30px;height:30px;border-radius:50%;margin:5px;cursor:pointer;box-shadow:0 0 2.5px 1px #00000080}.dm-color-picker-menu .dm-color-div:hover{box-shadow:0 0 5px 2px #00000080}.pointer{cursor:pointer}\n"], dependencies: [{ kind: "ngmodule", type: MatMenuModule }, { kind: "component", type: i1$1.MatMenu, selector: "mat-menu", inputs: ["backdropClass", "aria-label", "aria-labelledby", "aria-describedby", "xPosition", "yPosition", "overlapTrigger", "hasBackdrop", "class", "classList"], outputs: ["closed", "close"], exportAs: ["matMenu"] }, { kind: "directive", type: i1$1.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i2$1.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: MatSliderModule }, { kind: "component", type: i3$1.MatSlider, selector: "mat-slider", inputs: ["disabled", "discrete", "showTickMarks", "min", "color", "disableRipple", "max", "step", "displayWith"], exportAs: ["matSlider"] }, { kind: "directive", type: i3$1.MatSliderThumb, selector: "input[matSliderThumb]", inputs: ["value"], outputs: ["valueChange", "dragStart", "dragEnd"], exportAs: ["matSliderThumb"] }] });
750
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.3", type: DmColorPicker, isStandalone: true, selector: "dm-color-picker", inputs: { colors: { classPropertyName: "colors", publicName: "colors", isSignal: true, isRequired: false, transformFunction: null }, formControl: { classPropertyName: "formControl", publicName: "formControl", isSignal: true, isRequired: false, transformFunction: null }, width: { classPropertyName: "width", publicName: "width", isSignal: true, isRequired: false, transformFunction: null }, height: { classPropertyName: "height", publicName: "height", isSignal: true, isRequired: false, transformFunction: null }, borderRadius: { classPropertyName: "borderRadius", publicName: "borderRadius", isSignal: true, isRequired: false, transformFunction: null }, tooltip: { classPropertyName: "tooltip", publicName: "tooltip", isSignal: true, isRequired: false, transformFunction: null }, tooltipPosition: { classPropertyName: "tooltipPosition", publicName: "tooltipPosition", isSignal: true, isRequired: false, transformFunction: null }, customColor: { classPropertyName: "customColor", publicName: "customColor", isSignal: true, isRequired: false, transformFunction: null }, opacitySlider: { classPropertyName: "opacitySlider", publicName: "opacitySlider", isSignal: true, isRequired: false, transformFunction: null }, opacitySliderLabel: { classPropertyName: "opacitySliderLabel", publicName: "opacitySliderLabel", isSignal: true, isRequired: false, transformFunction: null }, customColorTooltip: { classPropertyName: "customColorTooltip", publicName: "customColorTooltip", isSignal: true, isRequired: false, transformFunction: null }, wrapperClass: { classPropertyName: "wrapperClass", publicName: "wrapperClass", isSignal: true, isRequired: false, transformFunction: null }, wrapperStyle: { classPropertyName: "wrapperStyle", publicName: "wrapperStyle", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { onColorChange: "onColorChange", value: "valueChange" }, ngImport: i0, template: "<div class=\"dm-color-picker-wrapper\" [class]=\"wrapperClass()\" [style]=\"wrapperStyle()\">\n <div\n class=\"dm-color-picker\"\n [matMenuTriggerFor]=\"colorPicker\"\n [style.background-color]=\"selectedColor()\"\n [matTooltip]=\"tooltip()\"\n [matTooltipPosition]=\"tooltipPosition()\"\n [style.width.px]=\"width()\"\n [style.height.px]=\"height()\"\n [style.border-radius]=\"radius()\"\n ></div>\n @if (opacitySlider()){\n <div class=\"dm-color-picker-slider-wrapper\">\n {{ opacitySliderLabel() }}\n <mat-slider min=\"0\" max=\"100\" step=\"1\" discrete [displayWith]=\"formatLabel\">\n <input\n matSliderThumb\n [value]=\"getOpacity()\"\n (input)=\"onOpacityChange($event)\"\n #slider\n (change)=\"updateSelectedColor()\"\n />\n </mat-slider>\n </div>\n }\n</div>\n\n<mat-menu #colorPicker=\"matMenu\">\n <div class=\"dm-color-picker-menu\">\n @for (color of colors(); track color.color){\n <div\n (click)=\"onColorSelected(color.color)\"\n class=\"dm-color-div\"\n [matTooltip]=\"color.tooltip || ''\"\n matTooltipPosition=\"above\"\n [style.background-color]=\"color.color\"\n ></div>\n } @if (customColor()){<input\n (click)=\"$event.stopPropagation()\"\n [matTooltip]=\"customColorTooltip()\"\n [matTooltipPosition]=\"tooltipPosition()\"\n [value]=\"selectedColor()\"\n type=\"color\"\n class=\"pointer\"\n (change)=\"_onColorChange($event)\"\n />}\n </div>\n</mat-menu>\n", styles: [".dm-color-picker-wrapper{display:flex;flex-direction:column;align-items:start;width:fit-content}.dm-color-picker-wrapper .dm-color-picker{cursor:pointer;padding:3px;box-shadow:0 0 2.5px 1px #00000080}.dm-color-picker-wrapper .dm-color-picker-slider-wrapper{display:flex;align-items:center;gap:5px}.dm-color-picker-menu{display:flex;flex-direction:row;flex-wrap:wrap;align-items:center;justify-content:center;width:100%;height:100%}.dm-color-picker-menu .dm-color-div{width:30px;height:30px;border-radius:50%;margin:5px;cursor:pointer;box-shadow:0 0 2.5px 1px #00000080}.dm-color-picker-menu .dm-color-div:hover{box-shadow:0 0 5px 2px #00000080}.pointer{cursor:pointer}\n"], dependencies: [{ kind: "ngmodule", type: MatMenuModule }, { kind: "component", type: i10.MatMenu, selector: "mat-menu", inputs: ["backdropClass", "aria-label", "aria-labelledby", "aria-describedby", "xPosition", "yPosition", "overlapTrigger", "hasBackdrop", "class", "classList"], outputs: ["closed", "close"], exportAs: ["matMenu"] }, { kind: "directive", type: i10.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i2$1.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: MatSliderModule }, { kind: "component", type: i3$1.MatSlider, selector: "mat-slider", inputs: ["disabled", "discrete", "showTickMarks", "min", "color", "disableRipple", "max", "step", "displayWith"], exportAs: ["matSlider"] }, { kind: "directive", type: i3$1.MatSliderThumb, selector: "input[matSliderThumb]", inputs: ["value"], outputs: ["valueChange", "dragStart", "dragEnd"], exportAs: ["matSliderThumb"] }] });
716
751
  }
717
752
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: DmColorPicker, decorators: [{
718
753
  type: Component,
@@ -848,9 +883,1314 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImpor
848
883
  args: [{ selector: 'dm-spinner', standalone: true, imports: [CommonModule], template: "@if ( (_spinnerService.visibility$() && (_spinnerService.spinnerToShow$() == name())) ||\n(_spinnerService.spinnerTasks$().size > 0 && name() == 'dm-spinner')) {\n\n<div class=\"dm-spinner-wrapper\">\n <div class=\"dm-spinner-inner-wrapper\">\n @switch (type()) { @case ('flower') {\n <div class=\"dm-spinner-flower\"></div>\n } @case ('rounded') {\n <div class=\"dm-spinner-rounded\"></div>\n } @case ('gif') {\n <img class=\"dm-spinner-gif\" [src]=\"gifSrc()\" [width]=\"size()\" [height]=\"'auto'\" />\n } }\n <div class=\"dm-spinner-text\" [style.font-size.px]=\"fontSize()\">\n {{ spinnerText() }}\n </div>\n </div>\n</div>\n}\n", styles: [":host-context(.loading-active) .dm-spinner-wrapper{pointer-events:none}:host-context(.loading-active) .dm-spinner-wrapper{pointer-events:auto}.dm-spinner-wrapper{position:var(--dm-spinner-position, absolute);top:0;left:0;height:100%;width:100%;background-color:var(--dm-spinner-background-color, rgba(0, 0, 0, .2));z-index:9999999999;-webkit-backdrop-filter:blur(var(--dm-spinner-background-blur, 5px));backdrop-filter:blur(var(--dm-spinner-background-blur, 5px))}.dm-spinner-wrapper .dm-spinner-inner-wrapper{position:relative;width:100%;height:100%;display:block}.dm-spinner-wrapper .dm-spinner-inner-wrapper .dm-spinner-rounded{width:calc(var(--dm-spinner-size, 60) * 1px);position:absolute;height:calc(var(--dm-spinner-size, 60) * 1px);transform-origin:center;top:calc(50% - var(--dm-spinner-size, 60) / 2 * 1px);left:calc(50% - var(--dm-spinner-size, 60) / 2 * 1px);border-top:calc(var(--dm-spinner-border-thikness, 5) * 1px) solid var(--dm-spinner-first-color, #1a4bd6);border-right:calc(var(--dm-spinner-border-thikness, 5) * 1px) solid var(--dm-spinner-second-color, #e6f0fb);border-bottom:calc(var(--dm-spinner-border-thikness, 5) * 1px) solid var(--dm-spinner-first-color, #1a4bd6);border-left:calc(var(--dm-spinner-border-thikness, 5) * 1px) solid var(--dm-spinner-second-color, #e6f0fb);border-radius:50%;animation:spin calc(var(--dm-spinner-speed, 2) * 1s) linear infinite}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.dm-spinner-wrapper .dm-spinner-inner-wrapper .dm-spinner-flower{width:calc(var(--dm-spinner-shape-size, 25) * 1px);position:absolute;height:calc(var(--dm-spinner-shape-size, 25) * 1px);background-color:none;border-radius:50%;transform-origin:center;top:calc(50% - var(--dm-spinner-shape-size, 25) / 2 * 1px);left:calc(50% - var(--dm-spinner-shape-size, 25) / 2 * 1px);animation:flower calc(var(--dm-spinner-speed, 2) * 1s) linear infinite}@keyframes flower{0%{rotate:0deg;transform:scale(0);box-shadow:calc(var(--dm-spinner-size, 60) / 2 * 1px) calc(var(--dm-spinner-size, 60) / 2 * 1px) 0 calc(var(--dm-spinner-size, 60) / 2 * 1px) var(--dm-spinner-first-color, #1a4bd6),calc(var(--dm-spinner-size, 60) / 2 * -1px) calc(var(--dm-spinner-size, 60) / 2 * 1px) 0 calc(var(--dm-spinner-size, 60) / 2 * 1px) var(--dm-spinner-second-color, #e6f0fb),calc(var(--dm-spinner-size, 60) / 2 * -1px) calc(var(--dm-spinner-size, 60) / 2 * -1px) 0 calc(var(--dm-spinner-size, 60) / 2 * 1px) var(--dm-spinner-thired-color, #1a4bd6),calc(var(--dm-spinner-size, 60) / 2 * 1px) calc(var(--dm-spinner-size, 60) / 2 * -1px) 0 calc(var(--dm-spinner-size, 60) / 2 * 1px) var(--dm-spinner-fourth-color, #e6f0fb)}25%{rotate:180deg;transform:scale(1);box-shadow:calc(var(--dm-spinner-size, 60) / 2 * 1px) calc(var(--dm-spinner-size, 60) / 2 * 1px) 0 var(--dm-spinner-fourth-color, #e6f0fb),calc(var(--dm-spinner-size, 60) / 2 * -1px) calc(var(--dm-spinner-size, 60) / 2 * 1px) 0 var(--dm-spinner-thired-color, #1a4bd6),calc(var(--dm-spinner-size, 60) / 2 * -1px) calc(var(--dm-spinner-size, 60) / 2 * -1px) 0 var(--dm-spinner-first-color, #1a4bd6),calc(var(--dm-spinner-size, 60) / 2 * 1px) calc(var(--dm-spinner-size, 60) / 2 * -1px) 0 var(--dm-spinner-second-color, #e6f0fb)}50%{rotate:360deg;transform:scale(1);box-shadow:0 0 0 var(--dm-spinner-first-color, #1a4bd6),0 0 0 var(--dm-spinner-second-color, #e6f0fb),0 0 0 var(--dm-spinner-thired-color, #1a4bd6),0 0 0 var(--dm-spinner-fourth-color, #e6f0fb)}75%{rotate:540deg;transform:scale(1);box-shadow:calc(var(--dm-spinner-size, 60) / 2 * 1px) calc(var(--dm-spinner-size, 60) / 2 * 1px) 0 var(--dm-spinner-second-color, #e6f0fb),calc(var(--dm-spinner-size, 60) / 2 * -1px) calc(var(--dm-spinner-size, 60) / 2 * 1px) 0 var(--dm-spinner-fourth-color, #e6f0fb),calc(var(--dm-spinner-size, 60) / 2 * -1px) calc(var(--dm-spinner-size, 60) / 2 * -1px) 0 var(--dm-spinner-first-color, #1a4bd6),calc(var(--dm-spinner-size, 60) / 2 * 1px) calc(var(--dm-spinner-size, 60) / 2 * -1px) 0 var(--dm-spinner-thired-color, #1a4bd6)}to{rotate:720deg;transform:scale(0);box-shadow:calc(var(--dm-spinner-size, 60) / 2 * 1px) calc(var(--dm-spinner-size, 60) / 2 * 1px) 0 calc(var(--dm-spinner-size, 60) / 2 * 1px) var(--dm-spinner-first-color, #1a4bd6),calc(var(--dm-spinner-size, 60) / 2 * -1px) calc(var(--dm-spinner-size, 60) / 2 * 1px) 0 calc(var(--dm-spinner-size, 60) / 2 * 1px) var(--dm-spinner-second-color, #e6f0fb),calc(var(--dm-spinner-size, 60) / 2 * -1px) calc(var(--dm-spinner-size, 60) / 2 * -1px) 0 calc(var(--dm-spinner-size, 60) / 2 * 1px) var(--dm-spinner-thired-color, #1a4bd6),calc(var(--dm-spinner-size, 60) / 2 * 1px) calc(var(--dm-spinner-size, 60) / 2 * -1px) 0 calc(var(--dm-spinner-size, 60) / 2 * 1px) var(--dm-spinner-fourth-color, #e6f0fb)}}.dm-spinner-wrapper .dm-spinner-inner-wrapper .dm-spinner-gif{width:calc(var(--dm-spinner-size, 60) * 1px);position:absolute;height:calc(var(--dm-spinner-size, 60) * 1px);transform-origin:center;top:calc(50% - var(--dm-spinner-size, 60) / 2 * 1px);left:calc(50% - var(--dm-spinner-size, 60) / 2 * 1px);background-size:cover}.dm-spinner-wrapper .dm-spinner-inner-wrapper .dm-spinner-text{position:relative;display:flow-root;top:calc(50% + var(--dm-spinner-size, 60) * 1px / 2 + 5px + var(--dm-spinner-font-size, 20) * 1px / 2 + var(--dm-spinner-text-position-y-offset, 0px) * 1px);margin:0 auto;color:var(--dm-spinner-text-color, #000);text-align:center;font-weight:700}\n"] }]
849
884
  }], ctorParameters: () => [{ type: DmSpinnerService }, { type: i0.Renderer2 }], propDecorators: { color: [{ type: i0.Input, args: [{ isSignal: true, alias: "color", required: false }] }], type: [{ type: i0.Input, args: [{ isSignal: true, alias: "type", required: false }] }], gifSrc: [{ type: i0.Input, args: [{ isSignal: true, alias: "gifSrc", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], shapeSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "shapeSize", required: false }] }], speed: [{ type: i0.Input, args: [{ isSignal: true, alias: "speed", required: false }] }], borderThikness: [{ type: i0.Input, args: [{ isSignal: true, alias: "borderThikness", required: false }] }], position: [{ type: i0.Input, args: [{ isSignal: true, alias: "position", required: false }] }], backgroundColor: [{ type: i0.Input, args: [{ isSignal: true, alias: "backgroundColor", required: false }] }], text: [{ type: i0.Input, args: [{ isSignal: true, alias: "text", required: false }] }], textColor: [{ type: i0.Input, args: [{ isSignal: true, alias: "textColor", required: false }] }], fontSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "fontSize", required: false }] }], textPosition: [{ type: i0.Input, args: [{ isSignal: true, alias: "textPosition", required: false }] }], colors: [{ type: i0.Input, args: [{ isSignal: true, alias: "colors", required: false }] }], backgroundBlur: [{ type: i0.Input, args: [{ isSignal: true, alias: "backgroundBlur", required: false }] }], textPositionYOffset: [{ type: i0.Input, args: [{ isSignal: true, alias: "textPositionYOffset", required: false }] }], name: [{ type: i0.Input, args: [{ isSignal: true, alias: "name", required: false }] }] } });
850
885
 
886
+ const shouldCacheColumn = (column) => {
887
+ return !!column.valueGetter || !!(column.type == 'date');
888
+ };
889
+ const DM_TABLE_HEADER_BACKGROUND_COLOR_CSS_VAR = '--dm-table-header-background-color';
890
+ const DM_TABLE_HEADER_COLOR_CSS_VAR = '--dm-table-header-color';
891
+ const DM_TABLE_SCROLLBAR_COLOR_CSS_VAR = '--dm-table-scrollbar-color';
892
+ const DM_TABLE_SCROLLBAR_HOVER_COLOR_CSS_VAR = '--dm-table-scrollbar-hover-color';
893
+ const DM_TABLE_SCROLLBAR_BACKGROUND_COLOR_CSS_VAR = '--dm-table-scrollbar-background-color';
894
+ const DM_TABLE_SCROLLBAR_WIDTH_CSS_VAR = '--dm-table-scrollbar-width';
895
+ const DM_TABLE_SCROLLBAR_BORDER_RADIUS_CSS_VAR = '--dm-table-scrollbar-border-radius';
896
+
897
+ class DmTableCellHost {
898
+ component = input.required(...(ngDevMode ? [{ debugName: "component" }] : []));
899
+ context = input.required(...(ngDevMode ? [{ debugName: "context" }] : []));
900
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: DmTableCellHost, deps: [], target: i0.ɵɵFactoryTarget.Component });
901
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.0.3", type: DmTableCellHost, isStandalone: true, selector: "dm-table-cell-host", inputs: { component: { classPropertyName: "component", publicName: "component", isSignal: true, isRequired: true, transformFunction: null }, context: { classPropertyName: "context", publicName: "context", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: "<ng-container\n *ngComponentOutlet=\"\n component();\n inputs: {\n row: context().row,\n column: context().column,\n }\n \"\n></ng-container>\n", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i11.NgComponentOutlet, selector: "[ngComponentOutlet]", inputs: ["ngComponentOutlet", "ngComponentOutletInputs", "ngComponentOutletInjector", "ngComponentOutletEnvironmentInjector", "ngComponentOutletContent", "ngComponentOutletNgModule"], exportAs: ["ngComponentOutlet"] }] });
902
+ }
903
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: DmTableCellHost, decorators: [{
904
+ type: Component,
905
+ args: [{ selector: 'dm-table-cell-host', standalone: true, imports: [CommonModule], template: "<ng-container\n *ngComponentOutlet=\"\n component();\n inputs: {\n row: context().row,\n column: context().column,\n }\n \"\n></ng-container>\n" }]
906
+ }], propDecorators: { component: [{ type: i0.Input, args: [{ isSignal: true, alias: "component", required: true }] }], context: [{ type: i0.Input, args: [{ isSignal: true, alias: "context", required: true }] }] } });
907
+
908
+ const daysOfWeek = {
909
+ en: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'],
910
+ he: ['ראשון', 'שני', 'שלישי', 'רביעי', 'חמישי', 'שישי', 'שבת'],
911
+ ar: ['الأحد', 'الاثنين', 'الثلاثاء', 'الأربعاء', 'الخميس', 'الجمعة', 'السبت'],
912
+ };
913
+ Date.prototype.getWeekOfYear = function () {
914
+ const d = new Date(Date.UTC(this.getFullYear(), this.getMonth(), this.getDate()));
915
+ const dayNum = d.getUTCDay() || 7;
916
+ d.setUTCDate(d.getUTCDate() + 4 - dayNum);
917
+ const yearStart = new Date(Date.UTC(d.getUTCFullYear(), 0, 1));
918
+ return Math.ceil(((d.getTime() - yearStart.getTime()) / 86400000 + 1) / 7);
919
+ };
920
+ Date.prototype.getWeekOfMonth = function () {
921
+ const firstDay = new Date(this.getFullYear(), this.getMonth(), 1).getDay();
922
+ const day = this.getDate();
923
+ return Math.ceil((day + firstDay) / 7);
924
+ };
925
+ Date.prototype.getDayOfYear = function () {
926
+ const start = new Date(this.getFullYear(), 0, 0);
927
+ const diff = this.getTime() - start.getTime();
928
+ const oneDay = 1000 * 60 * 60 * 24;
929
+ return Math.floor(diff / oneDay);
930
+ };
931
+ class DmDateService {
932
+ getDate(date) {
933
+ if (!date)
934
+ return null;
935
+ if (date instanceof Date)
936
+ return date;
937
+ if (typeof date === 'string') {
938
+ if (date == '')
939
+ return null;
940
+ return new Date(date) || null;
941
+ }
942
+ if ('seconds' in date && 'nanoseconds' in date) {
943
+ return new Date(date.seconds * 1000);
944
+ }
945
+ if ('_seconds' in date && '_nanoseconds' in date) {
946
+ return new Date(date._seconds * 1000);
947
+ }
948
+ if (!isNaN(Number(date))) {
949
+ return new Date(1900, 0, +date - 1);
950
+ }
951
+ return null;
952
+ }
953
+ /**
954
+ *
955
+ * @param date the date to transform
956
+ * @param format the format of the date
957
+ * @param lang the language of the date
958
+ * @returns the date as a string
959
+ *
960
+ * @example
961
+ * The format can be any string that contains the following:
962
+ * - 'dd' - the day of the month
963
+ * - 'MM' - the month
964
+ * - 'yyyy' - the year
965
+ * - 'yy' - the year (2 digits)
966
+ * - 'HH' - the hour
967
+ * - 'mm' - the minute
968
+ * - 'ss' - the second
969
+ * - 'SSS' - the millisecond
970
+ * - 'DM_a' - the AM/PM
971
+ * - 'DM_E' - the day of the week
972
+ * - 'DM_Z' - the time zone
973
+ * - 'DM_z' - the time zone offset
974
+ * - 'DM_yw' - the week of the year
975
+ * - 'DM_mw' - the week of the month
976
+ * - 'DM_yd' - the day of the year
977
+ */
978
+ getDateString(date, format = 'dd/MM/yyyy', lang = 'he') {
979
+ if (!date)
980
+ return '';
981
+ const res = this.getDate(date);
982
+ if (!res || !(res instanceof Date) || isNaN(res.getTime()))
983
+ return '';
984
+ // const day = res.getDate().toString().padStart(2, '0');
985
+ // const month = (res.getMonth() + 1).toString().padStart(2, '0');
986
+ // const year = res.getFullYear();
987
+ // const hours = res.getHours().toString().padStart(2, '0');
988
+ // const minutes = res.getMinutes().toString().padStart(2, '0');
989
+ const replacements = {
990
+ dd: res.getDate().toString().padStart(2, '0'),
991
+ MM: (res.getMonth() + 1).toString().padStart(2, '0'),
992
+ yyyy: res.getFullYear().toString(),
993
+ yy: res.getFullYear().toString().slice(-2),
994
+ HH: res.getHours().toString().padStart(2, '0'),
995
+ mm: res.getMinutes().toString().padStart(2, '0'),
996
+ SSS: res.getMilliseconds().toString().padStart(3, '0'),
997
+ ss: res.getSeconds().toString().padStart(2, '0'),
998
+ DD: daysOfWeek[lang][res.getDay()],
999
+ DM_a: res.getHours() < 12 ? 'AM' : 'PM',
1000
+ DM_E: res.getDay().toString(),
1001
+ DM_Z: res.toTimeString().match(/\(([^)]+)\)/)?.[1] || '',
1002
+ DM_z: res.getTimezoneOffset().toString(),
1003
+ DM_yw: res.getWeekOfYear().toString(),
1004
+ DM_mw: res.getWeekOfMonth().toString(),
1005
+ DM_yd: res.getDayOfYear().toString(),
1006
+ };
1007
+ // Replace format placeholders with actual values
1008
+ return format.replace(/(dd|MM|yyyy|yy|HH|mm|SSS|ss|DD|DM_a|DM_E|DM_Z|DM_z|DM_yw|DM_mw|DM_yd)/g, (match) => replacements[match] || match);
1009
+ // if (format === 'dd/MM/yyyy') {
1010
+ // return `${day}/${month}/${year}`;
1011
+ // }
1012
+ // if (format === 'yyyy/MM/dd') {
1013
+ // return `${year}/${month}/${day}`;
1014
+ // }
1015
+ // return `${day}/${month}/${year} ${hours}:${minutes}`;
1016
+ }
1017
+ /**
1018
+ *
1019
+ * @param date the date to transform
1020
+ * @param format the format of the date
1021
+ * @param lang the language of the date
1022
+ * @returns the date as a string
1023
+ *
1024
+ * @example
1025
+ * The format can be any string that contains the following:
1026
+ * - 'dd' - the day of the month
1027
+ * - 'MM' - the month
1028
+ * - 'yyyy' - the year
1029
+ * - 'yy' - the year (2 digits)
1030
+ * - 'HH' - the hour
1031
+ * - 'mm' - the minute
1032
+ * - 'ss' - the second
1033
+ * - 'SSS' - the millisecond
1034
+ * - 'DM_a' - the AM/PM
1035
+ * - 'DM_E' - the day of the week
1036
+ * - 'DM_Z' - the time zone
1037
+ * - 'DM_z' - the time zone offset
1038
+ * - 'DM_yw' - the week of the year
1039
+ * - 'DM_mw' - the week of the month
1040
+ * - 'DM_yd' - the day of the year
1041
+ */
1042
+ static getDateString(date, format = 'dd/MM/yyyy', lang = 'he') {
1043
+ if (!date)
1044
+ return '';
1045
+ const res = DmDateService.getDate(date);
1046
+ if (!res || !(res instanceof Date) || isNaN(res.getDate()))
1047
+ return '';
1048
+ const replacements = {
1049
+ dd: res.getDate().toString().padStart(2, '0'),
1050
+ MM: (res.getMonth() + 1).toString().padStart(2, '0'),
1051
+ yyyy: res.getFullYear().toString(),
1052
+ yy: res.getFullYear().toString().slice(-2),
1053
+ HH: res.getHours().toString().padStart(2, '0'),
1054
+ mm: res.getMinutes().toString().padStart(2, '0'),
1055
+ SSS: res.getMilliseconds().toString().padStart(3, '0'),
1056
+ ss: res.getSeconds().toString().padStart(2, '0'),
1057
+ DD: daysOfWeek[lang][res.getDay()],
1058
+ DM_a: res.getHours() < 12 ? 'AM' : 'PM',
1059
+ DM_E: res.getDay().toString(),
1060
+ DM_Z: res.toTimeString().match(/\(([^)]+)\)/)?.[1] || '',
1061
+ DM_z: res.getTimezoneOffset().toString(),
1062
+ DM_yw: res.getWeekOfYear().toString(),
1063
+ DM_mw: res.getWeekOfMonth().toString(),
1064
+ DM_yd: res.getDayOfYear().toString(),
1065
+ };
1066
+ // Replace format placeholders with actual values
1067
+ return format.replace(/(dd|MM|yyyy|yy|HH|mm|SSS|ss|DD|DM_a|DM_E|DM_Z|DM_z|DM_yw|DM_mw|DM_yd)/g, (match) => replacements[match] || match);
1068
+ // const day = res.getDate().toString().padStart(2, '0');
1069
+ // const month = (res.getMonth() + 1).toString().padStart(2, '0');
1070
+ // const year = res.getFullYear();
1071
+ // const hours = res.getHours().toString().padStart(2, '0');
1072
+ // const minutes = res.getMinutes().toString().padStart(2, '0');
1073
+ // if (format === 'dd/MM/yyyy') {
1074
+ // return `${day}/${month}/${year}`;
1075
+ // }
1076
+ // if (format === 'yyyy/MM/dd') {
1077
+ // return `${year}/${month}/${day}`;
1078
+ // }
1079
+ // return `${day}/${month}/${year} ${hours}:${minutes}`;
1080
+ }
1081
+ static getDate(date) {
1082
+ if (!date)
1083
+ return null;
1084
+ if (date instanceof Date)
1085
+ return date;
1086
+ if (typeof date === 'string') {
1087
+ if (date == '')
1088
+ return null;
1089
+ return new Date(date) || null;
1090
+ }
1091
+ if ('_seconds' in date && '_nanoseconds' in date) {
1092
+ return new Date(date._seconds * 1000);
1093
+ }
1094
+ if ('seconds' in date && 'nanoseconds' in date) {
1095
+ return new Date(date.seconds * 1000);
1096
+ }
1097
+ if (!isNaN(Number(date))) {
1098
+ return new Date(1900, 0, +date - 1);
1099
+ }
1100
+ return null;
1101
+ }
1102
+ static getTimeString(date) {
1103
+ if (!date)
1104
+ return '';
1105
+ const res = DmDateService.getDate(date);
1106
+ if (!res || !(res instanceof Date))
1107
+ return '';
1108
+ return `${(res.getHours() < 10 ? '0' : '') + res.getHours()}:${(res.getMinutes() < 10 ? '0' : '') + res.getMinutes()}`;
1109
+ }
1110
+ static now() {
1111
+ return new Date();
1112
+ }
1113
+ now() {
1114
+ return new Date();
1115
+ }
1116
+ getAge(date, fixed = null, result = 'number') {
1117
+ if (!date)
1118
+ return 0;
1119
+ const res = this.getDate(date);
1120
+ if (!res || !(res instanceof Date))
1121
+ return 0;
1122
+ const today = new Date();
1123
+ let age = today.getFullYear() - res.getFullYear();
1124
+ let monthDiff = today.getMonth() - res.getMonth();
1125
+ if (monthDiff < 0 || (monthDiff === 0 && today.getDate() < res.getDate())) {
1126
+ age--;
1127
+ monthDiff += 12;
1128
+ }
1129
+ const ageWithMonths = age + monthDiff / 12;
1130
+ if (result === 'string') {
1131
+ if (fixed || fixed === 0) {
1132
+ return ageWithMonths.toFixed(fixed);
1133
+ }
1134
+ return ageWithMonths;
1135
+ }
1136
+ if (fixed || fixed === 0) {
1137
+ return Number(ageWithMonths.toFixed(fixed));
1138
+ }
1139
+ return ageWithMonths;
1140
+ }
1141
+ static getAge(date, fixed = null, result = 'number') {
1142
+ if (!date)
1143
+ return 0;
1144
+ const res = DmDateService.getDate(date);
1145
+ if (!res || !(res instanceof Date))
1146
+ return 0;
1147
+ const today = new Date();
1148
+ let age = today.getFullYear() - res.getFullYear();
1149
+ let monthDiff = today.getMonth() - res.getMonth();
1150
+ if (monthDiff < 0 || (monthDiff === 0 && today.getDate() < res.getDate())) {
1151
+ age--;
1152
+ monthDiff += 12;
1153
+ }
1154
+ const ageWithMonths = age + monthDiff / 12;
1155
+ if (result === 'string') {
1156
+ if (fixed || fixed === 0) {
1157
+ return ageWithMonths.toFixed(fixed);
1158
+ }
1159
+ return ageWithMonths;
1160
+ }
1161
+ if (fixed || fixed === 0) {
1162
+ return Number(ageWithMonths.toFixed(fixed));
1163
+ }
1164
+ return ageWithMonths;
1165
+ }
1166
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: DmDateService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
1167
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: DmDateService, providedIn: 'root' });
1168
+ }
1169
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: DmDateService, decorators: [{
1170
+ type: Injectable,
1171
+ args: [{
1172
+ providedIn: 'root',
1173
+ }]
1174
+ }] });
1175
+
1176
+ const DEFAULT_PAGINATOR_SETTINGS = {
1177
+ pageSize: 10,
1178
+ pageSizeOptions: [10, 25, 50, 100],
1179
+ numberOfItemsPerPageLabel: 'מספר פריטים בדף',
1180
+ firstPageButtonLabel: 'דף ראשון',
1181
+ lastPageButtonLabel: 'דף אחרון',
1182
+ nextPageButtonLabel: 'הדף הבא',
1183
+ previousPageButtonLabel: 'הדף הקודם',
1184
+ showFirstAndLastPagesButtons: true,
1185
+ };
1186
+ const DEFAULT_TABLE_STYLE = {
1187
+ tableWrapper: {
1188
+ 'max-height': '800px',
1189
+ width: 'calc(100% - 10px)',
1190
+ display: 'block',
1191
+ 'overflow-x': 'auto',
1192
+ padding: '0 5px',
1193
+ },
1194
+ table: {
1195
+ root: {
1196
+ width: '100%',
1197
+ 'border-collapse': 'collapse',
1198
+ 'border-spacing': 0,
1199
+ 'box-shadow': '0px 5px 5px -3px #003, 0 8px 10px 1px #00000024, 0 3px 14px 2px #0000001f',
1200
+ padding: 0,
1201
+ 'font-size': '1rem',
1202
+ 'border-radius': '8px',
1203
+ 'page-break-inside': 'auto',
1204
+ },
1205
+ thead: {
1206
+ root: {
1207
+ 'background-color': '#f5f5f5',
1208
+ },
1209
+ th: {
1210
+ padding: '20px 15px',
1211
+ 'text-align': 'start',
1212
+ 'max-width': 'none',
1213
+ },
1214
+ },
1215
+ tbody: {
1216
+ hovered_row_style: {
1217
+ tr: {
1218
+ 'background-color': '#f5f5f5',
1219
+ },
1220
+ },
1221
+ even_row_style: {
1222
+ tr: {
1223
+ 'background-color': '#ffffff',
1224
+ },
1225
+ },
1226
+ odd_row_style: {
1227
+ tr: {
1228
+ 'background-color': '#fafafa',
1229
+ },
1230
+ },
1231
+ tr: {
1232
+ 'border-bottom': '1px solid #e0e0e0',
1233
+ 'page-break-inside': 'avoid',
1234
+ },
1235
+ td: {
1236
+ padding: '7px 15px',
1237
+ 'text-align': 'start',
1238
+ 'max-width': 'none',
1239
+ 'text-overflow': 'ellipsis',
1240
+ overflow: 'hidden',
1241
+ 'white-space': 'nowrap',
1242
+ },
1243
+ input: {
1244
+ background: 'white',
1245
+ border: '1px solid',
1246
+ 'border-radius': '3px',
1247
+ },
1248
+ },
1249
+ tfoot: {
1250
+ root: {
1251
+ 'background-color': '#f5f5f5',
1252
+ },
1253
+ td: {
1254
+ padding: '20px 15px',
1255
+ 'text-align': 'start',
1256
+ 'max-width': 'none',
1257
+ },
1258
+ },
1259
+ },
1260
+ paginator: {
1261
+ root: {
1262
+ 'background-color': '#f5f5f5',
1263
+ },
1264
+ p: {
1265
+ 'margin-bottom': '0',
1266
+ },
1267
+ },
1268
+ scrollbar: {
1269
+ width: '6px',
1270
+ },
1271
+ };
1272
+ const DEFAULT_PRINT_TABLE_BUTTON = {
1273
+ icon: 'print',
1274
+ buttonType: 'icon',
1275
+ tooltip: 'הדפס',
1276
+ color: '#5b81ffff',
1277
+ };
1278
+ const DM_TABLE_EDIT_COLUMNS_VISIBILITY_BUTTON = {
1279
+ icon: 'view_column',
1280
+ buttonType: 'icon',
1281
+ tooltip: 'ערוך תצוגה',
1282
+ color: '#6a6a6a',
1283
+ };
1284
+
1285
+ const buildRow = (item, columns) => {
1286
+ const result = { ...item };
1287
+ const setValue = (field, value) => {
1288
+ Object.defineProperty(result, field, {
1289
+ value: value,
1290
+ writable: false,
1291
+ enumerable: true,
1292
+ });
1293
+ };
1294
+ for (const col of columns) {
1295
+ if (col.type === '$index')
1296
+ continue;
1297
+ if (col.type == 'component')
1298
+ continue;
1299
+ if (!col.field)
1300
+ continue;
1301
+ let value = result[col.field];
1302
+ // handle valueGetter
1303
+ if (col.valueGetter) {
1304
+ value = col.valueGetter(result);
1305
+ }
1306
+ else {
1307
+ switch (col.type) {
1308
+ case 'date':
1309
+ if (col.dateFormat) {
1310
+ value = DmDateService.getDateString(value, col.dateFormat);
1311
+ }
1312
+ else {
1313
+ value = DmDateService.getDateString(value);
1314
+ }
1315
+ break;
1316
+ }
1317
+ }
1318
+ setValue(col.field, value);
1319
+ }
1320
+ return result;
1321
+ };
1322
+ function isPlainObject(value) {
1323
+ return value !== null && typeof value === 'object' && !Array.isArray(value);
1324
+ }
1325
+ function deepMerge(defaults, custom) {
1326
+ if (!isPlainObject(defaults)) {
1327
+ return custom ?? defaults;
1328
+ }
1329
+ const result = { ...defaults };
1330
+ if (!custom) {
1331
+ return result;
1332
+ }
1333
+ for (const key of Object.keys(custom)) {
1334
+ const customValue = custom[key];
1335
+ const defaultValue = defaults[key];
1336
+ if (isPlainObject(defaultValue) && isPlainObject(customValue)) {
1337
+ result[key] = deepMerge(defaultValue, customValue);
1338
+ }
1339
+ else if (customValue !== undefined) {
1340
+ // custom wins on leaf
1341
+ result[key] = customValue;
1342
+ }
1343
+ }
1344
+ return result;
1345
+ }
1346
+
1347
+ class DmTableColumnStateStorage {
1348
+ prefix = 'dm-table:columns';
1349
+ load(tableId) {
1350
+ const raw = localStorage.getItem(`${this.prefix}:${tableId}`);
1351
+ return raw ? JSON.parse(raw) : null;
1352
+ }
1353
+ save(tableId, state) {
1354
+ localStorage.setItem(`${this.prefix}:${tableId}`, JSON.stringify(state));
1355
+ }
1356
+ clear(tableId) {
1357
+ localStorage.removeItem(`${this.prefix}:${tableId}`);
1358
+ }
1359
+ }
1360
+
1361
+ class DmImportantStyleDirective {
1362
+ el;
1363
+ styles;
1364
+ constructor(el) {
1365
+ this.el = el;
1366
+ }
1367
+ ngOnChanges() {
1368
+ if (!this.styles)
1369
+ return;
1370
+ // reset styles
1371
+ this.el.nativeElement.style.cssText = '';
1372
+ Object.entries(this.styles).forEach(([key, value]) => {
1373
+ this.el.nativeElement.style.setProperty(key, value, 'important');
1374
+ });
1375
+ }
1376
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: DmImportantStyleDirective, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Directive });
1377
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.0.3", type: DmImportantStyleDirective, isStandalone: true, selector: "[dmImportantStyle]", inputs: { styles: ["dmImportantStyle", "styles"] }, usesOnChanges: true, ngImport: i0 });
1378
+ }
1379
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: DmImportantStyleDirective, decorators: [{
1380
+ type: Directive,
1381
+ args: [{
1382
+ selector: '[dmImportantStyle]',
1383
+ standalone: true,
1384
+ }]
1385
+ }], ctorParameters: () => [{ type: i0.ElementRef }], propDecorators: { styles: [{
1386
+ type: Input,
1387
+ args: ['dmImportantStyle']
1388
+ }] } });
1389
+
1390
+ class DmTable {
1391
+ shiftKeyPressed = signal(false, ...(ngDevMode ? [{ debugName: "shiftKeyPressed" }] : []));
1392
+ onShiftKeyDown(event) {
1393
+ this.shiftKeyPressed.set(true);
1394
+ }
1395
+ onShiftKeyUp(event) {
1396
+ this.shiftKeyPressed.set(false);
1397
+ }
1398
+ DEFAULT_PAGINATOR_SETTINGS = DEFAULT_PAGINATOR_SETTINGS;
1399
+ DEFAULT_TABLE_STYLE = DEFAULT_TABLE_STYLE;
1400
+ tableId = input(...(ngDevMode ? [undefined, { debugName: "tableId" }] : []));
1401
+ dataSource = input([], ...(ngDevMode ? [{ debugName: "dataSource" }] : []));
1402
+ columns = input([], ...(ngDevMode ? [{ debugName: "columns" }] : []));
1403
+ noDataMessage = input('אין נתונים להצגה', ...(ngDevMode ? [{ debugName: "noDataMessage" }] : []));
1404
+ enableSearch = input(false, { ...(ngDevMode ? { debugName: "enableSearch" } : {}), transform: booleanAttribute });
1405
+ searchPlaceholder = input('חיפוש...', ...(ngDevMode ? [{ debugName: "searchPlaceholder" }] : []));
1406
+ clearSearchTooltip = input('נקה חיפוש', ...(ngDevMode ? [{ debugName: "clearSearchTooltip" }] : []));
1407
+ searchInputAppearance = input('fill', ...(ngDevMode ? [{ debugName: "searchInputAppearance" }] : []));
1408
+ filterPredicate = input(null, ...(ngDevMode ? [{ debugName: "filterPredicate" }] : []));
1409
+ _filterPredicate = null;
1410
+ actionButtons = input([], ...(ngDevMode ? [{ debugName: "actionButtons" }] : []));
1411
+ enablePrint = input(false, { ...(ngDevMode ? { debugName: "enablePrint" } : {}), transform: booleanAttribute });
1412
+ printButton = input(DEFAULT_PRINT_TABLE_BUTTON, ...(ngDevMode ? [{ debugName: "printButton" }] : []));
1413
+ enablePagination = input(false, { ...(ngDevMode ? { debugName: "enablePagination" } : {}), transform: booleanAttribute });
1414
+ autoPaginationAboveRowsCount = input(100, { ...(ngDevMode ? { debugName: "autoPaginationAboveRowsCount" } : {}), transform: numberAttribute });
1415
+ paginatorSettings = input(DEFAULT_PAGINATOR_SETTINGS, ...(ngDevMode ? [{ debugName: "paginatorSettings" }] : []));
1416
+ enableLoadingProgressbar = input(true, { ...(ngDevMode ? { debugName: "enableLoadingProgressbar" } : {}), transform: booleanAttribute });
1417
+ enableColumnsDragAndDrop = input(false, { ...(ngDevMode ? { debugName: "enableColumnsDragAndDrop" } : {}), transform: booleanAttribute });
1418
+ enableColumnsDragHandle = input(true, { ...(ngDevMode ? { debugName: "enableColumnsDragHandle" } : {}), transform: booleanAttribute });
1419
+ enableTotalRow = input(false, { ...(ngDevMode ? { debugName: "enableTotalRow" } : {}), transform: booleanAttribute });
1420
+ tableStyle = input(DEFAULT_TABLE_STYLE, ...(ngDevMode ? [{ debugName: "tableStyle" }] : []));
1421
+ tableClasses = input(...(ngDevMode ? [undefined, { debugName: "tableClasses" }] : []));
1422
+ rowStyleFn = input(null, ...(ngDevMode ? [{ debugName: "rowStyleFn" }] : []));
1423
+ editColumnsVisibility = input(false, { ...(ngDevMode ? { debugName: "editColumnsVisibility" } : {}), transform: booleanAttribute });
1424
+ editColumnsVisibilityButton = input(DM_TABLE_EDIT_COLUMNS_VISIBILITY_BUTTON, ...(ngDevMode ? [{ debugName: "editColumnsVisibilityButton" }] : []));
1425
+ editColumnsVisibilitySelectAllLabel = input('הצג את כל העמודות', ...(ngDevMode ? [{ debugName: "editColumnsVisibilitySelectAllLabel" }] : []));
1426
+ columnsSortState = signal([], ...(ngDevMode ? [{ debugName: "columnsSortState" }] : []));
1427
+ mergedTableStyle = computed(() => {
1428
+ const defaults = { ...DEFAULT_TABLE_STYLE };
1429
+ const custom = this.tableStyle() || {};
1430
+ const newStyle = deepMerge(defaults, custom);
1431
+ this.saveScrollbarStyle(newStyle);
1432
+ return newStyle;
1433
+ }, ...(ngDevMode ? [{ debugName: "mergedTableStyle" }] : []));
1434
+ saveScrollbarStyle(mergedStyle) {
1435
+ console.log({ mergedStyle });
1436
+ const scrollbarColor = mergedStyle?.scrollbar?.['color'] ||
1437
+ mergedStyle?.table?.thead?.root?.['background-color'] ||
1438
+ '#949496';
1439
+ const scrollbarBackgroundColor = mergedStyle?.scrollbar?.['backgroundColor'] ||
1440
+ mergedStyle?.table?.tbody?.tr?.['background-color'] ||
1441
+ mergedStyle?.table?.tbody?.odd_row_style?.tr?.['background-color'] ||
1442
+ '#e0e0e0';
1443
+ const scrollbarHoverColor = mergedStyle?.scrollbar?.['hoverColor'] ||
1444
+ mergedStyle?.table?.thead?.root?.['background-color'] ||
1445
+ '#5f5f5f';
1446
+ const scrollbarWidth = mergedStyle?.scrollbar?.['width'] || '7px';
1447
+ const scrollbarBorderRadius = mergedStyle?.scrollbar?.['borderRadius'] || '4px';
1448
+ document.documentElement.style.setProperty(DM_TABLE_SCROLLBAR_COLOR_CSS_VAR, scrollbarColor);
1449
+ document.documentElement.style.setProperty(DM_TABLE_SCROLLBAR_BACKGROUND_COLOR_CSS_VAR, scrollbarBackgroundColor);
1450
+ document.documentElement.style.setProperty(DM_TABLE_SCROLLBAR_HOVER_COLOR_CSS_VAR, scrollbarHoverColor);
1451
+ document.documentElement.style.setProperty(DM_TABLE_SCROLLBAR_WIDTH_CSS_VAR, scrollbarWidth);
1452
+ document.documentElement.style.setProperty(DM_TABLE_SCROLLBAR_BORDER_RADIUS_CSS_VAR, scrollbarBorderRadius);
1453
+ }
1454
+ hoveredRowIndex = signal(null, ...(ngDevMode ? [{ debugName: "hoveredRowIndex" }] : []));
1455
+ datasource = signal(new DmCmpsDataSource([]), ...(ngDevMode ? [{ debugName: "datasource" }] : []));
1456
+ runtimeColumns = computed(() => {
1457
+ const cols = this.columns() ?? [];
1458
+ const normalized = this.normalizeColumns(cols);
1459
+ return this.reconcileColumns(normalized);
1460
+ }, ...(ngDevMode ? [{ debugName: "runtimeColumns" }] : []));
1461
+ hoveredColumnHeaderIndex = signal(null, ...(ngDevMode ? [{ debugName: "hoveredColumnHeaderIndex" }] : []));
1462
+ columnStateStorage = new DmTableColumnStateStorage();
1463
+ columnState = signal(null, ...(ngDevMode ? [{ debugName: "columnState" }] : []));
1464
+ visibleRuntimeColumns = computed(() => {
1465
+ const cols = this.runtimeColumns();
1466
+ const state = this.columnState();
1467
+ if (!state || !state.length) {
1468
+ return cols;
1469
+ }
1470
+ console.log('State changed => ', { state });
1471
+ const stateMap = new Map(state.map((s) => [s.id, s]));
1472
+ return cols
1473
+ .map((col, index) => ({
1474
+ col,
1475
+ state: stateMap.get(col.id) ?? {
1476
+ id: col.id,
1477
+ visible: true,
1478
+ order: index,
1479
+ },
1480
+ }))
1481
+ .filter((x) => x.state.visible !== false)
1482
+ .sort((a, b) => a.state.order - b.state.order)
1483
+ .map((x) => x.col);
1484
+ }, ...(ngDevMode ? [{ debugName: "visibleRuntimeColumns" }] : []));
1485
+ visibleColumns = computed(() => {
1486
+ return this.visibleRuntimeColumns().map((col) => col);
1487
+ }, ...(ngDevMode ? [{ debugName: "visibleColumns" }] : []));
1488
+ prevColumns = new Map();
1489
+ rowIdentifierField = input('_id', ...(ngDevMode ? [{ debugName: "rowIdentifierField" }] : []));
1490
+ modifiedRowsIds = signal(new Set(), ...(ngDevMode ? [{ debugName: "modifiedRowsIds" }] : []));
1491
+ searchTerm = signal('', ...(ngDevMode ? [{ debugName: "searchTerm" }] : []));
1492
+ totalRowValues = computed(() => {
1493
+ const ds = this.datasource();
1494
+ const cols = this.runtimeColumns();
1495
+ const dataVersion = ds.resultVersion(); //this is to make sure we recompute when data changes.. do not remove
1496
+ const map = new Map();
1497
+ for (const col of cols) {
1498
+ if (!col.totalRowValueGetter)
1499
+ continue;
1500
+ try {
1501
+ map.set(col.id, col.totalRowValueGetter(ds));
1502
+ }
1503
+ catch (e) {
1504
+ console.error(`Total row error for column ${col.id}`, e);
1505
+ map.set(col.id, null);
1506
+ }
1507
+ }
1508
+ return map;
1509
+ }, ...(ngDevMode ? [{ debugName: "totalRowValues" }] : []));
1510
+ totalRowStyles = computed(() => {
1511
+ const ds = this.datasource();
1512
+ const cols = this.runtimeColumns();
1513
+ const dataVersion = ds.resultVersion(); //this is to make sure we recompute when data changes.. do not remove
1514
+ const map = new Map();
1515
+ for (const col of cols) {
1516
+ if (!col.totalCellStyle)
1517
+ continue;
1518
+ const totalCellStyle = (typeof col.totalCellStyle === 'function' ? col.totalCellStyle(ds) : col.totalCellStyle) ||
1519
+ {};
1520
+ try {
1521
+ map.set(col.id, totalCellStyle);
1522
+ }
1523
+ catch (e) {
1524
+ console.error(`Total row style error for column ${col.id}`, e);
1525
+ map.set(col.id, {});
1526
+ }
1527
+ }
1528
+ return map;
1529
+ }, ...(ngDevMode ? [{ debugName: "totalRowStyles" }] : []));
1530
+ constructor() {
1531
+ this.runEffects();
1532
+ }
1533
+ runEffects() {
1534
+ effect(() => {
1535
+ const tableStyle = this.mergedTableStyle();
1536
+ document.documentElement.style.setProperty(DM_TABLE_HEADER_BACKGROUND_COLOR_CSS_VAR, this.mergedTableStyle().table?.thead?.root?.['background-color'] ??
1537
+ DM_TABLE_HEADER_BACKGROUND_COLOR_CSS_VAR);
1538
+ document.documentElement.style.setProperty(DM_TABLE_HEADER_COLOR_CSS_VAR, this.mergedTableStyle().table?.thead?.root?.['color'] ?? DM_TABLE_HEADER_COLOR_CSS_VAR);
1539
+ });
1540
+ effect(() => {
1541
+ const tableId = this.tableId();
1542
+ const cols = this.runtimeColumns();
1543
+ let stored = null;
1544
+ if (tableId) {
1545
+ stored = this.columnStateStorage.load(tableId);
1546
+ }
1547
+ // sanitize stored state to remove any columns that no longer exist
1548
+ if (stored) {
1549
+ const colIds = new Set(cols.map((c) => c.id));
1550
+ stored = stored.filter((s) => colIds.has(s.id));
1551
+ console.log('Stored columns sanitized!!!');
1552
+ }
1553
+ this.columnState.set(this.initColumnState(cols, stored));
1554
+ });
1555
+ effect(() => {
1556
+ const id = this.tableId();
1557
+ const state = this.columnState();
1558
+ if (!id || !state)
1559
+ return;
1560
+ this.columnStateStorage.save(id, state);
1561
+ });
1562
+ effect(() => {
1563
+ this._filterPredicate = this.filterPredicate();
1564
+ });
1565
+ effect(() => {
1566
+ const dataSource = this.dataSource();
1567
+ if (this._filterPredicate) {
1568
+ this.datasource().setFilterPredicate(this._filterPredicate);
1569
+ }
1570
+ if (this.enablePagination() || dataSource.length >= this.autoPaginationAboveRowsCount()) {
1571
+ this.datasource().applyPagination(this.paginatorSettings()?.pageSize || DEFAULT_PAGINATOR_SETTINGS.pageSize);
1572
+ }
1573
+ else {
1574
+ this.datasource().disablePagination();
1575
+ }
1576
+ this.datasource().setDatasource(dataSource);
1577
+ this.prevColumns.forEach((col) => delete col.__cache);
1578
+ console.log('data initialized => ', dataSource.length);
1579
+ });
1580
+ effect(() => {
1581
+ const cols = this.runtimeColumns();
1582
+ this.setFilterPredicate();
1583
+ });
1584
+ effect(() => {
1585
+ const sortState = this.columnsSortState();
1586
+ console.log({ sortState });
1587
+ if (!sortState || !sortState.length) {
1588
+ this.datasource().resetSorting();
1589
+ }
1590
+ else {
1591
+ this.datasource().sortByFields(sortState);
1592
+ }
1593
+ });
1594
+ }
1595
+ initColumnState(columns, stored) {
1596
+ // 1. If user has saved state → use it
1597
+ if (stored && stored.length) {
1598
+ return stored;
1599
+ }
1600
+ // 2. Otherwise derive defaults from columns
1601
+ return columns.map((col, index) => ({
1602
+ id: col.id,
1603
+ visible: col.visible ?? true,
1604
+ // width: col.width,
1605
+ order: index,
1606
+ }));
1607
+ }
1608
+ normalizeColumns(cols) {
1609
+ return cols.map((col, index) => ({
1610
+ ...col,
1611
+ id: col.id || `dm_table_col_${col.field ?? col.type}__${index}`,
1612
+ }));
1613
+ }
1614
+ isSameColumnDefinition(a, b) {
1615
+ return (a.field === b.field &&
1616
+ a.type === b.type &&
1617
+ a.valueGetter === b.valueGetter &&
1618
+ a.valueSetter === b.valueSetter &&
1619
+ a.dateFormat === b.dateFormat &&
1620
+ a.component === b.component);
1621
+ }
1622
+ // private diffColumns(prev: Map<string, DmTableRuntimeColumn<T>>, next: DmTableRuntimeColumn<T>[]) {
1623
+ // const added: DmTableRuntimeColumn<T>[] = [];
1624
+ // const removed: string[] = [];
1625
+ // const changed: DmTableRuntimeColumn<T>[] = [];
1626
+ // const nextMap = new Map(next.map((col) => [col.id, col]));
1627
+ // for (const [id, prevCol] of prev) {
1628
+ // const nextCol = nextMap.get(id);
1629
+ // if (!nextCol) {
1630
+ // removed.push(id);
1631
+ // } else {
1632
+ // if (!this.isSameColumnDefinition(prevCol, nextCol)) {
1633
+ // changed.push(nextCol);
1634
+ // }
1635
+ // }
1636
+ // }
1637
+ // for (const [id, nextCol] of nextMap) {
1638
+ // if (!prev.has(id)) {
1639
+ // added.push(nextCol);
1640
+ // }
1641
+ // }
1642
+ // return { added, removed, changed };
1643
+ // }
1644
+ reconcileColumns(next) {
1645
+ const result = [];
1646
+ for (const col of next) {
1647
+ const prevCol = this.prevColumns.get(col.id);
1648
+ if (prevCol && this.isSameColumnDefinition(prevCol, col)) {
1649
+ result.push(prevCol);
1650
+ }
1651
+ else {
1652
+ result.push(col);
1653
+ }
1654
+ }
1655
+ this.prevColumns = new Map(result.map((c) => [c.id, c]));
1656
+ return result;
1657
+ }
1658
+ setFilterPredicate() {
1659
+ if (this._filterPredicate)
1660
+ return;
1661
+ this.datasource().setFilterPredicate((row, filter) => {
1662
+ const filterLower = filter.toLowerCase();
1663
+ for (const col of this.runtimeColumns()) {
1664
+ const cellValue = this.resolveCellValue(row, col);
1665
+ if (cellValue != null && cellValue.toString().toLowerCase().includes(filterLower)) {
1666
+ return true;
1667
+ }
1668
+ }
1669
+ return false;
1670
+ });
1671
+ }
1672
+ createCellContext = (row, column) => ({
1673
+ $implicit: row,
1674
+ row,
1675
+ column: column,
1676
+ });
1677
+ resetRowCache(row) {
1678
+ this.runtimeColumns().forEach((col) => {
1679
+ col.__cache?.delete(row);
1680
+ });
1681
+ }
1682
+ resolveCellValue(row, column) {
1683
+ if (column.type === '$index') {
1684
+ return null;
1685
+ }
1686
+ if (!shouldCacheColumn(column)) {
1687
+ return row[column.field];
1688
+ }
1689
+ if (!column.__cache) {
1690
+ column.__cache = new WeakMap();
1691
+ }
1692
+ const cached = column.__cache.get(row);
1693
+ if (cached !== undefined) {
1694
+ return cached;
1695
+ }
1696
+ let value;
1697
+ if (column.valueGetter) {
1698
+ value = column.valueGetter(row);
1699
+ }
1700
+ else {
1701
+ if (column.type === 'date') {
1702
+ if (column.dateFormat) {
1703
+ value = DmDateService.getDateString(row[column.field], column.dateFormat);
1704
+ }
1705
+ else {
1706
+ value = DmDateService.getDateString(row[column.field]);
1707
+ }
1708
+ }
1709
+ else {
1710
+ value = row[column.field];
1711
+ }
1712
+ }
1713
+ column.__cache.set(row, value);
1714
+ return value;
1715
+ }
1716
+ applySearchFilter(event) {
1717
+ const input = event.target;
1718
+ const filterValue = input.value.trim().toLowerCase();
1719
+ this.datasource().search(filterValue);
1720
+ }
1721
+ resetSearch() {
1722
+ this.searchTerm.set('');
1723
+ this.datasource().search('');
1724
+ }
1725
+ printTable = () => {
1726
+ const resultData = this.datasource().getResultData();
1727
+ console.log('Print table triggered!!', resultData.length);
1728
+ };
1729
+ onPageSizeChange(event, option) {
1730
+ if (event.isUserInput) {
1731
+ this.datasource().setPageSize(option);
1732
+ }
1733
+ }
1734
+ getFooterTdStyle(column) {
1735
+ const totalCellStyle = this.totalRowStyles().get(column.id) || {};
1736
+ const generalStyle = this.mergedTableStyle().table?.tfoot?.td || DEFAULT_TABLE_STYLE.table?.tfoot?.td || {};
1737
+ return {
1738
+ ...generalStyle,
1739
+ ...totalCellStyle,
1740
+ };
1741
+ }
1742
+ getHeaderThStyle(column) {
1743
+ const headerStyle = typeof column.headerStyle === 'function'
1744
+ ? column.headerStyle(this.datasource())
1745
+ : column.headerStyle || {};
1746
+ const generalStyle = this.mergedTableStyle().table?.thead?.th || DEFAULT_TABLE_STYLE.table?.thead?.th || {};
1747
+ return {
1748
+ ...generalStyle,
1749
+ ...headerStyle,
1750
+ };
1751
+ }
1752
+ getHeaderThContentStyle(column) {
1753
+ const headerContentStyle = typeof column.headerContentStyle === 'function'
1754
+ ? column.headerContentStyle(this.datasource())
1755
+ : column.headerContentStyle || {};
1756
+ return {
1757
+ ...headerContentStyle,
1758
+ };
1759
+ }
1760
+ getBodyTdStyle(i, column, row) {
1761
+ const baseStyle = i % 2 === 0
1762
+ ? this.mergedTableStyle().table?.tbody?.even_row_style?.td ?? {}
1763
+ : this.mergedTableStyle().table?.tbody?.odd_row_style?.td ?? {};
1764
+ const rowHoverStyle = this.hoveredRowIndex() === i
1765
+ ? this.mergedTableStyle().table?.tbody?.hovered_row_style?.tr ?? {}
1766
+ : {};
1767
+ const tdHoverStyle = this.hoveredRowIndex() === i
1768
+ ? this.mergedTableStyle().table?.tbody?.hovered_row_style?.td ?? {}
1769
+ : {};
1770
+ const generalCellStyle = this.mergedTableStyle().table?.tbody?.td ?? {};
1771
+ const columnCellStyle = typeof column.cellStyle === 'function' ? column.cellStyle(row) : column.cellStyle || {};
1772
+ return {
1773
+ ...generalCellStyle,
1774
+ ...baseStyle,
1775
+ ...columnCellStyle,
1776
+ ...rowHoverStyle,
1777
+ ...tdHoverStyle,
1778
+ };
1779
+ }
1780
+ getBodyTdContentStyle(i, column, row) {
1781
+ const columnCellContentStyle = typeof column.cellContentStyle === 'function'
1782
+ ? column.cellContentStyle(row)
1783
+ : column.cellContentStyle || {};
1784
+ return {
1785
+ ...columnCellContentStyle,
1786
+ };
1787
+ }
1788
+ getBodyRowStyle(i, row) {
1789
+ const baseStyle = i % 2 === 0
1790
+ ? this.mergedTableStyle().table?.tbody?.even_row_style?.tr ?? {}
1791
+ : this.mergedTableStyle().table?.tbody?.odd_row_style?.tr ?? {};
1792
+ const hoverStyle = this.hoveredRowIndex() === i
1793
+ ? this.mergedTableStyle().table?.tbody?.hovered_row_style?.tr ?? {}
1794
+ : {};
1795
+ const generalRowStyle = this.mergedTableStyle().table?.tbody?.tr ?? {};
1796
+ const rowStyleFn = this.rowStyleFn();
1797
+ const rowStyleFromFn = rowStyleFn ? rowStyleFn(row) : {};
1798
+ return {
1799
+ ...generalRowStyle,
1800
+ ...baseStyle,
1801
+ ...rowStyleFromFn,
1802
+ ...hoverStyle,
1803
+ };
1804
+ }
1805
+ getInputStyle(column) {
1806
+ const inputStyle = this.mergedTableStyle().table?.tbody?.input || {};
1807
+ const colInputStyle = typeof column.inputStyle === 'function'
1808
+ ? column.inputStyle(null)
1809
+ : column.inputStyle || {};
1810
+ return {
1811
+ ...inputStyle,
1812
+ ...colInputStyle,
1813
+ };
1814
+ }
1815
+ headerClickHandler(column, event) {
1816
+ const onHeaderClick = column.onHeaderClick;
1817
+ if (onHeaderClick && typeof onHeaderClick === 'function') {
1818
+ onHeaderClick(this.datasource(), event);
1819
+ }
1820
+ else {
1821
+ this.columnHeaderSortClickHandler(column, event);
1822
+ }
1823
+ }
1824
+ headerDoubleClickHandler(column, event) {
1825
+ const onHeaderDoubleClick = column.onHeaderDoubleClick;
1826
+ if (onHeaderDoubleClick && typeof onHeaderDoubleClick === 'function') {
1827
+ onHeaderDoubleClick(this.datasource(), event);
1828
+ }
1829
+ }
1830
+ headerContextMenuHandler(column, event) {
1831
+ const headerContextMenu = column.headerContextMenu;
1832
+ if (headerContextMenu && typeof headerContextMenu === 'function') {
1833
+ headerContextMenu(this.datasource(), event);
1834
+ }
1835
+ }
1836
+ headerContentClickHandler(column, event) {
1837
+ const onHeaderContentClick = column.onHeaderContentClick;
1838
+ if (onHeaderContentClick && typeof onHeaderContentClick === 'function') {
1839
+ onHeaderContentClick(this.datasource(), event);
1840
+ }
1841
+ else {
1842
+ if (column.onHeaderClick && typeof column.onHeaderClick === 'function') {
1843
+ return;
1844
+ }
1845
+ this.columnHeaderSortClickHandler(column, event);
1846
+ }
1847
+ }
1848
+ headerContentDoubleClickHandler(column, event) {
1849
+ const onHeaderContentDoubleClick = column.onHeaderContentDoubleClick;
1850
+ if (onHeaderContentDoubleClick && typeof onHeaderContentDoubleClick === 'function') {
1851
+ onHeaderContentDoubleClick(this.datasource(), event);
1852
+ }
1853
+ }
1854
+ headerContentContextMenuHandler(column, event) {
1855
+ const headerContentContextMenu = column.headerContentContextMenu;
1856
+ if (headerContentContextMenu && typeof headerContentContextMenu === 'function') {
1857
+ headerContentContextMenu(this.datasource(), event);
1858
+ }
1859
+ }
1860
+ cellClickHandler(row, column, event) {
1861
+ const onCellClick = column.onCellClick;
1862
+ if (onCellClick && typeof onCellClick === 'function') {
1863
+ onCellClick(row, event);
1864
+ }
1865
+ }
1866
+ cellDoubleClickHandler(row, column, event) {
1867
+ const onCellDoubleClick = column.onCellDoubleClick;
1868
+ if (onCellDoubleClick && typeof onCellDoubleClick === 'function') {
1869
+ onCellDoubleClick(row, event);
1870
+ }
1871
+ }
1872
+ cellContextMenuHandler(row, column, event) {
1873
+ const cellContextMenu = column.cellContextMenu;
1874
+ if (cellContextMenu && typeof cellContextMenu === 'function') {
1875
+ cellContextMenu(row, event);
1876
+ }
1877
+ }
1878
+ cellContentClickHandler(row, column, event) {
1879
+ const onCellContentClick = column.onCellContentClick;
1880
+ if (onCellContentClick && typeof onCellContentClick === 'function') {
1881
+ onCellContentClick(row, event);
1882
+ }
1883
+ }
1884
+ cellContentDoubleClickHandler(row, column, event) {
1885
+ const onCellContentDoubleClick = column.onCellContentDoubleClick;
1886
+ if (onCellContentDoubleClick && typeof onCellContentDoubleClick === 'function') {
1887
+ onCellContentDoubleClick(row, event);
1888
+ }
1889
+ }
1890
+ cellContentContextMenuHandler(row, column, event) {
1891
+ const cellContentContextMenu = column.cellContentContextMenu;
1892
+ if (cellContentContextMenu && typeof cellContentContextMenu === 'function') {
1893
+ cellContentContextMenu(row, event);
1894
+ }
1895
+ }
1896
+ getCloseParentMenusFn = (rootTrigger) => {
1897
+ return () => {
1898
+ rootTrigger.closeMenu();
1899
+ };
1900
+ };
1901
+ onColumnDrop(event) {
1902
+ const visible = [...event.container.data]; // copy!
1903
+ moveItemInArray(visible, event.previousIndex, event.currentIndex);
1904
+ const state = [...(this.columnState() ?? [])];
1905
+ const stateMap = new Map(state.map((s) => [s.id, s]));
1906
+ // Rewrite order based on the NEW visible order
1907
+ visible.forEach((col, index) => {
1908
+ const s = stateMap.get(col.id);
1909
+ if (s) {
1910
+ s.order = index;
1911
+ }
1912
+ });
1913
+ this.columnState.set(state);
1914
+ console.log({ state });
1915
+ }
1916
+ isAllColumnsVisible() {
1917
+ const state = this.columnState();
1918
+ if (!state)
1919
+ return true;
1920
+ return state.every((s) => s.visible !== false);
1921
+ }
1922
+ toggleAllColumnsVisibility(event) {
1923
+ const state = [...(this.columnState() ?? [])];
1924
+ if (!state)
1925
+ return;
1926
+ state.forEach((s) => {
1927
+ s.visible = event.checked;
1928
+ });
1929
+ this.columnState.set(state);
1930
+ console.log({ state });
1931
+ }
1932
+ isColumnVisible(column) {
1933
+ const state = this.columnState();
1934
+ if (!state)
1935
+ return true;
1936
+ const colState = state.find((s) => s.id === column.id);
1937
+ if (!colState)
1938
+ return true;
1939
+ return colState.visible !== false;
1940
+ }
1941
+ toggleColumnVisibility(event, column) {
1942
+ const state = [...(this.columnState() ?? [])];
1943
+ if (!state)
1944
+ return;
1945
+ const colState = state.find((s) => s.id === column.id);
1946
+ if (!colState) {
1947
+ console.log('Column state not found for column:', column);
1948
+ const cols = this.runtimeColumns();
1949
+ this.columnState.set(this.initColumnState(cols, null));
1950
+ return;
1951
+ }
1952
+ colState.visible = event.checked;
1953
+ this.columnState.set(state);
1954
+ }
1955
+ isColumnSorted(column) {
1956
+ const sortState = this.columnsSortState();
1957
+ let matchedIndex = -1;
1958
+ const sort = sortState.find((s, index) => {
1959
+ const match = s.id === column.id;
1960
+ if (match) {
1961
+ matchedIndex = index;
1962
+ }
1963
+ return match;
1964
+ });
1965
+ return sort ? { ...sort, index: matchedIndex } : null;
1966
+ }
1967
+ columnHeaderSortClickHandler(column, event) {
1968
+ if (!column.sortable)
1969
+ return;
1970
+ event.stopPropagation();
1971
+ event.preventDefault();
1972
+ console.log('Column header clicked!! => ', { column });
1973
+ let sortState = [...this.columnsSortState()];
1974
+ const existingSortIndex = sortState.findIndex((s) => s.id === column.id);
1975
+ if (existingSortIndex >= 0) {
1976
+ if (this.shiftKeyPressed()) {
1977
+ if (sortState[existingSortIndex].direction === 'asc') {
1978
+ const newSort = {
1979
+ ...sortState[existingSortIndex],
1980
+ direction: 'desc',
1981
+ };
1982
+ sortState[existingSortIndex] = newSort;
1983
+ }
1984
+ else {
1985
+ const newSort = {
1986
+ ...sortState[existingSortIndex],
1987
+ direction: 'asc',
1988
+ };
1989
+ sortState[existingSortIndex] = newSort;
1990
+ }
1991
+ }
1992
+ else {
1993
+ if (sortState[existingSortIndex].direction === 'asc') {
1994
+ const newSort = {
1995
+ ...sortState[existingSortIndex],
1996
+ direction: 'desc',
1997
+ };
1998
+ sortState[existingSortIndex] = newSort;
1999
+ }
2000
+ else {
2001
+ sortState.splice(existingSortIndex, 1);
2002
+ }
2003
+ }
2004
+ }
2005
+ else {
2006
+ const sort = {
2007
+ id: column.id,
2008
+ field: column.field,
2009
+ direction: 'asc',
2010
+ };
2011
+ if (column.sortFn) {
2012
+ sort.sortFn = column.sortFn;
2013
+ }
2014
+ if (this.shiftKeyPressed()) {
2015
+ sortState.push(sort);
2016
+ }
2017
+ else {
2018
+ sortState = [sort];
2019
+ }
2020
+ }
2021
+ this.columnsSortState.set(sortState);
2022
+ }
2023
+ markRowAsModified(row) {
2024
+ console.log('Mark row as modified triggered!!!!!!!!!!!!!!');
2025
+ const identifierField = this.rowIdentifierField();
2026
+ const rowId = row[identifierField];
2027
+ if (rowId == null || rowId === '' || rowId === undefined)
2028
+ return;
2029
+ this.modifiedRowsIds.update((set) => {
2030
+ const next = new Set(set);
2031
+ next.add(rowId);
2032
+ return next;
2033
+ });
2034
+ }
2035
+ getModifiedRows() {
2036
+ const identifierField = this.rowIdentifierField();
2037
+ const modifiedIds = this.modifiedRowsIds();
2038
+ const allData = this.datasource().getDatasource();
2039
+ console.log({ allData });
2040
+ return allData.filter((row) => {
2041
+ const rowId = row[identifierField];
2042
+ return modifiedIds.has(rowId);
2043
+ });
2044
+ }
2045
+ inputCellSelectOptionChangeHandler(row, column, option, event) {
2046
+ if (!event.isUserInput)
2047
+ return;
2048
+ const valueSetter = column.valueSetter;
2049
+ const validator = column.inputValidator;
2050
+ if (validator && typeof validator === 'function') {
2051
+ const isValid = validator(row, option.value);
2052
+ if (!isValid) {
2053
+ const onFaild = column.onInputValidatorFailed;
2054
+ if (onFaild && typeof onFaild === 'function') {
2055
+ onFaild(row, option.value);
2056
+ }
2057
+ console.warn('Input value is not valid:', option.value);
2058
+ return;
2059
+ }
2060
+ }
2061
+ if (valueSetter && typeof valueSetter === 'function') {
2062
+ valueSetter(row, option.value);
2063
+ }
2064
+ else {
2065
+ row[column.field] = option.value;
2066
+ }
2067
+ this.resetRowCache(row);
2068
+ this.markRowAsModified(row);
2069
+ }
2070
+ inputCellChangeHandler(row, column, event) {
2071
+ const input = event.target;
2072
+ const newValue = input.value;
2073
+ const valueSetter = column.valueSetter;
2074
+ const validator = column.inputValidator;
2075
+ if (validator && typeof validator === 'function') {
2076
+ const isValid = validator(row, newValue);
2077
+ if (!isValid) {
2078
+ const onFaild = column.onInputValidatorFailed;
2079
+ if (onFaild && typeof onFaild === 'function') {
2080
+ onFaild(row, newValue);
2081
+ }
2082
+ console.warn('Input value is not valid:', newValue);
2083
+ input.value = this.resolveCellValue(row, column) ?? '';
2084
+ return;
2085
+ }
2086
+ }
2087
+ if (valueSetter && typeof valueSetter === 'function') {
2088
+ valueSetter(row, newValue);
2089
+ }
2090
+ else {
2091
+ row[column.field] = newValue;
2092
+ }
2093
+ this.resetRowCache(row);
2094
+ this.markRowAsModified(row);
2095
+ }
2096
+ inputCellCheckboxChangeHandler(row, column, event) {
2097
+ const newValue = event.checked;
2098
+ const valueSetter = column.valueSetter;
2099
+ const validator = column.inputValidator;
2100
+ if (validator && typeof validator === 'function') {
2101
+ const isValid = validator(row, newValue);
2102
+ if (!isValid) {
2103
+ const onFaild = column.onInputValidatorFailed;
2104
+ if (onFaild && typeof onFaild === 'function') {
2105
+ onFaild(row, newValue);
2106
+ }
2107
+ event.source.toggle();
2108
+ console.warn('Input value is not valid:', newValue);
2109
+ return;
2110
+ }
2111
+ }
2112
+ if (valueSetter && typeof valueSetter === 'function') {
2113
+ valueSetter(row, newValue);
2114
+ }
2115
+ else {
2116
+ row[column.field] = newValue;
2117
+ }
2118
+ this.resetRowCache(row);
2119
+ this.markRowAsModified(row);
2120
+ }
2121
+ getSlideToggleTooltip(row, column) {
2122
+ const tooltip = column.slideToggleTooltip;
2123
+ if (tooltip && typeof tooltip === 'function') {
2124
+ return tooltip(row);
2125
+ }
2126
+ return tooltip || '';
2127
+ }
2128
+ onSlideToggleChange(row, column, change) {
2129
+ const newValue = change.checked;
2130
+ const valueSetter = column.valueSetter;
2131
+ const validator = column.inputValidator;
2132
+ if (validator && typeof validator === 'function') {
2133
+ const isValid = validator(row, newValue);
2134
+ if (!isValid) {
2135
+ const onFaild = column.onInputValidatorFailed;
2136
+ if (onFaild && typeof onFaild === 'function') {
2137
+ onFaild(row, newValue);
2138
+ }
2139
+ change.source.toggle();
2140
+ console.warn('Input value is not valid:', newValue);
2141
+ return;
2142
+ }
2143
+ }
2144
+ if (valueSetter && typeof valueSetter === 'function') {
2145
+ valueSetter(row, newValue);
2146
+ }
2147
+ else {
2148
+ row[column.field] = newValue;
2149
+ }
2150
+ if (column.onSlideToggleChange && typeof column.onSlideToggleChange === 'function') {
2151
+ column.onSlideToggleChange(row, change);
2152
+ }
2153
+ this.resetRowCache(row);
2154
+ this.markRowAsModified(row);
2155
+ }
2156
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: DmTable, deps: [], target: i0.ɵɵFactoryTarget.Component });
2157
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.3", type: DmTable, isStandalone: true, selector: "dm-table", inputs: { tableId: { classPropertyName: "tableId", publicName: "tableId", isSignal: true, isRequired: false, transformFunction: null }, dataSource: { classPropertyName: "dataSource", publicName: "dataSource", isSignal: true, isRequired: false, transformFunction: null }, columns: { classPropertyName: "columns", publicName: "columns", isSignal: true, isRequired: false, transformFunction: null }, noDataMessage: { classPropertyName: "noDataMessage", publicName: "noDataMessage", isSignal: true, isRequired: false, transformFunction: null }, enableSearch: { classPropertyName: "enableSearch", publicName: "enableSearch", isSignal: true, isRequired: false, transformFunction: null }, searchPlaceholder: { classPropertyName: "searchPlaceholder", publicName: "searchPlaceholder", isSignal: true, isRequired: false, transformFunction: null }, clearSearchTooltip: { classPropertyName: "clearSearchTooltip", publicName: "clearSearchTooltip", isSignal: true, isRequired: false, transformFunction: null }, searchInputAppearance: { classPropertyName: "searchInputAppearance", publicName: "searchInputAppearance", isSignal: true, isRequired: false, transformFunction: null }, filterPredicate: { classPropertyName: "filterPredicate", publicName: "filterPredicate", isSignal: true, isRequired: false, transformFunction: null }, actionButtons: { classPropertyName: "actionButtons", publicName: "actionButtons", isSignal: true, isRequired: false, transformFunction: null }, enablePrint: { classPropertyName: "enablePrint", publicName: "enablePrint", isSignal: true, isRequired: false, transformFunction: null }, printButton: { classPropertyName: "printButton", publicName: "printButton", isSignal: true, isRequired: false, transformFunction: null }, enablePagination: { classPropertyName: "enablePagination", publicName: "enablePagination", isSignal: true, isRequired: false, transformFunction: null }, autoPaginationAboveRowsCount: { classPropertyName: "autoPaginationAboveRowsCount", publicName: "autoPaginationAboveRowsCount", isSignal: true, isRequired: false, transformFunction: null }, paginatorSettings: { classPropertyName: "paginatorSettings", publicName: "paginatorSettings", isSignal: true, isRequired: false, transformFunction: null }, enableLoadingProgressbar: { classPropertyName: "enableLoadingProgressbar", publicName: "enableLoadingProgressbar", isSignal: true, isRequired: false, transformFunction: null }, enableColumnsDragAndDrop: { classPropertyName: "enableColumnsDragAndDrop", publicName: "enableColumnsDragAndDrop", isSignal: true, isRequired: false, transformFunction: null }, enableColumnsDragHandle: { classPropertyName: "enableColumnsDragHandle", publicName: "enableColumnsDragHandle", isSignal: true, isRequired: false, transformFunction: null }, enableTotalRow: { classPropertyName: "enableTotalRow", publicName: "enableTotalRow", isSignal: true, isRequired: false, transformFunction: null }, tableStyle: { classPropertyName: "tableStyle", publicName: "tableStyle", isSignal: true, isRequired: false, transformFunction: null }, tableClasses: { classPropertyName: "tableClasses", publicName: "tableClasses", isSignal: true, isRequired: false, transformFunction: null }, rowStyleFn: { classPropertyName: "rowStyleFn", publicName: "rowStyleFn", isSignal: true, isRequired: false, transformFunction: null }, editColumnsVisibility: { classPropertyName: "editColumnsVisibility", publicName: "editColumnsVisibility", isSignal: true, isRequired: false, transformFunction: null }, editColumnsVisibilityButton: { classPropertyName: "editColumnsVisibilityButton", publicName: "editColumnsVisibilityButton", isSignal: true, isRequired: false, transformFunction: null }, editColumnsVisibilitySelectAllLabel: { classPropertyName: "editColumnsVisibilitySelectAllLabel", publicName: "editColumnsVisibilitySelectAllLabel", isSignal: true, isRequired: false, transformFunction: null }, rowIdentifierField: { classPropertyName: "rowIdentifierField", publicName: "rowIdentifierField", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "window:keydown.shift": "onShiftKeyDown($event)", "window:keyup.shift": "onShiftKeyUp($event)" } }, ngImport: i0, template: "<div id=\"dm-table-component-wrapper\">\n <div class=\"dm-table-top-section\">\n @if (enableSearch()) {\n <mat-form-field [appearance]=\"searchInputAppearance()\" class=\"dm-table-search-form-field\">\n <input\n matInput\n [placeholder]=\"searchPlaceholder()\"\n [(ngModel)]=\"searchTerm\"\n [ngModelOptions]=\"{ standalone: true }\"\n (keyup)=\"datasource().search($event.target.value)\"\n />\n @if (searchTerm()) {\n <button\n matSuffix\n mat-icon-button\n [matTooltip]=\"clearSearchTooltip()\"\n aria-label=\"Clear\"\n (click)=\"resetSearch()\"\n >\n <mat-icon>close</mat-icon>\n </button>\n }\n </mat-form-field>\n } @if (editColumnsVisibility() && editColumnsVisibilityButton()) {\n <ng-container\n *ngTemplateOutlet=\"\n editcolumnVisibilityMenuTrigger;\n context: { $implicit: editColumnsVisibilityButton() }\n \"\n ></ng-container>\n }\n <div class=\"spacer\"></div>\n @if (enablePrint()) {\n <ng-container\n *ngTemplateOutlet=\"\n dmTableActionButton;\n context: { $implicit: printButton(), defaultAction: printTable }\n \"\n ></ng-container>\n } @for (button of actionButtons(); track $index) { @if (!button.showIf ||\n button.showIf(visibleColumns(), datasource())) {\n <ng-container\n *ngTemplateOutlet=\"dmTableActionButton; context: { $implicit: button }\"\n ></ng-container>\n } }\n </div>\n <div\n [ngClass]=\"tableClasses()?.tableWrapper || {}\"\n [dmImportantStyle]=\"mergedTableStyle().tableWrapper || DEFAULT_TABLE_STYLE.tableWrapper || {}\"\n cdkScrollable\n >\n <table\n [ngStyle]=\"\n !tableClasses()?.table?.root\n ? mergedTableStyle().table?.root || DEFAULT_TABLE_STYLE.table?.root || {}\n : {}\n \"\n [ngClass]=\"tableClasses()?.table?.root || {}\"\n >\n <thead\n style=\"\n position: sticky !important;\n top: 0 !important;\n z-index: 10 !important;\n box-shadow: 0px 2px 2px 0px #0000006e;\n \"\n [ngStyle]=\"\n !tableClasses()?.table?.thead?.root\n ? mergedTableStyle().table?.thead?.root || DEFAULT_TABLE_STYLE.table?.thead?.root || {}\n : {}\n \"\n [ngClass]=\"tableClasses()?.table?.thead?.root || {}\"\n >\n @if (enableLoadingProgressbar()) {\n <tr style=\"height: 4px !important; max-height: 4px !important; line-height: 4px !important\">\n <th [attr.colspan]=\"visibleRuntimeColumns().length\" style=\"padding: 0 !important\">\n @if (datasource().isLoading()) {\n <mat-progress-bar mode=\"indeterminate\"></mat-progress-bar>\n }\n </th>\n </tr>\n }\n <tr\n [ngStyle]=\"\n !tableClasses()?.table?.thead?.tr\n ? mergedTableStyle().table?.thead?.tr || DEFAULT_TABLE_STYLE.table?.thead?.tr || {}\n : {}\n \"\n [ngClass]=\"tableClasses()?.table?.thead?.tr || {}\"\n cdkDropList\n [cdkDropListData]=\"visibleRuntimeColumns()\"\n [cdkDropListOrientation]=\"'horizontal'\"\n (cdkDropListDropped)=\"onColumnDrop($event)\"\n [cdkDropListAutoScrollStep]=\"20\"\n >\n @for (column of visibleRuntimeColumns(); let j = $index; track column.id) {\n <th\n cdkDrag\n [cdkDragDisabled]=\"!enableColumnsDragAndDrop()\"\n [ngStyle]=\"getHeaderThStyle(column)\"\n [ngClass]=\"tableClasses()?.table?.thead?.th || {}\"\n (mouseenter)=\"hoveredColumnHeaderIndex.set(j)\"\n (mouseleave)=\"hoveredColumnHeaderIndex.set(null)\"\n (click)=\"headerClickHandler(column, $event)\"\n (dblclick)=\"headerDoubleClickHandler(column, $event)\"\n (contextmenu)=\"headerContextMenuHandler(column, $event)\"\n >\n <div\n class=\"inner-header-cell\"\n [dmImportantStyle]=\"getHeaderThContentStyle(column)\"\n (click)=\"headerContentClickHandler(column, $event)\"\n (dblclick)=\"headerContentDoubleClickHandler(column, $event)\"\n (contextmenu)=\"headerContentContextMenuHandler(column, $event)\"\n >\n <span>\n {{ column.header }}\n </span>\n @if (column.sortable) {\n <span\n (click)=\"columnHeaderSortClickHandler(column, $event)\"\n style=\"display: flex; align-items: center\"\n >\n @if (isColumnSorted(column); as sort) {\n <mat-icon style=\"width: 20px; height: 20px; font-size: 20px\">{{\n sort.direction === 'asc' ? 'arrow_upward' : 'arrow_downward'\n }}</mat-icon>\n @if(columnsSortState().length > 1) { [{{ sort.index + 1 }}] } } @else if\n (hoveredColumnHeaderIndex() == j){\n <mat-icon style=\"opacity: 0.3; width: 20px; height: 20px; font-size: 20px\"\n >arrow_upward</mat-icon\n >\n }\n </span>\n } @if (enableColumnsDragHandle()) {\n\n <div class=\"spacer\"></div>\n <span>\n <ng-container\n *ngTemplateOutlet=\"dmTableHeaderMenuTrigger; context: { $implicit: column }\"\n />\n </span>\n <mat-icon style=\"cursor: move; font-size: 20px\" cdkDragHandle\n >drag_indicator</mat-icon\n >\n }\n </div>\n </th>\n }\n </tr>\n </thead>\n <tbody\n [dmImportantStyle]=\"\n !tableClasses()?.table?.tbody?.root\n ? mergedTableStyle().table?.tbody?.root || DEFAULT_TABLE_STYLE.table?.tbody?.root || {}\n : {}\n \"\n [ngClass]=\"tableClasses()?.table?.tbody?.root || {}\"\n >\n @for (row of datasource().result(); let i = $index; track row[rowIdentifierField()]) {\n <tr\n [dmImportantStyle]=\"getBodyRowStyle(i, row)\"\n (mouseenter)=\"hoveredRowIndex.set(i)\"\n (mouseleave)=\"hoveredRowIndex.set(null)\"\n >\n @for (column of visibleRuntimeColumns(); let j = $index; track j) {\n <td\n [dmImportantStyle]=\"getBodyTdStyle(i, column, row)\"\n (click)=\"cellClickHandler(row, column, $event)\"\n (contextmenu)=\"cellContextMenuHandler(row, column, $event)\"\n (dblclick)=\"cellDoubleClickHandler(row, column, $event)\"\n >\n <span\n [dmImportantStyle]=\"getBodyTdContentStyle(i, column, row)\"\n (click)=\"cellContentClickHandler(row, column, $event)\"\n (contextmenu)=\"cellContentContextMenuHandler(row, column, $event)\"\n (dblclick)=\"cellContentDoubleClickHandler(row, column, $event)\"\n >\n @switch (column.type) { @case ('$index') {\n {{ datasource().getFirstItemIndexInPage() + i + 1 }}\n } @case ('component') { @if (column.component) {\n <dm-table-cell-host\n [component]=\"column.component\"\n [context]=\"createCellContext(row, column)\"\n ></dm-table-cell-host>\n } } @case ('tel') {\n <a [href]=\"'tel:' + (column.field ? $any(row)[column.field] : '')\">{{\n resolveCellValue(row, column)\n }}</a>\n } @case ('mail') {\n <a [href]=\"'mailto:' + (column.field ? $any(row)[column.field] : '')\">{{\n resolveCellValue(row, column)\n }}</a>\n } @case ('link') {\n <a\n [href]=\"column.field ? $any(row)[column.field] : ''\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >{{ resolveCellValue(row, column) }}</a\n >\n } @case ('whatsapp') {\n <a\n [href]=\"'https://wa.me/' + (column.field ? $any(row)[column.field] : '')\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >{{ resolveCellValue(row, column) }}</a\n >\n } @case ('customHtml') { @if (column.customHtml) {\n <span [innerHTML]=\"column.customHtml\"></span>\n } @else if (column.customCellTemplate) {\n <ng-container\n *ngTemplateOutlet=\"\n column.customCellTemplate;\n context: createCellContext(row, column)\n \"\n >\n </ng-container>\n } } @case ('actions') {\n <span style=\"display: flex; align-items: center\">\n @for (button of column.actionsButtons || []; track $index) {\n <ng-container\n *ngTemplateOutlet=\"\n dmTableRowActionButton;\n context: {\n $implicit: button,\n row\n }\n \"\n ></ng-container>\n }\n </span>\n } @case('slideToggle') {\n <mat-slide-toggle\n [id]=\"'slideToggle_' + i + '_' + column.id\"\n [checked]=\"$any(row)[column.field!]\"\n [matTooltip]=\"getSlideToggleTooltip(row, column)\"\n (change)=\"onSlideToggleChange(row, column, $event)\"\n >\n <!-- {{ row[column.field!] }} -->\n {{ resolveCellValue(row, column) }}\n </mat-slide-toggle>\n } @case ('input') {\n <ng-container\n *ngTemplateOutlet=\"\n dmTableInputCell;\n context: {\n $implicit: row,\n column: column\n }\n \"\n />\n } @default {\n {{ resolveCellValue(row, column) }}\n } }\n </span>\n </td>\n }\n </tr>\n }\n </tbody>\n @if (enableTotalRow()) {\n <tfoot\n style=\"\n position: sticky !important;\n bottom: 0 !important;\n z-index: 10 !important;\n box-shadow: 0px -2px 2px 0px #0000006e;\n \"\n [ngStyle]=\"\n !tableClasses()?.table?.tfoot?.root\n ? mergedTableStyle().table?.tfoot?.root || DEFAULT_TABLE_STYLE.table?.tfoot?.root || {}\n : {}\n \"\n [ngClass]=\"tableClasses()?.table?.tfoot?.root || {}\"\n >\n <tr>\n @for (column of visibleRuntimeColumns(); let j = $index; track column.id) {\n <td\n [ngStyle]=\"getFooterTdStyle(column)\"\n [ngClass]=\"tableClasses()?.table?.tfoot?.td || {}\"\n >\n @if (column.totalRowValueType == 'html') {\n <span [innerHTML]=\"totalRowValues().get(column.id) || ''\"></span>\n } @else {\n {{ totalRowValues().get(column.id) || '' }}\n }\n </td>\n }\n </tr>\n </tfoot>\n }\n </table>\n </div>\n @if (datasource().result().length === 0) {\n <div class=\"dm-table-no-data\">\n <span>{{ noDataMessage() }}</span>\n </div>\n } @else { @if (datasource().isPaginationEnabled()) {\n <ng-container [ngTemplateOutlet]=\"paginator\" />\n } }\n</div>\n\n<!-- MARK: Action Button template -->\n<ng-template #dmTableActionButton let-button let-defaultAction=\"defaultAction\">\n @if (button.buttonType === 'icon') {\n <button\n #rootTrigger=\"matMenuTrigger\"\n mat-icon-button\n [matTooltip]=\"button.tooltip || ''\"\n aria-label=\"{{ button.tooltip }}\"\n [matMenuTriggerFor]=\"button.children && button.children.length > 0 ? tableButtonRootMenu : null\"\n [matMenuTriggerData]=\"{\n buttons: button.children,\n rootTrigger: rootTrigger\n }\"\n (click)=\"\n button.children && button.children.length > 0\n ? null\n : button.onClick\n ? button.onClick(visibleColumns(), datasource())\n : defaultAction\n ? defaultAction($event)\n : null\n \"\n [ngStyle]=\"{ 'background-color': button.backgroundColor ? button.backgroundColor : undefined }\"\n >\n <mat-icon [style.color]=\"button.color ? button.color : undefined\">{{ button.icon }}</mat-icon>\n </button>\n } @else {\n <button\n #rootTrigger=\"matMenuTrigger\"\n [matButton]=\"button.buttonType || 'filled'\"\n [ngStyle]=\"{ 'background-color': button.backgroundColor ? button.backgroundColor : undefined }\"\n aria-label=\"{{ button.label }}\"\n [matTooltip]=\"button.tooltip || ''\"\n [matMenuTriggerFor]=\"button.children && button.children.length > 0 ? tableButtonRootMenu : null\"\n [matMenuTriggerData]=\"{\n buttons: button.children,\n rootTrigger: rootTrigger\n }\"\n (click)=\"\n button.children && button.children.length > 0\n ? null\n : button.onClick\n ? button.onClick(visibleColumns(), datasource())\n : defaultAction\n ? defaultAction($event)\n : null\n \"\n >\n @if (button.icon) {\n <mat-icon class=\"button-icon\" [ngStyle]=\"{ color: button.color ? button.color : undefined }\">{{\n button.icon\n }}</mat-icon>\n }\n <span [ngStyle]=\"{ color: button.color ? button.color : undefined }\">\n {{ button.label }}\n </span>\n </button>\n }\n <!-- @if (button.buttonType === 'icon') {\n <button\n mat-icon-button\n [color]=\"button.color\"\n [matTooltip]=\"button.tooltip || ''\"\n aria-label=\"{{ button.tooltip }}\"\n (click)=\"\n button.children && button.children.length > 0\n ? null\n : button.onClick\n ? button.onClick(datasource())\n : defaultAction\n ? defaultAction()\n : null\n \"\n >\n <mat-icon>{{ button.icon }}</mat-icon>\n </button>\n } @else {\n <button\n [matButton]=\"button.buttonType || 'filled'\"\n [ngStyle]=\"{ 'background-color': button.color ? button.color : undefined }\"\n aria-label=\"{{ button.label }}\"\n [matTooltip]=\"button.tooltip || ''\"\n (click)=\"\n button.children && button.children.length > 0\n ? null\n : button.onClick\n ? button.onClick(datasource())\n : defaultAction\n ? defaultAction()\n : null\n \"\n >\n @if (button.icon) {\n <mat-icon\n class=\"button-icon\"\n [ngStyle]=\"{ color: button.textColor ? button.textColor : undefined }\"\n >{{ button.icon }}</mat-icon\n >\n }\n <span [ngStyle]=\"{ color: button.textColor ? button.textColor : undefined }\">\n {{ button.label }}\n </span>\n </button>\n } -->\n</ng-template>\n\n<!-- MARK: Action Button root menu -->\n<mat-menu #tableButtonRootMenu=\"matMenu\">\n <ng-template matMenuContent let-buttons=\"buttons\" let-rootTrigger=\"rootTrigger\">\n <ng-container\n *ngTemplateOutlet=\"\n tableButtonRecursiveMenu;\n context: { buttons: buttons, rootTrigger: rootTrigger }\n \"\n ></ng-container>\n </ng-template>\n</mat-menu>\n\n<!-- MARK: Action Button recursive menu -->\n<ng-template #tableButtonRecursiveMenu let-buttons=\"buttons\" let-rootTrigger=\"rootTrigger\">\n @for (button of buttons; track $index) { @if (!button.showIf || button.showIf(visibleColumns(),\n datasource())) { @if (button.children?.length) {\n <button\n mat-menu-item\n [matMenuTriggerFor]=\"subMenu\"\n [matMenuTriggerData]=\"{\n buttons: button.children,\n rootTrigger\n }\"\n (click)=\"$event.stopPropagation()\"\n [ngStyle]=\"{ 'background-color': button.backgroundColor ? button.backgroundColor : undefined }\"\n >\n <span style=\"display: flex; align-items: center; width: 100%\">\n @if (button.icon) {\n <mat-icon [style.color]=\"button.color ? button.color : undefined\">{{ button.icon }}</mat-icon>\n }\n <span [style.color]=\"button.color ? button.color : undefined\">{{ button.label }}</span>\n <span class=\"spacer\"></span>\n <mat-icon [style.color]=\"button.color ? button.color : undefined\" class=\"submenu-arrow\"\n >chevron_left</mat-icon\n >\n </span>\n </button>\n\n <mat-menu #subMenu=\"matMenu\">\n <ng-container\n *ngTemplateOutlet=\"\n tableButtonRecursiveMenu;\n context: { buttons: button.children, rootTrigger: rootTrigger }\n \"\n ></ng-container>\n </mat-menu>\n } @else {\n <button\n mat-menu-item\n [matTooltip]=\"button.tooltip || ''\"\n (click)=\"button.onClick?.(visibleColumns(), datasource(), $event, getCloseParentMenusFn(rootTrigger))\"\n [ngStyle]=\"{ 'background-color': button.backgroundColor ? button.backgroundColor : undefined }\"\n >\n @if (button.icon) {\n <mat-icon [style.color]=\"button.color ? button.color : undefined\">{{ button.icon }}</mat-icon>\n }\n <span [style.color]=\"button.color ? button.color : undefined\">{{ button.label }}</span>\n </button>\n }} }\n</ng-template>\n\n<!-- MARK: Row button root menu -->\n<mat-menu #rowButtonRootMenu=\"matMenu\">\n <ng-template matMenuContent let-buttons=\"buttons\" let-row=\"row\" let-rootTrigger=\"rootTrigger\">\n <ng-container\n *ngTemplateOutlet=\"\n rowButtonRecursiveMenu;\n context: { buttons: buttons, row: row, rootTrigger: rootTrigger }\n \"\n ></ng-container>\n </ng-template>\n</mat-menu>\n\n<!-- MARK: Row button recursive menu -->\n<ng-template\n #rowButtonRecursiveMenu\n let-buttons=\"buttons\"\n let-row=\"row\"\n let-rootTrigger=\"rootTrigger\"\n>\n @for (button of buttons; track $index) { @if (button.children?.length) {\n <button\n mat-menu-item\n [matMenuTriggerFor]=\"subMenu\"\n [matMenuTriggerData]=\"{\n buttons: button.children,\n row,\n rootTrigger\n }\"\n (click)=\"$event.stopPropagation()\"\n [ngStyle]=\"{ 'background-color': button.backgroundColor ? button.backgroundColor : undefined }\"\n >\n <span style=\"display: flex; align-items: center; width: 100%\">\n @if (button.icon) {\n <mat-icon [style.color]=\"button.color ? button.color : undefined\">{{ button.icon }}</mat-icon>\n }\n <span [style.color]=\"button.color ? button.color : undefined\">{{ button.label }}</span>\n <span class=\"spacer\"></span>\n <mat-icon [style.color]=\"button.color ? button.color : undefined\" class=\"submenu-arrow\"\n >chevron_left</mat-icon\n >\n </span>\n </button>\n\n <mat-menu #subMenu=\"matMenu\">\n <ng-container\n *ngTemplateOutlet=\"\n rowButtonRecursiveMenu;\n context: { buttons: button.children, row: row, rootTrigger: rootTrigger }\n \"\n ></ng-container>\n </mat-menu>\n\n } @else {\n <button\n mat-menu-item\n [matTooltip]=\"button.tooltip || ''\"\n (click)=\"button.onClick?.(row, $event, getCloseParentMenusFn(rootTrigger))\"\n [ngStyle]=\"{ 'background-color': button.backgroundColor ? button.backgroundColor : undefined }\"\n >\n @if (button.icon) {\n <mat-icon [style.color]=\"button.color ? button.color : undefined\">{{ button.icon }}</mat-icon>\n }\n <span [style.color]=\"button.color ? button.color : undefined\">{{ button.label }}</span>\n </button>\n } }\n</ng-template>\n\n<!-- MARK: Row Action Button template -->\n<ng-template #dmTableRowActionButton let-button let-row=\"row\" let-defaultAction=\"defaultAction\">\n @if (button.buttonType === 'icon') {\n <button\n #rootTrigger=\"matMenuTrigger\"\n mat-icon-button\n [matTooltip]=\"button.tooltip || ''\"\n aria-label=\"{{ button.tooltip }}\"\n [matMenuTriggerFor]=\"button.children && button.children.length > 0 ? rowButtonRootMenu : null\"\n [matMenuTriggerData]=\"{\n buttons: button.children,\n row,\n rootTrigger: rootTrigger\n }\"\n (click)=\"\n button.children && button.children.length > 0\n ? null\n : button.onClick\n ? button.onClick(row)\n : defaultAction\n ? defaultAction($event)\n : null\n \"\n >\n <mat-icon [style.color]=\"button.color ? button.color : undefined\">{{ button.icon }}</mat-icon>\n </button>\n } @else {\n <button\n [matButton]=\"button.buttonType || 'filled'\"\n [ngStyle]=\"{ 'background-color': button.backgroundColor ? button.backgroundColor : undefined }\"\n aria-label=\"{{ button.label }}\"\n [matTooltip]=\"button.tooltip || ''\"\n [matMenuTriggerFor]=\"button.children && button.children.length > 0 ? rowButtonRootMenu : null\"\n #rootTrigger=\"matMenuTrigger\"\n [matMenuTriggerData]=\"{\n buttons: button.children,\n row,\n rootTrigger: rootTrigger\n }\"\n (click)=\"\n button.children && button.children.length > 0\n ? null\n : button.onClick\n ? button.onClick(row)\n : defaultAction\n ? defaultAction($event)\n : null\n \"\n >\n @if (button.icon) {\n <mat-icon class=\"button-icon\" [ngStyle]=\"{ color: button.color ? button.color : undefined }\">{{\n button.icon\n }}</mat-icon>\n }\n <span [ngStyle]=\"{ color: button.color ? button.color : undefined }\">\n {{ button.label }}\n </span>\n </button>\n }\n</ng-template>\n\n<!-- <mat-menu #buttonChildren=\"matMenu\">\n <ng-template matMenuContent let-buttons=\"buttons\" let-row=\"row\">\n @for (button of buttons || []; track $index) { @if (button.children && button.children.length >\n 0) {\n <ng-container *ngTemplateOutlet=\"subMenuTrigger; context: { button, row }\"></ng-container>\n } @else {\n <button\n mat-menu-item\n [matTooltip]=\"button.tooltip || ''\"\n aria-label=\"{{ button.tooltip }}\"\n (click)=\"\n button.children && button.children.length > 0\n ? null\n : button.onClick\n ? button.onClick(row, $event)\n : null\n \"\n >\n @if (button.icon) {\n <mat-icon>{{ button.icon }}</mat-icon>\n }\n <span>{{ button.label }}</span>\n </button>\n } }\n </ng-template>\n</mat-menu>\n\n<ng-template #subMenuTrigger let-button=\"button\" let-row=\"row\">\n <button\n mat-menu-item\n [matMenuTriggerFor]=\"buttonChildren\"\n [matMenuTriggerData]=\"{\n buttons: button.children,\n row\n }\"\n [matTooltip]=\"button.tooltip || ''\"\n aria-label=\"{{ button.tooltip }}\"\n >\n @if (button.icon) {\n <mat-icon>{{ button.icon }}</mat-icon>\n }\n <span>{{ button.label }}</span>\n </button>\n</ng-template> -->\n\n<!-- MARK: Paginator template -->\n<ng-template #paginator>\n <div\n class=\"dm-table-paginator-row\"\n [ngStyle]=\"mergedTableStyle().paginator?.root || {}\"\n [ngClass]=\"tableClasses()?.paginator?.root || {}\"\n >\n <p\n class=\"mb-0\"\n [ngStyle]=\"mergedTableStyle().paginator?.p || {}\"\n [ngClass]=\"tableClasses()?.paginator?.p || {}\"\n >\n {{\n paginatorSettings()?.numberOfItemsPerPageLabel ||\n DEFAULT_PAGINATOR_SETTINGS.numberOfItemsPerPageLabel\n }}\n </p>\n\n <div>\n <mat-form-field\n style=\"width: 100px\"\n class=\"dm-paginator-form-field ms-2 me-2\"\n [appearance]=\"'fill'\"\n [ngStyle]=\"mergedTableStyle().paginator?.mat_form_field || {}\"\n [ngClass]=\"tableClasses()?.paginator?.mat_form_field || {}\"\n >\n <mat-select\n [value]=\"datasource().getPageSize()\"\n [ngStyle]=\"mergedTableStyle().paginator?.mat_select || {}\"\n [ngClass]=\"tableClasses()?.paginator?.mat_select || {}\"\n >\n @for (option of (paginatorSettings()?.pageSizeOptions ||\n DEFAULT_PAGINATOR_SETTINGS.pageSizeOptions); track option) {\n <mat-option\n [value]=\"option\"\n (onSelectionChange)=\"onPageSizeChange($event, option)\"\n [ngStyle]=\"mergedTableStyle().paginator?.mat_option || {}\"\n [ngClass]=\"tableClasses()?.paginator?.mat_option || {}\"\n >{{ option }}</mat-option\n >\n }\n </mat-select>\n </mat-form-field>\n </div>\n\n @if (datasource().getPageSize() > 0) {\n <div class=\"dm-table-paginator-page-info\">\n <p\n [ngClass]=\"tableClasses()?.paginator?.p || {}\"\n [ngStyle]=\"mergedTableStyle().paginator?.p || {}\"\n >\n {{ datasource().getFirstItemIndexInPage() + 1 }}\n </p>\n\n <p\n [ngClass]=\"tableClasses()?.paginator?.p || {}\"\n [ngStyle]=\"mergedTableStyle().paginator?.p || {}\"\n >\n -\n </p>\n\n <p\n [ngClass]=\"tableClasses()?.paginator?.p || {}\"\n [ngStyle]=\"mergedTableStyle().paginator?.p || {}\"\n >\n {{ datasource().getLastItemIndexInPage() + 1 }}\n </p>\n\n <p\n [ngClass]=\"tableClasses()?.paginator?.p || {}\"\n [ngStyle]=\"mergedTableStyle().paginator?.p || {}\"\n >\n \u05DE\u05EA\u05D5\u05DA\n </p>\n\n <p\n [ngClass]=\"tableClasses()?.paginator?.p || {}\"\n [ngStyle]=\"mergedTableStyle().paginator?.p || {}\"\n >\n {{ datasource().getTotalResultElementsCount() }}\n </p>\n </div>\n }\n\n <div>\n @if (paginatorSettings()?.showFirstAndLastPagesButtons ||\n DEFAULT_PAGINATOR_SETTINGS.showFirstAndLastPagesButtons) {\n <button\n [ngStyle]=\"mergedTableStyle().paginator?.button || {}\"\n [ngClass]=\"tableClasses()?.paginator?.button || {}\"\n mat-icon-button\n (click)=\"datasource().firstPage()\"\n [matTooltip]=\"\n paginatorSettings()?.firstPageButtonLabel ||\n DEFAULT_PAGINATOR_SETTINGS.firstPageButtonLabel\n \"\n [matTooltipPosition]=\"'above'\"\n >\n <mat-icon>keyboard_double_arrow_right</mat-icon>\n </button>\n }\n <button\n [ngStyle]=\"mergedTableStyle().paginator?.button || {}\"\n [ngClass]=\"tableClasses()?.paginator?.button || {}\"\n mat-icon-button\n (click)=\"datasource().firstPage()\"\n [matTooltip]=\"\n paginatorSettings()?.previousPageButtonLabel ||\n DEFAULT_PAGINATOR_SETTINGS.previousPageButtonLabel\n \"\n [matTooltipPosition]=\"'above'\"\n >\n <mat-icon>chevron_right</mat-icon>\n </button>\n <button\n [ngStyle]=\"mergedTableStyle().paginator?.button || {}\"\n [ngClass]=\"tableClasses()?.paginator?.button || {}\"\n mat-icon-button\n (click)=\"datasource().nextPage()\"\n [matTooltip]=\"\n paginatorSettings()?.nextPageButtonLabel || DEFAULT_PAGINATOR_SETTINGS.nextPageButtonLabel\n \"\n [matTooltipPosition]=\"'above'\"\n >\n <mat-icon>chevron_left</mat-icon>\n </button>\n @if (paginatorSettings()?.showFirstAndLastPagesButtons ||\n DEFAULT_PAGINATOR_SETTINGS.showFirstAndLastPagesButtons) {\n <button\n [ngStyle]=\"mergedTableStyle().paginator?.button || {}\"\n [ngClass]=\"tableClasses()?.paginator?.button || {}\"\n mat-icon-button\n (click)=\"datasource().lastPage()\"\n [matTooltip]=\"\n paginatorSettings()?.lastPageButtonLabel || DEFAULT_PAGINATOR_SETTINGS.lastPageButtonLabel\n \"\n [matTooltipPosition]=\"'above'\"\n >\n <mat-icon>keyboard_double_arrow_left</mat-icon>\n </button>\n }\n </div>\n </div>\n</ng-template>\n\n<!-- MARK: Edit Columns Visibility Menu Trigger -->\n<ng-template #editcolumnVisibilityMenuTrigger let-button>\n @if (button.buttonType == 'icon') {\n <button\n mat-icon-button\n [matTooltip]=\"button.tooltip || ''\"\n aria-label=\"{{ button.tooltip }}\"\n [matMenuTriggerFor]=\"columnVisibilityMenu\"\n #rootTrigger=\"matMenuTrigger\"\n >\n <mat-icon [style.color]=\"button.textColor ? button.textColor : undefined\">{{\n button.icon\n }}</mat-icon>\n </button>\n } @else {\n <button\n [matButton]=\"button.buttonType || 'filled'\"\n [ngStyle]=\"{ 'background-color': button.color ? button.color : undefined }\"\n aria-label=\"{{ button.label }}\"\n [matTooltip]=\"button.tooltip || ''\"\n [matMenuTriggerFor]=\"columnVisibilityMenu\"\n #rootTrigger=\"matMenuTrigger\"\n >\n @if (button.icon) {\n <mat-icon\n class=\"button-icon\"\n [ngStyle]=\"{ color: button.textColor ? button.textColor : undefined }\"\n >{{ button.icon }}</mat-icon\n >\n }\n <span [style.color]=\"button.textColor ? button.textColor : undefined\">\n {{ button.label }}\n </span>\n </button>\n }\n</ng-template>\n\n<!-- MARK: Edit Columns Visibility Menu -->\n<mat-menu #columnVisibilityMenu=\"matMenu\">\n <div mat-menu-item disableRipple (click)=\"$event.stopPropagation()\">\n <mat-checkbox\n [checked]=\"isAllColumnsVisible()\"\n (change)=\"toggleAllColumnsVisibility($event)\"\n (click)=\"$event.stopPropagation()\"\n >{{ editColumnsVisibilitySelectAllLabel() }}</mat-checkbox\n >\n </div>\n @for (column of runtimeColumns(); track column.id) {\n <div mat-menu-item disableRipple (click)=\"$event.stopPropagation()\">\n <mat-checkbox\n [checked]=\"isColumnVisible(column)\"\n (change)=\"toggleColumnVisibility($event, column)\"\n (click)=\"$event.stopPropagation()\"\n >{{ column.header }}</mat-checkbox\n >\n </div>\n }\n</mat-menu>\n\n<!-- MARK: Input Cell Template -->\n<ng-template #dmTableInputCell let-row let-column=\"column\">\n @switch (column.inputType) { @case ('select') {\n <mat-select\n [dmImportantStyle]=\"getInputStyle(column)\"\n panelWidth=\"null\"\n [value]=\"resolveCellValue(row, column)\"\n >\n @for (option of column.selectOptions || []; track option.value) {\n <mat-option\n [value]=\"option.value\"\n (onSelectionChange)=\"inputCellSelectOptionChangeHandler(row, column, option, $event)\"\n >{{ option.label }}</mat-option\n >\n }\n </mat-select>\n } @case ('checkbox') {\n <mat-checkbox\n [checked]=\"resolveCellValue(row, column)\"\n (change)=\"inputCellCheckboxChangeHandler(row, column, $event)\"\n ></mat-checkbox>\n } @default {\n <input\n [type]=\"column.inputType || 'text'\"\n [value]=\"resolveCellValue(row, column)\"\n (change)=\"inputCellChangeHandler(row, column, $event)\"\n [dmImportantStyle]=\"getInputStyle(column)\"\n />\n } }\n</ng-template>\n\n<!-- MARK: Header Menu Trigger Template -->\n<ng-template #dmTableHeaderMenuTrigger let-column>\n @if (column?.headerMenuItems?.length) {\n <!-- <button\n mat-icon-button\n (click)=\"$event.stopPropagation()\"\n aria-label=\"Column Menu\"\n >\n </button> -->\n <mat-icon\n #rootTrigger=\"matMenuTrigger\"\n [matMenuTriggerFor]=\"dmTableHeaderRootMenu\"\n [matMenuTriggerData]=\"{\n menuItems: column.headerMenuItems,\n rootTrigger: rootTrigger\n }\"\n [matTooltip]=\"column.headerMenuTooltip || ''\"\n style=\"font-size: 20px; cursor: pointer; margin-left: 4px; height: 20px\"\n [ngStyle]=\"{\n color: getHeaderThContentStyle(column)?.color || getHeaderThStyle(column)?.color || ''\n }\"\n >menu</mat-icon\n >\n }\n</ng-template>\n\n<!-- MARK: Header Root Menu -->\n<mat-menu #dmTableHeaderRootMenu=\"matMenu\">\n <ng-template matMenuContent let-menuItems=\"menuItems\" let-rootTrigger=\"rootTrigger\">\n <ng-container\n *ngTemplateOutlet=\"\n dmTableHeaderRecursiveMenu;\n context: { menuItems: menuItems, rootTrigger: rootTrigger }\n \"\n ></ng-container>\n </ng-template>\n</mat-menu>\n\n<!-- MARK: Header Recursive Menu -->\n<ng-template #dmTableHeaderRecursiveMenu let-menuItems=\"menuItems\" let-rootTrigger=\"rootTrigger\">\n @for (menuItem of menuItems; track $index) { @if (!menuItem.showIf || (menuItem.showIf &&\n menuItem.showIf(datasource()))) {@if (menuItem.children?.length) {\n <button\n mat-menu-item\n [matMenuTriggerFor]=\"dmTableHeaderSubMenu\"\n [matMenuTriggerData]=\"{\n menuItems: menuItem.children,\n rootTrigger\n }\"\n (click)=\"$event.stopPropagation()\"\n [ngStyle]=\"{\n 'background-color': menuItem.backgroundColor ? menuItem.backgroundColor : undefined\n }\"\n >\n <span style=\"display: flex; align-items: center; width: 100%\">\n @if (menuItem.icon) {\n <mat-icon [style.color]=\"menuItem.color ? menuItem.color : undefined\">{{\n menuItem.icon\n }}</mat-icon>\n }\n <span [style.color]=\"menuItem.color ? menuItem.color : undefined\">{{ menuItem.label }}</span>\n <span class=\"spacer\"></span>\n <mat-icon [style.color]=\"menuItem.color ? menuItem.color : undefined\" class=\"submenu-arrow\"\n >chevron_left</mat-icon\n >\n </span>\n </button>\n\n <mat-menu #dmTableHeaderSubMenu=\"matMenu\">\n <ng-container\n *ngTemplateOutlet=\"\n dmTableHeaderRecursiveMenu;\n context: { menuItems: menuItem.children, rootTrigger: rootTrigger }\n \"\n />\n </mat-menu>\n } @else {\n <button\n mat-menu-item\n [matTooltip]=\"menuItem.tooltip || ''\"\n (click)=\"menuItem.onClick?.(datasource(), $event, getCloseParentMenusFn(rootTrigger))\"\n [ngStyle]=\"{\n 'background-color': menuItem.backgroundColor ? menuItem.backgroundColor : undefined\n }\"\n >\n @if (menuItem.icon) {\n <mat-icon [style.color]=\"menuItem.color ? menuItem.color : undefined\">{{\n menuItem.icon\n }}</mat-icon>\n }\n <span [style.color]=\"menuItem.color ? menuItem.color : undefined\">{{ menuItem.label }}</span>\n </button>\n } }}\n</ng-template>\n", styles: ["#dm-table-component-wrapper{width:100%}#dm-table-component-wrapper ::-webkit-scrollbar{width:var(--dm-table-scrollbar-width, 7px);height:var(--dm-table-scrollbar-width, 7px)}#dm-table-component-wrapper ::-webkit-scrollbar-track{background:var(--dm-table-scrollbar-background-color, #e0e0e0)}#dm-table-component-wrapper ::-webkit-scrollbar-thumb{background:var(--dm-table-scrollbar-color, #949496);border-radius:var(--dm-table-scrollbar-border-radius, 4px)}#dm-table-component-wrapper ::-webkit-scrollbar-thumb:hover{background:var(--dm-table-scrollbar-hover-color, #5f5f5f)}#dm-table-component-wrapper .dm-table-top-section{width:calc(100% - 10px);display:flex;align-items:center;padding:0 5px;gap:5px;flex-wrap:wrap}#dm-table-component-wrapper .dm-table-table-wrapper .dm-table-classic{width:100%;border-collapse:collapse;border-spacing:0;box-shadow:0 5px 5px -3px #003,0 8px 10px 1px #00000024,0 3px 14px 2px #0000001f;padding:0;font-size:1rem;border-radius:8px;page-break-inside:auto}#dm-table-component-wrapper .dm-table-table-wrapper .dm-table-classic tr{page-break-inside:avoid}#dm-table-component-wrapper .dm-table-table-wrapper .dm-table-classic th,#dm-table-component-wrapper .dm-table-table-wrapper .dm-table-classic td{text-align:start;max-width:none}#dm-table-component-wrapper .inner-header-cell{display:flex;align-items:center;gap:5px}#dm-table-component-wrapper .dm-table-no-data{width:98%;margin:10px auto 0;line-height:60px;display:flex;justify-content:center;align-items:center;padding:10px;font-size:1.5rem;font-weight:700;color:#dd2f2f;box-shadow:0 4px 6px #000000d7}#dm-table-component-wrapper .dm-table-paginator-row{display:flex;flex-wrap:wrap;justify-content:center;align-items:center;gap:5px}#dm-table-component-wrapper .dm-table-paginator-row .dm-table-paginator-page-info{display:flex;align-items:center;gap:5px}:host ::ng-deep .dm-paginator-form-field>.mat-mdc-form-field-bottom-align:before{content:\"\";display:none;height:0px}:host ::ng-deep .dm-table-search-form-field>.mat-mdc-form-field-bottom-align:before{content:\"\";display:none;height:0px}.cdk-drag-preview{border:none;box-sizing:border-box;background-color:var(--dm-table-header-background-color, #f5f5f5);color:var(--dm-table-header-color, #000000);border-radius:4px;box-shadow:0 5px 5px -3px #0003,0 8px 10px 1px #00000024,0 3px 14px 2px #0000001f}.cdk-drag-preview .inner-header-cell{display:flex;align-items:center}.spacer{flex-grow:1}\n"], dependencies: [{ kind: "directive", type: DmImportantStyleDirective, selector: "[dmImportantStyle]", inputs: ["dmImportantStyle"] }, { kind: "ngmodule", type: MatProgressSpinnerModule }, { kind: "ngmodule", type: MatSlideToggleModule }, { kind: "component", type: i1$1.MatSlideToggle, selector: "mat-slide-toggle", inputs: ["name", "id", "labelPosition", "aria-label", "aria-labelledby", "aria-describedby", "required", "color", "disabled", "disableRipple", "tabIndex", "checked", "hideIcon", "disabledInteractive"], outputs: ["change", "toggleChange"], exportAs: ["matSlideToggle"] }, { kind: "ngmodule", type: MatProgressBarModule }, { kind: "component", type: i2$2.MatProgressBar, selector: "mat-progress-bar", inputs: ["color", "value", "bufferValue", "mode"], outputs: ["animationEnd"], exportAs: ["matProgressBar"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.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.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i2.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i2.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "ngmodule", type: MatCheckboxModule }, { kind: "component", type: i3.MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "aria-expanded", "aria-controls", "aria-owns", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "disabledInteractive", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { kind: "ngmodule", type: MatSelectModule }, { kind: "directive", type: i6$1.CdkScrollable, selector: "[cdk-scrollable], [cdkScrollable]" }, { kind: "component", type: i5.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth", "canSelectNullableOptions"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i5.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "component", type: DmTableCellHost, selector: "dm-table-cell-host", inputs: ["component", "context"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i8.MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i8.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i6.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatMenuModule }, { kind: "component", type: i10.MatMenu, selector: "mat-menu", inputs: ["backdropClass", "aria-label", "aria-labelledby", "aria-describedby", "xPosition", "yPosition", "overlapTrigger", "hasBackdrop", "class", "classList"], outputs: ["closed", "close"], exportAs: ["matMenu"] }, { kind: "component", type: i10.MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i10.MatMenuContent, selector: "ng-template[matMenuContent]" }, { kind: "directive", type: i10.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }, { kind: "directive", type: CdkDragHandle, selector: "[cdkDragHandle]", inputs: ["cdkDragHandleDisabled"] }, { kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i11.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i11.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i11.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer", "cdkDropListHasAnchor"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "ngmodule", type: A11yModule }, { kind: "directive", type: MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }] });
2158
+ }
2159
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: DmTable, decorators: [{
2160
+ type: Component,
2161
+ args: [{ selector: 'dm-table', imports: [
2162
+ DmImportantStyleDirective,
2163
+ MatProgressSpinnerModule,
2164
+ MatSlideToggleModule,
2165
+ MatProgressBarModule,
2166
+ ReactiveFormsModule,
2167
+ MatFormFieldModule,
2168
+ MatCheckboxModule,
2169
+ MatSelectModule,
2170
+ DmTableCellHost,
2171
+ MatButtonModule,
2172
+ MatInputModule,
2173
+ MatMenuModule,
2174
+ CdkDragHandle,
2175
+ CommonModule,
2176
+ FormsModule,
2177
+ CdkDropList,
2178
+ A11yModule,
2179
+ MatTooltip,
2180
+ MatIcon,
2181
+ CdkDrag,
2182
+ ], template: "<div id=\"dm-table-component-wrapper\">\n <div class=\"dm-table-top-section\">\n @if (enableSearch()) {\n <mat-form-field [appearance]=\"searchInputAppearance()\" class=\"dm-table-search-form-field\">\n <input\n matInput\n [placeholder]=\"searchPlaceholder()\"\n [(ngModel)]=\"searchTerm\"\n [ngModelOptions]=\"{ standalone: true }\"\n (keyup)=\"datasource().search($event.target.value)\"\n />\n @if (searchTerm()) {\n <button\n matSuffix\n mat-icon-button\n [matTooltip]=\"clearSearchTooltip()\"\n aria-label=\"Clear\"\n (click)=\"resetSearch()\"\n >\n <mat-icon>close</mat-icon>\n </button>\n }\n </mat-form-field>\n } @if (editColumnsVisibility() && editColumnsVisibilityButton()) {\n <ng-container\n *ngTemplateOutlet=\"\n editcolumnVisibilityMenuTrigger;\n context: { $implicit: editColumnsVisibilityButton() }\n \"\n ></ng-container>\n }\n <div class=\"spacer\"></div>\n @if (enablePrint()) {\n <ng-container\n *ngTemplateOutlet=\"\n dmTableActionButton;\n context: { $implicit: printButton(), defaultAction: printTable }\n \"\n ></ng-container>\n } @for (button of actionButtons(); track $index) { @if (!button.showIf ||\n button.showIf(visibleColumns(), datasource())) {\n <ng-container\n *ngTemplateOutlet=\"dmTableActionButton; context: { $implicit: button }\"\n ></ng-container>\n } }\n </div>\n <div\n [ngClass]=\"tableClasses()?.tableWrapper || {}\"\n [dmImportantStyle]=\"mergedTableStyle().tableWrapper || DEFAULT_TABLE_STYLE.tableWrapper || {}\"\n cdkScrollable\n >\n <table\n [ngStyle]=\"\n !tableClasses()?.table?.root\n ? mergedTableStyle().table?.root || DEFAULT_TABLE_STYLE.table?.root || {}\n : {}\n \"\n [ngClass]=\"tableClasses()?.table?.root || {}\"\n >\n <thead\n style=\"\n position: sticky !important;\n top: 0 !important;\n z-index: 10 !important;\n box-shadow: 0px 2px 2px 0px #0000006e;\n \"\n [ngStyle]=\"\n !tableClasses()?.table?.thead?.root\n ? mergedTableStyle().table?.thead?.root || DEFAULT_TABLE_STYLE.table?.thead?.root || {}\n : {}\n \"\n [ngClass]=\"tableClasses()?.table?.thead?.root || {}\"\n >\n @if (enableLoadingProgressbar()) {\n <tr style=\"height: 4px !important; max-height: 4px !important; line-height: 4px !important\">\n <th [attr.colspan]=\"visibleRuntimeColumns().length\" style=\"padding: 0 !important\">\n @if (datasource().isLoading()) {\n <mat-progress-bar mode=\"indeterminate\"></mat-progress-bar>\n }\n </th>\n </tr>\n }\n <tr\n [ngStyle]=\"\n !tableClasses()?.table?.thead?.tr\n ? mergedTableStyle().table?.thead?.tr || DEFAULT_TABLE_STYLE.table?.thead?.tr || {}\n : {}\n \"\n [ngClass]=\"tableClasses()?.table?.thead?.tr || {}\"\n cdkDropList\n [cdkDropListData]=\"visibleRuntimeColumns()\"\n [cdkDropListOrientation]=\"'horizontal'\"\n (cdkDropListDropped)=\"onColumnDrop($event)\"\n [cdkDropListAutoScrollStep]=\"20\"\n >\n @for (column of visibleRuntimeColumns(); let j = $index; track column.id) {\n <th\n cdkDrag\n [cdkDragDisabled]=\"!enableColumnsDragAndDrop()\"\n [ngStyle]=\"getHeaderThStyle(column)\"\n [ngClass]=\"tableClasses()?.table?.thead?.th || {}\"\n (mouseenter)=\"hoveredColumnHeaderIndex.set(j)\"\n (mouseleave)=\"hoveredColumnHeaderIndex.set(null)\"\n (click)=\"headerClickHandler(column, $event)\"\n (dblclick)=\"headerDoubleClickHandler(column, $event)\"\n (contextmenu)=\"headerContextMenuHandler(column, $event)\"\n >\n <div\n class=\"inner-header-cell\"\n [dmImportantStyle]=\"getHeaderThContentStyle(column)\"\n (click)=\"headerContentClickHandler(column, $event)\"\n (dblclick)=\"headerContentDoubleClickHandler(column, $event)\"\n (contextmenu)=\"headerContentContextMenuHandler(column, $event)\"\n >\n <span>\n {{ column.header }}\n </span>\n @if (column.sortable) {\n <span\n (click)=\"columnHeaderSortClickHandler(column, $event)\"\n style=\"display: flex; align-items: center\"\n >\n @if (isColumnSorted(column); as sort) {\n <mat-icon style=\"width: 20px; height: 20px; font-size: 20px\">{{\n sort.direction === 'asc' ? 'arrow_upward' : 'arrow_downward'\n }}</mat-icon>\n @if(columnsSortState().length > 1) { [{{ sort.index + 1 }}] } } @else if\n (hoveredColumnHeaderIndex() == j){\n <mat-icon style=\"opacity: 0.3; width: 20px; height: 20px; font-size: 20px\"\n >arrow_upward</mat-icon\n >\n }\n </span>\n } @if (enableColumnsDragHandle()) {\n\n <div class=\"spacer\"></div>\n <span>\n <ng-container\n *ngTemplateOutlet=\"dmTableHeaderMenuTrigger; context: { $implicit: column }\"\n />\n </span>\n <mat-icon style=\"cursor: move; font-size: 20px\" cdkDragHandle\n >drag_indicator</mat-icon\n >\n }\n </div>\n </th>\n }\n </tr>\n </thead>\n <tbody\n [dmImportantStyle]=\"\n !tableClasses()?.table?.tbody?.root\n ? mergedTableStyle().table?.tbody?.root || DEFAULT_TABLE_STYLE.table?.tbody?.root || {}\n : {}\n \"\n [ngClass]=\"tableClasses()?.table?.tbody?.root || {}\"\n >\n @for (row of datasource().result(); let i = $index; track row[rowIdentifierField()]) {\n <tr\n [dmImportantStyle]=\"getBodyRowStyle(i, row)\"\n (mouseenter)=\"hoveredRowIndex.set(i)\"\n (mouseleave)=\"hoveredRowIndex.set(null)\"\n >\n @for (column of visibleRuntimeColumns(); let j = $index; track j) {\n <td\n [dmImportantStyle]=\"getBodyTdStyle(i, column, row)\"\n (click)=\"cellClickHandler(row, column, $event)\"\n (contextmenu)=\"cellContextMenuHandler(row, column, $event)\"\n (dblclick)=\"cellDoubleClickHandler(row, column, $event)\"\n >\n <span\n [dmImportantStyle]=\"getBodyTdContentStyle(i, column, row)\"\n (click)=\"cellContentClickHandler(row, column, $event)\"\n (contextmenu)=\"cellContentContextMenuHandler(row, column, $event)\"\n (dblclick)=\"cellContentDoubleClickHandler(row, column, $event)\"\n >\n @switch (column.type) { @case ('$index') {\n {{ datasource().getFirstItemIndexInPage() + i + 1 }}\n } @case ('component') { @if (column.component) {\n <dm-table-cell-host\n [component]=\"column.component\"\n [context]=\"createCellContext(row, column)\"\n ></dm-table-cell-host>\n } } @case ('tel') {\n <a [href]=\"'tel:' + (column.field ? $any(row)[column.field] : '')\">{{\n resolveCellValue(row, column)\n }}</a>\n } @case ('mail') {\n <a [href]=\"'mailto:' + (column.field ? $any(row)[column.field] : '')\">{{\n resolveCellValue(row, column)\n }}</a>\n } @case ('link') {\n <a\n [href]=\"column.field ? $any(row)[column.field] : ''\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >{{ resolveCellValue(row, column) }}</a\n >\n } @case ('whatsapp') {\n <a\n [href]=\"'https://wa.me/' + (column.field ? $any(row)[column.field] : '')\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >{{ resolveCellValue(row, column) }}</a\n >\n } @case ('customHtml') { @if (column.customHtml) {\n <span [innerHTML]=\"column.customHtml\"></span>\n } @else if (column.customCellTemplate) {\n <ng-container\n *ngTemplateOutlet=\"\n column.customCellTemplate;\n context: createCellContext(row, column)\n \"\n >\n </ng-container>\n } } @case ('actions') {\n <span style=\"display: flex; align-items: center\">\n @for (button of column.actionsButtons || []; track $index) {\n <ng-container\n *ngTemplateOutlet=\"\n dmTableRowActionButton;\n context: {\n $implicit: button,\n row\n }\n \"\n ></ng-container>\n }\n </span>\n } @case('slideToggle') {\n <mat-slide-toggle\n [id]=\"'slideToggle_' + i + '_' + column.id\"\n [checked]=\"$any(row)[column.field!]\"\n [matTooltip]=\"getSlideToggleTooltip(row, column)\"\n (change)=\"onSlideToggleChange(row, column, $event)\"\n >\n <!-- {{ row[column.field!] }} -->\n {{ resolveCellValue(row, column) }}\n </mat-slide-toggle>\n } @case ('input') {\n <ng-container\n *ngTemplateOutlet=\"\n dmTableInputCell;\n context: {\n $implicit: row,\n column: column\n }\n \"\n />\n } @default {\n {{ resolveCellValue(row, column) }}\n } }\n </span>\n </td>\n }\n </tr>\n }\n </tbody>\n @if (enableTotalRow()) {\n <tfoot\n style=\"\n position: sticky !important;\n bottom: 0 !important;\n z-index: 10 !important;\n box-shadow: 0px -2px 2px 0px #0000006e;\n \"\n [ngStyle]=\"\n !tableClasses()?.table?.tfoot?.root\n ? mergedTableStyle().table?.tfoot?.root || DEFAULT_TABLE_STYLE.table?.tfoot?.root || {}\n : {}\n \"\n [ngClass]=\"tableClasses()?.table?.tfoot?.root || {}\"\n >\n <tr>\n @for (column of visibleRuntimeColumns(); let j = $index; track column.id) {\n <td\n [ngStyle]=\"getFooterTdStyle(column)\"\n [ngClass]=\"tableClasses()?.table?.tfoot?.td || {}\"\n >\n @if (column.totalRowValueType == 'html') {\n <span [innerHTML]=\"totalRowValues().get(column.id) || ''\"></span>\n } @else {\n {{ totalRowValues().get(column.id) || '' }}\n }\n </td>\n }\n </tr>\n </tfoot>\n }\n </table>\n </div>\n @if (datasource().result().length === 0) {\n <div class=\"dm-table-no-data\">\n <span>{{ noDataMessage() }}</span>\n </div>\n } @else { @if (datasource().isPaginationEnabled()) {\n <ng-container [ngTemplateOutlet]=\"paginator\" />\n } }\n</div>\n\n<!-- MARK: Action Button template -->\n<ng-template #dmTableActionButton let-button let-defaultAction=\"defaultAction\">\n @if (button.buttonType === 'icon') {\n <button\n #rootTrigger=\"matMenuTrigger\"\n mat-icon-button\n [matTooltip]=\"button.tooltip || ''\"\n aria-label=\"{{ button.tooltip }}\"\n [matMenuTriggerFor]=\"button.children && button.children.length > 0 ? tableButtonRootMenu : null\"\n [matMenuTriggerData]=\"{\n buttons: button.children,\n rootTrigger: rootTrigger\n }\"\n (click)=\"\n button.children && button.children.length > 0\n ? null\n : button.onClick\n ? button.onClick(visibleColumns(), datasource())\n : defaultAction\n ? defaultAction($event)\n : null\n \"\n [ngStyle]=\"{ 'background-color': button.backgroundColor ? button.backgroundColor : undefined }\"\n >\n <mat-icon [style.color]=\"button.color ? button.color : undefined\">{{ button.icon }}</mat-icon>\n </button>\n } @else {\n <button\n #rootTrigger=\"matMenuTrigger\"\n [matButton]=\"button.buttonType || 'filled'\"\n [ngStyle]=\"{ 'background-color': button.backgroundColor ? button.backgroundColor : undefined }\"\n aria-label=\"{{ button.label }}\"\n [matTooltip]=\"button.tooltip || ''\"\n [matMenuTriggerFor]=\"button.children && button.children.length > 0 ? tableButtonRootMenu : null\"\n [matMenuTriggerData]=\"{\n buttons: button.children,\n rootTrigger: rootTrigger\n }\"\n (click)=\"\n button.children && button.children.length > 0\n ? null\n : button.onClick\n ? button.onClick(visibleColumns(), datasource())\n : defaultAction\n ? defaultAction($event)\n : null\n \"\n >\n @if (button.icon) {\n <mat-icon class=\"button-icon\" [ngStyle]=\"{ color: button.color ? button.color : undefined }\">{{\n button.icon\n }}</mat-icon>\n }\n <span [ngStyle]=\"{ color: button.color ? button.color : undefined }\">\n {{ button.label }}\n </span>\n </button>\n }\n <!-- @if (button.buttonType === 'icon') {\n <button\n mat-icon-button\n [color]=\"button.color\"\n [matTooltip]=\"button.tooltip || ''\"\n aria-label=\"{{ button.tooltip }}\"\n (click)=\"\n button.children && button.children.length > 0\n ? null\n : button.onClick\n ? button.onClick(datasource())\n : defaultAction\n ? defaultAction()\n : null\n \"\n >\n <mat-icon>{{ button.icon }}</mat-icon>\n </button>\n } @else {\n <button\n [matButton]=\"button.buttonType || 'filled'\"\n [ngStyle]=\"{ 'background-color': button.color ? button.color : undefined }\"\n aria-label=\"{{ button.label }}\"\n [matTooltip]=\"button.tooltip || ''\"\n (click)=\"\n button.children && button.children.length > 0\n ? null\n : button.onClick\n ? button.onClick(datasource())\n : defaultAction\n ? defaultAction()\n : null\n \"\n >\n @if (button.icon) {\n <mat-icon\n class=\"button-icon\"\n [ngStyle]=\"{ color: button.textColor ? button.textColor : undefined }\"\n >{{ button.icon }}</mat-icon\n >\n }\n <span [ngStyle]=\"{ color: button.textColor ? button.textColor : undefined }\">\n {{ button.label }}\n </span>\n </button>\n } -->\n</ng-template>\n\n<!-- MARK: Action Button root menu -->\n<mat-menu #tableButtonRootMenu=\"matMenu\">\n <ng-template matMenuContent let-buttons=\"buttons\" let-rootTrigger=\"rootTrigger\">\n <ng-container\n *ngTemplateOutlet=\"\n tableButtonRecursiveMenu;\n context: { buttons: buttons, rootTrigger: rootTrigger }\n \"\n ></ng-container>\n </ng-template>\n</mat-menu>\n\n<!-- MARK: Action Button recursive menu -->\n<ng-template #tableButtonRecursiveMenu let-buttons=\"buttons\" let-rootTrigger=\"rootTrigger\">\n @for (button of buttons; track $index) { @if (!button.showIf || button.showIf(visibleColumns(),\n datasource())) { @if (button.children?.length) {\n <button\n mat-menu-item\n [matMenuTriggerFor]=\"subMenu\"\n [matMenuTriggerData]=\"{\n buttons: button.children,\n rootTrigger\n }\"\n (click)=\"$event.stopPropagation()\"\n [ngStyle]=\"{ 'background-color': button.backgroundColor ? button.backgroundColor : undefined }\"\n >\n <span style=\"display: flex; align-items: center; width: 100%\">\n @if (button.icon) {\n <mat-icon [style.color]=\"button.color ? button.color : undefined\">{{ button.icon }}</mat-icon>\n }\n <span [style.color]=\"button.color ? button.color : undefined\">{{ button.label }}</span>\n <span class=\"spacer\"></span>\n <mat-icon [style.color]=\"button.color ? button.color : undefined\" class=\"submenu-arrow\"\n >chevron_left</mat-icon\n >\n </span>\n </button>\n\n <mat-menu #subMenu=\"matMenu\">\n <ng-container\n *ngTemplateOutlet=\"\n tableButtonRecursiveMenu;\n context: { buttons: button.children, rootTrigger: rootTrigger }\n \"\n ></ng-container>\n </mat-menu>\n } @else {\n <button\n mat-menu-item\n [matTooltip]=\"button.tooltip || ''\"\n (click)=\"button.onClick?.(visibleColumns(), datasource(), $event, getCloseParentMenusFn(rootTrigger))\"\n [ngStyle]=\"{ 'background-color': button.backgroundColor ? button.backgroundColor : undefined }\"\n >\n @if (button.icon) {\n <mat-icon [style.color]=\"button.color ? button.color : undefined\">{{ button.icon }}</mat-icon>\n }\n <span [style.color]=\"button.color ? button.color : undefined\">{{ button.label }}</span>\n </button>\n }} }\n</ng-template>\n\n<!-- MARK: Row button root menu -->\n<mat-menu #rowButtonRootMenu=\"matMenu\">\n <ng-template matMenuContent let-buttons=\"buttons\" let-row=\"row\" let-rootTrigger=\"rootTrigger\">\n <ng-container\n *ngTemplateOutlet=\"\n rowButtonRecursiveMenu;\n context: { buttons: buttons, row: row, rootTrigger: rootTrigger }\n \"\n ></ng-container>\n </ng-template>\n</mat-menu>\n\n<!-- MARK: Row button recursive menu -->\n<ng-template\n #rowButtonRecursiveMenu\n let-buttons=\"buttons\"\n let-row=\"row\"\n let-rootTrigger=\"rootTrigger\"\n>\n @for (button of buttons; track $index) { @if (button.children?.length) {\n <button\n mat-menu-item\n [matMenuTriggerFor]=\"subMenu\"\n [matMenuTriggerData]=\"{\n buttons: button.children,\n row,\n rootTrigger\n }\"\n (click)=\"$event.stopPropagation()\"\n [ngStyle]=\"{ 'background-color': button.backgroundColor ? button.backgroundColor : undefined }\"\n >\n <span style=\"display: flex; align-items: center; width: 100%\">\n @if (button.icon) {\n <mat-icon [style.color]=\"button.color ? button.color : undefined\">{{ button.icon }}</mat-icon>\n }\n <span [style.color]=\"button.color ? button.color : undefined\">{{ button.label }}</span>\n <span class=\"spacer\"></span>\n <mat-icon [style.color]=\"button.color ? button.color : undefined\" class=\"submenu-arrow\"\n >chevron_left</mat-icon\n >\n </span>\n </button>\n\n <mat-menu #subMenu=\"matMenu\">\n <ng-container\n *ngTemplateOutlet=\"\n rowButtonRecursiveMenu;\n context: { buttons: button.children, row: row, rootTrigger: rootTrigger }\n \"\n ></ng-container>\n </mat-menu>\n\n } @else {\n <button\n mat-menu-item\n [matTooltip]=\"button.tooltip || ''\"\n (click)=\"button.onClick?.(row, $event, getCloseParentMenusFn(rootTrigger))\"\n [ngStyle]=\"{ 'background-color': button.backgroundColor ? button.backgroundColor : undefined }\"\n >\n @if (button.icon) {\n <mat-icon [style.color]=\"button.color ? button.color : undefined\">{{ button.icon }}</mat-icon>\n }\n <span [style.color]=\"button.color ? button.color : undefined\">{{ button.label }}</span>\n </button>\n } }\n</ng-template>\n\n<!-- MARK: Row Action Button template -->\n<ng-template #dmTableRowActionButton let-button let-row=\"row\" let-defaultAction=\"defaultAction\">\n @if (button.buttonType === 'icon') {\n <button\n #rootTrigger=\"matMenuTrigger\"\n mat-icon-button\n [matTooltip]=\"button.tooltip || ''\"\n aria-label=\"{{ button.tooltip }}\"\n [matMenuTriggerFor]=\"button.children && button.children.length > 0 ? rowButtonRootMenu : null\"\n [matMenuTriggerData]=\"{\n buttons: button.children,\n row,\n rootTrigger: rootTrigger\n }\"\n (click)=\"\n button.children && button.children.length > 0\n ? null\n : button.onClick\n ? button.onClick(row)\n : defaultAction\n ? defaultAction($event)\n : null\n \"\n >\n <mat-icon [style.color]=\"button.color ? button.color : undefined\">{{ button.icon }}</mat-icon>\n </button>\n } @else {\n <button\n [matButton]=\"button.buttonType || 'filled'\"\n [ngStyle]=\"{ 'background-color': button.backgroundColor ? button.backgroundColor : undefined }\"\n aria-label=\"{{ button.label }}\"\n [matTooltip]=\"button.tooltip || ''\"\n [matMenuTriggerFor]=\"button.children && button.children.length > 0 ? rowButtonRootMenu : null\"\n #rootTrigger=\"matMenuTrigger\"\n [matMenuTriggerData]=\"{\n buttons: button.children,\n row,\n rootTrigger: rootTrigger\n }\"\n (click)=\"\n button.children && button.children.length > 0\n ? null\n : button.onClick\n ? button.onClick(row)\n : defaultAction\n ? defaultAction($event)\n : null\n \"\n >\n @if (button.icon) {\n <mat-icon class=\"button-icon\" [ngStyle]=\"{ color: button.color ? button.color : undefined }\">{{\n button.icon\n }}</mat-icon>\n }\n <span [ngStyle]=\"{ color: button.color ? button.color : undefined }\">\n {{ button.label }}\n </span>\n </button>\n }\n</ng-template>\n\n<!-- <mat-menu #buttonChildren=\"matMenu\">\n <ng-template matMenuContent let-buttons=\"buttons\" let-row=\"row\">\n @for (button of buttons || []; track $index) { @if (button.children && button.children.length >\n 0) {\n <ng-container *ngTemplateOutlet=\"subMenuTrigger; context: { button, row }\"></ng-container>\n } @else {\n <button\n mat-menu-item\n [matTooltip]=\"button.tooltip || ''\"\n aria-label=\"{{ button.tooltip }}\"\n (click)=\"\n button.children && button.children.length > 0\n ? null\n : button.onClick\n ? button.onClick(row, $event)\n : null\n \"\n >\n @if (button.icon) {\n <mat-icon>{{ button.icon }}</mat-icon>\n }\n <span>{{ button.label }}</span>\n </button>\n } }\n </ng-template>\n</mat-menu>\n\n<ng-template #subMenuTrigger let-button=\"button\" let-row=\"row\">\n <button\n mat-menu-item\n [matMenuTriggerFor]=\"buttonChildren\"\n [matMenuTriggerData]=\"{\n buttons: button.children,\n row\n }\"\n [matTooltip]=\"button.tooltip || ''\"\n aria-label=\"{{ button.tooltip }}\"\n >\n @if (button.icon) {\n <mat-icon>{{ button.icon }}</mat-icon>\n }\n <span>{{ button.label }}</span>\n </button>\n</ng-template> -->\n\n<!-- MARK: Paginator template -->\n<ng-template #paginator>\n <div\n class=\"dm-table-paginator-row\"\n [ngStyle]=\"mergedTableStyle().paginator?.root || {}\"\n [ngClass]=\"tableClasses()?.paginator?.root || {}\"\n >\n <p\n class=\"mb-0\"\n [ngStyle]=\"mergedTableStyle().paginator?.p || {}\"\n [ngClass]=\"tableClasses()?.paginator?.p || {}\"\n >\n {{\n paginatorSettings()?.numberOfItemsPerPageLabel ||\n DEFAULT_PAGINATOR_SETTINGS.numberOfItemsPerPageLabel\n }}\n </p>\n\n <div>\n <mat-form-field\n style=\"width: 100px\"\n class=\"dm-paginator-form-field ms-2 me-2\"\n [appearance]=\"'fill'\"\n [ngStyle]=\"mergedTableStyle().paginator?.mat_form_field || {}\"\n [ngClass]=\"tableClasses()?.paginator?.mat_form_field || {}\"\n >\n <mat-select\n [value]=\"datasource().getPageSize()\"\n [ngStyle]=\"mergedTableStyle().paginator?.mat_select || {}\"\n [ngClass]=\"tableClasses()?.paginator?.mat_select || {}\"\n >\n @for (option of (paginatorSettings()?.pageSizeOptions ||\n DEFAULT_PAGINATOR_SETTINGS.pageSizeOptions); track option) {\n <mat-option\n [value]=\"option\"\n (onSelectionChange)=\"onPageSizeChange($event, option)\"\n [ngStyle]=\"mergedTableStyle().paginator?.mat_option || {}\"\n [ngClass]=\"tableClasses()?.paginator?.mat_option || {}\"\n >{{ option }}</mat-option\n >\n }\n </mat-select>\n </mat-form-field>\n </div>\n\n @if (datasource().getPageSize() > 0) {\n <div class=\"dm-table-paginator-page-info\">\n <p\n [ngClass]=\"tableClasses()?.paginator?.p || {}\"\n [ngStyle]=\"mergedTableStyle().paginator?.p || {}\"\n >\n {{ datasource().getFirstItemIndexInPage() + 1 }}\n </p>\n\n <p\n [ngClass]=\"tableClasses()?.paginator?.p || {}\"\n [ngStyle]=\"mergedTableStyle().paginator?.p || {}\"\n >\n -\n </p>\n\n <p\n [ngClass]=\"tableClasses()?.paginator?.p || {}\"\n [ngStyle]=\"mergedTableStyle().paginator?.p || {}\"\n >\n {{ datasource().getLastItemIndexInPage() + 1 }}\n </p>\n\n <p\n [ngClass]=\"tableClasses()?.paginator?.p || {}\"\n [ngStyle]=\"mergedTableStyle().paginator?.p || {}\"\n >\n \u05DE\u05EA\u05D5\u05DA\n </p>\n\n <p\n [ngClass]=\"tableClasses()?.paginator?.p || {}\"\n [ngStyle]=\"mergedTableStyle().paginator?.p || {}\"\n >\n {{ datasource().getTotalResultElementsCount() }}\n </p>\n </div>\n }\n\n <div>\n @if (paginatorSettings()?.showFirstAndLastPagesButtons ||\n DEFAULT_PAGINATOR_SETTINGS.showFirstAndLastPagesButtons) {\n <button\n [ngStyle]=\"mergedTableStyle().paginator?.button || {}\"\n [ngClass]=\"tableClasses()?.paginator?.button || {}\"\n mat-icon-button\n (click)=\"datasource().firstPage()\"\n [matTooltip]=\"\n paginatorSettings()?.firstPageButtonLabel ||\n DEFAULT_PAGINATOR_SETTINGS.firstPageButtonLabel\n \"\n [matTooltipPosition]=\"'above'\"\n >\n <mat-icon>keyboard_double_arrow_right</mat-icon>\n </button>\n }\n <button\n [ngStyle]=\"mergedTableStyle().paginator?.button || {}\"\n [ngClass]=\"tableClasses()?.paginator?.button || {}\"\n mat-icon-button\n (click)=\"datasource().firstPage()\"\n [matTooltip]=\"\n paginatorSettings()?.previousPageButtonLabel ||\n DEFAULT_PAGINATOR_SETTINGS.previousPageButtonLabel\n \"\n [matTooltipPosition]=\"'above'\"\n >\n <mat-icon>chevron_right</mat-icon>\n </button>\n <button\n [ngStyle]=\"mergedTableStyle().paginator?.button || {}\"\n [ngClass]=\"tableClasses()?.paginator?.button || {}\"\n mat-icon-button\n (click)=\"datasource().nextPage()\"\n [matTooltip]=\"\n paginatorSettings()?.nextPageButtonLabel || DEFAULT_PAGINATOR_SETTINGS.nextPageButtonLabel\n \"\n [matTooltipPosition]=\"'above'\"\n >\n <mat-icon>chevron_left</mat-icon>\n </button>\n @if (paginatorSettings()?.showFirstAndLastPagesButtons ||\n DEFAULT_PAGINATOR_SETTINGS.showFirstAndLastPagesButtons) {\n <button\n [ngStyle]=\"mergedTableStyle().paginator?.button || {}\"\n [ngClass]=\"tableClasses()?.paginator?.button || {}\"\n mat-icon-button\n (click)=\"datasource().lastPage()\"\n [matTooltip]=\"\n paginatorSettings()?.lastPageButtonLabel || DEFAULT_PAGINATOR_SETTINGS.lastPageButtonLabel\n \"\n [matTooltipPosition]=\"'above'\"\n >\n <mat-icon>keyboard_double_arrow_left</mat-icon>\n </button>\n }\n </div>\n </div>\n</ng-template>\n\n<!-- MARK: Edit Columns Visibility Menu Trigger -->\n<ng-template #editcolumnVisibilityMenuTrigger let-button>\n @if (button.buttonType == 'icon') {\n <button\n mat-icon-button\n [matTooltip]=\"button.tooltip || ''\"\n aria-label=\"{{ button.tooltip }}\"\n [matMenuTriggerFor]=\"columnVisibilityMenu\"\n #rootTrigger=\"matMenuTrigger\"\n >\n <mat-icon [style.color]=\"button.textColor ? button.textColor : undefined\">{{\n button.icon\n }}</mat-icon>\n </button>\n } @else {\n <button\n [matButton]=\"button.buttonType || 'filled'\"\n [ngStyle]=\"{ 'background-color': button.color ? button.color : undefined }\"\n aria-label=\"{{ button.label }}\"\n [matTooltip]=\"button.tooltip || ''\"\n [matMenuTriggerFor]=\"columnVisibilityMenu\"\n #rootTrigger=\"matMenuTrigger\"\n >\n @if (button.icon) {\n <mat-icon\n class=\"button-icon\"\n [ngStyle]=\"{ color: button.textColor ? button.textColor : undefined }\"\n >{{ button.icon }}</mat-icon\n >\n }\n <span [style.color]=\"button.textColor ? button.textColor : undefined\">\n {{ button.label }}\n </span>\n </button>\n }\n</ng-template>\n\n<!-- MARK: Edit Columns Visibility Menu -->\n<mat-menu #columnVisibilityMenu=\"matMenu\">\n <div mat-menu-item disableRipple (click)=\"$event.stopPropagation()\">\n <mat-checkbox\n [checked]=\"isAllColumnsVisible()\"\n (change)=\"toggleAllColumnsVisibility($event)\"\n (click)=\"$event.stopPropagation()\"\n >{{ editColumnsVisibilitySelectAllLabel() }}</mat-checkbox\n >\n </div>\n @for (column of runtimeColumns(); track column.id) {\n <div mat-menu-item disableRipple (click)=\"$event.stopPropagation()\">\n <mat-checkbox\n [checked]=\"isColumnVisible(column)\"\n (change)=\"toggleColumnVisibility($event, column)\"\n (click)=\"$event.stopPropagation()\"\n >{{ column.header }}</mat-checkbox\n >\n </div>\n }\n</mat-menu>\n\n<!-- MARK: Input Cell Template -->\n<ng-template #dmTableInputCell let-row let-column=\"column\">\n @switch (column.inputType) { @case ('select') {\n <mat-select\n [dmImportantStyle]=\"getInputStyle(column)\"\n panelWidth=\"null\"\n [value]=\"resolveCellValue(row, column)\"\n >\n @for (option of column.selectOptions || []; track option.value) {\n <mat-option\n [value]=\"option.value\"\n (onSelectionChange)=\"inputCellSelectOptionChangeHandler(row, column, option, $event)\"\n >{{ option.label }}</mat-option\n >\n }\n </mat-select>\n } @case ('checkbox') {\n <mat-checkbox\n [checked]=\"resolveCellValue(row, column)\"\n (change)=\"inputCellCheckboxChangeHandler(row, column, $event)\"\n ></mat-checkbox>\n } @default {\n <input\n [type]=\"column.inputType || 'text'\"\n [value]=\"resolveCellValue(row, column)\"\n (change)=\"inputCellChangeHandler(row, column, $event)\"\n [dmImportantStyle]=\"getInputStyle(column)\"\n />\n } }\n</ng-template>\n\n<!-- MARK: Header Menu Trigger Template -->\n<ng-template #dmTableHeaderMenuTrigger let-column>\n @if (column?.headerMenuItems?.length) {\n <!-- <button\n mat-icon-button\n (click)=\"$event.stopPropagation()\"\n aria-label=\"Column Menu\"\n >\n </button> -->\n <mat-icon\n #rootTrigger=\"matMenuTrigger\"\n [matMenuTriggerFor]=\"dmTableHeaderRootMenu\"\n [matMenuTriggerData]=\"{\n menuItems: column.headerMenuItems,\n rootTrigger: rootTrigger\n }\"\n [matTooltip]=\"column.headerMenuTooltip || ''\"\n style=\"font-size: 20px; cursor: pointer; margin-left: 4px; height: 20px\"\n [ngStyle]=\"{\n color: getHeaderThContentStyle(column)?.color || getHeaderThStyle(column)?.color || ''\n }\"\n >menu</mat-icon\n >\n }\n</ng-template>\n\n<!-- MARK: Header Root Menu -->\n<mat-menu #dmTableHeaderRootMenu=\"matMenu\">\n <ng-template matMenuContent let-menuItems=\"menuItems\" let-rootTrigger=\"rootTrigger\">\n <ng-container\n *ngTemplateOutlet=\"\n dmTableHeaderRecursiveMenu;\n context: { menuItems: menuItems, rootTrigger: rootTrigger }\n \"\n ></ng-container>\n </ng-template>\n</mat-menu>\n\n<!-- MARK: Header Recursive Menu -->\n<ng-template #dmTableHeaderRecursiveMenu let-menuItems=\"menuItems\" let-rootTrigger=\"rootTrigger\">\n @for (menuItem of menuItems; track $index) { @if (!menuItem.showIf || (menuItem.showIf &&\n menuItem.showIf(datasource()))) {@if (menuItem.children?.length) {\n <button\n mat-menu-item\n [matMenuTriggerFor]=\"dmTableHeaderSubMenu\"\n [matMenuTriggerData]=\"{\n menuItems: menuItem.children,\n rootTrigger\n }\"\n (click)=\"$event.stopPropagation()\"\n [ngStyle]=\"{\n 'background-color': menuItem.backgroundColor ? menuItem.backgroundColor : undefined\n }\"\n >\n <span style=\"display: flex; align-items: center; width: 100%\">\n @if (menuItem.icon) {\n <mat-icon [style.color]=\"menuItem.color ? menuItem.color : undefined\">{{\n menuItem.icon\n }}</mat-icon>\n }\n <span [style.color]=\"menuItem.color ? menuItem.color : undefined\">{{ menuItem.label }}</span>\n <span class=\"spacer\"></span>\n <mat-icon [style.color]=\"menuItem.color ? menuItem.color : undefined\" class=\"submenu-arrow\"\n >chevron_left</mat-icon\n >\n </span>\n </button>\n\n <mat-menu #dmTableHeaderSubMenu=\"matMenu\">\n <ng-container\n *ngTemplateOutlet=\"\n dmTableHeaderRecursiveMenu;\n context: { menuItems: menuItem.children, rootTrigger: rootTrigger }\n \"\n />\n </mat-menu>\n } @else {\n <button\n mat-menu-item\n [matTooltip]=\"menuItem.tooltip || ''\"\n (click)=\"menuItem.onClick?.(datasource(), $event, getCloseParentMenusFn(rootTrigger))\"\n [ngStyle]=\"{\n 'background-color': menuItem.backgroundColor ? menuItem.backgroundColor : undefined\n }\"\n >\n @if (menuItem.icon) {\n <mat-icon [style.color]=\"menuItem.color ? menuItem.color : undefined\">{{\n menuItem.icon\n }}</mat-icon>\n }\n <span [style.color]=\"menuItem.color ? menuItem.color : undefined\">{{ menuItem.label }}</span>\n </button>\n } }}\n</ng-template>\n", styles: ["#dm-table-component-wrapper{width:100%}#dm-table-component-wrapper ::-webkit-scrollbar{width:var(--dm-table-scrollbar-width, 7px);height:var(--dm-table-scrollbar-width, 7px)}#dm-table-component-wrapper ::-webkit-scrollbar-track{background:var(--dm-table-scrollbar-background-color, #e0e0e0)}#dm-table-component-wrapper ::-webkit-scrollbar-thumb{background:var(--dm-table-scrollbar-color, #949496);border-radius:var(--dm-table-scrollbar-border-radius, 4px)}#dm-table-component-wrapper ::-webkit-scrollbar-thumb:hover{background:var(--dm-table-scrollbar-hover-color, #5f5f5f)}#dm-table-component-wrapper .dm-table-top-section{width:calc(100% - 10px);display:flex;align-items:center;padding:0 5px;gap:5px;flex-wrap:wrap}#dm-table-component-wrapper .dm-table-table-wrapper .dm-table-classic{width:100%;border-collapse:collapse;border-spacing:0;box-shadow:0 5px 5px -3px #003,0 8px 10px 1px #00000024,0 3px 14px 2px #0000001f;padding:0;font-size:1rem;border-radius:8px;page-break-inside:auto}#dm-table-component-wrapper .dm-table-table-wrapper .dm-table-classic tr{page-break-inside:avoid}#dm-table-component-wrapper .dm-table-table-wrapper .dm-table-classic th,#dm-table-component-wrapper .dm-table-table-wrapper .dm-table-classic td{text-align:start;max-width:none}#dm-table-component-wrapper .inner-header-cell{display:flex;align-items:center;gap:5px}#dm-table-component-wrapper .dm-table-no-data{width:98%;margin:10px auto 0;line-height:60px;display:flex;justify-content:center;align-items:center;padding:10px;font-size:1.5rem;font-weight:700;color:#dd2f2f;box-shadow:0 4px 6px #000000d7}#dm-table-component-wrapper .dm-table-paginator-row{display:flex;flex-wrap:wrap;justify-content:center;align-items:center;gap:5px}#dm-table-component-wrapper .dm-table-paginator-row .dm-table-paginator-page-info{display:flex;align-items:center;gap:5px}:host ::ng-deep .dm-paginator-form-field>.mat-mdc-form-field-bottom-align:before{content:\"\";display:none;height:0px}:host ::ng-deep .dm-table-search-form-field>.mat-mdc-form-field-bottom-align:before{content:\"\";display:none;height:0px}.cdk-drag-preview{border:none;box-sizing:border-box;background-color:var(--dm-table-header-background-color, #f5f5f5);color:var(--dm-table-header-color, #000000);border-radius:4px;box-shadow:0 5px 5px -3px #0003,0 8px 10px 1px #00000024,0 3px 14px 2px #0000001f}.cdk-drag-preview .inner-header-cell{display:flex;align-items:center}.spacer{flex-grow:1}\n"] }]
2183
+ }], ctorParameters: () => [], propDecorators: { onShiftKeyDown: [{
2184
+ type: HostListener,
2185
+ args: ['window:keydown.shift', ['$event']]
2186
+ }], onShiftKeyUp: [{
2187
+ type: HostListener,
2188
+ args: ['window:keyup.shift', ['$event']]
2189
+ }], tableId: [{ type: i0.Input, args: [{ isSignal: true, alias: "tableId", required: false }] }], dataSource: [{ type: i0.Input, args: [{ isSignal: true, alias: "dataSource", required: false }] }], columns: [{ type: i0.Input, args: [{ isSignal: true, alias: "columns", required: false }] }], noDataMessage: [{ type: i0.Input, args: [{ isSignal: true, alias: "noDataMessage", required: false }] }], enableSearch: [{ type: i0.Input, args: [{ isSignal: true, alias: "enableSearch", required: false }] }], searchPlaceholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "searchPlaceholder", required: false }] }], clearSearchTooltip: [{ type: i0.Input, args: [{ isSignal: true, alias: "clearSearchTooltip", required: false }] }], searchInputAppearance: [{ type: i0.Input, args: [{ isSignal: true, alias: "searchInputAppearance", required: false }] }], filterPredicate: [{ type: i0.Input, args: [{ isSignal: true, alias: "filterPredicate", required: false }] }], actionButtons: [{ type: i0.Input, args: [{ isSignal: true, alias: "actionButtons", required: false }] }], enablePrint: [{ type: i0.Input, args: [{ isSignal: true, alias: "enablePrint", required: false }] }], printButton: [{ type: i0.Input, args: [{ isSignal: true, alias: "printButton", required: false }] }], enablePagination: [{ type: i0.Input, args: [{ isSignal: true, alias: "enablePagination", required: false }] }], autoPaginationAboveRowsCount: [{ type: i0.Input, args: [{ isSignal: true, alias: "autoPaginationAboveRowsCount", required: false }] }], paginatorSettings: [{ type: i0.Input, args: [{ isSignal: true, alias: "paginatorSettings", required: false }] }], enableLoadingProgressbar: [{ type: i0.Input, args: [{ isSignal: true, alias: "enableLoadingProgressbar", required: false }] }], enableColumnsDragAndDrop: [{ type: i0.Input, args: [{ isSignal: true, alias: "enableColumnsDragAndDrop", required: false }] }], enableColumnsDragHandle: [{ type: i0.Input, args: [{ isSignal: true, alias: "enableColumnsDragHandle", required: false }] }], enableTotalRow: [{ type: i0.Input, args: [{ isSignal: true, alias: "enableTotalRow", required: false }] }], tableStyle: [{ type: i0.Input, args: [{ isSignal: true, alias: "tableStyle", required: false }] }], tableClasses: [{ type: i0.Input, args: [{ isSignal: true, alias: "tableClasses", required: false }] }], rowStyleFn: [{ type: i0.Input, args: [{ isSignal: true, alias: "rowStyleFn", required: false }] }], editColumnsVisibility: [{ type: i0.Input, args: [{ isSignal: true, alias: "editColumnsVisibility", required: false }] }], editColumnsVisibilityButton: [{ type: i0.Input, args: [{ isSignal: true, alias: "editColumnsVisibilityButton", required: false }] }], editColumnsVisibilitySelectAllLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "editColumnsVisibilitySelectAllLabel", required: false }] }], rowIdentifierField: [{ type: i0.Input, args: [{ isSignal: true, alias: "rowIdentifierField", required: false }] }] } });
2190
+
851
2191
  /**
852
2192
  * Generated bundle index. Do not edit.
853
2193
  */
854
2194
 
855
- export { DmCmpsDataSource, DmColorPicker, DmMatSelect, DmSpinner, DmSpinnerService };
2195
+ export { DmCmpsDataSource, DmColorPicker, DmMatSelect, DmSpinner, DmSpinnerService, DmTable };
856
2196
  //# sourceMappingURL=dmlibs-dm-cmps.mjs.map