@one-paragon/angular-utilities 1.3.1 → 2.0.0-beta.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/action-state/ngrx.d.ts +1 -1
  2. package/fesm2022/one-paragon-angular-utilities.mjs +1095 -1091
  3. package/fesm2022/one-paragon-angular-utilities.mjs.map +1 -1
  4. package/ngrx/actionable-selector.d.ts +3 -3
  5. package/package.json +7 -8
  6. package/table-builder/classes/TableBuilderDataSource.d.ts +8 -2
  7. package/table-builder/classes/TableState.d.ts +1 -0
  8. package/table-builder/classes/filter-info.d.ts +3 -1
  9. package/table-builder/classes/table-builder-general-settings.d.ts +18 -6
  10. package/table-builder/classes/table-builder.d.ts +1 -1
  11. package/table-builder/classes/table-store.d.ts +61 -66
  12. package/table-builder/classes/table-store.helpers.d.ts +29 -0
  13. package/table-builder/components/column-builder/column-builder.component.d.ts +19 -29
  14. package/table-builder/components/filter/filter.component.d.ts +3 -3
  15. package/table-builder/components/filter/in-list/in-list-filter.component.d.ts +9 -10
  16. package/table-builder/components/generic-table/generic-table.component.d.ts +27 -39
  17. package/table-builder/components/generic-table/paginator.component.d.ts +2 -5
  18. package/table-builder/components/header-menu/header-menu.component.d.ts +3 -5
  19. package/table-builder/components/in-filter/in-filter.component.d.ts +2 -2
  20. package/table-builder/components/number-filter/number-filter.component.d.ts +3 -3
  21. package/table-builder/components/sort-menu/sort-menu.component-store.d.ts +4 -4
  22. package/table-builder/components/sort-menu/sort-menu.component.d.ts +6 -11
  23. package/table-builder/components/table-container/table-container-imports.d.ts +2 -3
  24. package/table-builder/components/table-container/table-container.d.ts +56 -52
  25. package/table-builder/components/table-container/table-container.helpers/filter-state.helpers.d.ts +2 -0
  26. package/table-builder/components/table-container/table-container.helpers/meta-data.helpers.d.ts +2 -0
  27. package/table-builder/components/table-container/tableProps.d.ts +0 -2
  28. package/table-builder/components/table-container/virtual-scroll-container.d.ts +12 -3
  29. package/table-builder/components/table-container-filter/filter-list/filter-list.component.d.ts +1 -1
  30. package/table-builder/components/table-container-filter/table-wrapper-filter-store.d.ts +1 -1
  31. package/table-builder/directives/custom-cell-directive.d.ts +17 -16
  32. package/table-builder/directives/multi-sort.directive.d.ts +1 -1
  33. package/table-builder/directives/table-wrapper.directive.d.ts +1 -1
  34. package/table-builder/directives/tb-filter.directive.d.ts +13 -15
  35. package/table-builder/interfaces/report-def.d.ts +13 -2
  36. package/table-builder/pipes/format-filter-value.pipe.d.ts +1 -2
  37. package/table-builder/pipes/key-display.d.ts +1 -2
  38. package/table-builder/services/transform-creator.d.ts +1 -2
  39. package/utilities/pipes/function.pipe.d.ts +5 -1
@@ -1,16 +1,17 @@
1
1
  import * as i0 from '@angular/core';
2
- import { Directive, Input, inject, Injector, TemplateRef, ViewContainerRef, NgModule, assertInInjectionContext, DestroyRef, computed, isSignal, Injectable, Pipe, Renderer2, ElementRef, booleanAttribute, signal, InjectionToken, makeEnvironmentProviders, HostListener, Component, ChangeDetectionStrategy, EventEmitter, untracked, Output, ContentChildren, ChangeDetectorRef, input, output, ViewChild, EnvironmentInjector, createComponent, viewChild, effect, contentChild, forwardRef, contentChildren, runInInjectionContext, ContentChild, APP_INITIALIZER } from '@angular/core';
3
- import { shareReplay, switchAll, map, filter, tap, catchError, startWith, switchMap, mergeMap, concatMap as concatMap$1, takeUntil, debounceTime, distinctUntilChanged, first as first$1, observeOn, scan as scan$1, timestamp as timestamp$1, mergeAll } from 'rxjs/operators';
2
+ import { Directive, Input, inject, Injector, TemplateRef, ViewContainerRef, NgModule, assertInInjectionContext, DestroyRef, computed, isSignal, Injectable, Pipe, input, signal, Renderer2, ElementRef, booleanAttribute, InjectionToken, makeEnvironmentProviders, Component, ChangeDetectionStrategy, HostListener, EventEmitter, untracked, Output, ContentChildren, ChangeDetectorRef, output, ViewChild, EnvironmentInjector, createComponent, viewChild, effect, linkedSignal, contentChild, forwardRef, contentChildren, model, runInInjectionContext, provideAppInitializer } from '@angular/core';
3
+ import { shareReplay, switchAll, map, filter, tap, catchError, startWith, switchMap, mergeMap, concatMap as concatMap$1, takeUntil, distinctUntilChanged, observeOn, scan as scan$1, timestamp as timestamp$1, first as first$1 } from 'rxjs/operators';
4
4
  import * as i1 from 'rxjs';
5
- import { Subject, isObservable, of, ReplaySubject, filter as filter$1, first, map as map$1, Observable, combineLatest, Subscription, startWith as startWith$1, pairwise, concatMap, merge, delay, fromEvent, BehaviorSubject, takeUntil as takeUntil$1, tap as tap$1, switchMap as switchMap$1, scan, animationFrameScheduler, timestamp } from 'rxjs';
5
+ import { Subject, isObservable, of, ReplaySubject, filter as filter$1, first, map as map$1, Observable, combineLatest, Subscription, startWith as startWith$1, pairwise, concatMap, merge, delay, fromEvent, takeUntil as takeUntil$1, tap as tap$1, switchMap as switchMap$1, scan, animationFrameScheduler, debounceTime, timestamp, BehaviorSubject } from 'rxjs';
6
6
  import { ComponentStore } from '@ngrx/component-store';
7
- import { toObservable, toSignal } from '@angular/core/rxjs-interop';
7
+ import { toObservable, toSignal, outputFromObservable } from '@angular/core/rxjs-interop';
8
8
  import * as i1$8 from '@angular/common';
9
- import { DatePipe, CurrencyPipe, AsyncPipe, KeyValuePipe, NgTemplateOutlet, NgClass, DecimalPipe, CommonModule } from '@angular/common';
9
+ import { DatePipe, CurrencyPipe, KeyValuePipe, NgTemplateOutlet, DecimalPipe, CommonModule, AsyncPipe } from '@angular/common';
10
10
  import * as i3$2 from '@angular/material/sort';
11
11
  import { MatSort, MatSortModule } from '@angular/material/sort';
12
- import { merge as merge$1, get, sumBy, difference, intersection, groupBy, orderBy, set, cloneDeep } from 'lodash';
12
+ import { merge as merge$1, get, sumBy, difference, intersection, groupBy, orderBy, set, isFunction as isFunction$1 } from 'lodash';
13
13
  import { CdkColumnDef } from '@angular/cdk/table';
14
+ import { coerceBooleanProperty } from '@angular/cdk/coercion';
14
15
  import { MatSlideToggle } from '@angular/material/slide-toggle';
15
16
  import * as i10 from '@angular/material/radio';
16
17
  import { MatRadioButton, MatRadioModule } from '@angular/material/radio';
@@ -29,10 +30,10 @@ import * as i1$1 from '@angular/material/input';
29
30
  import { MatInputModule, MatInput } from '@angular/material/input';
30
31
  import * as i4 from '@angular/material/datepicker';
31
32
  import { MatDatepickerModule } from '@angular/material/datepicker';
32
- import { MatDialog, MatDialogModule } from '@angular/material/dialog';
33
33
  import * as i6 from '@angular/material/form-field';
34
34
  import * as i1$3 from '@angular/material/card';
35
35
  import { MatCardModule } from '@angular/material/card';
36
+ import { MatDialog, MatDialogModule } from '@angular/material/dialog';
36
37
  import * as i3$1 from '@angular/material/button';
37
38
  import { MatButtonModule, MatIconButton, MatButton } from '@angular/material/button';
38
39
  import * as i4$1 from '@angular/material/tooltip';
@@ -43,8 +44,6 @@ import * as i8 from '@angular/material/select';
43
44
  import { MatSelectModule } from '@angular/material/select';
44
45
  import * as i4$2 from '@angular/material/menu';
45
46
  import { MatMenuModule, MatMenuTrigger } from '@angular/material/menu';
46
- import * as i3$3 from '@ngrx/component';
47
- import { LetDirective } from '@ngrx/component';
48
47
  import * as i4$3 from '@angular/material/chips';
49
48
  import { MatChipsModule } from '@angular/material/chips';
50
49
  import * as i1$5 from '@angular/material/table';
@@ -152,7 +151,7 @@ class HttpRequestStateDirective {
152
151
  }
153
152
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: HttpRequestStateDirective, decorators: [{
154
153
  type: Directive,
155
- args: [{ selector: '[httpRequestState]', standalone: true }]
154
+ args: [{ selector: '[httpRequestState]', }]
156
155
  }], ctorParameters: () => [{ type: i0.TemplateRef }, { type: i0.ViewContainerRef }], propDecorators: { stateStore: [{
157
156
  type: Input,
158
157
  args: ['httpRequestState']
@@ -201,7 +200,7 @@ class HttpErrorStateDirective extends HttpStateDirectiveBase {
201
200
  }
202
201
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: HttpErrorStateDirective, decorators: [{
203
202
  type: Directive,
204
- args: [{ selector: '[httpErrorState]', standalone: true }]
203
+ args: [{ selector: '[httpErrorState]', }]
205
204
  }] });
206
205
 
207
206
  class HttpInProgressStateDirective extends HttpStateDirectiveBase {
@@ -220,7 +219,7 @@ class HttpInProgressStateDirective extends HttpStateDirectiveBase {
220
219
  }
221
220
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: HttpInProgressStateDirective, decorators: [{
222
221
  type: Directive,
223
- args: [{ selector: '[httpInProgressState]', standalone: true }]
222
+ args: [{ selector: '[httpInProgressState]', }]
224
223
  }] });
225
224
 
226
225
  class HttpNotStartedStateDirective extends HttpStateDirectiveBase {
@@ -239,7 +238,7 @@ class HttpNotStartedStateDirective extends HttpStateDirectiveBase {
239
238
  }
240
239
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: HttpNotStartedStateDirective, decorators: [{
241
240
  type: Directive,
242
- args: [{ selector: '[httpNotStartedState]', standalone: true }]
241
+ args: [{ selector: '[httpNotStartedState]', }]
243
242
  }] });
244
243
 
245
244
  class HttpSuccessStateDirective extends HttpStateDirectiveBase {
@@ -262,7 +261,7 @@ class HttpSuccessStateDirective extends HttpStateDirectiveBase {
262
261
  }
263
262
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: HttpSuccessStateDirective, decorators: [{
264
263
  type: Directive,
265
- args: [{ selector: '[httpSuccessState]', standalone: true }]
264
+ args: [{ selector: '[httpSuccessState]', }]
266
265
  }], propDecorators: { httpSuccessStateTypeSafety: [{
267
266
  type: Input
268
267
  }] } });
@@ -694,7 +693,7 @@ class SpaceCasePipe {
694
693
  }
695
694
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: SpaceCasePipe, decorators: [{
696
695
  type: Pipe,
697
- args: [{ name: 'spaceCase', standalone: true }]
696
+ args: [{ name: 'spaceCase' }]
698
697
  }] });
699
698
  /**
700
699
  * Adds a space before uppercase letters that either
@@ -706,10 +705,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImpor
706
705
  * Turns underscores into spaces
707
706
  */
708
707
  function spaceCase(value) {
709
- const phrase = value?.replace(/([a-z0-9])([A-Z])|([a-zA-Z0-9])([A-Z])(?=[a-z])|_/g, '$1$3 $2$4');
708
+ const phrase = value?.replace(regex1, '$1$3 $2$4');
710
709
  // uppercase the first character of every word
711
- return phrase?.replace(/(^| )(\w)/g, x => x.toUpperCase());
710
+ return phrase?.replace(regex2, x => x.toUpperCase());
712
711
  }
712
+ const regex1 = /([a-z0-9])([A-Z])|([a-zA-Z0-9])([A-Z])(?=[a-z])|_/g;
713
+ const regex2 = /(^| )(\w)/g;
713
714
 
714
715
  var FieldType;
715
716
  (function (FieldType) {
@@ -786,9 +787,10 @@ class TableColumnHeaderSettings {
786
787
  noHeader = false;
787
788
  }
788
789
  class TableSettings {
789
- usePaginator = true;
790
+ usePaginator = undefined;
790
791
  useVirtualScroll = undefined;
791
- includeAllInPaginatorOptions = false;
792
+ paginatorSettings = undefined;
793
+ virtualScrollSettings = undefined;
792
794
  rowHeight = undefined;
793
795
  groupHeaderHeight = undefined;
794
796
  minColumnWidth;
@@ -824,22 +826,32 @@ class NotPersistedTableSettings {
824
826
  newNpts.hideColumnHeaderFilters = tableSettings.columnHeaderSettings?.noFilters ?? newNpts.hideColumnHeaderFilters;
825
827
  newNpts.hideColumnHeader = tableSettings.columnHeaderSettings?.noHeader ?? newNpts.hideColumnHeader;
826
828
  newNpts.usePaginator = tableSettings.tableSettings?.usePaginator ?? newNpts.usePaginator;
827
- newNpts.useVirtualScroll = tableSettings.tableSettings?.useVirtualScroll ?? newNpts.useVirtualScroll;
828
- newNpts.includeAllInPaginatorOptions = tableSettings.tableSettings?.includeAllInPaginatorOptions ?? newNpts.includeAllInPaginatorOptions;
829
+ newNpts.useVirtualScroll = tableSettings.tableSettings?.useVirtualScroll != undefined ? tableSettings.tableSettings?.useVirtualScroll :
830
+ tableSettings.tableSettings?.virtualScrollSettings ? true
831
+ : newNpts.useVirtualScroll;
829
832
  newNpts.rowHeight = tableSettings.tableSettings?.rowHeight ?? newNpts.rowHeight;
830
833
  newNpts.headerHeight = tableSettings.headerSettings?.headerHeight ?? newNpts.headerHeight;
831
834
  newNpts.groupHeaderHeight = tableSettings.tableSettings?.groupHeaderHeight ?? newNpts.groupHeaderHeight;
832
835
  newNpts.minColumnWidth = tableSettings.tableSettings?.minColumnWidth ?? newNpts.minColumnWidth;
833
- if (tableSettings.tableSettings?.useVirtualScroll) {
834
- const currVirt = tableSettings.tableSettings.useVirtualScroll === true ? new VirtualScrollOptions() : tableSettings.tableSettings.useVirtualScroll;
835
- if (!currVirt.headerHeight || tableSettings.tableSettings.useVirtualScroll === true) {
836
+ if (tableSettings.tableSettings?.virtualScrollSettings) {
837
+ const currVirt = tableSettings.tableSettings?.virtualScrollSettings || newNpts.virtualSettings;
838
+ if (!currVirt.headerHeight) {
836
839
  currVirt.headerHeight = (typeof tableSettings.headerSettings?.headerHeight === 'number' ? tableSettings.headerSettings?.headerHeight : DefaultVirtualScrollOptions.headerHeight);
837
840
  }
838
- if (!currVirt.rowHeight || tableSettings.tableSettings.useVirtualScroll === true) {
841
+ if (!currVirt.rowHeight) {
839
842
  currVirt.rowHeight = (typeof tableSettings.tableSettings?.rowHeight === 'number' ? tableSettings.tableSettings?.rowHeight : DefaultVirtualScrollOptions.rowHeight);
840
843
  }
841
- this.useVirtualScroll = { ...new VirtualScrollOptions(), ...currVirt };
844
+ newNpts.virtualSettings = { ...new VirtualScrollOptions(), ...currVirt };
845
+ }
846
+ else
847
+ newNpts.virtualSettings ??= new VirtualScrollOptions();
848
+ if (tableSettings.tableSettings?.paginatorSettings) {
849
+ const currPag = tableSettings.tableSettings?.paginatorSettings ? merge$1(newNpts.paginatorSettings, tableSettings.tableSettings?.paginatorSettings) : (newNpts.paginatorSettings ?? new PaginatorOptions());
850
+ currPag.includeAllInOptions = (currPag.defaultAll && currPag.includeAllInOptions !== false) || currPag.includeAllInOptions;
851
+ newNpts.paginatorSettings = { ...new PaginatorOptions(), ...currPag };
842
852
  }
853
+ else
854
+ newNpts.paginatorSettings ??= new PaginatorOptions();
843
855
  }
844
856
  return newNpts;
845
857
  }
@@ -852,15 +864,15 @@ class NotPersistedTableSettings {
852
864
  hideColumnHeaderFilters = false;
853
865
  hideColumnHeader = false;
854
866
  usePaginator = true;
855
- useVirtualScroll = undefined;
856
- includeAllInPaginatorOptions = false;
867
+ useVirtualScroll = false;
868
+ paginatorSettings = undefined;
869
+ virtualSettings = undefined;
857
870
  groupHeaderHeight = undefined;
858
871
  rowHeight;
859
872
  headerHeight = undefined;
860
873
  minColumnWidth;
861
874
  }
862
875
  class VirtualScrollOptions {
863
- virtualAsDefault = true;
864
876
  rowHeight = 48;
865
877
  enforceRowHeight = true;
866
878
  headerHeight = 56;
@@ -870,6 +882,17 @@ class VirtualScrollOptions {
870
882
  * This will win over `amountOfVisibleItems`
871
883
  */
872
884
  maxViewPortHeight = undefined;
885
+ /**
886
+ * Will try to bring the table to the bottom of the screen
887
+ * If `amountOfVisibleItems` is set that will be the minimum number of rows
888
+ * If `maxViewPortHeight` is set that will be the max table size
889
+ */
890
+ dynamicHeight = false;
891
+ }
892
+ class PaginatorOptions {
893
+ pageSize = undefined;
894
+ defaultAll = false;
895
+ includeAllInOptions = false;
873
896
  }
874
897
  const DefaultVirtualScrollOptions = {
875
898
  rowHeight: 48,
@@ -923,6 +946,11 @@ const defaultDataState = {
923
946
  },
924
947
  };
925
948
 
949
+ const ArrayDefaults = {
950
+ limit: 3,
951
+ arrayStyle: ArrayStyle.CommaDelimited
952
+ };
953
+
926
954
  // here is how to use it
927
955
  // <generic-table [report]="report">
928
956
  // <p *customCell="'column1'; let element = element" [class.makeMeRed]="element?.port">If Port, i will be red</p>
@@ -931,65 +959,51 @@ const defaultDataState = {
931
959
  class CustomCellDirective {
932
960
  templateRef = inject(TemplateRef, { optional: true });
933
961
  columnDef = inject(CdkColumnDef, { optional: true });
934
- customCell;
935
- displayName;
936
- preSort;
937
- TemplateRef;
938
- customCellOrder;
939
- customCellWidth;
940
- customCellTableRef;
962
+ $customCell = input.required({ alias: 'customCell' });
963
+ $displayName = input(undefined, { alias: 'customCellDisplayName' });
964
+ $preSort = input(undefined, { alias: 'preSort' });
965
+ $templateRef = input(this.templateRef || undefined, { alias: 'templateRef' });
966
+ $customCellOrder = input(undefined, { alias: 'customCellOrder' });
967
+ $customCellWidth = input(undefined, { alias: 'customCellWidth' });
968
+ /**
969
+ * for type safety, this is a reference to the table builder instance.
970
+ */
971
+ $customCellTableRef = input(undefined, { alias: 'customCellTableRef' });
941
972
  /**
942
973
  * true if column not mapped to a property in the data source. Default is false.
943
974
  */
944
- customCellNotMapped = false;
945
- constructor() {
946
- if (this.templateRef !== null)
947
- this.TemplateRef = this.templateRef;
948
- }
975
+ $customCellNotMapped = input(false, { alias: 'customCellNotMapped', transform: coerceBooleanProperty });
976
+ $metaData = computed(() => {
977
+ const c = this.$customCell();
978
+ if (!c)
979
+ return;
980
+ return ({
981
+ key: this.$customCell(),
982
+ displayName: this.$displayName(),
983
+ preSort: this.$preSort(),
984
+ fieldType: this.$customCellNotMapped() ? FieldType.NotMapped : FieldType.Unknown,
985
+ order: this.$customCellOrder(),
986
+ width: this.$customCellWidth(),
987
+ customCell: true,
988
+ noExport: true,
989
+ });
990
+ });
991
+ $inited = signal(false);
949
992
  ngOnInit() {
950
- this.$metaData.next(this.getMetaData());
993
+ this.$inited.set(true);
951
994
  }
952
- $metaData = new ReplaySubject();
953
- getMetaData = () => {
954
- return {
955
- key: this.customCell,
956
- displayName: this.displayName,
957
- preSort: this.preSort,
958
- fieldType: this.customCellNotMapped ? FieldType.NotMapped : FieldType.Unknown,
959
- order: this.customCellOrder,
960
- width: this.customCellWidth,
961
- customCell: true,
962
- };
963
- };
964
995
  static ngTemplateContextGuard(dir, ctx) {
965
996
  return true;
966
997
  }
967
998
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: CustomCellDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
968
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.0.0", type: CustomCellDirective, isStandalone: true, selector: "[customCell]", inputs: { customCell: "customCell", displayName: "displayName", preSort: "preSort", TemplateRef: "TemplateRef", customCellOrder: "customCellOrder", customCellWidth: "customCellWidth", customCellTableRef: "customCellTableRef", customCellNotMapped: "customCellNotMapped" }, ngImport: i0 });
999
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "19.0.0", type: CustomCellDirective, isStandalone: true, selector: "[customCell]", inputs: { $customCell: { classPropertyName: "$customCell", publicName: "customCell", isSignal: true, isRequired: true, transformFunction: null }, $displayName: { classPropertyName: "$displayName", publicName: "customCellDisplayName", isSignal: true, isRequired: false, transformFunction: null }, $preSort: { classPropertyName: "$preSort", publicName: "preSort", isSignal: true, isRequired: false, transformFunction: null }, $templateRef: { classPropertyName: "$templateRef", publicName: "templateRef", isSignal: true, isRequired: false, transformFunction: null }, $customCellOrder: { classPropertyName: "$customCellOrder", publicName: "customCellOrder", isSignal: true, isRequired: false, transformFunction: null }, $customCellWidth: { classPropertyName: "$customCellWidth", publicName: "customCellWidth", isSignal: true, isRequired: false, transformFunction: null }, $customCellTableRef: { classPropertyName: "$customCellTableRef", publicName: "customCellTableRef", isSignal: true, isRequired: false, transformFunction: null }, $customCellNotMapped: { classPropertyName: "$customCellNotMapped", publicName: "customCellNotMapped", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0 });
969
1000
  }
970
1001
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: CustomCellDirective, decorators: [{
971
1002
  type: Directive,
972
1003
  args: [{
973
1004
  selector: '[customCell]',
974
- standalone: true
975
1005
  }]
976
- }], ctorParameters: () => [], propDecorators: { customCell: [{
977
- type: Input
978
- }], displayName: [{
979
- type: Input
980
- }], preSort: [{
981
- type: Input
982
- }], TemplateRef: [{
983
- type: Input
984
- }], customCellOrder: [{
985
- type: Input
986
- }], customCellWidth: [{
987
- type: Input
988
- }], customCellTableRef: [{
989
- type: Input
990
- }], customCellNotMapped: [{
991
- type: Input
992
- }] } });
1006
+ }] });
993
1007
 
994
1008
  class ResizeColumnDirective {
995
1009
  renderer = inject(Renderer2);
@@ -1063,7 +1077,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImpor
1063
1077
  type: Directive,
1064
1078
  args: [{
1065
1079
  selector: "[resizeColumn]",
1066
- standalone: true
1067
1080
  }]
1068
1081
  }], propDecorators: { resizable: [{
1069
1082
  type: Input,
@@ -1084,7 +1097,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImpor
1084
1097
  type: Directive,
1085
1098
  args: [{
1086
1099
  selector: '[tbWrapper]',
1087
- standalone: true,
1088
1100
  }]
1089
1101
  }] });
1090
1102
 
@@ -1124,14 +1136,13 @@ const inputs = [
1124
1136
  class TableCustomFilterDirective {
1125
1137
  filterId;
1126
1138
  savable = false;
1127
- used = false;
1128
1139
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: TableCustomFilterDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
1129
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.0.0", type: TableCustomFilterDirective, isStandalone: true, selector: " ", ngImport: i0 });
1140
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.0.0", type: TableCustomFilterDirective, isStandalone: true, selector: "tb-abstract", ngImport: i0 });
1130
1141
  }
1131
1142
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: TableCustomFilterDirective, decorators: [{
1132
1143
  type: Directive,
1133
1144
  args: [{
1134
- selector: ' '
1145
+ selector: 'tb-abstract'
1135
1146
  }]
1136
1147
  }] });
1137
1148
  class TableFilterDirective {
@@ -1143,6 +1154,9 @@ class TableFilterDirective {
1143
1154
  }
1144
1155
  if (this.model) {
1145
1156
  subscriber(this.model.valueChanges, val => {
1157
+ if (this.filterType === FilterTypes.StringContains && val === '') {
1158
+ val = undefined;
1159
+ }
1146
1160
  this.filterValue = val;
1147
1161
  this.update();
1148
1162
  });
@@ -1151,7 +1165,7 @@ class TableFilterDirective {
1151
1165
  reset() {
1152
1166
  this.filterValue = undefined;
1153
1167
  }
1154
- filter$ = new Subject;
1168
+ filter$ = new ReplaySubject(1);
1155
1169
  filterType;
1156
1170
  key;
1157
1171
  fieldType;
@@ -1168,7 +1182,6 @@ class TableFilterDirective {
1168
1182
  this.filterValue = value;
1169
1183
  }
1170
1184
  }
1171
- used = false;
1172
1185
  savable = false;
1173
1186
  ready = false;
1174
1187
  _userActive = true;
@@ -1208,7 +1221,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImpor
1208
1221
  type: Directive,
1209
1222
  args: [{
1210
1223
  selector: "[tbFilter]",
1211
- standalone: true,
1212
1224
  }]
1213
1225
  }], ctorParameters: () => [], propDecorators: { filterType: [{
1214
1226
  type: Input
@@ -1259,11 +1271,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImpor
1259
1271
  'filterId: filterId',
1260
1272
  'active: active',
1261
1273
  ],
1262
- standalone: true,
1263
1274
  }]
1264
1275
  }], ctorParameters: () => [] });
1265
1276
  class TableCustomFilterDirectiveBase extends TableCustomFilterDirective {
1266
- filter$;
1277
+ filter$ = new ReplaySubject(1);
1267
1278
  filter;
1268
1279
  _predicate;
1269
1280
  set predicate(val) {
@@ -1301,7 +1312,7 @@ class TableCustomFilterDirectiveBase extends TableCustomFilterDirective {
1301
1312
  predicate: this._predicate,
1302
1313
  };
1303
1314
  this.ready = true;
1304
- this.filter$ = new BehaviorSubject(this.filter);
1315
+ this.filter$.next(this.filter);
1305
1316
  }
1306
1317
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: TableCustomFilterDirectiveBase, deps: null, target: i0.ɵɵFactoryTarget.Directive });
1307
1318
  static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.0.0", type: TableCustomFilterDirectiveBase, isStandalone: true, selector: "[tbCustomFilter]", inputs: { predicate: ["tbCustomFilter", "predicate"], active: "active" }, usesInheritance: true, ngImport: i0 });
@@ -1372,7 +1383,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImpor
1372
1383
  ...inputs
1373
1384
  ],
1374
1385
  providers: [{ provide: TableCustomFilterDirective, useExisting: MatCheckboxTbFilterDirective }],
1375
- standalone: true,
1376
1386
  }]
1377
1387
  }], ctorParameters: () => [] });
1378
1388
  class MatSlideToggleTbFilterDirective extends TbSelectedFilterDirective {
@@ -1400,7 +1410,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImpor
1400
1410
  ...inputs
1401
1411
  ],
1402
1412
  providers: [{ provide: TableCustomFilterDirective, useExisting: MatSlideToggleTbFilterDirective }],
1403
- standalone: true,
1404
1413
  }]
1405
1414
  }], ctorParameters: () => [] });
1406
1415
  // Radio button
@@ -1427,7 +1436,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImpor
1427
1436
  selector: 'mat-radio-button[tbCustomFilter]',
1428
1437
  inputs: ['predicate: tbCustomFilter'],
1429
1438
  providers: [{ provide: TableCustomFilterDirective, useExisting: MatRadioButtonTbFilterDirective }],
1430
- standalone: true,
1431
1439
  }]
1432
1440
  }], ctorParameters: () => [] });
1433
1441
  // Option (select)
@@ -1465,7 +1473,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImpor
1465
1473
  ...inputs
1466
1474
  ],
1467
1475
  providers: [{ provide: TableCustomFilterDirective, useExisting: MatOptionTbFilterDirective }],
1468
- standalone: true,
1469
1476
  }]
1470
1477
  }], ctorParameters: () => [] });
1471
1478
  // Button toggle
@@ -1494,7 +1501,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImpor
1494
1501
  ...inputs
1495
1502
  ],
1496
1503
  providers: [{ provide: TableCustomFilterDirective, useExisting: MatButtonToggleFilterDirective }],
1497
- standalone: true,
1498
1504
  }]
1499
1505
  }], ctorParameters: () => [] });
1500
1506
 
@@ -1513,9 +1519,15 @@ class PhoneNumberPipe {
1513
1519
  }
1514
1520
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: PhoneNumberPipe, decorators: [{
1515
1521
  type: Pipe,
1516
- args: [{ name: 'phone', standalone: true }]
1522
+ args: [{ name: 'phone' }]
1517
1523
  }] });
1518
1524
 
1525
+ const defaultConfig = {
1526
+ defaultTableSettings: {
1527
+ pageSize: 10
1528
+ },
1529
+ arrayDefaults: ArrayDefaults
1530
+ };
1519
1531
  const TableBuilderConfigToken = new InjectionToken('TableBuilderConfig');
1520
1532
  function provideTableBuilder(config) {
1521
1533
  return makeEnvironmentProviders([
@@ -1524,7 +1536,7 @@ function provideTableBuilder(config) {
1524
1536
  DatePipe,
1525
1537
  CurrencyPipe,
1526
1538
  PhoneNumberPipe,
1527
- { provide: TableBuilderConfigToken, useValue: config || defaultTableState }
1539
+ { provide: TableBuilderConfigToken, useValue: config || defaultConfig }
1528
1540
  ]);
1529
1541
  }
1530
1542
 
@@ -1537,8 +1549,8 @@ const isNull = (filterInfo) => {
1537
1549
  };
1538
1550
 
1539
1551
  const stringEqualFunc = (filterInfo) => {
1540
- const equelsVal = prepareForStringCompare(filterInfo.filterValue);
1541
- return ((val) => prepareForStringCompare(val) === equelsVal);
1552
+ const equalsVal = prepareForStringCompare(filterInfo.filterValue);
1553
+ return ((val) => prepareForStringCompare(val) === equalsVal);
1542
1554
  };
1543
1555
  const stringContainsFunc = (filterInfo) => {
1544
1556
  const containsVal = prepareForStringCompare(filterInfo.filterValue);
@@ -1573,7 +1585,7 @@ const EnumFilterFuncs = {
1573
1585
  [FilterTypes.IsNull]: isNull,
1574
1586
  [FilterTypes.In]: multipleStringValuesEqualsFunc,
1575
1587
  };
1576
- const prepareForStringCompare = (val) => val?.toString().trim().toLowerCase();
1588
+ const prepareForStringCompare = (val) => (val?.toString().trim().toLowerCase());
1577
1589
 
1578
1590
  const numberEqalsFunc = (filterInfo) => (val) => {
1579
1591
  return val === filterInfo.filterValue;
@@ -1670,11 +1682,11 @@ const BooleanFilterFuncs = {
1670
1682
 
1671
1683
  const filterFactoryMap = {
1672
1684
  [FilterTypes.And]: (filter) => {
1673
- const filters = filter.filterValue.map(createFilterFunc);
1685
+ const filters = createFilterFuncs(filter.filterValue);
1674
1686
  return (obj) => filters.every(f => f(obj));
1675
1687
  },
1676
1688
  [FilterTypes.In]: (filter) => {
1677
- const filters = filter.filterValue.map(createFilterFunc);
1689
+ const filters = createFilterFuncs(filter.filterValue);
1678
1690
  return (obj) => filters.some(f => f(obj));
1679
1691
  },
1680
1692
  };
@@ -1699,11 +1711,20 @@ function isFilterInfo(filter) {
1699
1711
  return filter && typeof filter.key === 'string' && filter.filterType !== FilterTypes.Custom;
1700
1712
  }
1701
1713
  const defaultPredicate = () => true;
1714
+ function createFilterFuncs(filters) {
1715
+ return filters.filter(needsFilterCreation).map(createFilterFunc);
1716
+ }
1717
+ function needsFilterCreation(filter) {
1718
+ if (isCustomFilter(filter)) {
1719
+ return filter.active !== false;
1720
+ }
1721
+ return filter.filterValue != undefined && filter.active !== false;
1722
+ }
1702
1723
  function createFilterFunc(filter) {
1703
1724
  if (isCustomFilter(filter)) {
1704
1725
  return filter.active ? filter.predicate : defaultPredicate;
1705
1726
  }
1706
- if (filter.filterValue === undefined) {
1727
+ if (filter.filterValue == undefined) {
1707
1728
  return defaultPredicate;
1708
1729
  }
1709
1730
  const func = filterTypeFuncMap[filter.fieldType][filter.filterType](filter);
@@ -1720,7 +1741,12 @@ function createFilterFunc(filter) {
1720
1741
  : func(value);
1721
1742
  };
1722
1743
  }
1723
- const FalseyValueCanBeIncludedFilterTypes = [FilterTypes.IsNull, FilterTypes.NumberNotEqual, FilterTypes.DateIsNotOn, FilterTypes.StringDoesNotContain];
1744
+ const FalseyValueCanBeIncludedFilterTypes = [
1745
+ FilterTypes.IsNull,
1746
+ FilterTypes.NumberNotEqual,
1747
+ FilterTypes.DateIsNotOn,
1748
+ FilterTypes.StringDoesNotContain,
1749
+ ];
1724
1750
 
1725
1751
  const replaceInArrayWithClone = (arr, findMeth, actionOnClone = ((t) => { })) => {
1726
1752
  const index = arr.findIndex(findMeth);
@@ -1736,9 +1762,93 @@ const replaceInArrayWithClone = (arr, findMeth, actionOnClone = ((t) => { })) =>
1736
1762
  return clonedArray;
1737
1763
  };
1738
1764
 
1739
- function stateIs(initializationState) {
1740
- return (state) => state.initializationState === initializationState;
1765
+ const orderedStateVisibleMetaData = (state) => {
1766
+ const ordered = orderStateMetaData(state);
1767
+ const orderedVisible = ordered
1768
+ .filter(metaData => !state.hiddenKeys.includes(metaData.key) && state.metaData[metaData.key].fieldType !== FieldType.Hidden);
1769
+ return orderedVisible;
1770
+ };
1771
+ const orderedCodeVisibleMetaData = (state) => orderStateMetaData(state).filter(md => md.fieldType !== FieldType.Hidden);
1772
+ const orderStateMetaData = (state) => {
1773
+ return orderMetaData(state.metaData, state.userDefined.order);
1774
+ };
1775
+ const orderMetaData = (metaData, userDefined) => {
1776
+ const userOrderArr = Object.entries(userDefined);
1777
+ return userOrderArr.length ?
1778
+ Object.values(metaData).sort((a, b) => {
1779
+ const orderA = userDefined[a.key];
1780
+ const orderB = userDefined[b.key];
1781
+ return order(orderA, orderB);
1782
+ })
1783
+ :
1784
+ Object.values(metaData).sort((a, b) => {
1785
+ const orderA = a.order;
1786
+ const orderB = b.order;
1787
+ return order(orderA, orderB);
1788
+ });
1789
+ };
1790
+ function order(orderA, orderB) {
1791
+ if (orderA == null && orderB == null) {
1792
+ return 0;
1793
+ }
1794
+ if (orderA == null) {
1795
+ return 1;
1796
+ }
1797
+ if (orderB == null) {
1798
+ return -1;
1799
+ }
1800
+ return orderA - orderB;
1801
+ }
1802
+ function cleanPersistedState(state, pState) {
1803
+ const metas = Object.values(state.metaData);
1804
+ const filters = Object.values(pState.filters).filter(fltr => isCustomFilter(fltr) || metas.some(m => m.key === fltr.key)).reduce((obj, filter) => {
1805
+ obj[filter.filterId] = pState.filters[filter.filterId];
1806
+ return obj;
1807
+ }, {});
1808
+ const sorted = pState.sorted.filter(s => metas.some(m => m.key === s.active));
1809
+ return ({ ...pState, filters, sorted });
1741
1810
  }
1811
+ const mapSaveableState = (s) => {
1812
+ const savableState = { ...s };
1813
+ keysToDelete.forEach(key => delete savableState[key]);
1814
+ return savableState;
1815
+ };
1816
+ const createPreSort = (metaDatas) => {
1817
+ return Object.values(metaDatas).filter((metaData) => !!metaData.preSort)
1818
+ .sort(({ preSort: ps1 }, { preSort: ps2 }) => (ps1.precedence || Number.MAX_VALUE) - (ps2.precedence || Number.MAX_VALUE))
1819
+ .map(({ key, preSort: { direction } }) => ({ active: key, direction }));
1820
+ };
1821
+ const mergeMeta = (orig, merge) => {
1822
+ return {
1823
+ key: orig.key,
1824
+ displayName: merge.displayName ?? orig.displayName,
1825
+ fieldType: merge.fieldType || orig.fieldType,
1826
+ additional: { ...orig.additional, ...merge.additional },
1827
+ order: merge.order ?? orig.order,
1828
+ preSort: merge.preSort ?? orig.preSort,
1829
+ width: merge.width ?? orig.width,
1830
+ noExport: merge.noExport || orig.noExport,
1831
+ noFilter: merge.noFilter || orig.noFilter,
1832
+ customCell: merge.customCell ?? orig.customCell,
1833
+ transform: merge.transform ?? orig.transform,
1834
+ map: merge.map ?? orig.map,
1835
+ click: merge.click ?? orig.click,
1836
+ classes: merge.classes ?? orig.classes,
1837
+ noSort: merge.noSort ?? orig.noSort,
1838
+ template: merge.template ?? orig.template,
1839
+ toolTip: merge.toolTip ?? orig.toolTip,
1840
+ useIcon: merge.useIcon ?? orig.useIcon,
1841
+ };
1842
+ };
1843
+ const initializeOrder = (state, mds) => {
1844
+ const viewableMetaDataArr = Object.values(mds).filter(a => a.fieldType !== FieldType.Hidden);
1845
+ let userDefinedOrder = state.userDefined.order;
1846
+ if (viewableMetaDataArr.some(meta => userDefinedOrder[meta.key] == null)) {
1847
+ return {};
1848
+ }
1849
+ return userDefinedOrder;
1850
+ };
1851
+
1742
1852
  class TableStore extends ComponentStore {
1743
1853
  constructor() {
1744
1854
  const config = inject(TableBuilderConfigToken);
@@ -1747,45 +1857,136 @@ class TableStore extends ComponentStore {
1747
1857
  notPersistedTableSettings: new NotPersistedTableSettings().merge(config.defaultTableSettings),
1748
1858
  };
1749
1859
  if (config.defaultTableSettings?.pageSize) {
1750
- settingsFromConfig['pageSize'] = config.defaultTableSettings?.pageSize;
1860
+ settingsFromConfig.notPersistedTableSettings.paginatorSettings.pageSize = config.defaultTableSettings?.pageSize;
1751
1861
  }
1752
- super({ ...defaultTableState, ...settingsFromConfig });
1753
- }
1754
- selectStateReady = this.select(state => state.initializationState).pipe(filter(i => i === InitializationState.Ready));
1755
- getSavableState() {
1756
- return this.state$.pipe(debounceTime(300), map(s => {
1757
- return this.mapSaveableState(s);
1758
- }));
1862
+ const pageSize = settingsFromConfig.notPersistedTableSettings.paginatorSettings.pageSize || defaultTableState.pageSize;
1863
+ const showAll = settingsFromConfig.notPersistedTableSettings.paginatorSettings.defaultAll || defaultTableState.showAll;
1864
+ super({ ...defaultTableState, ...settingsFromConfig, pageSize, showAll });
1759
1865
  }
1760
- getSavableStateSignal = computed(() => {
1866
+ $initializationState = this.selectSignal(state => state.initializationState);
1867
+ $savableState = computed(() => {
1761
1868
  const state = this.state();
1762
- return this.mapSaveableState(state);
1869
+ return mapSaveableState(state);
1763
1870
  });
1764
- mapSaveableState = (s) => {
1765
- const savableState = { ...s };
1766
- keysToDelete.forEach(key => delete savableState[key]);
1767
- return savableState;
1768
- };
1769
- on = (srcObservable, func) => {
1770
- this.effect(() => srcObservable.pipe(tap(func)));
1771
- return this;
1772
- };
1871
+ $userDefinedOrder = this.selectSignal(state => state.userDefined.order);
1773
1872
  metaData$ = this.select(state => state.metaData);
1774
1873
  $metaData = this.selectSignal(state => state.metaData);
1775
- $userDefinedOrder = this.selectSignal(state => state.userDefined.order);
1776
- $hiddenKeys = this.selectSignal(state => state.hiddenKeys);
1777
1874
  $metaDataArray = this.selectSignal(this.$metaData, this.$userDefinedOrder, orderMetaData);
1778
- getMetaData$ = (key) => {
1779
- return this.select(state => state.metaData[key]).pipe(tap(meta => { if (!meta)
1780
- console.warn(`Meta data with key ${key} not found`); }), notNull());
1781
- };
1782
- $getUserDefinedWidth = (key) => this.selectSignal(state => state.userDefined.widths[key]);
1875
+ $orderedCodeVisibleMetaDatas = this.selectSignal(this.$metaDataArray, (mds) => mds.filter(m => m.fieldType !== FieldType.Hidden), { equal: (a, b) => b.length === a.length && b.every((s, i) => a[i].key === s.key) });
1876
+ $getMetaData = (key) => computed(() => {
1877
+ const metaData = this.state().metaData[key];
1878
+ if (!metaData)
1879
+ console.warn(`Meta data with key ${key} not found`);
1880
+ return metaData;
1881
+ });
1882
+ $hiddenKeys = this.selectSignal(state => state.hiddenKeys);
1883
+ $orderedVisibleColumns = this.selectSignal(this.$orderedCodeVisibleMetaDatas, this.$hiddenKeys, (cs, hiddenKeys) => cs.filter(m => !hiddenKeys.includes(m.key)).map(m => m.key));
1783
1884
  $getUserDefinedWidths = this.selectSignal(state => state.userDefined.widths);
1784
- tableSettingsMinWidth = this.selectSignal(state => state.notPersistedTableSettings.minColumnWidth);
1885
+ $tableSettingsMinWidth = this.selectSignal(state => state.notPersistedTableSettings.minColumnWidth);
1886
+ $getUserDefinedWidth = (key) => this.selectSignal(this.$getUserDefinedWidths, widths => widths[key]);
1887
+ $filters = this.selectSignal(state => state.filters);
1888
+ filters$ = this.select(state => state.filters);
1889
+ $getFilter = (filterId) => {
1890
+ return this.selectSignal(this.$filters, filters => filters[filterId]);
1891
+ };
1892
+ $selectSorted = this.selectSignal(state => state.sorted, {
1893
+ equal: sortsAreSame
1894
+ });
1895
+ selectSorted$ = this.select(state => state.sorted).pipe(distinctUntilChanged(sortsAreSame));
1896
+ sort$ = this.select(state => state.initializationState).pipe(filter(i => i === InitializationState.Ready))
1897
+ .pipe(switchMap(() => this.selectSorted$));
1898
+ $getUserDefinedTableWidth = this.selectSignal(state => state.userDefined.table.width);
1899
+ getUserDefinedTableWidth$ = this.select(state => state.userDefined.table.width);
1900
+ $footerCollapsed = this.selectSignal(state => state.persistedTableSettings.collapseFooter);
1901
+ $headerCollapsed = this.selectSignal(state => state.persistedTableSettings.collapseHeader);
1902
+ $groupBy = this.selectSignal(state => state.groupBy);
1903
+ $groupByKeys = this.selectSignal(this.$groupBy, gb => gb.map(gbk => gbk.key), {
1904
+ equal: (prev, curr) => prev.length === curr.length && curr.every((k, i) => prev[i] === k)
1905
+ });
1906
+ groupByKeys$ = this.select(state => state.groupBy.map(gbk => gbk.key))
1907
+ .pipe(distinctUntilChanged((prev, curr) => prev.length === curr.length && curr.every((k, i) => prev[i] === k)));
1908
+ expandedGroups$ = this.select(state => state.groupBy).pipe(distinctUntilChanged((a, b) => {
1909
+ const aa = a.flatMap(g => g.expandedHeaders);
1910
+ const bb = b.flatMap(g => g.expandedHeaders);
1911
+ return aa.length === bb.length && aa.every((k) => bb.includes(k));
1912
+ }));
1913
+ $getIsExpanded = (columnKey, groupHeaderKey) => {
1914
+ return this.selectSignal(state => !!state.groupBy.filter(g => g.key === columnKey && g.expandedHeaders.includes(groupHeaderKey)).length);
1915
+ };
1916
+ $currentPage = this.selectSignal(state => state.currentPage);
1917
+ $pageSize = this.selectSignal(s => s.userDefined?.pageSize || s.pageSize);
1918
+ $showAll = this.selectSignal(s => s.userDefined?.showAll ?? s.showAll);
1919
+ $tableSettings = this.selectSignal(state => {
1920
+ const ts = { ...state.persistedTableSettings, ...state.notPersistedTableSettings };
1921
+ return ts;
1922
+ });
1923
+ tableSettings$ = toObservable(this.$tableSettings);
1924
+ $props = this.selectSignal(s => s.props);
1925
+ $getLinkInfo = (md) => this.selectSignal(state => state.linkMaps[md.key]);
1926
+ $isVirtual = this.selectSignal(state => state.notPersistedTableSettings.useVirtualScroll
1927
+ || state.showAll
1928
+ || state.userDefined?.showAll);
1929
+ $viewType = this.selectSignal(state => {
1930
+ const usePaginator = state.notPersistedTableSettings.usePaginator;
1931
+ const showAll = state.showAll;
1932
+ const useVirtualScroll = state.notPersistedTableSettings.useVirtualScroll;
1933
+ if (showAll || (useVirtualScroll && !usePaginator)) {
1934
+ return 'virtual all';
1935
+ }
1936
+ else if (useVirtualScroll && usePaginator) {
1937
+ return 'virtual paginator';
1938
+ }
1939
+ else if (usePaginator) {
1940
+ return 'paginator';
1941
+ }
1942
+ else {
1943
+ return 'all';
1944
+ }
1945
+ });
1785
1946
  resetState = this.updater((state) => {
1786
- const sorted = this.createPreSort(state.metaData);
1947
+ const sorted = createPreSort(state.metaData);
1787
1948
  return ({ ...state, hiddenKeys: [], sorted, filters: {}, groupBy: [], userDefined: { widths: {}, order: {}, table: {} } });
1788
1949
  });
1950
+ updateStateFromPersistedState = this.updater((state, persistedState) => {
1951
+ const incomingTableState = cleanPersistedState(state, persistedState);
1952
+ const newState = this.updateStateFunc(state, incomingTableState);
1953
+ newState.initializationState = state.initializationState === InitializationState.MetaDataLoaded ? InitializationState.LoadedFromStore : state.initializationState;
1954
+ return newState;
1955
+ });
1956
+ updateStateFunc = (state, incomingTableState) => {
1957
+ const metaData = state.metaData;
1958
+ const sorted = incomingTableState.sorted?.length ? incomingTableState.sorted
1959
+ : state.initializationState === InitializationState.Created ? createPreSort(metaData) : state.sorted;
1960
+ return { ...state, ...incomingTableState, metaData, sorted };
1961
+ };
1962
+ setTableSettings = this.updater((state, settings) => {
1963
+ const s = {
1964
+ ...state,
1965
+ persistedTableSettings: state.persistedTableSettings.merge(settings),
1966
+ notPersistedTableSettings: state.notPersistedTableSettings.merge(settings),
1967
+ initializationState: InitializationState.Ready
1968
+ };
1969
+ s.pageSize = settings.tableSettings?.paginatorSettings?.pageSize ?? s.pageSize;
1970
+ s.showAll = settings.tableSettings?.paginatorSettings?.defaultAll ?? s.showAll;
1971
+ return s;
1972
+ });
1973
+ setMetaData = this.updater((state, md) => {
1974
+ const metaData = md
1975
+ .reduce((prev, curr) => {
1976
+ if (prev[curr.key]) {
1977
+ prev[curr.key] = mergeMeta(prev[curr.key], curr);
1978
+ }
1979
+ else {
1980
+ prev[curr.key] = curr;
1981
+ }
1982
+ return prev;
1983
+ }, {});
1984
+ const sortedInitialized = state.sorted.length > 0;
1985
+ const sorted = sortedInitialized ? state.sorted : createPreSort(metaData);
1986
+ const order = initializeOrder(state, metaData);
1987
+ const initializationState = state.initializationState == InitializationState.Created ? InitializationState.MetaDataLoaded : state.initializationState;
1988
+ return { ...state, initializationState, metaData, sorted, userDefined: { ...state.userDefined, order: order } };
1989
+ });
1789
1990
  showColumn = this.updater((state, key) => ({
1790
1991
  ...state,
1791
1992
  hiddenKeys: state.hiddenKeys.filter(k => k !== key),
@@ -1814,17 +2015,23 @@ class TableStore extends ComponentStore {
1814
2015
  }, {});
1815
2016
  return ({ ...state, userDefined: { ...state.userDefined, order: userDefinedOrder } });
1816
2017
  });
1817
- $filters = this.selectSignal(state => state.filters);
1818
- filters$ = this.select(state => state.filters);
1819
- getFilter$ = (filterId) => {
1820
- return this.select(state => state.filters[filterId]);
1821
- };
1822
2018
  addFilter = this.updater((state, filter) => {
1823
2019
  return this.addFiltersToState(state, [filter]);
1824
2020
  });
1825
2021
  addFilters = this.updater((state, filters) => {
1826
2022
  return this.addFiltersToState(state, filters);
1827
2023
  });
2024
+ removeFilter = this.updater((state, filterId) => {
2025
+ const filtersCopy = { ...state.filters };
2026
+ delete filtersCopy[filterId];
2027
+ return ({ ...state, filters: filtersCopy });
2028
+ });
2029
+ removeFilters = this.updater((state, filterIds) => {
2030
+ const filtersCopy = { ...state.filters };
2031
+ filterIds.forEach(id => { delete filtersCopy[id]; });
2032
+ return ({ ...state, filters: filtersCopy });
2033
+ });
2034
+ clearFilters = this.updater((state) => ({ ...state, filters: {} }));
1828
2035
  addFiltersToState = (state, filters) => {
1829
2036
  var customFilters = filters.filter(isCustomFilter);
1830
2037
  var filterInfos = filters.filter(isFilterInfo);
@@ -1848,24 +2055,6 @@ class TableStore extends ComponentStore {
1848
2055
  filters: { ...state.filters, ...filtersObj }
1849
2056
  };
1850
2057
  };
1851
- removeFilter = this.updater((state, filterId) => {
1852
- const filtersCopy = { ...state.filters };
1853
- delete filtersCopy[filterId];
1854
- return ({ ...state, filters: filtersCopy });
1855
- });
1856
- removeFilters = this.updater((state, filterIds) => {
1857
- const filtersCopy = { ...state.filters };
1858
- filterIds.forEach(id => { delete filtersCopy[id]; });
1859
- return ({ ...state, filters: filtersCopy });
1860
- });
1861
- clearFilters = this.updater((state) => ({ ...state, filters: {} }));
1862
- selectSorted = this.select(state => state.sorted).pipe(distinctUntilChanged((f, s) => !isDifferent(f, s)));
1863
- sort$ = this.select(this.selectStateReady, this.selectSorted, (_, s) => s);
1864
- createPreSort = (metaDatas) => {
1865
- return Object.values(metaDatas).filter((metaData) => !!metaData.preSort)
1866
- .sort(({ preSort: ps1 }, { preSort: ps2 }) => (ps1.precedence || Number.MAX_VALUE) - (ps2.precedence || Number.MAX_VALUE))
1867
- .map(({ key, preSort: { direction } }) => ({ active: key, direction }));
1868
- };
1869
2058
  setSort = this.updater((state, { key, direction }) => {
1870
2059
  const sortArray = state.sorted.filter(s => s.active !== key);
1871
2060
  if (direction) {
@@ -1882,85 +2071,17 @@ class TableStore extends ComponentStore {
1882
2071
  sorted: sortArray,
1883
2072
  };
1884
2073
  });
1885
- updateStateFunc = (state, incomingTableState) => {
1886
- const metaData = state.metaData;
1887
- const sorted = incomingTableState.sorted?.length ? incomingTableState.sorted
1888
- : state.initializationState === InitializationState.Created ? this.createPreSort(metaData) : state.sorted;
1889
- return { ...state, ...incomingTableState, metaData, sorted };
1890
- };
1891
- setPageSize = this.updater((state, pageSize) => ({ ...state, pageSize, userDefined: { ...state.userDefined, pageSize } }));
1892
- getPageSize = this.select(state => state.userDefined.pageSize || state.pageSize);
1893
- updateState = this.updater(this.updateStateFunc);
1894
- updateStateFromPersistedState = this.updater((state, persistedState) => {
1895
- const incomingTableState = cleanPersistedState(state, persistedState);
1896
- const newState = this.updateStateFunc(state, incomingTableState);
1897
- newState.initializationState = state.initializationState === InitializationState.MetaDataLoaded ? InitializationState.LoadedFromStore : state.initializationState;
1898
- return newState;
2074
+ setCurrentPage = this.updater((state, currentPage) => ({ ...state, currentPage }));
2075
+ setPageSize = this.updater((state, pageSize) => ({ ...state, pageSize }));
2076
+ setUserDefinedPageSize = this.updater((state, pageSize) => ({ ...state, userDefined: { ...state.userDefined, pageSize } }));
2077
+ setUserDefinedShowAll = this.updater((state, showAll) => ({ ...state, showAll, userDefined: { ...state.userDefined, showAll } }));
2078
+ setProps = this.updater((state, props) => {
2079
+ return ({ ...state, props });
1899
2080
  });
1900
- getUserDefinedTableSize = this.selectSignal(state => state.userDefined.table.width);
1901
- getUserDefinedTableSize$ = this.select(state => state.userDefined.table.width);
1902
2081
  setTableWidth = this.updater((state, widthInPixels) => ({ ...state, userDefined: { ...state.userDefined, table: { width: widthInPixels } } }));
1903
- mergeMeta = (orig, merge) => {
1904
- return {
1905
- key: orig.key,
1906
- displayName: merge.displayName ?? orig.displayName,
1907
- fieldType: merge.fieldType || orig.fieldType,
1908
- additional: { ...orig.additional, ...merge.additional },
1909
- order: merge.order ?? orig.order,
1910
- preSort: merge.preSort ?? orig.preSort,
1911
- width: merge.width ?? orig.width,
1912
- noExport: merge.noExport || orig.noExport,
1913
- noFilter: merge.noFilter || orig.noFilter,
1914
- customCell: merge.customCell ?? orig.customCell,
1915
- transform: merge.transform ?? orig.transform,
1916
- map: merge.map ?? orig.map,
1917
- click: merge.click ?? orig.click,
1918
- classes: merge.classes ?? orig.classes,
1919
- noSort: merge.noSort ?? orig.noSort,
1920
- template: merge.template ?? orig.template,
1921
- toolTip: merge.toolTip ?? orig.toolTip,
1922
- useIcon: merge.useIcon ?? orig.useIcon,
1923
- };
1924
- };
1925
2082
  setInitializationState = this.updater((state, initializationState) => {
1926
2083
  return { ...state, initializationState };
1927
2084
  });
1928
- runOnceWhen(predicate, func) {
1929
- const obs = this.state$.pipe(onceWhen(predicate));
1930
- this.on(obs, (state) => {
1931
- func(state);
1932
- });
1933
- }
1934
- onReady(func) {
1935
- this.runOnceWhen(stateIs(InitializationState.Ready), func);
1936
- }
1937
- setMetaData = this.updater((state, md) => {
1938
- const metaData = md
1939
- .reduce((prev, curr) => {
1940
- if (prev[curr.key]) {
1941
- prev[curr.key] = this.mergeMeta(prev[curr.key], curr);
1942
- }
1943
- else {
1944
- prev[curr.key] = curr;
1945
- }
1946
- return prev;
1947
- }, {});
1948
- let sorted = state.sorted;
1949
- if (sorted.length === 0) {
1950
- sorted = this.createPreSort(metaData);
1951
- }
1952
- const order = this.initializeOrder(state, metaData);
1953
- const initializationState = state.initializationState == InitializationState.Created ? InitializationState.MetaDataLoaded : state.initializationState;
1954
- return { ...state, initializationState, metaData, sorted, userDefined: { ...state.userDefined, order: order } };
1955
- });
1956
- initializeOrder = (state, mds) => {
1957
- const viewableMetaDataArr = Object.values(mds).filter(a => a.fieldType !== FieldType.Hidden);
1958
- let userDefinedOrder = state.userDefined.order;
1959
- if (viewableMetaDataArr.some(meta => userDefinedOrder[meta.key] == null)) {
1960
- return {};
1961
- }
1962
- return userDefinedOrder;
1963
- };
1964
2085
  toggleCollapseHeader = this.updater((state) => {
1965
2086
  const tableSettings = { ...state.persistedTableSettings };
1966
2087
  tableSettings.collapseHeader = !tableSettings.collapseHeader;
@@ -1971,8 +2092,6 @@ class TableStore extends ComponentStore {
1971
2092
  tableSettings.collapseFooter = !tableSettings.collapseFooter;
1972
2093
  return ({ ...state, persistedTableSettings: new PersistedTableSettings(tableSettings) });
1973
2094
  });
1974
- $collapseFooter = this.selectSignal(state => state.persistedTableSettings.collapseFooter);
1975
- $collapseHeader = this.selectSignal(state => state.persistedTableSettings.collapseHeader);
1976
2095
  addGroupByKey = this.updater((state, metaDataKey) => ({
1977
2096
  ...state,
1978
2097
  groupBy: [...state.groupBy, { key: metaDataKey, expandedHeaders: [] }]
@@ -2008,106 +2127,19 @@ class TableStore extends ComponentStore {
2008
2127
  expandedHeaders: data.keys.includes(gb.key) ? [] : gb.expandedHeaders
2009
2128
  }))
2010
2129
  }));
2011
- groupByKeys$ = this.select(state => state.groupBy.map(gbk => gbk.key))
2012
- .pipe(distinctUntilChanged((prev, curr) => prev.length === curr.length && curr.every((k, i) => prev[i] === k)));
2013
- expandedGroups$ = this.select(state => state.groupBy).pipe(distinctUntilChanged((a, b) => {
2014
- const aa = a.flatMap(g => g.expandedHeaders);
2015
- const bb = b.flatMap(g => g.expandedHeaders);
2016
- return aa.length === bb.length && aa.every((k) => bb.includes(k));
2017
- }));
2018
- setTableSettings = this.updater((state, settings) => {
2019
- const s = {
2020
- ...state,
2021
- persistedTableSettings: state.persistedTableSettings.merge(settings),
2022
- notPersistedTableSettings: state.notPersistedTableSettings.merge(settings)
2023
- };
2024
- return s;
2025
- });
2026
- tableSettings = this.selectSignal(state => {
2027
- const ts = { ...state.persistedTableSettings, ...state.notPersistedTableSettings };
2028
- return ts;
2029
- });
2030
- tableSettings$ = toObservable(this.tableSettings);
2031
- props = this.selectSignal(s => s.props);
2032
2130
  setLinkMaps = this.updater((state, maps) => {
2033
- return { ...state, linkMaps: maps };
2131
+ return ({ ...state, linkMaps: maps });
2034
2132
  });
2035
- getLinkInfo = (md) => this.selectSignal(state => state.linkMaps[md.key]);
2036
- getIsExpanded = (columnKey, groupHeaderKey) => {
2037
- return this.selectSignal(state => !!state.groupBy.filter(g => g.key === columnKey && g.expandedHeaders.includes(groupHeaderKey)).length);
2133
+ on = (srcObservable, func) => {
2134
+ this.effect(() => srcObservable.pipe(tap(func)));
2135
+ return this;
2038
2136
  };
2039
- $isVirtual = this.selectSignal(state => state.notPersistedTableSettings.useVirtualScroll === true || state.notPersistedTableSettings.useVirtualScroll?.virtualAsDefault || state.showAll);
2040
- $viewType = this.selectSignal(state => {
2041
- const usePaginator = state.notPersistedTableSettings.usePaginator;
2042
- if (state.showAll || (this.$isVirtual() && !usePaginator)) {
2043
- return 'virtual all';
2044
- }
2045
- else if (this.$isVirtual() && usePaginator) {
2046
- return 'virtual paginator';
2047
- }
2048
- else if (usePaginator) {
2049
- return 'paginator';
2050
- }
2051
- else {
2052
- return 'all';
2053
- }
2054
- });
2055
- $orderedCodeVisibleMetaDatas = this.selectSignal(this.$metaDataArray, (mds) => mds.filter(m => m.fieldType !== FieldType.Hidden), { equal: (a, b) => b.length === a.length && b.every((s, i) => a[i].key === s.key) });
2056
- $orderedVisibleColumns = this.selectSignal(this.$orderedCodeVisibleMetaDatas, this.$hiddenKeys, (cs, hiddenKeys) => cs.filter(m => !hiddenKeys.includes(m.key)).map(m => m.key));
2057
- $currentPage = this.selectSignal(state => state.currentPage);
2058
- $pageSize = this.selectSignal(s => s.userDefined?.pageSize || s.pageSize);
2059
2137
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: TableStore, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
2060
2138
  static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: TableStore });
2061
2139
  }
2062
2140
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: TableStore, decorators: [{
2063
2141
  type: Injectable
2064
2142
  }], ctorParameters: () => [] });
2065
- const orderedStateVisibleMetaData = (state) => {
2066
- const ordered = orderStateMetaData(state);
2067
- const orderedVisible = ordered
2068
- .filter(metaData => !state.hiddenKeys.includes(metaData.key) && state.metaData[metaData.key].fieldType !== FieldType.Hidden);
2069
- return orderedVisible;
2070
- };
2071
- const orderedCodeVisibleMetaData = (state) => orderStateMetaData(state).filter(md => md.fieldType !== FieldType.Hidden);
2072
- const orderStateMetaData = (state) => {
2073
- return orderMetaData(state.metaData, state.userDefined.order);
2074
- };
2075
- const orderMetaData = (metaData, userDefined) => {
2076
- const userOrderArr = Object.entries(userDefined);
2077
- return userOrderArr.length ?
2078
- Object.values(metaData).sort((a, b) => {
2079
- const orderA = userDefined[a.key];
2080
- const orderB = userDefined[b.key];
2081
- return order(orderA, orderB);
2082
- })
2083
- :
2084
- Object.values(metaData).sort((a, b) => {
2085
- const orderA = a.order;
2086
- const orderB = b.order;
2087
- return order(orderA, orderB);
2088
- });
2089
- };
2090
- function order(orderA, orderB) {
2091
- if (orderA == null && orderB == null) {
2092
- return 0;
2093
- }
2094
- if (orderA == null) {
2095
- return 1;
2096
- }
2097
- if (orderB == null) {
2098
- return -1;
2099
- }
2100
- return orderA - orderB;
2101
- }
2102
- function cleanPersistedState(state, pState) {
2103
- const metas = Object.values(state.metaData);
2104
- const filters = Object.values(pState.filters).filter(fltr => isCustomFilter(fltr) || metas.some(m => m.key === fltr.key)).reduce((obj, filter) => {
2105
- obj[filter.filterId] = pState.filters[filter.filterId];
2106
- return obj;
2107
- }, {});
2108
- const sorted = pState.sorted.filter(s => metas.some(m => m.key === s.active));
2109
- return ({ ...pState, filters, sorted });
2110
- }
2111
2143
 
2112
2144
  class MultiSortDirective extends MatSort {
2113
2145
  state = inject(TableStore);
@@ -2139,21 +2171,38 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImpor
2139
2171
  providers: [
2140
2172
  { provide: MatSort, useExisting: MultiSortDirective }
2141
2173
  ],
2142
- standalone: true
2143
2174
  }]
2144
2175
  }], ctorParameters: () => [] });
2145
- function isDifferent(a, b) {
2176
+ function sortsAreSame(a, b) {
2146
2177
  if (a.length !== b.length) {
2147
- return true;
2178
+ return false;
2148
2179
  }
2149
2180
  for (let i = 0; i < a.length; i++) {
2150
2181
  if (a[i].active !== b[i].active || a[i].direction !== b[i].direction) {
2151
- return true;
2182
+ return false;
2152
2183
  }
2153
2184
  }
2154
- return false;
2185
+ return true;
2155
2186
  }
2156
2187
 
2188
+ class DateFilterComponent {
2189
+ FilterType = FilterTypes;
2190
+ info;
2191
+ CurrentFilterType;
2192
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: DateFilterComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
2193
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.0", type: DateFilterComponent, isStandalone: true, selector: "tb-date-filter", inputs: { info: "info", CurrentFilterType: "CurrentFilterType" }, ngImport: i0, template: "@if (CurrentFilterType !== FilterType.DateBetween && CurrentFilterType !== FilterType.IsNull) {\r\n <mat-form-field>\r\n <input matInput name=\"filterValue\" [ngModel]=\"info.filterValue\" [matDatepicker]=\"cal\"/>\r\n <mat-datepicker-toggle class=\"small-button date-toggle\" matSuffix [for]=\"cal\" preventEnter />\r\n <mat-datepicker #cal />\r\n </mat-form-field>\r\n}\r\n@if(CurrentFilterType === FilterType.DateBetween){\r\n <ng-container ngModelGroup=\"filterValue\">\r\n <mat-form-field class=\"my-filter\" >\r\n <input matInput name=\"Start\" [ngModel]=\"info.filterValue?.Start\" placeholder=\"From\" [matDatepicker]=\"fromVal\"\r\n (click)=\"fromVal.open()\"/>\r\n <mat-datepicker-toggle matSuffix class=\"small-button date-toggle\" [for]=\"fromVal\" preventEnter />\r\n <mat-datepicker #fromVal></mat-datepicker>\r\n </mat-form-field>\r\n <mat-form-field>\r\n <input matInput name=\"End\" [ngModel]=\"info.filterValue?.End\" placeholder=\"To\" [matDatepicker]=\"toVal\" (click)=\"toVal.open()\"/>\r\n <mat-datepicker-toggle matSuffix class=\"small-button date-toggle\" [for]=\"toVal\" preventEnter />\r\n <mat-datepicker #toVal />\r\n </mat-form-field>\r\n </ng-container>\r\n}\r\n\r\n", styles: [".filter-name{color:#6495ed;margin:10px 0;font-weight:600;display:inline-block}.switch{display:inline-block}.head-row{display:flex;width:100%;align-items:center;justify-content:space-between}.filter-row{display:flex;align-items:center;gap:1rem}mat-card.filter-card::ng-deep mat-form-field{width:150px}mat-card.filter-card::ng-deep .mat-mdc-form-field-subscript-wrapper{line-height:0}mat-card.filter-card::ng-deep .mat-mdc-form-field-subscript-wrapper:before{height:0}.inline{display:inline-block}.small-button{height:18px;width:18px;font-size:18px;padding:0;margin:0}.small-button ::ng-deep *{line-height:initial;font-size:initial;height:18px;width:18px;font-size:18px;bottom:initial}.cancel-button{font-weight:700}.date-toggle ::ng-deep svg{position:absolute;left:0;top:0}\n"], dependencies: [{ kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i1$1.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "component", type: i6.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i6.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i3.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: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i3.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i3.NgModelGroup, selector: "[ngModelGroup]", inputs: ["ngModelGroup"], exportAs: ["ngModelGroup"] }, { kind: "ngmodule", type: MatDatepickerModule }, { kind: "component", type: i4.MatDatepicker, selector: "mat-datepicker", exportAs: ["matDatepicker"] }, { kind: "directive", type: i4.MatDatepickerInput, selector: "input[matDatepicker]", inputs: ["matDatepicker", "min", "max", "matDatepickerFilter"], exportAs: ["matDatepickerInput"] }, { kind: "component", type: i4.MatDatepickerToggle, selector: "mat-datepicker-toggle", inputs: ["for", "tabIndex", "aria-label", "disabled", "disableRipple"], exportAs: ["matDatepickerToggle"] }], viewProviders: [{ provide: ControlContainer, useExisting: NgForm }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
2194
+ }
2195
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: DateFilterComponent, decorators: [{
2196
+ type: Component,
2197
+ args: [{ selector: 'tb-date-filter', changeDetection: ChangeDetectionStrategy.OnPush, viewProviders: [{ provide: ControlContainer, useExisting: NgForm }], imports: [
2198
+ MatInputModule, FormsModule, MatDatepickerModule
2199
+ ], template: "@if (CurrentFilterType !== FilterType.DateBetween && CurrentFilterType !== FilterType.IsNull) {\r\n <mat-form-field>\r\n <input matInput name=\"filterValue\" [ngModel]=\"info.filterValue\" [matDatepicker]=\"cal\"/>\r\n <mat-datepicker-toggle class=\"small-button date-toggle\" matSuffix [for]=\"cal\" preventEnter />\r\n <mat-datepicker #cal />\r\n </mat-form-field>\r\n}\r\n@if(CurrentFilterType === FilterType.DateBetween){\r\n <ng-container ngModelGroup=\"filterValue\">\r\n <mat-form-field class=\"my-filter\" >\r\n <input matInput name=\"Start\" [ngModel]=\"info.filterValue?.Start\" placeholder=\"From\" [matDatepicker]=\"fromVal\"\r\n (click)=\"fromVal.open()\"/>\r\n <mat-datepicker-toggle matSuffix class=\"small-button date-toggle\" [for]=\"fromVal\" preventEnter />\r\n <mat-datepicker #fromVal></mat-datepicker>\r\n </mat-form-field>\r\n <mat-form-field>\r\n <input matInput name=\"End\" [ngModel]=\"info.filterValue?.End\" placeholder=\"To\" [matDatepicker]=\"toVal\" (click)=\"toVal.open()\"/>\r\n <mat-datepicker-toggle matSuffix class=\"small-button date-toggle\" [for]=\"toVal\" preventEnter />\r\n <mat-datepicker #toVal />\r\n </mat-form-field>\r\n </ng-container>\r\n}\r\n\r\n", styles: [".filter-name{color:#6495ed;margin:10px 0;font-weight:600;display:inline-block}.switch{display:inline-block}.head-row{display:flex;width:100%;align-items:center;justify-content:space-between}.filter-row{display:flex;align-items:center;gap:1rem}mat-card.filter-card::ng-deep mat-form-field{width:150px}mat-card.filter-card::ng-deep .mat-mdc-form-field-subscript-wrapper{line-height:0}mat-card.filter-card::ng-deep .mat-mdc-form-field-subscript-wrapper:before{height:0}.inline{display:inline-block}.small-button{height:18px;width:18px;font-size:18px;padding:0;margin:0}.small-button ::ng-deep *{line-height:initial;font-size:initial;height:18px;width:18px;font-size:18px;bottom:initial}.cancel-button{font-weight:700}.date-toggle ::ng-deep svg{position:absolute;left:0;top:0}\n"] }]
2200
+ }], propDecorators: { info: [{
2201
+ type: Input
2202
+ }], CurrentFilterType: [{
2203
+ type: Input
2204
+ }] } });
2205
+
2157
2206
  class PreventEnterDirective {
2158
2207
  onKeyDown() {
2159
2208
  return false;
@@ -2165,7 +2214,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImpor
2165
2214
  type: Directive,
2166
2215
  args: [{
2167
2216
  selector: 'preventEnter',
2168
- standalone: true
2169
2217
  }]
2170
2218
  }], propDecorators: { onKeyDown: [{
2171
2219
  type: HostListener,
@@ -2186,7 +2234,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImpor
2186
2234
  type: Directive,
2187
2235
  args: [{
2188
2236
  selector: "[stop-propagation]",
2189
- standalone: true
2190
2237
  }]
2191
2238
  }], propDecorators: { onClick: [{
2192
2239
  type: HostListener,
@@ -2213,7 +2260,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImpor
2213
2260
  type: Directive,
2214
2261
  args: [{
2215
2262
  selector: '[autoFocus]',
2216
- standalone: true,
2217
2263
  }]
2218
2264
  }], propDecorators: { autoFocus: [{
2219
2265
  type: Input
@@ -2238,7 +2284,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImpor
2238
2284
  host: {
2239
2285
  '(click)': 'next(this._val)'
2240
2286
  },
2241
- standalone: true,
2242
2287
  }]
2243
2288
  }], ctorParameters: () => [], propDecorators: { clickSubject: [{
2244
2289
  type: Input,
@@ -2260,7 +2305,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImpor
2260
2305
  host: {
2261
2306
  '(click)': 'next(true)'
2262
2307
  },
2263
- standalone: true,
2264
2308
  }]
2265
2309
  }], ctorParameters: () => [] });
2266
2310
 
@@ -2311,7 +2355,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImpor
2311
2355
  args: [{
2312
2356
  selector: 'dialog-wrapper',
2313
2357
  template: ``,
2314
- standalone: true,
2315
2358
  changeDetection: ChangeDetectionStrategy.OnPush,
2316
2359
  }]
2317
2360
  }] });
@@ -2406,7 +2449,7 @@ class DialogDirective {
2406
2449
  }
2407
2450
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: DialogDirective, decorators: [{
2408
2451
  type: Directive,
2409
- args: [{ selector: '[opDialog]', standalone: true }]
2452
+ args: [{ selector: '[opDialog]', }]
2410
2453
  }], propDecorators: { opDialogClosed: [{
2411
2454
  type: Output
2412
2455
  }], opDialogAddDialogClass: [{
@@ -2452,7 +2495,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImpor
2452
2495
  type: Directive,
2453
2496
  args: [{
2454
2497
  selector: '[styler]',
2455
- standalone: true
2456
2498
  }]
2457
2499
  }], propDecorators: { element: [{
2458
2500
  type: Input
@@ -2504,7 +2546,6 @@ class MatSlideToggleGroupDirective {
2504
2546
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: MatSlideToggleGroupDirective, decorators: [{
2505
2547
  type: Directive,
2506
2548
  args: [{ selector: '[opMatSlideToggleGroup]',
2507
- standalone: true
2508
2549
  }]
2509
2550
  }], propDecorators: { allowMultiple: [{
2510
2551
  type: Input
@@ -2534,7 +2575,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImpor
2534
2575
  type: Directive,
2535
2576
  args: [{
2536
2577
  selector: 'input[trimWhitespace]',
2537
- standalone: true
2538
2578
  }]
2539
2579
  }], propDecorators: { onBlur: [{
2540
2580
  type: HostListener,
@@ -2557,7 +2597,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImpor
2557
2597
  type: Pipe,
2558
2598
  args: [{
2559
2599
  name: 'func',
2560
- standalone: true
2561
2600
  }]
2562
2601
  }] });
2563
2602
 
@@ -2586,7 +2625,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImpor
2586
2625
  type: Directive,
2587
2626
  args: [{
2588
2627
  selector: '[conditionalClasses]',
2589
- standalone: true
2590
2628
  }]
2591
2629
  }], propDecorators: { element: [{
2592
2630
  type: Input
@@ -2669,28 +2707,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImpor
2669
2707
  }]
2670
2708
  }] });
2671
2709
 
2672
- class DateFilterComponent {
2673
- FilterType = FilterTypes;
2674
- info;
2675
- CurrentFilterType;
2676
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: DateFilterComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
2677
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.0", type: DateFilterComponent, isStandalone: true, selector: "tb-date-filter", inputs: { info: "info", CurrentFilterType: "CurrentFilterType" }, ngImport: i0, template: "@if (CurrentFilterType !== FilterType.DateBetween && CurrentFilterType !== FilterType.IsNull) {\r\n <mat-form-field>\r\n <input matInput name=\"filterValue\" [ngModel]=\"info.filterValue\" [matDatepicker]=\"cal\"/>\r\n <mat-datepicker-toggle class=\"small-button date-toggle\" matSuffix [for]=\"cal\" preventEnter />\r\n <mat-datepicker #cal />\r\n </mat-form-field>\r\n}\r\n@if(CurrentFilterType === FilterType.DateBetween){\r\n <ng-container ngModelGroup=\"filterValue\">\r\n <mat-form-field class=\"my-filter\" >\r\n <input matInput name=\"Start\" [ngModel]=\"info.filterValue?.Start\" placeholder=\"From\" [matDatepicker]=\"fromVal\"\r\n (click)=\"fromVal.open()\"/>\r\n <mat-datepicker-toggle matSuffix class=\"small-button date-toggle\" [for]=\"fromVal\" preventEnter />\r\n <mat-datepicker #fromVal></mat-datepicker>\r\n </mat-form-field>\r\n <mat-form-field>\r\n <input matInput name=\"End\" [ngModel]=\"info.filterValue?.End\" placeholder=\"To\" [matDatepicker]=\"toVal\" (click)=\"toVal.open()\"/>\r\n <mat-datepicker-toggle matSuffix class=\"small-button date-toggle\" [for]=\"toVal\" preventEnter />\r\n <mat-datepicker #toVal />\r\n </mat-form-field>\r\n </ng-container>\r\n}\r\n\r\n", styles: [".filter-name{color:#6495ed;margin:10px 0;font-weight:600;display:inline-block}.switch{display:inline-block}.head-row{display:flex;width:100%;align-items:center;justify-content:space-between}.filter-row{display:flex;align-items:center;gap:1rem}mat-card.filter-card::ng-deep mat-form-field{width:150px}mat-card.filter-card::ng-deep .mat-mdc-form-field-subscript-wrapper{line-height:0}mat-card.filter-card::ng-deep .mat-mdc-form-field-subscript-wrapper:before{height:0}.inline{display:inline-block}.small-button{height:18px;width:18px;font-size:18px;padding:0;margin:0}.small-button ::ng-deep *{line-height:initial;font-size:initial;height:18px;width:18px;font-size:18px;bottom:initial}.cancel-button{font-weight:700}.date-toggle ::ng-deep svg{position:absolute;left:0;top:0}\n"], dependencies: [{ kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i1$1.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "component", type: i6.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i6.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i3.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: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i3.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i3.NgModelGroup, selector: "[ngModelGroup]", inputs: ["ngModelGroup"], exportAs: ["ngModelGroup"] }, { kind: "ngmodule", type: MatDatepickerModule }, { kind: "component", type: i4.MatDatepicker, selector: "mat-datepicker", exportAs: ["matDatepicker"] }, { kind: "directive", type: i4.MatDatepickerInput, selector: "input[matDatepicker]", inputs: ["matDatepicker", "min", "max", "matDatepickerFilter"], exportAs: ["matDatepickerInput"] }, { kind: "component", type: i4.MatDatepickerToggle, selector: "mat-datepicker-toggle", inputs: ["for", "tabIndex", "aria-label", "disabled", "disableRipple"], exportAs: ["matDatepickerToggle"] }], viewProviders: [{ provide: ControlContainer, useExisting: NgForm }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
2678
- }
2679
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: DateFilterComponent, decorators: [{
2680
- type: Component,
2681
- args: [{ selector: 'tb-date-filter', changeDetection: ChangeDetectionStrategy.OnPush, viewProviders: [{ provide: ControlContainer, useExisting: NgForm }], standalone: true, imports: [
2682
- MatInputModule, FormsModule, MatDatepickerModule, PreventEnterDirective
2683
- ], template: "@if (CurrentFilterType !== FilterType.DateBetween && CurrentFilterType !== FilterType.IsNull) {\r\n <mat-form-field>\r\n <input matInput name=\"filterValue\" [ngModel]=\"info.filterValue\" [matDatepicker]=\"cal\"/>\r\n <mat-datepicker-toggle class=\"small-button date-toggle\" matSuffix [for]=\"cal\" preventEnter />\r\n <mat-datepicker #cal />\r\n </mat-form-field>\r\n}\r\n@if(CurrentFilterType === FilterType.DateBetween){\r\n <ng-container ngModelGroup=\"filterValue\">\r\n <mat-form-field class=\"my-filter\" >\r\n <input matInput name=\"Start\" [ngModel]=\"info.filterValue?.Start\" placeholder=\"From\" [matDatepicker]=\"fromVal\"\r\n (click)=\"fromVal.open()\"/>\r\n <mat-datepicker-toggle matSuffix class=\"small-button date-toggle\" [for]=\"fromVal\" preventEnter />\r\n <mat-datepicker #fromVal></mat-datepicker>\r\n </mat-form-field>\r\n <mat-form-field>\r\n <input matInput name=\"End\" [ngModel]=\"info.filterValue?.End\" placeholder=\"To\" [matDatepicker]=\"toVal\" (click)=\"toVal.open()\"/>\r\n <mat-datepicker-toggle matSuffix class=\"small-button date-toggle\" [for]=\"toVal\" preventEnter />\r\n <mat-datepicker #toVal />\r\n </mat-form-field>\r\n </ng-container>\r\n}\r\n\r\n", styles: [".filter-name{color:#6495ed;margin:10px 0;font-weight:600;display:inline-block}.switch{display:inline-block}.head-row{display:flex;width:100%;align-items:center;justify-content:space-between}.filter-row{display:flex;align-items:center;gap:1rem}mat-card.filter-card::ng-deep mat-form-field{width:150px}mat-card.filter-card::ng-deep .mat-mdc-form-field-subscript-wrapper{line-height:0}mat-card.filter-card::ng-deep .mat-mdc-form-field-subscript-wrapper:before{height:0}.inline{display:inline-block}.small-button{height:18px;width:18px;font-size:18px;padding:0;margin:0}.small-button ::ng-deep *{line-height:initial;font-size:initial;height:18px;width:18px;font-size:18px;bottom:initial}.cancel-button{font-weight:700}.date-toggle ::ng-deep svg{position:absolute;left:0;top:0}\n"] }]
2684
- }], propDecorators: { info: [{
2685
- type: Input
2686
- }], CurrentFilterType: [{
2687
- type: Input
2688
- }] } });
2689
-
2690
2710
  class InFilterComponent {
2691
2711
  ref = inject(ChangeDetectorRef);
2692
2712
  FieldType = FieldType;
2693
- type;
2713
+ $type = input.required({ alias: 'type' });
2694
2714
  value = [undefined];
2695
2715
  constructor() {
2696
2716
  this.value = [undefined];
@@ -2727,11 +2747,11 @@ class InFilterComponent {
2727
2747
  this.onChange(this.value);
2728
2748
  }
2729
2749
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: InFilterComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
2730
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.0", type: InFilterComponent, isStandalone: true, selector: "lib-in-filter", inputs: { type: "type" }, providers: [{
2750
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.0", type: InFilterComponent, isStandalone: true, selector: "lib-in-filter", inputs: { $type: { classPropertyName: "$type", publicName: "type", isSignal: true, isRequired: true, transformFunction: null } }, providers: [{
2731
2751
  provide: NG_VALUE_ACCESSOR,
2732
2752
  useExisting: InFilterComponent,
2733
2753
  multi: true
2734
- }], ngImport: i0, template: "<div class=inline>\r\n @for (val of value; track $index) {\r\n <div>\r\n @if(type === FieldType.Number || type === FieldType.Currency){\r\n <input [ngModel]=\"val\" (ngModelChange)=\"onValueChange($index, $event)\"\r\n [readonly]=\"$index + 1 < value.length\" type=\"number\" [ngModelOptions]=\"{standalone:true}\" [autoFocus]=\"$index === value.length - 1\"/>\r\n }\r\n @else {\r\n <input [ngModel]=\"val\" (ngModelChange)=\"onValueChange($index ,$event)\"\r\n [readonly]=\"$index + 1 < value.length\" type=\"string\" [ngModelOptions]=\"{standalone:true}\"\r\n #input [autoFocus]=\"$index === value.length - 1\" />\r\n }\r\n </div>\r\n <button [disabled]=\"value.length <= 1\" (click)=\"removeInput($index)\">-</button>\r\n @if ($index === value.length - 1) {\r\n <button [disabled]=\"val == undefined || val === ''\" (click)=\"addInput()\">+</button>\r\n }\r\n \r\n }\r\n</div>\r\n", styles: [".inline{display:inline-block}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i3.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: i3.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: AutoFocusDirective, selector: "[autoFocus]", inputs: ["autoFocus"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
2754
+ }], ngImport: i0, template: "<div class=inline>\r\n @for (val of value; track $index) {\r\n <div>\r\n @if($type() === FieldType.Number || $type() === FieldType.Currency){\r\n <input [ngModel]=\"val\" (ngModelChange)=\"onValueChange($index, $event)\"\r\n [readonly]=\"$index + 1 < value.length\" type=\"number\" [ngModelOptions]=\"{standalone:true}\" [autoFocus]=\"$index === value.length - 1\"/>\r\n }\r\n @else {\r\n <input [ngModel]=\"val\" (ngModelChange)=\"onValueChange($index ,$event)\"\r\n [readonly]=\"$index + 1 < value.length\" type=\"string\" [ngModelOptions]=\"{standalone:true}\"\r\n #input [autoFocus]=\"$index === value.length - 1\" />\r\n }\r\n </div>\r\n <button [disabled]=\"value.length <= 1\" (click)=\"removeInput($index)\">-</button>\r\n @if ($index === value.length - 1) {\r\n <button [disabled]=\"val == undefined || val === ''\" (click)=\"addInput()\">+</button>\r\n }\r\n }\r\n</div>\r\n", styles: [".inline{display:inline-block}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i3.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: i3.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: AutoFocusDirective, selector: "[autoFocus]", inputs: ["autoFocus"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
2735
2755
  }
2736
2756
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: InFilterComponent, decorators: [{
2737
2757
  type: Component,
@@ -2739,31 +2759,25 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImpor
2739
2759
  provide: NG_VALUE_ACCESSOR,
2740
2760
  useExisting: InFilterComponent,
2741
2761
  multi: true
2742
- }], standalone: true, imports: [
2762
+ }], imports: [
2743
2763
  FormsModule, AutoFocusDirective
2744
- ], template: "<div class=inline>\r\n @for (val of value; track $index) {\r\n <div>\r\n @if(type === FieldType.Number || type === FieldType.Currency){\r\n <input [ngModel]=\"val\" (ngModelChange)=\"onValueChange($index, $event)\"\r\n [readonly]=\"$index + 1 < value.length\" type=\"number\" [ngModelOptions]=\"{standalone:true}\" [autoFocus]=\"$index === value.length - 1\"/>\r\n }\r\n @else {\r\n <input [ngModel]=\"val\" (ngModelChange)=\"onValueChange($index ,$event)\"\r\n [readonly]=\"$index + 1 < value.length\" type=\"string\" [ngModelOptions]=\"{standalone:true}\"\r\n #input [autoFocus]=\"$index === value.length - 1\" />\r\n }\r\n </div>\r\n <button [disabled]=\"value.length <= 1\" (click)=\"removeInput($index)\">-</button>\r\n @if ($index === value.length - 1) {\r\n <button [disabled]=\"val == undefined || val === ''\" (click)=\"addInput()\">+</button>\r\n }\r\n \r\n }\r\n</div>\r\n", styles: [".inline{display:inline-block}\n"] }]
2745
- }], ctorParameters: () => [], propDecorators: { type: [{
2746
- type: Input
2747
- }] } });
2764
+ ], template: "<div class=inline>\r\n @for (val of value; track $index) {\r\n <div>\r\n @if($type() === FieldType.Number || $type() === FieldType.Currency){\r\n <input [ngModel]=\"val\" (ngModelChange)=\"onValueChange($index, $event)\"\r\n [readonly]=\"$index + 1 < value.length\" type=\"number\" [ngModelOptions]=\"{standalone:true}\" [autoFocus]=\"$index === value.length - 1\"/>\r\n }\r\n @else {\r\n <input [ngModel]=\"val\" (ngModelChange)=\"onValueChange($index ,$event)\"\r\n [readonly]=\"$index + 1 < value.length\" type=\"string\" [ngModelOptions]=\"{standalone:true}\"\r\n #input [autoFocus]=\"$index === value.length - 1\" />\r\n }\r\n </div>\r\n <button [disabled]=\"value.length <= 1\" (click)=\"removeInput($index)\">-</button>\r\n @if ($index === value.length - 1) {\r\n <button [disabled]=\"val == undefined || val === ''\" (click)=\"addInput()\">+</button>\r\n }\r\n }\r\n</div>\r\n", styles: [".inline{display:inline-block}\n"] }]
2765
+ }], ctorParameters: () => [] });
2748
2766
 
2749
2767
  class NumberFilterComponent {
2750
2768
  FilterType = FilterTypes;
2751
2769
  FieldType = FieldType;
2752
- CurrentFilterType;
2753
- info;
2770
+ $currentFilterType = input.required({ alias: 'CurrentFilterType' });
2771
+ $info = input.required({ alias: 'info' });
2754
2772
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: NumberFilterComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
2755
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.0", type: NumberFilterComponent, isStandalone: true, selector: "tb-number-filter", inputs: { CurrentFilterType: "CurrentFilterType", info: "info" }, ngImport: i0, template: "@if(CurrentFilterType !== FilterType.NumberBetween && CurrentFilterType !== FilterType.IsNull && CurrentFilterType !== FilterType.In){\r\n <mat-form-field class=\"my-filter\">\r\n <input matInput name=\"filterValue\" [ngModel]=\"info.filterValue\" type=\"number\"/>\r\n </mat-form-field>\r\n}\r\n@if(CurrentFilterType === FilterType.NumberBetween){\r\n <ng-container ngModelGroup=\"filterValue\" >\r\n <mat-form-field class=\"my-filter\">\r\n <input matInput name=\"Start\" [ngModel]=\"info.filterValue?.Start\" placeholder=\"Start\" type=\"number\"/>\r\n </mat-form-field>\r\n <mat-form-field class=\"my-filter\">\r\n <input matInput name=\"End\" [ngModel]=\"info.filterValue?.End\" placeholder=\"End\" type=\"number\"/>\r\n </mat-form-field>\r\n </ng-container>\r\n}\r\n\r\n@if (CurrentFilterType === FilterType.In) {\r\n <lib-in-filter name='filterValue' [type]=\"FieldType.Number\" [(ngModel)]='info.filterValue' />\r\n}\r\n", styles: [".switch{display:inline-block}.my-filter{margin-right:15px}.inline{display:inline-block}\n"], dependencies: [{ kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i1$1.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "component", type: i6.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i3.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: i3.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i3.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i3.NgModelGroup, selector: "[ngModelGroup]", inputs: ["ngModelGroup"], exportAs: ["ngModelGroup"] }, { kind: "component", type: InFilterComponent, selector: "lib-in-filter", inputs: ["type"] }], viewProviders: [{ provide: ControlContainer, useExisting: NgForm }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
2773
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.0", type: NumberFilterComponent, isStandalone: true, selector: "tb-number-filter", inputs: { $currentFilterType: { classPropertyName: "$currentFilterType", publicName: "CurrentFilterType", isSignal: true, isRequired: true, transformFunction: null }, $info: { classPropertyName: "$info", publicName: "info", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: "@let CurrentFilterType = $currentFilterType();\r\n@let info = $info();\r\n\r\n@if(CurrentFilterType !== FilterType.NumberBetween && CurrentFilterType !== FilterType.IsNull && CurrentFilterType !== FilterType.In){\r\n <mat-form-field class=\"my-filter\">\r\n <input matInput name=\"filterValue\" [ngModel]=\"info.filterValue\" type=\"number\"/>\r\n </mat-form-field>\r\n}\r\n@if(CurrentFilterType === FilterType.NumberBetween){\r\n <ng-container ngModelGroup=\"filterValue\" >\r\n <mat-form-field class=\"my-filter\">\r\n <input matInput name=\"Start\" [ngModel]=\"info.filterValue?.Start\" placeholder=\"Start\" type=\"number\"/>\r\n </mat-form-field>\r\n <mat-form-field class=\"my-filter\">\r\n <input matInput name=\"End\" [ngModel]=\"info.filterValue?.End\" placeholder=\"End\" type=\"number\"/>\r\n </mat-form-field>\r\n </ng-container>\r\n}\r\n\r\n@if (CurrentFilterType === FilterType.In) {\r\n <lib-in-filter name='filterValue' [type]=\"FieldType.Number\" [(ngModel)]='info.filterValue' />\r\n}\r\n", styles: [".switch{display:inline-block}.my-filter{margin-right:15px}.inline{display:inline-block}\n"], dependencies: [{ kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i1$1.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "component", type: i6.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i3.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: i3.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i3.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i3.NgModelGroup, selector: "[ngModelGroup]", inputs: ["ngModelGroup"], exportAs: ["ngModelGroup"] }, { kind: "component", type: InFilterComponent, selector: "lib-in-filter", inputs: ["type"] }], viewProviders: [{ provide: ControlContainer, useExisting: NgForm }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
2756
2774
  }
2757
2775
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: NumberFilterComponent, decorators: [{
2758
2776
  type: Component,
2759
- args: [{ selector: 'tb-number-filter', changeDetection: ChangeDetectionStrategy.OnPush, viewProviders: [{ provide: ControlContainer, useExisting: NgForm }], standalone: true, imports: [
2777
+ args: [{ selector: 'tb-number-filter', changeDetection: ChangeDetectionStrategy.OnPush, viewProviders: [{ provide: ControlContainer, useExisting: NgForm }], imports: [
2760
2778
  MatInputModule, FormsModule, InFilterComponent
2761
- ], template: "@if(CurrentFilterType !== FilterType.NumberBetween && CurrentFilterType !== FilterType.IsNull && CurrentFilterType !== FilterType.In){\r\n <mat-form-field class=\"my-filter\">\r\n <input matInput name=\"filterValue\" [ngModel]=\"info.filterValue\" type=\"number\"/>\r\n </mat-form-field>\r\n}\r\n@if(CurrentFilterType === FilterType.NumberBetween){\r\n <ng-container ngModelGroup=\"filterValue\" >\r\n <mat-form-field class=\"my-filter\">\r\n <input matInput name=\"Start\" [ngModel]=\"info.filterValue?.Start\" placeholder=\"Start\" type=\"number\"/>\r\n </mat-form-field>\r\n <mat-form-field class=\"my-filter\">\r\n <input matInput name=\"End\" [ngModel]=\"info.filterValue?.End\" placeholder=\"End\" type=\"number\"/>\r\n </mat-form-field>\r\n </ng-container>\r\n}\r\n\r\n@if (CurrentFilterType === FilterType.In) {\r\n <lib-in-filter name='filterValue' [type]=\"FieldType.Number\" [(ngModel)]='info.filterValue' />\r\n}\r\n", styles: [".switch{display:inline-block}.my-filter{margin-right:15px}.inline{display:inline-block}\n"] }]
2762
- }], propDecorators: { CurrentFilterType: [{
2763
- type: Input
2764
- }], info: [{
2765
- type: Input
2766
- }] } });
2779
+ ], template: "@let CurrentFilterType = $currentFilterType();\r\n@let info = $info();\r\n\r\n@if(CurrentFilterType !== FilterType.NumberBetween && CurrentFilterType !== FilterType.IsNull && CurrentFilterType !== FilterType.In){\r\n <mat-form-field class=\"my-filter\">\r\n <input matInput name=\"filterValue\" [ngModel]=\"info.filterValue\" type=\"number\"/>\r\n </mat-form-field>\r\n}\r\n@if(CurrentFilterType === FilterType.NumberBetween){\r\n <ng-container ngModelGroup=\"filterValue\" >\r\n <mat-form-field class=\"my-filter\">\r\n <input matInput name=\"Start\" [ngModel]=\"info.filterValue?.Start\" placeholder=\"Start\" type=\"number\"/>\r\n </mat-form-field>\r\n <mat-form-field class=\"my-filter\">\r\n <input matInput name=\"End\" [ngModel]=\"info.filterValue?.End\" placeholder=\"End\" type=\"number\"/>\r\n </mat-form-field>\r\n </ng-container>\r\n}\r\n\r\n@if (CurrentFilterType === FilterType.In) {\r\n <lib-in-filter name='filterValue' [type]=\"FieldType.Number\" [(ngModel)]='info.filterValue' />\r\n}\r\n", styles: [".switch{display:inline-block}.my-filter{margin-right:15px}.inline{display:inline-block}\n"] }]
2780
+ }] });
2767
2781
 
2768
2782
  class DateTimeFilterComponent {
2769
2783
  FilterType = FilterTypes;
@@ -2774,8 +2788,8 @@ class DateTimeFilterComponent {
2774
2788
  }
2775
2789
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: DateTimeFilterComponent, decorators: [{
2776
2790
  type: Component,
2777
- args: [{ selector: 'tb-date-time-filter', changeDetection: ChangeDetectionStrategy.OnPush, viewProviders: [{ provide: ControlContainer, useExisting: NgForm }], standalone: true, imports: [
2778
- FormsModule, PreventEnterDirective
2791
+ args: [{ selector: 'tb-date-time-filter', changeDetection: ChangeDetectionStrategy.OnPush, viewProviders: [{ provide: ControlContainer, useExisting: NgForm }], imports: [
2792
+ FormsModule
2779
2793
  ], template: "@if(CurrentFilterType !== FilterType.DateTimeBetween && CurrentFilterType !== FilterType.IsNull){\r\n <input type=\"datetime-local\" [ngModel]=\"info.filterValue\" preventEnter name=\"filterValue\" class=\"op-date-time-input\"/>\r\n}\r\n@if(CurrentFilterType === FilterType.DateTimeBetween){\r\n <ng-container ngModelGroup=\"filterValue\">\r\n <input type=\"datetime-local\" [ngModel]=\"info.filterValue?.Start\" preventEnter name=\"Start\" class=\"op-date-time-input\"/>\r\n <input type=\"datetime-local\" [ngModel]=\"info.filterValue?.End\" preventEnter name=\"End\" class=\"op-date-time-input\"/>\r\n </ng-container>\r\n}", styles: [".filter-name{color:#6495ed;margin:10px 0;font-weight:600;display:inline-block}.switch{display:inline-block}.head-row{display:flex;width:100%;align-items:center;justify-content:space-between}.filter-row{display:flex;align-items:center;gap:1rem}mat-card.filter-card::ng-deep mat-form-field{width:150px}mat-card.filter-card::ng-deep .mat-mdc-form-field-subscript-wrapper{line-height:0}mat-card.filter-card::ng-deep .mat-mdc-form-field-subscript-wrapper:before{height:0}.inline{display:inline-block}.small-button{height:18px;width:18px;font-size:18px;padding:0;margin:0}.small-button ::ng-deep *{line-height:initial;font-size:initial;height:18px;width:18px;font-size:18px;bottom:initial}.cancel-button{font-weight:700}.date-toggle ::ng-deep svg{position:absolute;left:0;top:0}\n"] }]
2780
2794
  }], propDecorators: { info: [{
2781
2795
  type: Input
@@ -2791,7 +2805,7 @@ class InListFilterComponent {
2791
2805
  writeValue(obj) {
2792
2806
  this.value = obj;
2793
2807
  if (this.value) {
2794
- this.selectedKeys = this.value.map(f => f);
2808
+ this.$selectedKeys.set(this.value.map(f => f));
2795
2809
  }
2796
2810
  this.ref.markForCheck();
2797
2811
  }
@@ -2803,58 +2817,56 @@ class InListFilterComponent {
2803
2817
  registerOnTouched(fn) {
2804
2818
  this.onTouched = fn;
2805
2819
  }
2806
- key;
2807
- keyValues$;
2808
- selectedKeys = [];
2809
- metaData;
2810
- ngOnInit() {
2811
- this.keyValues$ = this.tableState.getMetaData$(this.key).pipe(tap(metaData => this.metaData = metaData), map(metaData => {
2812
- if (metaData.additional?.filterOptions?.filterableValues) {
2813
- return metaData.additional.filterOptions.filterableValues.reduce((prev, cur) => { prev[cur] = cur; return prev; }, {});
2814
- }
2815
- else {
2816
- if (metaData.fieldType === FieldType.Enum) {
2817
- return metaData.additional.enumMap;
2818
- }
2820
+ $key = input.required({ alias: 'key' });
2821
+ $selectedKeys = signal([]);
2822
+ $metaData = computed(() => this.tableState.$getMetaData(this.$key())());
2823
+ $keyValues = computed(() => {
2824
+ const metaData = this.$metaData();
2825
+ if (metaData?.additional?.filterOptions?.filterableValues) {
2826
+ return metaData.additional.filterOptions.filterableValues.reduce((prev, cur) => { prev[cur] = cur; return prev; }, {});
2827
+ }
2828
+ else {
2829
+ if (metaData?.fieldType === FieldType.Enum) {
2830
+ return metaData.additional.enumMap;
2819
2831
  }
2820
- return {};
2821
- }));
2822
- }
2832
+ }
2833
+ return {};
2834
+ });
2823
2835
  selectFilterChanged($event, val) {
2824
2836
  if ($event.checked) {
2825
- this.selectedKeys = [...this.selectedKeys, val];
2837
+ this.$selectedKeys.update(keys => [...keys, val]);
2826
2838
  }
2827
2839
  else {
2828
- this.selectedKeys = this.selectedKeys.filter(item => item !== val);
2840
+ this.$selectedKeys.update(keys => keys.filter(item => item !== val));
2829
2841
  }
2830
- this.value = this.selectedKeys;
2842
+ this.value = this.$selectedKeys();
2831
2843
  this.onChange(this.value);
2832
2844
  }
2833
2845
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: InListFilterComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
2834
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.0", type: InListFilterComponent, isStandalone: true, selector: "tb-in-list-filter , [tb-in-list-filter]", inputs: { key: "key" }, providers: [{
2846
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.0", type: InListFilterComponent, isStandalone: true, selector: "tb-in-list-filter , [tb-in-list-filter]", inputs: { $key: { classPropertyName: "$key", publicName: "key", isSignal: true, isRequired: true, transformFunction: null } }, providers: [{
2835
2847
  provide: NG_VALUE_ACCESSOR,
2836
2848
  useExisting: InListFilterComponent,
2837
2849
  multi: true
2838
2850
  }], ngImport: i0, template: `
2839
- @for (item of keyValues$ | async| keyvalue; track item.key) {
2851
+ @for (item of $keyValues() | keyvalue; track item.key) {
2840
2852
  <div>
2841
- <mat-checkbox [checked]='selectedKeys.includes(item.key)' stop-propagation (change)='selectFilterChanged($event, item.key)' >
2842
- {{metaData.fieldType === FieldType.Enum ? (item.value | spaceCase) : item.value}}
2853
+ <mat-checkbox [checked]="'includes' | func : $selectedKeys() : item.key" stop-propagation (change)='selectFilterChanged($event, item.key)' >
2854
+ {{$metaData().fieldType === FieldType.Enum ? (item.value | spaceCase) : item.value}}
2843
2855
  </mat-checkbox>
2844
2856
  </div>
2845
2857
  }
2846
2858
 
2847
- `, isInline: true, dependencies: [{ kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "pipe", type: KeyValuePipe, name: "keyvalue" }, { kind: "ngmodule", type: MatCheckboxModule }, { kind: "component", type: i1$2.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: "directive", type: StopPropagationDirective, selector: "[stop-propagation]" }, { kind: "pipe", type: SpaceCasePipe, name: "spaceCase" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
2859
+ `, isInline: true, dependencies: [{ kind: "pipe", type: KeyValuePipe, name: "keyvalue" }, { kind: "ngmodule", type: MatCheckboxModule }, { kind: "component", type: i1$2.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: "directive", type: StopPropagationDirective, selector: "[stop-propagation]" }, { kind: "pipe", type: SpaceCasePipe, name: "spaceCase" }, { kind: "pipe", type: FunctionPipe, name: "func" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
2848
2860
  }
2849
2861
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: InListFilterComponent, decorators: [{
2850
2862
  type: Component,
2851
2863
  args: [{
2852
2864
  selector: 'tb-in-list-filter , [tb-in-list-filter]',
2853
2865
  template: `
2854
- @for (item of keyValues$ | async| keyvalue; track item.key) {
2866
+ @for (item of $keyValues() | keyvalue; track item.key) {
2855
2867
  <div>
2856
- <mat-checkbox [checked]='selectedKeys.includes(item.key)' stop-propagation (change)='selectFilterChanged($event, item.key)' >
2857
- {{metaData.fieldType === FieldType.Enum ? (item.value | spaceCase) : item.value}}
2868
+ <mat-checkbox [checked]="'includes' | func : $selectedKeys() : item.key" stop-propagation (change)='selectFilterChanged($event, item.key)' >
2869
+ {{$metaData().fieldType === FieldType.Enum ? (item.value | spaceCase) : item.value}}
2858
2870
  </mat-checkbox>
2859
2871
  </div>
2860
2872
  }
@@ -2866,14 +2878,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImpor
2866
2878
  useExisting: InListFilterComponent,
2867
2879
  multi: true
2868
2880
  }],
2869
- standalone: true,
2870
2881
  imports: [
2871
- AsyncPipe, KeyValuePipe, MatCheckboxModule, StopPropagationDirective, SpaceCasePipe
2882
+ KeyValuePipe, MatCheckboxModule, StopPropagationDirective, SpaceCasePipe, FunctionPipe
2872
2883
  ]
2873
2884
  }]
2874
- }], propDecorators: { key: [{
2875
- type: Input
2876
- }] } });
2885
+ }] });
2877
2886
 
2878
2887
  class FilterComponent {
2879
2888
  state = inject(TableStore);
@@ -2900,7 +2909,7 @@ class FilterComponent {
2900
2909
  }
2901
2910
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: FilterComponent, decorators: [{
2902
2911
  type: Component,
2903
- args: [{ selector: 'tb-filter', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [
2912
+ args: [{ selector: 'tb-filter', changeDetection: ChangeDetectionStrategy.OnPush, imports: [
2904
2913
  MatCardModule, FormsModule, SpaceCasePipe, MatButtonModule, MatTooltipModule, MatIconModule,
2905
2914
  MatInputModule, MatSelectModule, NumberFilterComponent,
2906
2915
  DateFilterComponent, DateTimeFilterComponent, MatRadioModule, InFilterComponent, InListFilterComponent,
@@ -2934,8 +2943,8 @@ class GenColDisplayerComponent {
2934
2943
  }
2935
2944
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: GenColDisplayerComponent, decorators: [{
2936
2945
  type: Component,
2937
- args: [{ selector: 'tb-col-displayer', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [
2938
- AsyncPipe, MatTooltipModule, MatIconModule, MatButtonModule, MatMenuModule, StopPropagationDirective,
2946
+ args: [{ selector: 'tb-col-displayer', changeDetection: ChangeDetectionStrategy.OnPush, imports: [
2947
+ MatTooltipModule, MatIconModule, MatButtonModule, MatMenuModule, StopPropagationDirective,
2939
2948
  DragDropModule, SpaceCasePipe
2940
2949
  ], template: "@if($columns(); as displayCols){\r\n <span matTooltip=\"Show/hide columns\">\r\n <button mat-icon-button [matMenuTriggerFor]=\"menu\">\r\n <mat-icon color=\"primary\">visibility_off</mat-icon>\r\n </button>\r\n </span>\r\n <mat-menu #menu=\"matMenu\" class=\"my-mat-menu\">\r\n\r\n <button mat-menu-item>\r\n <span matTooltip=\"Close\">\r\n <button class=\"filter-button\" mat-icon-button>\r\n <mat-icon>close</mat-icon>\r\n </button>\r\n </span>\r\n </button>\r\n\r\n <button mat-menu-item stop-propagation>\r\n <span matTooltip=\"Show all columns\">\r\n <button mat-icon-button (click)=\"reset(displayCols)\">\r\n <mat-icon color=\"primary\">done_all</mat-icon>\r\n </button>\r\n </span>\r\n\r\n <span matTooltip=\"Hide all columns\">\r\n <button mat-icon-button (click)=\"unset(displayCols)\">\r\n <mat-icon color=\"primary\">cancel</mat-icon>\r\n </button>\r\n </span>\r\n </button>\r\n\r\n <div cdkDropList (cdkDropListDropped)=\"drop($event)\" stop-propagation [cdkDropListLockAxis]=\"'y'\">\r\n @for (col of displayCols; track col.key) {\r\n <button [class.isHidden]=\"!col.isVisible\" stop-propagation mat-menu-item cdkDrag [cdkDragData]=\"col\">\r\n <div (click)=\"col.isVisible = !col.isVisible; emit(displayCols)\" style=\"display: flex; align-items: center;\">\r\n @if(col.isVisible){\r\n <button mat-icon-button matTooltip=\"Hide Column\" class=\"show-hide\">\r\n <mat-icon color=\"primary\">check_box</mat-icon>\r\n </button>\r\n } @else {\r\n <button mat-icon-button matTooltip=\"Show Column\" class=\"show-hide\">\r\n <mat-icon>indeterminate_check_box</mat-icon>\r\n </button>\r\n }\r\n \r\n <p class=\"label\">\r\n {{col.displayName || (col.key | spaceCase) }}\r\n </p>\r\n\r\n </div>\r\n </button>\r\n }\r\n\r\n </div>\r\n </mat-menu>\r\n}", styles: [".show-hide{margin-right:15px;height:24px;width:24px;padding:4px}.label{color:#6495ed;text-overflow:ellipsis;overflow:hidden;white-space:nowrap;text-align:left;margin:0;font-size:17px;font-weight:700;display:inline-block;width:66%}.row{margin:0;padding:0}.isHidden{background-color:#d3d3d3;color:#a9a9a9;font-weight:700;font-size:17px;white-space:nowrap}.filter-button{margin-top:10px}.cdk-drag-preview{box-sizing:border-box;border-radius:4px;box-shadow:0 5px 5px -3px #0003,0 8px 10px 1px #00000024,0 3px 14px 2px #0000001f}.cdk-drag-placeholder{opacity:0}.cdk-drag-animating{transition:transform .25s cubic-bezier(0,0,.2,1)}.mdc-list-item__primary-text{display:inline-block;width:100%}\n"] }]
2941
2950
  }] });
@@ -2950,7 +2959,7 @@ class WrapperFilterStore extends ComponentStore {
2950
2959
  arr.splice(index, 1);
2951
2960
  return { filterInfo: arr };
2952
2961
  });
2953
- currentFilters$ = this.state$.pipe(map(state => state.filterInfo));
2962
+ $currentFilters = this.selectSignal(state => state.filterInfo);
2954
2963
  addFilter = this.updater((state, filter) => {
2955
2964
  return ({ ...state, filterInfo: [...state.filterInfo, filter] });
2956
2965
  });
@@ -2976,7 +2985,7 @@ class GenFilterDisplayerComponent {
2976
2985
  }
2977
2986
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: GenFilterDisplayerComponent, decorators: [{
2978
2987
  type: Component,
2979
- args: [{ selector: 'tb-filter-displayer', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [
2988
+ args: [{ selector: 'tb-filter-displayer', changeDetection: ChangeDetectionStrategy.OnPush, imports: [
2980
2989
  MatButtonModule, MatMenuModule, MatTooltipModule, StopPropagationDirective, MatIconModule,
2981
2990
  SpaceCasePipe
2982
2991
  ], template: "<button stop-propagation class=\"filter-button\" mat-icon-button [matMenuTriggerFor]=\"menu\" [matTooltip]=\"'Add Filter'\">\r\n <mat-icon class=\"filter-icon\" color=\"primary\">filter_list</mat-icon>\r\n</button>\r\n<mat-menu #menu=\"matMenu\">\r\n @for (md of $filterCols(); track md.key) {\r\n <button (click)=\"addFilter(md)\" mat-menu-item>\r\n <span class=\"filter-labels\">{{md.displayName || (md.key | spaceCase)}}</span>\r\n </button>\r\n }\r\n</mat-menu>\r\n", styles: [".filter{margin:15px;display:inline-block}.filter-button{color:#6495ed;font-size:22px;font-weight:700}.cancel-button{margin-right:30px;font-weight:700}.filter-wrapper{margin-top:1em;margin-bottom:1em;float:right}.menu{margin-bottom:10px;width:109.1%}.filter-labels{color:#6495ed;font-size:17px;font-weight:600}.float{position:absolute;width:fit-content;z-index:101;top:10px;right:180px;max-width:90vw}.d-w{display:flex;flex-direction:row;justify-content:flex-end}\n"] }]
@@ -2984,15 +2993,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImpor
2984
2993
 
2985
2994
  class KeyDisplayPipe {
2986
2995
  tableState = inject(TableStore);
2987
- transform(key) {
2988
- return this.tableState.getMetaData$(key).pipe(map(metaData => metaData.displayName || spaceCase(key)));
2989
- }
2996
+ transform = (key) => computed(() => this.tableState.$getMetaData(key)()?.displayName || spaceCase(key));
2990
2997
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: KeyDisplayPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
2991
2998
  static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "19.0.0", ngImport: i0, type: KeyDisplayPipe, isStandalone: true, name: "keyDisplay" });
2992
2999
  }
2993
3000
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: KeyDisplayPipe, decorators: [{
2994
3001
  type: Pipe,
2995
- args: [{ name: 'keyDisplay', standalone: true }]
3002
+ args: [{ name: 'keyDisplay' }]
2996
3003
  }] });
2997
3004
 
2998
3005
  class FormatFilterTypePipe {
@@ -3007,42 +3014,43 @@ class FormatFilterTypePipe {
3007
3014
  }
3008
3015
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: FormatFilterTypePipe, decorators: [{
3009
3016
  type: Pipe,
3010
- args: [{ name: 'formatFilterType', standalone: true }]
3017
+ args: [{ name: 'formatFilterType' }]
3011
3018
  }] });
3012
3019
 
3013
3020
  class FormatFilterValuePipe {
3014
3021
  tableState = inject(TableStore);
3015
3022
  datePipe = inject(DatePipe);
3016
3023
  transform(value, key, filterType) {
3017
- return this.tableState.getMetaData$(key).pipe(map(md => {
3018
- if (filterType === FilterTypes.IsNull) {
3019
- return '';
3020
- }
3021
- if (value && (filterType === FilterTypes.In)) {
3022
- if (md.fieldType === FieldType.Enum) {
3023
- return value.map((v) => spaceCase(md.additional.enumMap[v])).join(', ') ?? value;
3024
- }
3025
- return value.join(', ') ?? value;
3026
- }
3027
- if (filterType === FilterTypes.NumberBetween) {
3028
- return value.Start + ' - ' + value.End;
3029
- }
3030
- if (md.fieldType === FieldType.Date) {
3031
- return this.datePipe.transform(value, 'MM/dd/yy');
3032
- }
3033
- if (md.fieldType === FieldType.DateTime) {
3034
- return !!DateTimeFilterFuncs[filterType] ? this.datePipe.transform(value, 'short') : this.datePipe.transform(value, 'MM/dd/yy');
3035
- }
3036
- return value;
3037
- }));
3024
+ return computed(() => transform(value, this.tableState.$getMetaData(key)(), filterType));
3038
3025
  }
3039
3026
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: FormatFilterValuePipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
3040
3027
  static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "19.0.0", ngImport: i0, type: FormatFilterValuePipe, isStandalone: true, name: "formatFilterValue" });
3041
3028
  }
3042
3029
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: FormatFilterValuePipe, decorators: [{
3043
3030
  type: Pipe,
3044
- args: [{ name: 'formatFilterValue', standalone: true }]
3031
+ args: [{ name: 'formatFilterValue' }]
3045
3032
  }] });
3033
+ const transform = (value, meta, filterType) => {
3034
+ if (filterType === FilterTypes.IsNull) {
3035
+ return '';
3036
+ }
3037
+ if (value && (filterType === FilterTypes.In)) {
3038
+ if (meta.fieldType === FieldType.Enum) {
3039
+ return value.map((v) => spaceCase(meta.additional.enumMap[v])).join(', ') ?? value;
3040
+ }
3041
+ return value.join(', ') ?? value;
3042
+ }
3043
+ if (filterType === FilterTypes.NumberBetween) {
3044
+ return value.Start + ' - ' + value.End;
3045
+ }
3046
+ if (meta.fieldType === FieldType.Date) {
3047
+ return new DatePipe('en-US').transform(value, 'MM/dd/yy') || '';
3048
+ }
3049
+ if (meta.fieldType === FieldType.DateTime) {
3050
+ return (!!DateTimeFilterFuncs[filterType] ? new DatePipe('en-US').transform(value, 'short') : new DatePipe('en-US').transform(value, 'MM/dd/yy')) || '';
3051
+ }
3052
+ return value;
3053
+ };
3046
3054
 
3047
3055
  class FilterChipsComponent {
3048
3056
  tableState = inject(TableStore);
@@ -3057,16 +3065,16 @@ class FilterChipsComponent {
3057
3065
  clearAll() {
3058
3066
  this.filterStore.clearAll();
3059
3067
  }
3060
- currentFilters$ = this.filterStore.currentFilters$;
3068
+ $currentFilters = this.filterStore.$currentFilters;
3061
3069
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: FilterChipsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
3062
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.0", type: FilterChipsComponent, isStandalone: true, selector: "lib-filter-list", ngImport: i0, template: "<div class=\"d-w\" *ngrxLet=\"currentFilters$ as currentFilters\" >\r\n\r\n @if (currentFilters.length) {\r\n <button class=\"cancel-button\" mat-icon-button (click)=\"clearAll()\" matTooltip=\"Close all Filters Cards\">\r\n <mat-icon class=\"cancel-button\" color=\"primary\">close</mat-icon>\r\n </button>\r\n <div class=\"float\">\r\n @for (filter of currentFilters; track filter.key) {\r\n <div class=\"filter\">\r\n <tb-filter [filter]=\"filter\" (close)=\"deleteByIndex($index)\" />\r\n </div>\r\n }\r\n </div>\r\n }\r\n\r\n <mat-chip-set>\r\n @for (filter of $filters(); track filter.key) {\r\n <mat-chip (dblclick)=\"addFilter(filter)\" (removed)=\"tableState.removeFilter(filter.filterId!)\">\r\n {{ filter.key | keyDisplay | async }} {{filter.filterType | formatFilterType : filter.filterValue}} {{ filter.filterValue | formatFilterValue: filter.key : filter.filterType | async }}\r\n <mat-icon matChipRemove>cancel</mat-icon>\r\n </mat-chip>\r\n }\r\n @if ($filters().length > 1) {\r\n <mat-chip (removed)=\"tableState.clearFilters()\">\r\n Clear All\r\n <mat-icon matChipRemove>cancel</mat-icon>\r\n </mat-chip>\r\n }\r\n </mat-chip-set>\r\n\r\n</div>\r\n", styles: [".filter{margin:15px;display:inline-block}.filter-button{color:#6495ed;font-size:22px;font-weight:700}.cancel-button{margin-right:30px;font-weight:700}.filter-wrapper{margin-top:1em;margin-bottom:1em;float:right}.menu{margin-bottom:10px;width:109.1%}.filter-labels{color:#6495ed;font-size:17px;font-weight:600}.float{position:absolute;width:fit-content;z-index:101;top:10px;right:180px;max-width:90vw}.d-w{display:flex;flex-direction:row;justify-content:flex-end}\n"], dependencies: [{ kind: "directive", type: LetDirective, selector: "[ngrxLet]", inputs: ["ngrxLet", "ngrxLetSuspenseTpl"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i3$1.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i4$1.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: FilterComponent, selector: "tb-filter", inputs: ["filter"], outputs: ["close"] }, { kind: "ngmodule", type: MatChipsModule }, { kind: "component", type: i4$3.MatChip, selector: "mat-basic-chip, [mat-basic-chip], mat-chip, [mat-chip]", inputs: ["role", "id", "aria-label", "aria-description", "value", "color", "removable", "highlighted", "disableRipple", "disabled"], outputs: ["removed", "destroyed"], exportAs: ["matChip"] }, { kind: "directive", type: i4$3.MatChipRemove, selector: "[matChipRemove]" }, { kind: "component", type: i4$3.MatChipSet, selector: "mat-chip-set", inputs: ["disabled", "role", "tabIndex"] }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "pipe", type: KeyDisplayPipe, name: "keyDisplay" }, { kind: "pipe", type: FormatFilterTypePipe, name: "formatFilterType" }, { kind: "pipe", type: FormatFilterValuePipe, name: "formatFilterValue" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
3070
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.0", type: FilterChipsComponent, isStandalone: true, selector: "lib-filter-list", ngImport: i0, template: "<div class=\"d-w\">\r\n\r\n @if ($currentFilters().length) {\r\n <button class=\"cancel-button\" mat-icon-button (click)=\"clearAll()\" matTooltip=\"Close all Filters Cards\">\r\n <mat-icon class=\"cancel-button\" color=\"primary\">close</mat-icon>\r\n </button>\r\n <div class=\"float\">\r\n @for (filter of $currentFilters(); track filter.key) {\r\n <div class=\"filter\">\r\n <tb-filter [filter]=\"filter\" (close)=\"deleteByIndex($index)\" />\r\n </div>\r\n }\r\n </div>\r\n }\r\n\r\n <mat-chip-set>\r\n @for (filter of $filters(); track filter.key) {\r\n <mat-chip (dblclick)=\"addFilter(filter)\" (removed)=\"tableState.removeFilter(filter.filterId!)\">\r\n {{ (filter.key | keyDisplay)() }} {{filter.filterType | formatFilterType : filter.filterValue}} {{ (filter.filterValue | formatFilterValue: filter.key : filter.filterType)() }}\r\n <mat-icon matChipRemove>cancel</mat-icon>\r\n </mat-chip>\r\n }\r\n @if ($filters().length > 1) {\r\n <mat-chip (removed)=\"tableState.clearFilters()\">\r\n Clear All\r\n <mat-icon matChipRemove>cancel</mat-icon>\r\n </mat-chip>\r\n }\r\n </mat-chip-set>\r\n\r\n</div>\r\n", styles: [".filter{margin:15px;display:inline-block}.filter-button{color:#6495ed;font-size:22px;font-weight:700}.cancel-button{margin-right:30px;font-weight:700}.filter-wrapper{margin-top:1em;margin-bottom:1em;float:right}.menu{margin-bottom:10px;width:109.1%}.filter-labels{color:#6495ed;font-size:17px;font-weight:600}.float{position:absolute;width:fit-content;z-index:101;top:10px;right:180px;max-width:90vw}.d-w{display:flex;flex-direction:row;justify-content:flex-end}\n"], dependencies: [{ kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i3$1.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i4$1.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: FilterComponent, selector: "tb-filter", inputs: ["filter"], outputs: ["close"] }, { kind: "ngmodule", type: MatChipsModule }, { kind: "component", type: i4$3.MatChip, selector: "mat-basic-chip, [mat-basic-chip], mat-chip, [mat-chip]", inputs: ["role", "id", "aria-label", "aria-description", "value", "color", "removable", "highlighted", "disableRipple", "disabled"], outputs: ["removed", "destroyed"], exportAs: ["matChip"] }, { kind: "directive", type: i4$3.MatChipRemove, selector: "[matChipRemove]" }, { kind: "component", type: i4$3.MatChipSet, selector: "mat-chip-set", inputs: ["disabled", "role", "tabIndex"] }, { kind: "pipe", type: KeyDisplayPipe, name: "keyDisplay" }, { kind: "pipe", type: FormatFilterTypePipe, name: "formatFilterType" }, { kind: "pipe", type: FormatFilterValuePipe, name: "formatFilterValue" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
3063
3071
  }
3064
3072
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: FilterChipsComponent, decorators: [{
3065
3073
  type: Component,
3066
- args: [{ selector: 'lib-filter-list', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [
3067
- LetDirective, MatButtonModule, MatTooltipModule, MatIconModule, FilterComponent,
3068
- MatChipsModule, AsyncPipe, KeyDisplayPipe, FormatFilterTypePipe, FormatFilterValuePipe
3069
- ], template: "<div class=\"d-w\" *ngrxLet=\"currentFilters$ as currentFilters\" >\r\n\r\n @if (currentFilters.length) {\r\n <button class=\"cancel-button\" mat-icon-button (click)=\"clearAll()\" matTooltip=\"Close all Filters Cards\">\r\n <mat-icon class=\"cancel-button\" color=\"primary\">close</mat-icon>\r\n </button>\r\n <div class=\"float\">\r\n @for (filter of currentFilters; track filter.key) {\r\n <div class=\"filter\">\r\n <tb-filter [filter]=\"filter\" (close)=\"deleteByIndex($index)\" />\r\n </div>\r\n }\r\n </div>\r\n }\r\n\r\n <mat-chip-set>\r\n @for (filter of $filters(); track filter.key) {\r\n <mat-chip (dblclick)=\"addFilter(filter)\" (removed)=\"tableState.removeFilter(filter.filterId!)\">\r\n {{ filter.key | keyDisplay | async }} {{filter.filterType | formatFilterType : filter.filterValue}} {{ filter.filterValue | formatFilterValue: filter.key : filter.filterType | async }}\r\n <mat-icon matChipRemove>cancel</mat-icon>\r\n </mat-chip>\r\n }\r\n @if ($filters().length > 1) {\r\n <mat-chip (removed)=\"tableState.clearFilters()\">\r\n Clear All\r\n <mat-icon matChipRemove>cancel</mat-icon>\r\n </mat-chip>\r\n }\r\n </mat-chip-set>\r\n\r\n</div>\r\n", styles: [".filter{margin:15px;display:inline-block}.filter-button{color:#6495ed;font-size:22px;font-weight:700}.cancel-button{margin-right:30px;font-weight:700}.filter-wrapper{margin-top:1em;margin-bottom:1em;float:right}.menu{margin-bottom:10px;width:109.1%}.filter-labels{color:#6495ed;font-size:17px;font-weight:600}.float{position:absolute;width:fit-content;z-index:101;top:10px;right:180px;max-width:90vw}.d-w{display:flex;flex-direction:row;justify-content:flex-end}\n"] }]
3074
+ args: [{ selector: 'lib-filter-list', changeDetection: ChangeDetectionStrategy.OnPush, imports: [
3075
+ MatButtonModule, MatTooltipModule, MatIconModule, FilterComponent,
3076
+ MatChipsModule, KeyDisplayPipe, FormatFilterTypePipe, FormatFilterValuePipe
3077
+ ], template: "<div class=\"d-w\">\r\n\r\n @if ($currentFilters().length) {\r\n <button class=\"cancel-button\" mat-icon-button (click)=\"clearAll()\" matTooltip=\"Close all Filters Cards\">\r\n <mat-icon class=\"cancel-button\" color=\"primary\">close</mat-icon>\r\n </button>\r\n <div class=\"float\">\r\n @for (filter of $currentFilters(); track filter.key) {\r\n <div class=\"filter\">\r\n <tb-filter [filter]=\"filter\" (close)=\"deleteByIndex($index)\" />\r\n </div>\r\n }\r\n </div>\r\n }\r\n\r\n <mat-chip-set>\r\n @for (filter of $filters(); track filter.key) {\r\n <mat-chip (dblclick)=\"addFilter(filter)\" (removed)=\"tableState.removeFilter(filter.filterId!)\">\r\n {{ (filter.key | keyDisplay)() }} {{filter.filterType | formatFilterType : filter.filterValue}} {{ (filter.filterValue | formatFilterValue: filter.key : filter.filterType)() }}\r\n <mat-icon matChipRemove>cancel</mat-icon>\r\n </mat-chip>\r\n }\r\n @if ($filters().length > 1) {\r\n <mat-chip (removed)=\"tableState.clearFilters()\">\r\n Clear All\r\n <mat-icon matChipRemove>cancel</mat-icon>\r\n </mat-chip>\r\n }\r\n </mat-chip-set>\r\n\r\n</div>\r\n", styles: [".filter{margin:15px;display:inline-block}.filter-button{color:#6495ed;font-size:22px;font-weight:700}.cancel-button{margin-right:30px;font-weight:700}.filter-wrapper{margin-top:1em;margin-bottom:1em;float:right}.menu{margin-bottom:10px;width:109.1%}.filter-labels{color:#6495ed;font-size:17px;font-weight:600}.float{position:absolute;width:fit-content;z-index:101;top:10px;right:180px;max-width:90vw}.d-w{display:flex;flex-direction:row;justify-content:flex-end}\n"] }]
3070
3078
  }] });
3071
3079
 
3072
3080
  function isPipe(o) {
@@ -3076,16 +3084,20 @@ class TransformCreator {
3076
3084
  datePipe = inject(DatePipe);
3077
3085
  currencyPipe = inject(CurrencyPipe);
3078
3086
  phonePipe = inject(PhoneNumberPipe);
3079
- casePipe = inject(SpaceCasePipe);
3080
3087
  config = inject(TableBuilderConfigToken);
3081
- createTransformer(metaData, noIcons = false) {
3088
+ createTransformer(metaData, noIcons = false, forItem = false) {
3082
3089
  const nested = metaData.key.includes('.');
3083
3090
  const defaultFunc = nested ? (value) => get(value, metaData.key) : (value) => value[metaData.key];
3084
- if (metaData.map) {
3091
+ if (metaData.map && !forItem) {
3085
3092
  return (value) => {
3086
3093
  return metaData.map(value);
3087
3094
  };
3088
3095
  }
3096
+ if (metaData.mapItem) {
3097
+ return (value) => {
3098
+ return metaData.mapItem(defaultFunc(value));
3099
+ };
3100
+ }
3089
3101
  if (metaData.transform) {
3090
3102
  if (isPipe(metaData.transform)) {
3091
3103
  return (value) => metaData.transform.transform(defaultFunc(value));
@@ -3110,7 +3122,7 @@ class TransformCreator {
3110
3122
  case FieldType.PhoneNumber:
3111
3123
  return (value) => this.phonePipe.transform(defaultFunc(value));
3112
3124
  case FieldType.Enum:
3113
- return (value) => this.casePipe.transform(metaData.additional?.enumMap[defaultFunc(value)]);
3125
+ return (value) => spaceCase(metaData.additional?.enumMap[defaultFunc(value)]);
3114
3126
  case FieldType.Boolean:
3115
3127
  if (noIcons) {
3116
3128
  return defaultFunc;
@@ -3185,7 +3197,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImpor
3185
3197
  type: Component,
3186
3198
  args: [{
3187
3199
  selector: "tb-router-link-column",
3188
- standalone: true,
3189
3200
  changeDetection: ChangeDetectionStrategy.OnPush,
3190
3201
  imports: [
3191
3202
  RouterModule
@@ -3220,7 +3231,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImpor
3220
3231
  type: Component,
3221
3232
  args: [{
3222
3233
  selector: "tb-link-column",
3223
- standalone: true,
3224
3234
  changeDetection: ChangeDetectionStrategy.OnPush,
3225
3235
  template: `
3226
3236
  <a target="{{additional().target}}"
@@ -3246,7 +3256,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImpor
3246
3256
  type: Component,
3247
3257
  args: [{
3248
3258
  selector: 'tb-comma-array-column',
3249
- standalone: true,
3250
3259
  template: `
3251
3260
  @for(val of displayArray(); track $index){
3252
3261
  {{val + (!$last ? ',' : '')}}
@@ -3271,7 +3280,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImpor
3271
3280
  type: Component,
3272
3281
  args: [{
3273
3282
  selector: 'tb-new-line-array-column',
3274
- standalone: true,
3275
3283
  template: `
3276
3284
  @for(val of displayArray(); track $index){
3277
3285
  {{val}}
@@ -3295,8 +3303,8 @@ class InitializationComponent {
3295
3303
  }
3296
3304
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: InitializationComponent, decorators: [{
3297
3305
  type: Component,
3298
- args: [{ selector: 'initialization', standalone: true, imports: [
3299
- LinkColumnComponent, ArrayCommaColumnComponent, MatIconModule, FunctionPipe,
3306
+ args: [{ selector: 'initialization', imports: [
3307
+ LinkColumnComponent, ArrayCommaColumnComponent, MatIconModule,
3300
3308
  RouterLinkColumnComponent, ArrayNewLineColumnComponent
3301
3309
  ], template: "<ng-template #link let-value='value' let-element='element' let-additional=\"additional\">\r\n <tb-link-column [element]=\"element\" [value]=\"value\" [additional]=\"additional\" />\r\n</ng-template>\r\n\r\n<ng-template #routerLink let-value='value' let-element='element' let-additional=\"additional\">\r\n <tb-router-link-column [element]=\"element\" [value]=\"value\" [additional]=\"additional\"/>\r\n</ng-template>\r\n\r\n<ng-template #imageUrl let-value='value'>\r\n <span>\r\n <img src=\"{{value}}\" height=\"75px\" width=\"75px\" />\r\n </span>\r\n</ng-template>\r\n\r\n<ng-template #arrayNewLine let-value='value' let-element='element' let-additional=\"additional\">\r\n <tb-new-line-array-column [value]='value' [additional]='additional'/>\r\n</ng-template>\r\n\r\n<ng-template #arrayComma let-value='value' let-element='element' let-additional=\"additional\">\r\n <tb-comma-array-column [value]='value' [additional]='additional'/>\r\n</ng-template>\r\n\r\n<ng-template #default let-value='value'>\r\n <span>{{ value }}</span>\r\n</ng-template>\r\n\r\n<ng-template #defaultWithIcon let-value='value'>\r\n <mat-icon>{{ value}}</mat-icon>\r\n</ng-template>\r\n" }]
3302
3310
  }], propDecorators: { linkTemplate: [{
@@ -3345,10 +3353,11 @@ class TableTemplateService {
3345
3353
  this.templates[FieldType.Enum] = this.instance.defaultTemplate;
3346
3354
  }
3347
3355
  getTemplate(metaData) {
3356
+ const arrayStyle = metaData.additional?.arrayStyle ?? this.tableConfig?.arrayDefaults?.arrayStyle;
3348
3357
  let tmp = metaData.fieldType === FieldType.Link && metaData.additional?.link?.useRouterLink
3349
3358
  ? this.templates[FieldType.Link + .5]
3350
3359
  :
3351
- metaData.fieldType === FieldType.Array && (metaData.additional?.arrayStyle === ArrayStyle.CommaDelimited || this.tableConfig?.arrayDefaults?.arrayStyle === ArrayStyle.CommaDelimited)
3360
+ metaData.fieldType === FieldType.Array && arrayStyle === ArrayStyle.CommaDelimited
3352
3361
  ? this.templates[FieldType.Array + .5]
3353
3362
  :
3354
3363
  this.templates[metaData.fieldType];
@@ -3381,23 +3390,20 @@ class HeaderMenuComponent {
3381
3390
  FieldType = FieldType;
3382
3391
  FilterType = FilterTypes;
3383
3392
  myFilterType;
3384
- myFilterValue;
3385
- filter;
3386
- metaData;
3387
- trigger;
3393
+ $metaData = input.required({ alias: 'metaData' });
3394
+ $trigger = viewChild(MatMenuTrigger);
3388
3395
  hideField(key) {
3389
3396
  this.tableState.hideColumn(key);
3390
3397
  }
3391
3398
  ngOnInit() {
3392
- this.filter = { key: this.metaData.key, fieldType: this.metaData.fieldType };
3393
3399
  this.resetFilterType();
3394
3400
  }
3395
3401
  resetFilterType() {
3396
- if (this.metaData.additional?.filterOptions?.filterableValues) {
3402
+ if (this.$metaData().additional?.filterOptions?.filterableValues) {
3397
3403
  this.myFilterType = FilterTypes.In;
3398
3404
  return;
3399
3405
  }
3400
- switch (this.metaData.fieldType) {
3406
+ switch (this.$metaData().fieldType) {
3401
3407
  case FieldType.String:
3402
3408
  case FieldType.Link:
3403
3409
  case FieldType.PhoneNumber:
@@ -3435,24 +3441,19 @@ class HeaderMenuComponent {
3435
3441
  onEnter(filter) {
3436
3442
  if (filter.filterValue != undefined && filter.filterType) {
3437
3443
  this.tableState.addFilter(filter);
3438
- this.trigger.closeMenu();
3444
+ this.$trigger().closeMenu();
3439
3445
  }
3440
3446
  }
3441
3447
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: HeaderMenuComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
3442
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.0", type: HeaderMenuComponent, isStandalone: true, selector: "tb-header-menu", inputs: { metaData: "metaData" }, viewQueries: [{ propertyName: "trigger", first: true, predicate: MatMenuTrigger, descendants: true }], ngImport: i0, template: "<button mat-icon-button class=\"open-menu-icon-button\" disableRipple [matMenuTriggerFor]=\"menu\" [matMenuTriggerRestoreFocus]=\"false\">\r\n <mat-icon class=\"menu-icon\">more_vert</mat-icon>\r\n</button>\r\n<mat-menu #menu=\"matMenu\" >\r\n @if (!(metaData.fieldType === FieldType.NotMapped))\r\n {\r\n <button mat-menu-item (click)=\"tableState.addGroupByKey(metaData.key)\">\r\n <mat-icon color=\"primary\">group</mat-icon>\r\n <span>Group By</span>\r\n </button>\r\n }\r\n <button mat-menu-item (click)=hideField(metaData.key)>\r\n <mat-icon color=\"primary\">visibility_off</mat-icon>\r\n <span>Hide Column</span>\r\n </button>\r\n @if (!(metaData.fieldType === FieldType.NotMapped))\r\n {\r\n <ng-form #myForm=\"ngForm\" (keydown.enter)=\"onEnter(myForm.value)\" class=\"tb-header-filter\">\r\n <input type=\"hidden\" name=\"filterId\" [ngModel]=\"'header-column-' + metaData.key\" />\r\n <input type=\"hidden\" name=\"filterType\" [ngModel]=\"myFilterType\" />\r\n <input type=\"hidden\" name=\"key\" [ngModel]=\"metaData.key\" />\r\n <input type=\"hidden\" name=\"fieldType\" [ngModel]=\"metaData.fieldType\" />\r\n \r\n @if(myFilterType === FilterType.Or || myFilterType === FilterType.In){\r\n <tb-in-list-filter name='filterValue' [key]='metaData.key' [(ngModel)]='myFilterValue'/>\r\n }\r\n @else if(metaData.fieldType === FieldType.Link || metaData.fieldType === FieldType.String || metaData.fieldType === FieldType.Array || metaData.fieldType === FieldType.Unknown || metaData.fieldType === FieldType.PhoneNumber) {\r\n <mat-form-field stop-propagation class=\"font auto-width\">\r\n <mat-icon matPrefix class=\"search-icon\">search</mat-icon>\r\n <mat-label>{{myFilterType === FilterType.StringDoesNotContain ? 'Does Not Contain...' : 'Contains...'}}</mat-label>\r\n <input matInput name=\"filterValue\" [ngModel]=\"filter.filterValue\" />\r\n <span matSuffix [matTooltip]=\"myFilterType === FilterType.StringDoesNotContain ? 'Contains' : 'Does Not Contain'\">\r\n <button mat-icon-button color=\"primary\" (click)=\"setStringFilterType()\" class=\"header-filter-icon-button\">\r\n <mat-icon [ngClass]=\"{'chosen-icon': myFilterType === FilterType.StringDoesNotContain }\">\r\n block\r\n </mat-icon>\r\n </button>\r\n </span>\r\n </mat-form-field>\r\n }\r\n @else if (metaData.fieldType === FieldType.Number || metaData.fieldType === FieldType.Currency) {\r\n <mat-form-field class=\"auto-width\" stop-propagation>\r\n <mat-label>{{myFilterType === FilterType.NumberEquals ? 'Equals...' : myFilterType === FilterType.NumberLessThan ? 'Less Than...' : 'More Than...'}}</mat-label>\r\n <input matInput type='number' name=\"filterValue\" [ngModel]=\"filter.filterValue\" />\r\n <span matPrefix class=\"tb-header-prefix\">\r\n <button mat-icon-button disableRipple class=\"header-filter-icon-button\" (click)=\"setFilterType(FilterType.NumberLessThan)\"\r\n [ngClass]=\"{'chosen-icon': myFilterType === FilterType.NumberLessThan }\">\r\n <mat-icon class=\"suffix-icons\"\r\n >\r\n arrow_back_ios</mat-icon>\r\n </button>\r\n <button mat-icon-button disableRipple class=\"header-filter-icon-button\" (click)=\"setFilterType(FilterType.NumberGreaterThan)\"\r\n [ngClass]=\"{'chosen-icon': myFilterType === FilterType.NumberGreaterThan }\" >\r\n <mat-icon class=\"suffix-icons\">arrow_forward_ios</mat-icon>\r\n </button>\r\n <button mat-icon-button disableRipple class=\"header-filter-icon-button\" (click)=\"setFilterType(FilterType.NumberEquals)\"\r\n [ngClass]=\"{'chosen-icon': myFilterType === FilterType.NumberEquals }\">\r\n <span class=\"suffix-icons\">=</span>\r\n </button>\r\n </span>\r\n </mat-form-field>\r\n }\r\n @else if (metaData.fieldType === FieldType.Boolean) {\r\n <div>\r\n <label>\r\n <mat-icon class=\"search-icon\">filter_list</mat-icon>\r\n </label>\r\n <mat-radio-group stop-propagation #ctrl=\"matRadioGroup\" #boolField='ngModel' class=\"font\" name=\"filterValue\" [ngModel]=\"myFilterValue\" >\r\n <mat-radio-button class=\"filter-radio-button\" (click)=\"myFilterValue = true;\" [value]=\"true\">True</mat-radio-button><br/>\r\n <mat-radio-button class=\"filter-radio-button\" (click)=\"myFilterValue = false\" [value]=\"false\">False</mat-radio-button><br/>\r\n </mat-radio-group>\r\n </div>\r\n }\r\n @else if (metaData.fieldType === FieldType.Date || metaData.fieldType === FieldType.DateTime) {\r\n <mat-form-field class=\"font auto-width\" stop-propagation >\r\n <span matPrefix class=\"tb-header-prefix\">\r\n <button mat-icon-button disableRipple class=\"header-filter-icon-button\" (click)=\"setFilterType(FilterType.DateOnOrAfter)\"\r\n [ngClass]=\"{'chosen-icon': myFilterType === FilterType.DateOnOrAfter }\">\r\n <mat-icon class=\"suffix-icons underline\">arrow_forward_ios</mat-icon>\r\n </button>\r\n <button mat-icon-button disableRipple class=\"header-filter-icon-button\" (click)=\"setFilterType(FilterType.DateOnOrBefore)\"\r\n [ngClass]=\"{'chosen-icon': myFilterType === FilterType.DateOnOrBefore }\">\r\n <mat-icon class=\"suffix-icons underline\">arrow_back_ios</mat-icon>\r\n </button>\r\n <button mat-icon-button disableRipple class=\"header-filter-icon-button\" (click)=\"setFilterType(FilterType.DateIsOn)\"\r\n [ngClass]=\"{'chosen-icon': myFilterType === FilterType.DateIsOn }\">\r\n <span class=\"suffix-icons underline\"> =</span>\r\n </button>\r\n </span>\r\n <mat-label>{{myFilterType === FilterType.DateIsOn ? 'On...' :\r\n myFilterType === FilterType.DateOnOrBefore ? 'On or Before...' : 'On or After...'}}</mat-label>\r\n <input matInput name=\"filterValue\" [ngModel]=\"filter.filterValue\" [matDatepicker]=\"calendar\"\r\n (click)=\"calendar.open()\"/>\r\n <mat-datepicker-toggle class=\"date-toggle header-filter-icon-button\" matSuffix [for]=\"calendar\" preventEnter></mat-datepicker-toggle>\r\n <mat-datepicker #calendar></mat-datepicker>\r\n </mat-form-field>\r\n }\r\n \r\n <button mat-button (click)=\"onEnter(myForm.value)\" [disabled]=\"myForm.value.filterValue == undefined\" disableRipple>\r\n Apply\r\n </button>\r\n </ng-form>\r\n }\r\n</mat-menu>\r\n", styles: [":host{--mdc-text-button-container-height: 24px}:host{--mdc-filled-button-container-height: 24px}:host{--mdc-protected-button-container-height: 24px}:host{--mdc-outlined-button-container-height: 24px}:host{--mat-text-button-touch-target-display: none}:host{--mat-filled-button-touch-target-display: none}:host{--mat-protected-button-touch-target-display: none}:host{--mat-outlined-button-touch-target-display: none}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{-webkit-appearance:none;margin:0}.menu-icon{font-size:16px;line-height:16px;vertical-align:top;height:16px;width:16px}.search-icon{margin-right:16px;vertical-align:middle;height:24px;color:#0000008a;font-size:21px;line-height:1.125}.font{font-size:14px}.filter-radio-button:first-of-type{padding-left:0}.filter-radio-button{padding:10px 40px;min-width:110px}.auto-width{width:260px;margin:5px;display:block;height:55px}.open-menu-icon-button{height:28px;width:28px;padding:6px}.header-filter-icon-button{height:18px;width:18px;font-size:18px;padding:0;margin:0 2px}.header-filter-icon-button ::ng-deep *{line-height:initial;font-size:initial;height:18px;width:18px;font-size:18px;bottom:initial}.header-filter-icon-button.chosen-icon,.header-filter-icon-button.chosen-icon ::ng-deep *{height:22px;width:22px;font-size:22px;color:green}mat-icon.mat-icon.suffix-icons.underline{height:20px;text-decoration:underline .1px solid}.chosen-icon mat-icon.mat-icon.suffix-icons.underline{height:24px}::ng-deep .mat-mdc-form-field-icon-prefix:has(.tb-header-prefix),.tb-header-prefix{padding:0;flex-basis:36%}.tb-header-filter ::ng-deep .mat-mdc-form-field-subscript-wrapper{line-height:0}.tb-header-filter ::ng-deep .mat-mdc-form-field-subscript-wrapper:before{height:0}.date-toggle ::ng-deep svg{position:absolute;left:0;top:0}\n"], dependencies: [{ kind: "ngmodule", type: MatMenuModule }, { kind: "component", type: i4$2.MatMenu, selector: "mat-menu", inputs: ["backdropClass", "aria-label", "aria-labelledby", "aria-describedby", "xPosition", "yPosition", "overlapTrigger", "hasBackdrop", "class", "classList"], outputs: ["closed", "close"], exportAs: ["matMenu"] }, { kind: "component", type: i4$2.MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i4$2.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i3$1.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "component", type: i3$1.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i3.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: i3.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i3.NgForm, selector: "form:not([ngNoForm]):not([formGroup]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: InListFilterComponent, selector: "tb-in-list-filter , [tb-in-list-filter]", inputs: ["key"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i1$1.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "component", type: i6.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i6.MatLabel, selector: "mat-label" }, { kind: "directive", type: i6.MatPrefix, selector: "[matPrefix], [matIconPrefix], [matTextPrefix]", inputs: ["matTextPrefix"] }, { kind: "directive", type: i6.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i4$1.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: StopPropagationDirective, selector: "[stop-propagation]" }, { kind: "ngmodule", type: MatRadioModule }, { kind: "directive", type: i10.MatRadioGroup, selector: "mat-radio-group", inputs: ["color", "name", "labelPosition", "value", "selected", "disabled", "required", "disabledInteractive"], outputs: ["change"], exportAs: ["matRadioGroup"] }, { kind: "component", type: i10.MatRadioButton, selector: "mat-radio-button", inputs: ["id", "name", "aria-label", "aria-labelledby", "aria-describedby", "disableRipple", "tabIndex", "checked", "value", "labelPosition", "disabled", "required", "color", "disabledInteractive"], outputs: ["change"], exportAs: ["matRadioButton"] }, { kind: "ngmodule", type: MatDatepickerModule }, { kind: "component", type: i4.MatDatepicker, selector: "mat-datepicker", exportAs: ["matDatepicker"] }, { kind: "directive", type: i4.MatDatepickerInput, selector: "input[matDatepicker]", inputs: ["matDatepicker", "min", "max", "matDatepickerFilter"], exportAs: ["matDatepickerInput"] }, { kind: "component", type: i4.MatDatepickerToggle, selector: "mat-datepicker-toggle", inputs: ["for", "tabIndex", "aria-label", "disabled", "disableRipple"], exportAs: ["matDatepickerToggle"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
3448
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.0", type: HeaderMenuComponent, isStandalone: true, selector: "tb-header-menu", inputs: { $metaData: { classPropertyName: "$metaData", publicName: "metaData", isSignal: true, isRequired: true, transformFunction: null } }, viewQueries: [{ propertyName: "$trigger", first: true, predicate: MatMenuTrigger, descendants: true, isSignal: true }], ngImport: i0, template: "@let metaData = $metaData();\r\n\r\n<button mat-icon-button class=\"open-menu-icon-button\" disableRipple [matMenuTriggerFor]=\"menu\" [matMenuTriggerRestoreFocus]=\"false\">\r\n <mat-icon class=\"menu-icon\">more_vert</mat-icon>\r\n</button>\r\n<mat-menu #menu=\"matMenu\" >\r\n @if (!(metaData.fieldType === FieldType.NotMapped))\r\n {\r\n <button mat-menu-item (click)=\"tableState.addGroupByKey(metaData.key)\">\r\n <mat-icon color=\"primary\">group</mat-icon>\r\n <span>Group By</span>\r\n </button>\r\n }\r\n <button mat-menu-item (click)=hideField(metaData.key)>\r\n <mat-icon color=\"primary\">visibility_off</mat-icon>\r\n <span>Hide Column</span>\r\n </button>\r\n @if (!(metaData.fieldType === FieldType.NotMapped))\r\n {\r\n <ng-form #myForm=\"ngForm\" (keydown.enter)=\"onEnter(myForm.value)\" class=\"tb-header-filter\">\r\n <input type=\"hidden\" name=\"filterId\" [ngModel]=\"'header-column-' + metaData.key\" />\r\n <input type=\"hidden\" name=\"filterType\" [ngModel]=\"myFilterType\" />\r\n <input type=\"hidden\" name=\"key\" [ngModel]=\"metaData.key\" />\r\n <input type=\"hidden\" name=\"fieldType\" [ngModel]=\"metaData.fieldType\" />\r\n \r\n @if(myFilterType === FilterType.Or || myFilterType === FilterType.In){\r\n <tb-in-list-filter name='filterValue' [key]='metaData.key' [ngModel]=\"undefined\"/>\r\n }\r\n @else if(metaData.fieldType === FieldType.Link || metaData.fieldType === FieldType.String || metaData.fieldType === FieldType.Array || metaData.fieldType === FieldType.Unknown || metaData.fieldType === FieldType.PhoneNumber) {\r\n <mat-form-field stop-propagation class=\"font auto-width\">\r\n <mat-icon matPrefix class=\"search-icon\">search</mat-icon>\r\n <mat-label>{{myFilterType === FilterType.StringDoesNotContain ? 'Does Not Contain...' : 'Contains...'}}</mat-label>\r\n <input matInput name=\"filterValue\" [ngModel]=\"undefined\"/>\r\n <span matSuffix [matTooltip]=\"myFilterType === FilterType.StringDoesNotContain ? 'Contains' : 'Does Not Contain'\">\r\n <button mat-icon-button color=\"primary\" (click)=\"setStringFilterType()\" class=\"header-filter-icon-button\">\r\n <mat-icon [class]=\"{'chosen-icon': myFilterType === FilterType.StringDoesNotContain }\">\r\n block\r\n </mat-icon>\r\n </button>\r\n </span>\r\n </mat-form-field>\r\n }\r\n @else if (metaData.fieldType === FieldType.Number || metaData.fieldType === FieldType.Currency) {\r\n <mat-form-field class=\"auto-width\" stop-propagation>\r\n <mat-label>{{myFilterType === FilterType.NumberEquals ? 'Equals...' : myFilterType === FilterType.NumberLessThan ? 'Less Than...' : 'More Than...'}}</mat-label>\r\n <input matInput type='number' name=\"filterValue\" [ngModel]=\"undefined\" />\r\n <span matPrefix class=\"tb-header-prefix\">\r\n <button mat-icon-button disableRipple class=\"header-filter-icon-button\" (click)=\"setFilterType(FilterType.NumberLessThan)\"\r\n [class]=\"{'chosen-icon': myFilterType === FilterType.NumberLessThan }\">\r\n <mat-icon class=\"suffix-icons\"\r\n >\r\n arrow_back_ios</mat-icon>\r\n </button>\r\n <button mat-icon-button disableRipple class=\"header-filter-icon-button\" (click)=\"setFilterType(FilterType.NumberGreaterThan)\"\r\n [class]=\"{'chosen-icon': myFilterType === FilterType.NumberGreaterThan }\" >\r\n <mat-icon class=\"suffix-icons\">arrow_forward_ios</mat-icon>\r\n </button>\r\n <button mat-icon-button disableRipple class=\"header-filter-icon-button\" (click)=\"setFilterType(FilterType.NumberEquals)\"\r\n [class]=\"{'chosen-icon': myFilterType === FilterType.NumberEquals }\">\r\n <span class=\"suffix-icons\">=</span>\r\n </button>\r\n </span>\r\n </mat-form-field>\r\n }\r\n @else if (metaData.fieldType === FieldType.Boolean) {\r\n <div>\r\n <label>\r\n <mat-icon class=\"search-icon\">filter_list</mat-icon>\r\n </label>\r\n <mat-radio-group stop-propagation #ctrl=\"matRadioGroup\" #boolField='ngModel' class=\"font\" name=\"filterValue\" [ngModel]=\"undefined\" >\r\n <mat-radio-button class=\"filter-radio-button\" (click)=\"boolField.control.setValue(true);\" [value]=\"true\">True</mat-radio-button><br/>\r\n <mat-radio-button class=\"filter-radio-button\" (click)=\"boolField.control.setValue(false)\" [value]=\"false\">False</mat-radio-button><br/>\r\n </mat-radio-group>\r\n </div>\r\n }\r\n @else if (metaData.fieldType === FieldType.Date || metaData.fieldType === FieldType.DateTime) {\r\n <mat-form-field class=\"font auto-width\" stop-propagation >\r\n <span matPrefix class=\"tb-header-prefix\">\r\n <button mat-icon-button disableRipple class=\"header-filter-icon-button\" (click)=\"setFilterType(FilterType.DateOnOrAfter)\"\r\n [class]=\"{'chosen-icon': myFilterType === FilterType.DateOnOrAfter }\">\r\n <mat-icon class=\"suffix-icons underline\">arrow_forward_ios</mat-icon>\r\n </button>\r\n <button mat-icon-button disableRipple class=\"header-filter-icon-button\" (click)=\"setFilterType(FilterType.DateOnOrBefore)\"\r\n [class]=\"{'chosen-icon': myFilterType === FilterType.DateOnOrBefore }\">\r\n <mat-icon class=\"suffix-icons underline\">arrow_back_ios</mat-icon>\r\n </button>\r\n <button mat-icon-button disableRipple class=\"header-filter-icon-button\" (click)=\"setFilterType(FilterType.DateIsOn)\"\r\n [class]=\"{'chosen-icon': myFilterType === FilterType.DateIsOn }\">\r\n <span class=\"suffix-icons underline\"> =</span>\r\n </button>\r\n </span>\r\n <mat-label>{{myFilterType === FilterType.DateIsOn ? 'On...' :\r\n myFilterType === FilterType.DateOnOrBefore ? 'On or Before...' : 'On or After...'}}</mat-label>\r\n <input matInput name=\"filterValue\" [ngModel]=\"undefined\" [matDatepicker]=\"calendar\"\r\n (click)=\"calendar.open()\"/>\r\n <mat-datepicker-toggle class=\"date-toggle header-filter-icon-button\" matSuffix [for]=\"calendar\" preventEnter></mat-datepicker-toggle>\r\n <mat-datepicker #calendar></mat-datepicker>\r\n </mat-form-field>\r\n }\r\n <button mat-button (click)=\"onEnter(myForm.value)\" [disabled]=\"myForm.value.filterValue == undefined\" disableRipple>\r\n Apply\r\n </button>\r\n </ng-form>\r\n }\r\n</mat-menu>\r\n", styles: [":host{--mdc-text-button-container-height: 24px}:host{--mdc-filled-button-container-height: 24px}:host{--mdc-protected-button-container-height: 24px}:host{--mdc-outlined-button-container-height: 24px}:host{--mat-text-button-touch-target-display: none}:host{--mat-filled-button-touch-target-display: none}:host{--mat-protected-button-touch-target-display: none}:host{--mat-outlined-button-touch-target-display: none}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{-webkit-appearance:none;margin:0}.menu-icon{font-size:16px;line-height:16px;vertical-align:top;height:16px;width:16px}.search-icon{margin-right:16px;vertical-align:middle;height:24px;color:#0000008a;font-size:21px;line-height:1.125}.font{font-size:14px}.filter-radio-button:first-of-type{padding-left:0}.filter-radio-button{padding:10px 40px;min-width:110px}.auto-width{width:260px;margin:5px;display:block;height:55px}.open-menu-icon-button{height:28px;width:28px;padding:6px}.header-filter-icon-button{height:18px;width:18px;font-size:18px;padding:0;margin:0 2px}.header-filter-icon-button ::ng-deep *{line-height:initial;font-size:initial;height:18px;width:18px;font-size:18px;bottom:initial}.header-filter-icon-button.chosen-icon,.header-filter-icon-button.chosen-icon ::ng-deep *{height:22px;width:22px;font-size:22px;color:green}mat-icon.mat-icon.suffix-icons.underline{height:20px;text-decoration:underline .1px solid}.chosen-icon mat-icon.mat-icon.suffix-icons.underline{height:24px}::ng-deep .mat-mdc-form-field-icon-prefix:has(.tb-header-prefix),.tb-header-prefix{padding:0;flex-basis:36%}.tb-header-filter ::ng-deep .mat-mdc-form-field-subscript-wrapper{line-height:0}.tb-header-filter ::ng-deep .mat-mdc-form-field-subscript-wrapper:before{height:0}.date-toggle ::ng-deep svg{position:absolute;left:0;top:0}\n"], dependencies: [{ kind: "ngmodule", type: MatMenuModule }, { kind: "component", type: i4$2.MatMenu, selector: "mat-menu", inputs: ["backdropClass", "aria-label", "aria-labelledby", "aria-describedby", "xPosition", "yPosition", "overlapTrigger", "hasBackdrop", "class", "classList"], outputs: ["closed", "close"], exportAs: ["matMenu"] }, { kind: "component", type: i4$2.MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i4$2.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i3$1.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "component", type: i3$1.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i3.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: i3.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i3.NgForm, selector: "form:not([ngNoForm]):not([formGroup]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: InListFilterComponent, selector: "tb-in-list-filter , [tb-in-list-filter]", inputs: ["key"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i1$1.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "component", type: i6.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i6.MatLabel, selector: "mat-label" }, { kind: "directive", type: i6.MatPrefix, selector: "[matPrefix], [matIconPrefix], [matTextPrefix]", inputs: ["matTextPrefix"] }, { kind: "directive", type: i6.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i4$1.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "directive", type: StopPropagationDirective, selector: "[stop-propagation]" }, { kind: "ngmodule", type: MatRadioModule }, { kind: "directive", type: i10.MatRadioGroup, selector: "mat-radio-group", inputs: ["color", "name", "labelPosition", "value", "selected", "disabled", "required", "disabledInteractive"], outputs: ["change"], exportAs: ["matRadioGroup"] }, { kind: "component", type: i10.MatRadioButton, selector: "mat-radio-button", inputs: ["id", "name", "aria-label", "aria-labelledby", "aria-describedby", "disableRipple", "tabIndex", "checked", "value", "labelPosition", "disabled", "required", "color", "disabledInteractive"], outputs: ["change"], exportAs: ["matRadioButton"] }, { kind: "ngmodule", type: MatDatepickerModule }, { kind: "component", type: i4.MatDatepicker, selector: "mat-datepicker", exportAs: ["matDatepicker"] }, { kind: "directive", type: i4.MatDatepickerInput, selector: "input[matDatepicker]", inputs: ["matDatepicker", "min", "max", "matDatepickerFilter"], exportAs: ["matDatepickerInput"] }, { kind: "component", type: i4.MatDatepickerToggle, selector: "mat-datepicker-toggle", inputs: ["for", "tabIndex", "aria-label", "disabled", "disableRipple"], exportAs: ["matDatepickerToggle"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
3443
3449
  }
3444
3450
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: HeaderMenuComponent, decorators: [{
3445
3451
  type: Component,
3446
- args: [{ selector: 'tb-header-menu', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [
3452
+ args: [{ selector: 'tb-header-menu', changeDetection: ChangeDetectionStrategy.OnPush, imports: [
3447
3453
  MatMenuModule, MatIconModule, MatButtonModule, FormsModule, InListFilterComponent,
3448
- MatInputModule, MatTooltipModule, NgClass, StopPropagationDirective, MatRadioModule, MatDatepickerModule
3449
- ], template: "<button mat-icon-button class=\"open-menu-icon-button\" disableRipple [matMenuTriggerFor]=\"menu\" [matMenuTriggerRestoreFocus]=\"false\">\r\n <mat-icon class=\"menu-icon\">more_vert</mat-icon>\r\n</button>\r\n<mat-menu #menu=\"matMenu\" >\r\n @if (!(metaData.fieldType === FieldType.NotMapped))\r\n {\r\n <button mat-menu-item (click)=\"tableState.addGroupByKey(metaData.key)\">\r\n <mat-icon color=\"primary\">group</mat-icon>\r\n <span>Group By</span>\r\n </button>\r\n }\r\n <button mat-menu-item (click)=hideField(metaData.key)>\r\n <mat-icon color=\"primary\">visibility_off</mat-icon>\r\n <span>Hide Column</span>\r\n </button>\r\n @if (!(metaData.fieldType === FieldType.NotMapped))\r\n {\r\n <ng-form #myForm=\"ngForm\" (keydown.enter)=\"onEnter(myForm.value)\" class=\"tb-header-filter\">\r\n <input type=\"hidden\" name=\"filterId\" [ngModel]=\"'header-column-' + metaData.key\" />\r\n <input type=\"hidden\" name=\"filterType\" [ngModel]=\"myFilterType\" />\r\n <input type=\"hidden\" name=\"key\" [ngModel]=\"metaData.key\" />\r\n <input type=\"hidden\" name=\"fieldType\" [ngModel]=\"metaData.fieldType\" />\r\n \r\n @if(myFilterType === FilterType.Or || myFilterType === FilterType.In){\r\n <tb-in-list-filter name='filterValue' [key]='metaData.key' [(ngModel)]='myFilterValue'/>\r\n }\r\n @else if(metaData.fieldType === FieldType.Link || metaData.fieldType === FieldType.String || metaData.fieldType === FieldType.Array || metaData.fieldType === FieldType.Unknown || metaData.fieldType === FieldType.PhoneNumber) {\r\n <mat-form-field stop-propagation class=\"font auto-width\">\r\n <mat-icon matPrefix class=\"search-icon\">search</mat-icon>\r\n <mat-label>{{myFilterType === FilterType.StringDoesNotContain ? 'Does Not Contain...' : 'Contains...'}}</mat-label>\r\n <input matInput name=\"filterValue\" [ngModel]=\"filter.filterValue\" />\r\n <span matSuffix [matTooltip]=\"myFilterType === FilterType.StringDoesNotContain ? 'Contains' : 'Does Not Contain'\">\r\n <button mat-icon-button color=\"primary\" (click)=\"setStringFilterType()\" class=\"header-filter-icon-button\">\r\n <mat-icon [ngClass]=\"{'chosen-icon': myFilterType === FilterType.StringDoesNotContain }\">\r\n block\r\n </mat-icon>\r\n </button>\r\n </span>\r\n </mat-form-field>\r\n }\r\n @else if (metaData.fieldType === FieldType.Number || metaData.fieldType === FieldType.Currency) {\r\n <mat-form-field class=\"auto-width\" stop-propagation>\r\n <mat-label>{{myFilterType === FilterType.NumberEquals ? 'Equals...' : myFilterType === FilterType.NumberLessThan ? 'Less Than...' : 'More Than...'}}</mat-label>\r\n <input matInput type='number' name=\"filterValue\" [ngModel]=\"filter.filterValue\" />\r\n <span matPrefix class=\"tb-header-prefix\">\r\n <button mat-icon-button disableRipple class=\"header-filter-icon-button\" (click)=\"setFilterType(FilterType.NumberLessThan)\"\r\n [ngClass]=\"{'chosen-icon': myFilterType === FilterType.NumberLessThan }\">\r\n <mat-icon class=\"suffix-icons\"\r\n >\r\n arrow_back_ios</mat-icon>\r\n </button>\r\n <button mat-icon-button disableRipple class=\"header-filter-icon-button\" (click)=\"setFilterType(FilterType.NumberGreaterThan)\"\r\n [ngClass]=\"{'chosen-icon': myFilterType === FilterType.NumberGreaterThan }\" >\r\n <mat-icon class=\"suffix-icons\">arrow_forward_ios</mat-icon>\r\n </button>\r\n <button mat-icon-button disableRipple class=\"header-filter-icon-button\" (click)=\"setFilterType(FilterType.NumberEquals)\"\r\n [ngClass]=\"{'chosen-icon': myFilterType === FilterType.NumberEquals }\">\r\n <span class=\"suffix-icons\">=</span>\r\n </button>\r\n </span>\r\n </mat-form-field>\r\n }\r\n @else if (metaData.fieldType === FieldType.Boolean) {\r\n <div>\r\n <label>\r\n <mat-icon class=\"search-icon\">filter_list</mat-icon>\r\n </label>\r\n <mat-radio-group stop-propagation #ctrl=\"matRadioGroup\" #boolField='ngModel' class=\"font\" name=\"filterValue\" [ngModel]=\"myFilterValue\" >\r\n <mat-radio-button class=\"filter-radio-button\" (click)=\"myFilterValue = true;\" [value]=\"true\">True</mat-radio-button><br/>\r\n <mat-radio-button class=\"filter-radio-button\" (click)=\"myFilterValue = false\" [value]=\"false\">False</mat-radio-button><br/>\r\n </mat-radio-group>\r\n </div>\r\n }\r\n @else if (metaData.fieldType === FieldType.Date || metaData.fieldType === FieldType.DateTime) {\r\n <mat-form-field class=\"font auto-width\" stop-propagation >\r\n <span matPrefix class=\"tb-header-prefix\">\r\n <button mat-icon-button disableRipple class=\"header-filter-icon-button\" (click)=\"setFilterType(FilterType.DateOnOrAfter)\"\r\n [ngClass]=\"{'chosen-icon': myFilterType === FilterType.DateOnOrAfter }\">\r\n <mat-icon class=\"suffix-icons underline\">arrow_forward_ios</mat-icon>\r\n </button>\r\n <button mat-icon-button disableRipple class=\"header-filter-icon-button\" (click)=\"setFilterType(FilterType.DateOnOrBefore)\"\r\n [ngClass]=\"{'chosen-icon': myFilterType === FilterType.DateOnOrBefore }\">\r\n <mat-icon class=\"suffix-icons underline\">arrow_back_ios</mat-icon>\r\n </button>\r\n <button mat-icon-button disableRipple class=\"header-filter-icon-button\" (click)=\"setFilterType(FilterType.DateIsOn)\"\r\n [ngClass]=\"{'chosen-icon': myFilterType === FilterType.DateIsOn }\">\r\n <span class=\"suffix-icons underline\"> =</span>\r\n </button>\r\n </span>\r\n <mat-label>{{myFilterType === FilterType.DateIsOn ? 'On...' :\r\n myFilterType === FilterType.DateOnOrBefore ? 'On or Before...' : 'On or After...'}}</mat-label>\r\n <input matInput name=\"filterValue\" [ngModel]=\"filter.filterValue\" [matDatepicker]=\"calendar\"\r\n (click)=\"calendar.open()\"/>\r\n <mat-datepicker-toggle class=\"date-toggle header-filter-icon-button\" matSuffix [for]=\"calendar\" preventEnter></mat-datepicker-toggle>\r\n <mat-datepicker #calendar></mat-datepicker>\r\n </mat-form-field>\r\n }\r\n \r\n <button mat-button (click)=\"onEnter(myForm.value)\" [disabled]=\"myForm.value.filterValue == undefined\" disableRipple>\r\n Apply\r\n </button>\r\n </ng-form>\r\n }\r\n</mat-menu>\r\n", styles: [":host{--mdc-text-button-container-height: 24px}:host{--mdc-filled-button-container-height: 24px}:host{--mdc-protected-button-container-height: 24px}:host{--mdc-outlined-button-container-height: 24px}:host{--mat-text-button-touch-target-display: none}:host{--mat-filled-button-touch-target-display: none}:host{--mat-protected-button-touch-target-display: none}:host{--mat-outlined-button-touch-target-display: none}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{-webkit-appearance:none;margin:0}.menu-icon{font-size:16px;line-height:16px;vertical-align:top;height:16px;width:16px}.search-icon{margin-right:16px;vertical-align:middle;height:24px;color:#0000008a;font-size:21px;line-height:1.125}.font{font-size:14px}.filter-radio-button:first-of-type{padding-left:0}.filter-radio-button{padding:10px 40px;min-width:110px}.auto-width{width:260px;margin:5px;display:block;height:55px}.open-menu-icon-button{height:28px;width:28px;padding:6px}.header-filter-icon-button{height:18px;width:18px;font-size:18px;padding:0;margin:0 2px}.header-filter-icon-button ::ng-deep *{line-height:initial;font-size:initial;height:18px;width:18px;font-size:18px;bottom:initial}.header-filter-icon-button.chosen-icon,.header-filter-icon-button.chosen-icon ::ng-deep *{height:22px;width:22px;font-size:22px;color:green}mat-icon.mat-icon.suffix-icons.underline{height:20px;text-decoration:underline .1px solid}.chosen-icon mat-icon.mat-icon.suffix-icons.underline{height:24px}::ng-deep .mat-mdc-form-field-icon-prefix:has(.tb-header-prefix),.tb-header-prefix{padding:0;flex-basis:36%}.tb-header-filter ::ng-deep .mat-mdc-form-field-subscript-wrapper{line-height:0}.tb-header-filter ::ng-deep .mat-mdc-form-field-subscript-wrapper:before{height:0}.date-toggle ::ng-deep svg{position:absolute;left:0;top:0}\n"] }]
3450
- }], propDecorators: { metaData: [{
3451
- type: Input
3452
- }], trigger: [{
3453
- type: ViewChild,
3454
- args: [MatMenuTrigger]
3455
- }] } });
3454
+ MatInputModule, MatTooltipModule, StopPropagationDirective, MatRadioModule, MatDatepickerModule
3455
+ ], template: "@let metaData = $metaData();\r\n\r\n<button mat-icon-button class=\"open-menu-icon-button\" disableRipple [matMenuTriggerFor]=\"menu\" [matMenuTriggerRestoreFocus]=\"false\">\r\n <mat-icon class=\"menu-icon\">more_vert</mat-icon>\r\n</button>\r\n<mat-menu #menu=\"matMenu\" >\r\n @if (!(metaData.fieldType === FieldType.NotMapped))\r\n {\r\n <button mat-menu-item (click)=\"tableState.addGroupByKey(metaData.key)\">\r\n <mat-icon color=\"primary\">group</mat-icon>\r\n <span>Group By</span>\r\n </button>\r\n }\r\n <button mat-menu-item (click)=hideField(metaData.key)>\r\n <mat-icon color=\"primary\">visibility_off</mat-icon>\r\n <span>Hide Column</span>\r\n </button>\r\n @if (!(metaData.fieldType === FieldType.NotMapped))\r\n {\r\n <ng-form #myForm=\"ngForm\" (keydown.enter)=\"onEnter(myForm.value)\" class=\"tb-header-filter\">\r\n <input type=\"hidden\" name=\"filterId\" [ngModel]=\"'header-column-' + metaData.key\" />\r\n <input type=\"hidden\" name=\"filterType\" [ngModel]=\"myFilterType\" />\r\n <input type=\"hidden\" name=\"key\" [ngModel]=\"metaData.key\" />\r\n <input type=\"hidden\" name=\"fieldType\" [ngModel]=\"metaData.fieldType\" />\r\n \r\n @if(myFilterType === FilterType.Or || myFilterType === FilterType.In){\r\n <tb-in-list-filter name='filterValue' [key]='metaData.key' [ngModel]=\"undefined\"/>\r\n }\r\n @else if(metaData.fieldType === FieldType.Link || metaData.fieldType === FieldType.String || metaData.fieldType === FieldType.Array || metaData.fieldType === FieldType.Unknown || metaData.fieldType === FieldType.PhoneNumber) {\r\n <mat-form-field stop-propagation class=\"font auto-width\">\r\n <mat-icon matPrefix class=\"search-icon\">search</mat-icon>\r\n <mat-label>{{myFilterType === FilterType.StringDoesNotContain ? 'Does Not Contain...' : 'Contains...'}}</mat-label>\r\n <input matInput name=\"filterValue\" [ngModel]=\"undefined\"/>\r\n <span matSuffix [matTooltip]=\"myFilterType === FilterType.StringDoesNotContain ? 'Contains' : 'Does Not Contain'\">\r\n <button mat-icon-button color=\"primary\" (click)=\"setStringFilterType()\" class=\"header-filter-icon-button\">\r\n <mat-icon [class]=\"{'chosen-icon': myFilterType === FilterType.StringDoesNotContain }\">\r\n block\r\n </mat-icon>\r\n </button>\r\n </span>\r\n </mat-form-field>\r\n }\r\n @else if (metaData.fieldType === FieldType.Number || metaData.fieldType === FieldType.Currency) {\r\n <mat-form-field class=\"auto-width\" stop-propagation>\r\n <mat-label>{{myFilterType === FilterType.NumberEquals ? 'Equals...' : myFilterType === FilterType.NumberLessThan ? 'Less Than...' : 'More Than...'}}</mat-label>\r\n <input matInput type='number' name=\"filterValue\" [ngModel]=\"undefined\" />\r\n <span matPrefix class=\"tb-header-prefix\">\r\n <button mat-icon-button disableRipple class=\"header-filter-icon-button\" (click)=\"setFilterType(FilterType.NumberLessThan)\"\r\n [class]=\"{'chosen-icon': myFilterType === FilterType.NumberLessThan }\">\r\n <mat-icon class=\"suffix-icons\"\r\n >\r\n arrow_back_ios</mat-icon>\r\n </button>\r\n <button mat-icon-button disableRipple class=\"header-filter-icon-button\" (click)=\"setFilterType(FilterType.NumberGreaterThan)\"\r\n [class]=\"{'chosen-icon': myFilterType === FilterType.NumberGreaterThan }\" >\r\n <mat-icon class=\"suffix-icons\">arrow_forward_ios</mat-icon>\r\n </button>\r\n <button mat-icon-button disableRipple class=\"header-filter-icon-button\" (click)=\"setFilterType(FilterType.NumberEquals)\"\r\n [class]=\"{'chosen-icon': myFilterType === FilterType.NumberEquals }\">\r\n <span class=\"suffix-icons\">=</span>\r\n </button>\r\n </span>\r\n </mat-form-field>\r\n }\r\n @else if (metaData.fieldType === FieldType.Boolean) {\r\n <div>\r\n <label>\r\n <mat-icon class=\"search-icon\">filter_list</mat-icon>\r\n </label>\r\n <mat-radio-group stop-propagation #ctrl=\"matRadioGroup\" #boolField='ngModel' class=\"font\" name=\"filterValue\" [ngModel]=\"undefined\" >\r\n <mat-radio-button class=\"filter-radio-button\" (click)=\"boolField.control.setValue(true);\" [value]=\"true\">True</mat-radio-button><br/>\r\n <mat-radio-button class=\"filter-radio-button\" (click)=\"boolField.control.setValue(false)\" [value]=\"false\">False</mat-radio-button><br/>\r\n </mat-radio-group>\r\n </div>\r\n }\r\n @else if (metaData.fieldType === FieldType.Date || metaData.fieldType === FieldType.DateTime) {\r\n <mat-form-field class=\"font auto-width\" stop-propagation >\r\n <span matPrefix class=\"tb-header-prefix\">\r\n <button mat-icon-button disableRipple class=\"header-filter-icon-button\" (click)=\"setFilterType(FilterType.DateOnOrAfter)\"\r\n [class]=\"{'chosen-icon': myFilterType === FilterType.DateOnOrAfter }\">\r\n <mat-icon class=\"suffix-icons underline\">arrow_forward_ios</mat-icon>\r\n </button>\r\n <button mat-icon-button disableRipple class=\"header-filter-icon-button\" (click)=\"setFilterType(FilterType.DateOnOrBefore)\"\r\n [class]=\"{'chosen-icon': myFilterType === FilterType.DateOnOrBefore }\">\r\n <mat-icon class=\"suffix-icons underline\">arrow_back_ios</mat-icon>\r\n </button>\r\n <button mat-icon-button disableRipple class=\"header-filter-icon-button\" (click)=\"setFilterType(FilterType.DateIsOn)\"\r\n [class]=\"{'chosen-icon': myFilterType === FilterType.DateIsOn }\">\r\n <span class=\"suffix-icons underline\"> =</span>\r\n </button>\r\n </span>\r\n <mat-label>{{myFilterType === FilterType.DateIsOn ? 'On...' :\r\n myFilterType === FilterType.DateOnOrBefore ? 'On or Before...' : 'On or After...'}}</mat-label>\r\n <input matInput name=\"filterValue\" [ngModel]=\"undefined\" [matDatepicker]=\"calendar\"\r\n (click)=\"calendar.open()\"/>\r\n <mat-datepicker-toggle class=\"date-toggle header-filter-icon-button\" matSuffix [for]=\"calendar\" preventEnter></mat-datepicker-toggle>\r\n <mat-datepicker #calendar></mat-datepicker>\r\n </mat-form-field>\r\n }\r\n <button mat-button (click)=\"onEnter(myForm.value)\" [disabled]=\"myForm.value.filterValue == undefined\" disableRipple>\r\n Apply\r\n </button>\r\n </ng-form>\r\n }\r\n</mat-menu>\r\n", styles: [":host{--mdc-text-button-container-height: 24px}:host{--mdc-filled-button-container-height: 24px}:host{--mdc-protected-button-container-height: 24px}:host{--mdc-outlined-button-container-height: 24px}:host{--mat-text-button-touch-target-display: none}:host{--mat-filled-button-touch-target-display: none}:host{--mat-protected-button-touch-target-display: none}:host{--mat-outlined-button-touch-target-display: none}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{-webkit-appearance:none;margin:0}.menu-icon{font-size:16px;line-height:16px;vertical-align:top;height:16px;width:16px}.search-icon{margin-right:16px;vertical-align:middle;height:24px;color:#0000008a;font-size:21px;line-height:1.125}.font{font-size:14px}.filter-radio-button:first-of-type{padding-left:0}.filter-radio-button{padding:10px 40px;min-width:110px}.auto-width{width:260px;margin:5px;display:block;height:55px}.open-menu-icon-button{height:28px;width:28px;padding:6px}.header-filter-icon-button{height:18px;width:18px;font-size:18px;padding:0;margin:0 2px}.header-filter-icon-button ::ng-deep *{line-height:initial;font-size:initial;height:18px;width:18px;font-size:18px;bottom:initial}.header-filter-icon-button.chosen-icon,.header-filter-icon-button.chosen-icon ::ng-deep *{height:22px;width:22px;font-size:22px;color:green}mat-icon.mat-icon.suffix-icons.underline{height:20px;text-decoration:underline .1px solid}.chosen-icon mat-icon.mat-icon.suffix-icons.underline{height:24px}::ng-deep .mat-mdc-form-field-icon-prefix:has(.tb-header-prefix),.tb-header-prefix{padding:0;flex-basis:36%}.tb-header-filter ::ng-deep .mat-mdc-form-field-subscript-wrapper{line-height:0}.tb-header-filter ::ng-deep .mat-mdc-form-field-subscript-wrapper:before{height:0}.date-toggle ::ng-deep svg{position:absolute;left:0;top:0}\n"] }]
3456
+ }] });
3456
3457
 
3457
3458
  class ColumnTotalPipe {
3458
3459
  transform(data, metaData) {
@@ -3469,7 +3470,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImpor
3469
3470
  type: Pipe,
3470
3471
  args: [{
3471
3472
  name: 'columnTotal',
3472
- standalone: true
3473
3473
  }]
3474
3474
  }] });
3475
3475
 
@@ -3518,57 +3518,76 @@ const columnsStyles = (metaDatas, userDefinedWidths) => {
3518
3518
  };
3519
3519
 
3520
3520
  class ColumnBuilderComponent {
3521
+ FieldType = FieldType;
3521
3522
  transformCreator = inject(TransformCreator);
3522
3523
  table = inject(MatTable);
3523
3524
  state = inject(TableStore);
3524
3525
  templateService = inject(TableTemplateService);
3525
- injector = inject(Injector);
3526
- columnDef;
3527
- bodyTemplate;
3528
3526
  tableConfig = inject(TableBuilderConfigToken);
3529
- FieldType = FieldType;
3530
- filter;
3531
- _metaData;
3532
- get metaData() {
3533
- return this._metaData;
3534
- }
3535
- set metaData(md) {
3536
- if (this.metaData && this.metaData.fieldType !== md.fieldType) {
3537
- this._metaData = md;
3538
- this.initialSetUp();
3539
- this.furtherSetUp();
3527
+ injector = inject(Injector);
3528
+ $columnDef = viewChild(MatColumnDef);
3529
+ $bodyTemplate = viewChild('body');
3530
+ $metaData = signal(undefined);
3531
+ $additional = computed(() => {
3532
+ const metaData = this.$metaData();
3533
+ if (!metaData)
3534
+ return;
3535
+ if (metaData.fieldType === FieldType.Link) {
3536
+ return this.state.$getLinkInfo(metaData)();
3540
3537
  }
3541
- else {
3542
- this._metaData = md;
3538
+ if (metaData.fieldType === FieldType.Array) {
3539
+ return metaData.additional?.limit || this.tableConfig?.arrayDefaults?.limit;
3543
3540
  }
3544
- }
3545
- customCell = undefined;
3546
- data$;
3547
- outerTemplate;
3548
- innerTemplate;
3549
- transform;
3550
- getInnerTemplate() {
3551
- if (this.metaData.template)
3552
- return this.metaData.template;
3553
- if (this.customCell?.TemplateRef)
3554
- return this.customCell.TemplateRef;
3555
- return this.templateService.getTemplate(this.metaData);
3556
- }
3557
- showFilters$;
3558
- getOuterTemplate() {
3559
- return this.customCell?.columnDef?.cell?.template ?? this.bodyTemplate;
3560
- }
3561
- classes;
3562
- styles = computed(() => {
3563
- return columnStyles(this.metaData, this.state.$getUserDefinedWidth(this.metaData.key)(), this.state.tableSettingsMinWidth());
3541
+ return undefined;
3542
+ });
3543
+ setMetaData(md) {
3544
+ this.$metaData.set(md);
3545
+ }
3546
+ $customCell = signal(undefined);
3547
+ $data;
3548
+ $transform = computed(() => {
3549
+ const metaData = this.$metaData();
3550
+ if (!metaData)
3551
+ return;
3552
+ return this.transformCreator.createTransformer(metaData);
3553
+ });
3554
+ $innerTemplate = computed(() => {
3555
+ const metaData = this.$metaData();
3556
+ if (!metaData)
3557
+ return;
3558
+ return metaData.template || this.$customCell()?.$templateRef() || this.templateService.getTemplate(metaData);
3559
+ });
3560
+ $showFilters = computed(() => {
3561
+ const metaData = this.$metaData();
3562
+ if (!metaData)
3563
+ return;
3564
+ const settings = this.state.$tableSettings();
3565
+ return !(settings.hideColumnHeaderFilters || metaData.noFilter);
3566
+ });
3567
+ $outerTemplate = computed(() => {
3568
+ return this.$customCell()?.columnDef?.cell?.template ?? this.$bodyTemplate();
3569
+ });
3570
+ $classes = computed(() => {
3571
+ const metaData = this.$metaData();
3572
+ if (!metaData)
3573
+ return;
3574
+ if (metaData.fieldType === FieldType.Currency) {
3575
+ return ({
3576
+ ['negative-currency']: (element) => element[metaData.key] < 0,
3577
+ ...metaData.classes
3578
+ });
3579
+ }
3580
+ return metaData.classes;
3581
+ });
3582
+ $styles = computed(() => {
3583
+ const metaData = this.$metaData();
3584
+ if (!metaData)
3585
+ return;
3586
+ return columnStyles(metaData, this.state.$getUserDefinedWidth(metaData.key)(), this.state.$tableSettingsMinWidth());
3564
3587
  });
3565
- ngOnInit() {
3566
- this.initialSetUp();
3567
- }
3568
3588
  viewInited = false;
3569
3589
  ngAfterViewInit() {
3570
- this.furtherSetUp();
3571
- this.table.addColumnDef(this.columnDef);
3590
+ this.table.addColumnDef(this.$columnDef());
3572
3591
  this.onViewInit();
3573
3592
  this.viewInited = true;
3574
3593
  }
@@ -3580,44 +3599,23 @@ class ColumnBuilderComponent {
3580
3599
  }
3581
3600
  this.onViewInit = callback;
3582
3601
  };
3583
- initialSetUp() {
3584
- if (this.metaData.fieldType === FieldType.Currency) {
3585
- this.classes = {
3586
- ['negative-currency']: (element) => element[this.metaData.key] < 0,
3587
- ...this.metaData.classes
3588
- };
3589
- }
3590
- else {
3591
- this.classes = this.metaData.classes;
3592
- }
3593
- this.filter = { key: this.metaData.key, fieldType: this.metaData.fieldType };
3594
- this.showFilters$ = this.state.tableSettings$.pipe(map(settings => !(settings.hideColumnHeaderFilters || this.metaData.noFilter)));
3595
- this.additional = this.metaData.fieldType === FieldType.Link
3596
- ? this.state.getLinkInfo(this.metaData)()
3597
- :
3598
- this.metaData.fieldType === FieldType.Array
3599
- ? this.metaData.additional?.limit || this.tableConfig?.arrayDefaults?.arrayStyle
3600
- : undefined;
3601
- }
3602
- furtherSetUp() {
3603
- this.outerTemplate = this.getOuterTemplate();
3604
- this.innerTemplate = this.getInnerTemplate();
3605
- this.transform = this.transformCreator.createTransformer(this.metaData);
3606
- }
3607
3602
  cellClicked(element, key) {
3608
- if (this.metaData.click) {
3609
- this.metaData.click(element, key);
3603
+ const metaData = this.$metaData();
3604
+ if (metaData?.click) {
3605
+ metaData.click(element, key);
3610
3606
  }
3611
3607
  }
3612
3608
  getTooltip = (element) => {
3613
- if (typeof this.metaData.toolTip === 'string') {
3614
- return this.metaData.toolTip;
3609
+ const metaData = this.$metaData();
3610
+ if (!metaData?.toolTip)
3611
+ return;
3612
+ if (typeof metaData.toolTip === 'string') {
3613
+ return metaData.toolTip;
3615
3614
  }
3616
- return this.metaData.toolTip(element);
3615
+ return metaData.toolTip(element);
3617
3616
  };
3618
- additional;
3619
3617
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: ColumnBuilderComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
3620
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.0", type: ColumnBuilderComponent, isStandalone: true, selector: "ng-component", viewQueries: [{ propertyName: "columnDef", first: true, predicate: MatColumnDef, descendants: true }, { propertyName: "bodyTemplate", first: true, predicate: ["body"], descendants: true }], ngImport: i0, template: "<ng-container [matColumnDef]=\"metaData.key\" *ngrxLet=\"styles() as styles\" >\r\n\r\n <!-- header -->\r\n <ng-template matHeaderCellDef #myHeader>\r\n <mat-header-cell cdkDrag [style]='styles.header' resizeColumn [key]=\"metaData.key\" class=\"column-head\"\r\n [class]='metaData.additional?.columnPartClasses?.header'>\r\n <div class=\"header-container\" cdkDragHandle>\r\n @if(!customCell?.columnDef?.headerCell)\r\n {\r\n @if(metaData.fieldType !== FieldType.NotMapped){\r\n <div mat-sort-header [disabled]=\"metaData.noSort\" style=\"width: 100%\">\r\n {{ metaData.displayName ? metaData.displayName : ( metaData.key | spaceCase ) }}\r\n </div>\r\n } @else if(metaData.fieldType === FieldType.NotMapped){\r\n <div style=\"width: 100%\">\r\n {{ metaData.displayName ? metaData.displayName : ( metaData.key | spaceCase ) }}\r\n </div>\r\n }\r\n @if((showFilters$ | async)){\r\n <tb-header-menu #menu [metaData]='metaData' />\r\n }\r\n }\r\n @else\r\n {\r\n <ng-container *ngTemplateOutlet=\"customCell!.columnDef!.headerCell.template; context: {metaData: metaData, styles: styles.header} \">\r\n </ng-container>\r\n }\r\n </div>\r\n </mat-header-cell>\r\n </ng-template>\r\n\r\n <!-- body -->\r\n <ng-container *matCellDef=\"let element;\">\r\n <ng-container *ngTemplateOutlet=\"outerTemplate; context: { metaData: metaData, element: element , styles: styles.body, $implicit: element }\"/>\r\n </ng-container>\r\n <ng-template #body let-element='element' >\r\n <mat-cell [matTooltip]=\"metaData.toolTip ? (getTooltip | func : element) : ''\" [conditionalClasses]='metaData.classes' [element]='element' [styler]='styles.body' (click)='cellClicked(element, metaData.key)' >\r\n <ng-container *ngTemplateOutlet=\"innerTemplate; context: { value: (transform | func : element), element: element, additional: additional, $implicit: element }; Injector: injector\" />\r\n </mat-cell>\r\n </ng-template>\r\n\r\n <!-- footer -->\r\n <ng-template matFooterCellDef>\r\n @if(customCell?.columnDef?.footerCell){\r\n <ng-container\r\n *ngTemplateOutlet=\"customCell!.columnDef!.footerCell.template; context: {metaData: metaData, data: data$, styles : styles.footer }\"/>\r\n } @else {\r\n <mat-footer-cell [style]='styles.footer' *ngrxLet=\"data$ as data\" [class]='metaData.additional?.columnPartClasses?.footer'>\r\n @if(!!data?.length && metaData.additional?.footer){\r\n <span class=\"bold\">\r\n @switch (metaData.fieldType) {\r\n @case (FieldType.Currency) { {{ data | columnTotal: metaData | currency }} }\r\n @case (FieldType.Number) { {{ data | columnTotal: metaData | number }} }\r\n }\r\n </span>\r\n }\r\n\r\n </mat-footer-cell>\r\n }\r\n </ng-template>\r\n</ng-container>\r\n", styles: [".header-container{display:flex;flex-direction:row;width:100%;align-items:center}.negative-currency{color:red}.column-head{position:relative}.bold,.group-footer{font-weight:900}.cdk-drag-preview{background:#fff;border-radius:4px;box-shadow:0 5px 5px -3px #0003,0 8px 10px 1px #00000024,0 3px 14px 2px #0000001f}.cdk-drag-placeholder{opacity:33%;border-right-width:0px}.cdk-drag-animating{transition:transform .25s cubic-bezier(0,0,.2,1)}.drag-handle{color:#add8e6;cursor:move;margin-right:9px}\n"], dependencies: [{ kind: "ngmodule", type: MatTableModule }, { kind: "directive", type: i1$5.MatHeaderCellDef, selector: "[matHeaderCellDef]" }, { kind: "directive", type: i1$5.MatColumnDef, selector: "[matColumnDef]", inputs: ["matColumnDef"] }, { kind: "directive", type: i1$5.MatCellDef, selector: "[matCellDef]" }, { kind: "directive", type: i1$5.MatFooterCellDef, selector: "[matFooterCellDef]" }, { kind: "directive", type: i1$5.MatHeaderCell, selector: "mat-header-cell, th[mat-header-cell]" }, { kind: "directive", type: i1$5.MatCell, selector: "mat-cell, td[mat-cell]" }, { kind: "directive", type: i1$5.MatFooterCell, selector: "mat-footer-cell, td[mat-footer-cell]" }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: ResizeColumnDirective, selector: "[resizeColumn]", inputs: ["resizeColumn", "key"] }, { kind: "pipe", type: FunctionPipe, name: "func" }, { kind: "directive", type: StylerDirective, selector: "[styler]", inputs: ["element", "styler"] }, { kind: "directive", type: ConditionalClassesDirective, selector: "[conditionalClasses]", inputs: ["element", "conditionalClasses"] }, { kind: "ngmodule", type: DragDropModule }, { kind: "directive", type: i5.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"] }, { kind: "directive", type: i5.CdkDragHandle, selector: "[cdkDragHandle]", inputs: ["cdkDragHandleDisabled"] }, { kind: "ngmodule", type: MatSortModule }, { kind: "component", type: i3$2.MatSortHeader, selector: "[mat-sort-header]", inputs: ["mat-sort-header", "arrowPosition", "start", "disabled", "sortActionDescription", "disableClear"], exportAs: ["matSortHeader"] }, { kind: "pipe", type: SpaceCasePipe, name: "spaceCase" }, { kind: "component", type: HeaderMenuComponent, selector: "tb-header-menu", inputs: ["metaData"] }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i4$1.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "directive", type: LetDirective, selector: "[ngrxLet]", inputs: ["ngrxLet", "ngrxLetSuspenseTpl"] }, { kind: "pipe", type: ColumnTotalPipe, name: "columnTotal" }, { kind: "pipe", type: CurrencyPipe, name: "currency" }, { kind: "pipe", type: DecimalPipe, name: "number" }], viewProviders: [
3618
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.0", type: ColumnBuilderComponent, isStandalone: true, selector: "ng-component", viewQueries: [{ propertyName: "$columnDef", first: true, predicate: MatColumnDef, descendants: true, isSignal: true }, { propertyName: "$bodyTemplate", first: true, predicate: ["body"], descendants: true, isSignal: true }], ngImport: i0, template: "@let metaData = $metaData();\r\n@let customCell = $customCell();\r\n@let styles = $styles()!;\r\n\r\n@if(metaData)\r\n{\r\n <ng-container [matColumnDef]=\"metaData.key\">\r\n\r\n <!-- header -->\r\n <ng-template matHeaderCellDef #myHeader>\r\n <mat-header-cell cdkDrag [style]='styles?.header' resizeColumn [key]=\"metaData.key\" class=\"column-head\"\r\n [class]='metaData.additional?.columnPartClasses?.header'>\r\n <div class=\"header-container\" cdkDragHandle>\r\n @if(!customCell?.columnDef?.headerCell)\r\n {\r\n @if(metaData.fieldType !== FieldType.NotMapped){\r\n <div mat-sort-header [disabled]=\"metaData.noSort\" style=\"width: 100%\">\r\n {{ metaData.displayName ? metaData.displayName : ( metaData.key | spaceCase ) }}\r\n </div>\r\n } @else if(metaData.fieldType === FieldType.NotMapped){\r\n <div style=\"width: 100%\">\r\n {{ metaData.displayName ? metaData.displayName : ( metaData.key | spaceCase ) }}\r\n </div>\r\n }\r\n @if($showFilters()){\r\n <tb-header-menu #menu [metaData]='metaData' />\r\n }\r\n }\r\n @else\r\n {\r\n <ng-container *ngTemplateOutlet=\"customCell!.columnDef!.headerCell.template; context: {metaData: metaData, styles: styles?.header} \">\r\n </ng-container>\r\n }\r\n </div>\r\n </mat-header-cell>\r\n </ng-template>\r\n \r\n <!-- body -->\r\n <ng-container *matCellDef=\"let element;\">\r\n <ng-container *ngTemplateOutlet=\"$outerTemplate()!; context: { metaData: metaData, element: element , styles: styles?.body, $implicit: element }\"/>\r\n </ng-container>\r\n <ng-template #body let-element='element' >\r\n <mat-cell [matTooltip]=\"metaData.toolTip ? (getTooltip | func : element) : ''\" [conditionalClasses]='metaData.classes' [element]='element' [styler]='styles.body' (click)='cellClicked(element, metaData.key)' >\r\n <ng-container *ngTemplateOutlet=\"$innerTemplate()!; context: { value: ($transform()! | func : element), element: element, additional: $additional(), $implicit: element }; Injector: injector\" />\r\n </mat-cell>\r\n </ng-template>\r\n \r\n <!-- footer -->\r\n <ng-template matFooterCellDef>\r\n @if(customCell?.columnDef?.footerCell){\r\n <ng-container\r\n *ngTemplateOutlet=\"customCell!.columnDef!.footerCell.template; context: {metaData: metaData, data: $data, styles : styles.footer }\"/>\r\n } @else {\r\n @let data = $data();\r\n <mat-footer-cell [style]='styles.footer' [class]='metaData.additional?.columnPartClasses?.footer'>\r\n @if(!!data?.length && metaData.additional?.footer){\r\n <span class=\"bold\">\r\n @switch (metaData.fieldType) {\r\n @case (FieldType.Currency) { {{ data | columnTotal: metaData | currency }} }\r\n @case (FieldType.Number) { {{ data | columnTotal: metaData | number }} }\r\n }\r\n </span>\r\n }\r\n \r\n </mat-footer-cell>\r\n }\r\n </ng-template>\r\n </ng-container>\r\n}", styles: [".header-container{display:flex;flex-direction:row;width:100%;align-items:center}.negative-currency{color:red}.column-head{position:relative}.bold,.group-footer{font-weight:900}.cdk-drag-preview{background:#fff;border-radius:4px;box-shadow:0 5px 5px -3px #0003,0 8px 10px 1px #00000024,0 3px 14px 2px #0000001f}.cdk-drag-placeholder{opacity:33%;border-right-width:0px}.cdk-drag-animating{transition:transform .25s cubic-bezier(0,0,.2,1)}.drag-handle{color:#add8e6;cursor:move;margin-right:9px}\n"], dependencies: [{ kind: "ngmodule", type: MatTableModule }, { kind: "directive", type: i1$5.MatHeaderCellDef, selector: "[matHeaderCellDef]" }, { kind: "directive", type: i1$5.MatColumnDef, selector: "[matColumnDef]", inputs: ["matColumnDef"] }, { kind: "directive", type: i1$5.MatCellDef, selector: "[matCellDef]" }, { kind: "directive", type: i1$5.MatFooterCellDef, selector: "[matFooterCellDef]" }, { kind: "directive", type: i1$5.MatHeaderCell, selector: "mat-header-cell, th[mat-header-cell]" }, { kind: "directive", type: i1$5.MatCell, selector: "mat-cell, td[mat-cell]" }, { kind: "directive", type: i1$5.MatFooterCell, selector: "mat-footer-cell, td[mat-footer-cell]" }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: ResizeColumnDirective, selector: "[resizeColumn]", inputs: ["resizeColumn", "key"] }, { kind: "pipe", type: FunctionPipe, name: "func" }, { kind: "directive", type: StylerDirective, selector: "[styler]", inputs: ["element", "styler"] }, { kind: "directive", type: ConditionalClassesDirective, selector: "[conditionalClasses]", inputs: ["element", "conditionalClasses"] }, { kind: "ngmodule", type: DragDropModule }, { kind: "directive", type: i5.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"] }, { kind: "directive", type: i5.CdkDragHandle, selector: "[cdkDragHandle]", inputs: ["cdkDragHandleDisabled"] }, { kind: "ngmodule", type: MatSortModule }, { kind: "component", type: i3$2.MatSortHeader, selector: "[mat-sort-header]", inputs: ["mat-sort-header", "arrowPosition", "start", "disabled", "sortActionDescription", "disableClear"], exportAs: ["matSortHeader"] }, { kind: "pipe", type: SpaceCasePipe, name: "spaceCase" }, { kind: "component", type: HeaderMenuComponent, selector: "tb-header-menu", inputs: ["metaData"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i4$1.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "pipe", type: ColumnTotalPipe, name: "columnTotal" }, { kind: "pipe", type: CurrencyPipe, name: "currency" }, { kind: "pipe", type: DecimalPipe, name: "number" }], viewProviders: [
3621
3619
  { provide: CDK_DROP_LIST, useExisting: CdkDropList },
3622
3620
  ], changeDetection: i0.ChangeDetectionStrategy.OnPush });
3623
3621
  }
@@ -3625,18 +3623,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImpor
3625
3623
  type: Component,
3626
3624
  args: [{ changeDetection: ChangeDetectionStrategy.OnPush, viewProviders: [
3627
3625
  { provide: CDK_DROP_LIST, useExisting: CdkDropList },
3628
- ], standalone: true, imports: [
3626
+ ], imports: [
3629
3627
  MatTableModule, NgTemplateOutlet, ResizeColumnDirective, FunctionPipe, StylerDirective,
3630
3628
  ConditionalClassesDirective, DragDropModule, MatSortModule, SpaceCasePipe, HeaderMenuComponent,
3631
- AsyncPipe, MatTooltipModule, LetDirective, ColumnTotalPipe, CurrencyPipe, DecimalPipe
3632
- ], template: "<ng-container [matColumnDef]=\"metaData.key\" *ngrxLet=\"styles() as styles\" >\r\n\r\n <!-- header -->\r\n <ng-template matHeaderCellDef #myHeader>\r\n <mat-header-cell cdkDrag [style]='styles.header' resizeColumn [key]=\"metaData.key\" class=\"column-head\"\r\n [class]='metaData.additional?.columnPartClasses?.header'>\r\n <div class=\"header-container\" cdkDragHandle>\r\n @if(!customCell?.columnDef?.headerCell)\r\n {\r\n @if(metaData.fieldType !== FieldType.NotMapped){\r\n <div mat-sort-header [disabled]=\"metaData.noSort\" style=\"width: 100%\">\r\n {{ metaData.displayName ? metaData.displayName : ( metaData.key | spaceCase ) }}\r\n </div>\r\n } @else if(metaData.fieldType === FieldType.NotMapped){\r\n <div style=\"width: 100%\">\r\n {{ metaData.displayName ? metaData.displayName : ( metaData.key | spaceCase ) }}\r\n </div>\r\n }\r\n @if((showFilters$ | async)){\r\n <tb-header-menu #menu [metaData]='metaData' />\r\n }\r\n }\r\n @else\r\n {\r\n <ng-container *ngTemplateOutlet=\"customCell!.columnDef!.headerCell.template; context: {metaData: metaData, styles: styles.header} \">\r\n </ng-container>\r\n }\r\n </div>\r\n </mat-header-cell>\r\n </ng-template>\r\n\r\n <!-- body -->\r\n <ng-container *matCellDef=\"let element;\">\r\n <ng-container *ngTemplateOutlet=\"outerTemplate; context: { metaData: metaData, element: element , styles: styles.body, $implicit: element }\"/>\r\n </ng-container>\r\n <ng-template #body let-element='element' >\r\n <mat-cell [matTooltip]=\"metaData.toolTip ? (getTooltip | func : element) : ''\" [conditionalClasses]='metaData.classes' [element]='element' [styler]='styles.body' (click)='cellClicked(element, metaData.key)' >\r\n <ng-container *ngTemplateOutlet=\"innerTemplate; context: { value: (transform | func : element), element: element, additional: additional, $implicit: element }; Injector: injector\" />\r\n </mat-cell>\r\n </ng-template>\r\n\r\n <!-- footer -->\r\n <ng-template matFooterCellDef>\r\n @if(customCell?.columnDef?.footerCell){\r\n <ng-container\r\n *ngTemplateOutlet=\"customCell!.columnDef!.footerCell.template; context: {metaData: metaData, data: data$, styles : styles.footer }\"/>\r\n } @else {\r\n <mat-footer-cell [style]='styles.footer' *ngrxLet=\"data$ as data\" [class]='metaData.additional?.columnPartClasses?.footer'>\r\n @if(!!data?.length && metaData.additional?.footer){\r\n <span class=\"bold\">\r\n @switch (metaData.fieldType) {\r\n @case (FieldType.Currency) { {{ data | columnTotal: metaData | currency }} }\r\n @case (FieldType.Number) { {{ data | columnTotal: metaData | number }} }\r\n }\r\n </span>\r\n }\r\n\r\n </mat-footer-cell>\r\n }\r\n </ng-template>\r\n</ng-container>\r\n", styles: [".header-container{display:flex;flex-direction:row;width:100%;align-items:center}.negative-currency{color:red}.column-head{position:relative}.bold,.group-footer{font-weight:900}.cdk-drag-preview{background:#fff;border-radius:4px;box-shadow:0 5px 5px -3px #0003,0 8px 10px 1px #00000024,0 3px 14px 2px #0000001f}.cdk-drag-placeholder{opacity:33%;border-right-width:0px}.cdk-drag-animating{transition:transform .25s cubic-bezier(0,0,.2,1)}.drag-handle{color:#add8e6;cursor:move;margin-right:9px}\n"] }]
3633
- }], propDecorators: { columnDef: [{
3634
- type: ViewChild,
3635
- args: [MatColumnDef]
3636
- }], bodyTemplate: [{
3637
- type: ViewChild,
3638
- args: ['body']
3639
- }] } });
3629
+ MatTooltipModule, ColumnTotalPipe, CurrencyPipe, DecimalPipe
3630
+ ], template: "@let metaData = $metaData();\r\n@let customCell = $customCell();\r\n@let styles = $styles()!;\r\n\r\n@if(metaData)\r\n{\r\n <ng-container [matColumnDef]=\"metaData.key\">\r\n\r\n <!-- header -->\r\n <ng-template matHeaderCellDef #myHeader>\r\n <mat-header-cell cdkDrag [style]='styles?.header' resizeColumn [key]=\"metaData.key\" class=\"column-head\"\r\n [class]='metaData.additional?.columnPartClasses?.header'>\r\n <div class=\"header-container\" cdkDragHandle>\r\n @if(!customCell?.columnDef?.headerCell)\r\n {\r\n @if(metaData.fieldType !== FieldType.NotMapped){\r\n <div mat-sort-header [disabled]=\"metaData.noSort\" style=\"width: 100%\">\r\n {{ metaData.displayName ? metaData.displayName : ( metaData.key | spaceCase ) }}\r\n </div>\r\n } @else if(metaData.fieldType === FieldType.NotMapped){\r\n <div style=\"width: 100%\">\r\n {{ metaData.displayName ? metaData.displayName : ( metaData.key | spaceCase ) }}\r\n </div>\r\n }\r\n @if($showFilters()){\r\n <tb-header-menu #menu [metaData]='metaData' />\r\n }\r\n }\r\n @else\r\n {\r\n <ng-container *ngTemplateOutlet=\"customCell!.columnDef!.headerCell.template; context: {metaData: metaData, styles: styles?.header} \">\r\n </ng-container>\r\n }\r\n </div>\r\n </mat-header-cell>\r\n </ng-template>\r\n \r\n <!-- body -->\r\n <ng-container *matCellDef=\"let element;\">\r\n <ng-container *ngTemplateOutlet=\"$outerTemplate()!; context: { metaData: metaData, element: element , styles: styles?.body, $implicit: element }\"/>\r\n </ng-container>\r\n <ng-template #body let-element='element' >\r\n <mat-cell [matTooltip]=\"metaData.toolTip ? (getTooltip | func : element) : ''\" [conditionalClasses]='metaData.classes' [element]='element' [styler]='styles.body' (click)='cellClicked(element, metaData.key)' >\r\n <ng-container *ngTemplateOutlet=\"$innerTemplate()!; context: { value: ($transform()! | func : element), element: element, additional: $additional(), $implicit: element }; Injector: injector\" />\r\n </mat-cell>\r\n </ng-template>\r\n \r\n <!-- footer -->\r\n <ng-template matFooterCellDef>\r\n @if(customCell?.columnDef?.footerCell){\r\n <ng-container\r\n *ngTemplateOutlet=\"customCell!.columnDef!.footerCell.template; context: {metaData: metaData, data: $data, styles : styles.footer }\"/>\r\n } @else {\r\n @let data = $data();\r\n <mat-footer-cell [style]='styles.footer' [class]='metaData.additional?.columnPartClasses?.footer'>\r\n @if(!!data?.length && metaData.additional?.footer){\r\n <span class=\"bold\">\r\n @switch (metaData.fieldType) {\r\n @case (FieldType.Currency) { {{ data | columnTotal: metaData | currency }} }\r\n @case (FieldType.Number) { {{ data | columnTotal: metaData | number }} }\r\n }\r\n </span>\r\n }\r\n \r\n </mat-footer-cell>\r\n }\r\n </ng-template>\r\n </ng-container>\r\n}", styles: [".header-container{display:flex;flex-direction:row;width:100%;align-items:center}.negative-currency{color:red}.column-head{position:relative}.bold,.group-footer{font-weight:900}.cdk-drag-preview{background:#fff;border-radius:4px;box-shadow:0 5px 5px -3px #0003,0 8px 10px 1px #00000024,0 3px 14px 2px #0000001f}.cdk-drag-placeholder{opacity:33%;border-right-width:0px}.cdk-drag-animating{transition:transform .25s cubic-bezier(0,0,.2,1)}.drag-handle{color:#add8e6;cursor:move;margin-right:9px}\n"] }]
3631
+ }] });
3640
3632
 
3641
3633
  // If we are only sorting due to a change in the Sorts[] we can 'optimize'. If the sort array was first by column a asc then by column b desc then by column c asc,
3642
3634
  // and now it is first by column d asc then by column a desc then by column b desc then by column c asc, we dont need to rerun the tail, i.e. for culumn b and c.
@@ -3689,132 +3681,115 @@ class GenericTableComponent {
3689
3681
  dataStore = inject(DataStore);
3690
3682
  viewContainer = inject(ViewContainerRef);
3691
3683
  transformCreator = inject(TransformCreator);
3684
+ _injector = inject(Injector);
3692
3685
  smallFooter = 10;
3693
3686
  $headerRow = viewChild(MatHeaderRowDef);
3694
3687
  $footerRow = viewChild(MatFooterRowDef);
3695
3688
  $table = viewChild(MatTable);
3696
- drop(event) {
3697
- this.state.setUserDefinedOrder({ newOrder: event.currentIndex, oldOrder: event.previousIndex });
3698
- }
3699
- _trackBy;
3700
- set trackBy(trackBy) {
3701
- if (trackBy) {
3702
- this._trackBy = trackBy;
3703
- this.trackByFunction = (index, item) => item[trackBy];
3704
- }
3705
- this.setUpSelections(trackBy);
3706
- }
3707
- get trackBy() { return this._trackBy; }
3708
- $displayData = input.required({ alias: 'displayData' });
3709
- $displayDataLength = computed(() => this.$displayData()?.length || 0);
3710
- $hasFooterMeta = computed(() => this.state.$metaDataArray().some(md => !!md.additional?.footer));
3689
+ $dropList = viewChild(CdkDropList);
3690
+ selection$ = output({ alias: 'selection' });
3691
+ $displayDataLength = input.required({ alias: 'displayDataLength' });
3711
3692
  $data = input.required({ alias: 'data' });
3712
- data$ = toObservable(this.$data);
3713
3693
  $rows = input([], { alias: 'rows' });
3714
3694
  $columnInfos = input.required({ alias: 'columnInfos' });
3695
+ $dataSource = input.required({ alias: 'dataSource' });
3696
+ $keys = computed(() => {
3697
+ const displayed = this.state.$orderedVisibleColumns();
3698
+ const built = this.$columns();
3699
+ const keys = displayed.filter(d => !!built[d]);
3700
+ if (this.$hasSelectColumn()) {
3701
+ keys.unshift('select');
3702
+ }
3703
+ if (this.$hasIndexColumn()) {
3704
+ keys.unshift('index');
3705
+ }
3706
+ return keys;
3707
+ });
3708
+ keys$ = toObservable(this.$keys);
3709
+ $trackBy = input(undefined, { alias: 'trackBy' });
3710
+ $trackByFunction = computed(() => {
3711
+ const trackBy = this.$trackBy();
3712
+ if (!trackBy)
3713
+ return (index, item) => item[initIndexSymbol];
3714
+ return ((index, item) => item[trackBy]);
3715
+ });
3716
+ $hasFooterMeta = computed(() => this.state.$metaDataArray().some(md => !!md.additional?.footer));
3715
3717
  $hasCustomFooter = computed(() => this.$columnInfos()?.some(ci => !!ci.customCell?.columnDef?.footerCell));
3716
- dropList;
3717
3718
  $footerRowStyle = computed(() => {
3718
3719
  const hasData = !!this.$displayDataLength();
3719
3720
  const metaFooter = this.$hasFooterMeta();
3720
3721
  const customFooter = this.$hasCustomFooter();
3721
- const hasSelectionColumn = this.state.props().selectionColumn;
3722
+ const hasSelectionColumn = this.state.$props().selectionColumn;
3722
3723
  return customFooter || (hasData && (metaFooter || hasSelectionColumn)) ? 'regular-footer' : hasData ? 'no-footer' : 'small-footer';
3723
3724
  });
3724
3725
  $showFooterRow = computed(() => this.$footerRowStyle() !== 'no-footer');
3725
- _injector = inject(Injector);
3726
3726
  injector = Injector.create({
3727
3727
  providers: [
3728
3728
  { provide: MatTable, useFactory: () => this.$table() },
3729
- { provide: CdkDropList, useFactory: () => this.dropList },
3729
+ { provide: CdkDropList, useFactory: () => this.$dropList() },
3730
3730
  ],
3731
3731
  parent: this._injector
3732
3732
  });
3733
- $hasSelectColumn = computed(() => this.state.selectSignal(state => state.props.selectionColumn)());
3734
3733
  $hasIndexColumn = computed(() => this.state.selectSignal(state => state.props.indexColumn)());
3735
3734
  $columns = signal({});
3736
- $showHeader = computed(() => !this.state.tableSettings().hideColumnHeader);
3737
- offset$ = this.dataStore.select(s => s.virtualScrollOffset);
3738
- constructor() {
3739
- this.setUpSelections();
3740
- effect(() => {
3741
- const columnInfos = this.$columnInfos() || [];
3742
- const table = this.$table();
3743
- if (!table)
3744
- return;
3745
- untracked(() => {
3746
- Object.entries(this.$columns()).forEach(([key, value]) => {
3747
- const columnInfo = columnInfos.find(ci => ci.metaData.key === key);
3748
- if (!columnInfo || columnInfo.customCell !== value.customCell) {
3749
- delete this.$columns()[key];
3750
- table?.removeColumnDef(value.columnDef);
3751
- }
3752
- });
3753
- columnInfos.forEach(ci => this.buildColumn(ci));
3754
- });
3755
- });
3756
- effect(() => {
3757
- const table = this.$table();
3758
- const rows = this.$rows();
3759
- const keys = this.$keys();
3760
- if (!table)
3761
- return;
3762
- untracked(() => {
3763
- rows.forEach(row => {
3764
- table.removeRowDef(row);
3765
- row.columns = keys;
3766
- table.addRowDef(row);
3767
- });
3735
+ $showHeader = computed(() => !this.state.$tableSettings().hideColumnHeader);
3736
+ $offset = this.dataStore.selectSignal(s => s.virtualScrollOffset);
3737
+ drop(event) {
3738
+ this.state.setUserDefinedOrder({ newOrder: event.currentIndex, oldOrder: event.previousIndex });
3739
+ }
3740
+ #buildColumnsEffect = effect(() => {
3741
+ const columnInfos = this.$columnInfos() || [];
3742
+ const table = this.$table();
3743
+ if (!table)
3744
+ return;
3745
+ untracked(() => {
3746
+ Object.entries(this.$columns()).forEach(([key, value]) => {
3747
+ const columnInfo = columnInfos.find(ci => ci.metaData.key === key);
3748
+ if (!columnInfo || columnInfo.customCell !== value.$customCell()) {
3749
+ delete this.$columns()[key];
3750
+ table?.removeColumnDef(value.$columnDef());
3751
+ }
3768
3752
  });
3753
+ columnInfos.forEach(ci => this.buildColumn(ci));
3769
3754
  });
3770
- effect(() => {
3771
- const headerRow = this.$headerRow();
3772
- const showHeader = this.$showHeader();
3773
- const table = this.$table();
3774
- untracked(() => {
3775
- if (headerRow && showHeader && table)
3776
- table.addHeaderRowDef(headerRow);
3777
- else if (headerRow && table)
3778
- table.removeHeaderRowDef(headerRow);
3755
+ });
3756
+ #buildRowsEffect = effect(() => {
3757
+ const table = this.$table();
3758
+ const rows = this.$rows();
3759
+ const keys = this.$keys();
3760
+ if (!table)
3761
+ return;
3762
+ untracked(() => {
3763
+ rows.forEach(row => {
3764
+ table.removeRowDef(row);
3765
+ row.columns = keys;
3766
+ table.addRowDef(row);
3779
3767
  });
3780
3768
  });
3781
- effect(() => {
3782
- const footerRow = this.$footerRow();
3783
- const showFooter = this.$showFooterRow();
3784
- const table = this.$table();
3785
- untracked(() => {
3786
- if (footerRow && showFooter && table)
3787
- table.addFooterRowDef(footerRow);
3788
- else if (footerRow && table)
3789
- table.removeFooterRowDef(footerRow);
3790
- });
3769
+ });
3770
+ #buildHeaderRowEffect = effect(() => {
3771
+ const headerRow = this.$headerRow();
3772
+ const showHeader = this.$showHeader();
3773
+ const table = this.$table();
3774
+ untracked(() => {
3775
+ if (headerRow && showHeader && table)
3776
+ table.addHeaderRowDef(headerRow);
3777
+ else if (headerRow && table)
3778
+ table.removeHeaderRowDef(headerRow);
3791
3779
  });
3792
- }
3793
- defaultTrackBy = (index, item) => item[initIndexSymbol];
3794
- trackByFunction = this.defaultTrackBy;
3795
- $keys = computed(() => {
3796
- const displayed = this.state.$orderedVisibleColumns();
3797
- const built = this.$columns();
3798
- const keys = displayed.filter(d => !!built[d]);
3799
- if (this.$hasSelectColumn()) {
3800
- keys.unshift('select');
3801
- }
3802
- if (this.$hasIndexColumn()) {
3803
- keys.unshift('index');
3804
- }
3805
- return keys;
3806
3780
  });
3807
- keys$ = toObservable(this.$keys);
3808
- ngOnInit() {
3809
- this.state.on(this.selectableData$, (data) => {
3810
- if (this.selection.selected.length) {
3811
- const trackByFunction = this.trackBy ? (s) => data.every(d => d[this.trackBy] !== s[this.trackBy]) : s => !data.includes(s);
3812
- const removed = this.selection.selected.filter(trackByFunction);
3813
- this.selection.deselect(...removed);
3814
- }
3781
+ #buildFooterEffect = effect(() => {
3782
+ const footerRow = this.$footerRow();
3783
+ const showFooter = this.$showFooterRow();
3784
+ const table = this.$table();
3785
+ untracked(() => {
3786
+ if (footerRow && showFooter && table)
3787
+ table.addFooterRowDef(footerRow);
3788
+ else if (footerRow && table)
3789
+ table.removeFooterRowDef(footerRow);
3815
3790
  });
3816
- }
3817
- $usePaginator = computed(() => this.state.tableSettings().usePaginator);
3791
+ });
3792
+ $usePaginator = computed(() => this.state.$tableSettings().usePaginator);
3818
3793
  $useVirtualScroll = computed(() => this.state.$viewType().includes('virtual'));
3819
3794
  $offsetIndex = computed(() => {
3820
3795
  const virtualStart = this.dataStore.selectSignal(d => d.virtualEnds.start)();
@@ -3837,16 +3812,16 @@ class GenericTableComponent {
3837
3812
  buildColumn(column) {
3838
3813
  const alreadyBuiltColumn = this.$columns()[column.metaData.key];
3839
3814
  if (alreadyBuiltColumn) {
3840
- alreadyBuiltColumn.metaData = column.metaData;
3815
+ alreadyBuiltColumn.setMetaData(column.metaData);
3841
3816
  }
3842
3817
  else {
3843
3818
  const component = this.viewContainer.createComponent(ColumnBuilderComponent, {
3844
3819
  index: 0,
3845
3820
  injector: this.injector
3846
3821
  });
3847
- component.instance.customCell = column.customCell;
3848
- component.instance.metaData = column.metaData;
3849
- component.instance.data$ = this.data$;
3822
+ component.instance.$customCell.set(column.customCell);
3823
+ component.instance.setMetaData(column.metaData);
3824
+ component.instance.$data = this.$data;
3850
3825
  component.instance.whenViewInited(() => {
3851
3826
  this.$columns.update(columnsDict => ({
3852
3827
  ...columnsDict,
@@ -3855,14 +3830,34 @@ class GenericTableComponent {
3855
3830
  });
3856
3831
  }
3857
3832
  }
3858
- selection;
3859
- selection$ = new EventEmitter();
3860
- masterToggleChecked$ = this.selection$.pipe(map(() => this.selection.hasValue() && this.isAllSelected()));
3861
- masterToggleIndeterminate$ = this.selection$.pipe(map(() => this.selection.hasValue() && !this.isAllSelected()));
3862
- setUpSelections(trackBy) {
3863
- this.selection = trackBy ? new SelectionModel(true, [], true, (a, b) => a[trackBy] === b[trackBy]) : new SelectionModel(true, []);
3864
- this.state.on(this.selection.changed, c => this.selection$.emit(c));
3865
- }
3833
+ $hasSelectColumn = computed(() => this.state.selectSignal(state => state.props.selectionColumn)());
3834
+ $selection = computed(() => {
3835
+ const trackBy = this.$trackBy();
3836
+ if (trackBy) {
3837
+ return new SelectionModel(true, [], true, (a, b) => a[trackBy] === b[trackBy]);
3838
+ }
3839
+ return new SelectionModel(true, []);
3840
+ });
3841
+ selectionChange$ = toObservable(this.$selection).pipe(switchMap(s => s.changed));
3842
+ $selectionChange = toSignal(this.selectionChange$);
3843
+ onSelectionChangeEffect = effect(() => {
3844
+ const selectionChange = this.$selectionChange();
3845
+ if (!selectionChange)
3846
+ return;
3847
+ untracked(() => this.selection$.emit(selectionChange));
3848
+ });
3849
+ $isAllSelected = computed(() => {
3850
+ this.$selectionChange();
3851
+ const selected = this.$selection()?.selected;
3852
+ if (!selected)
3853
+ return false;
3854
+ return this.$selectableData()?.length === selected.length;
3855
+ });
3856
+ $masterToggleChecked = this.$isAllSelected;
3857
+ $masterToggleIndeterminate = computed(() => {
3858
+ this.$selectionChange();
3859
+ return !!this.$selection()?.selected.length && !this.$masterToggleChecked();
3860
+ });
3866
3861
  $selectableData = computed(() => {
3867
3862
  if (this.state.$viewType() === 'virtual paginator' || this.state.$viewType() === 'paginator') {
3868
3863
  const previousPageRecords = this.state.$currentPage() * this.state.$pageSize();
@@ -3873,46 +3868,55 @@ class GenericTableComponent {
3873
3868
  }
3874
3869
  return [];
3875
3870
  });
3876
- selectableData$ = toObservable(this.$selectableData);
3877
- isAllSelected() {
3878
- const numSelected = this.selection.selected.length;
3879
- const numRows = this.$selectableData()?.length || 0;
3880
- return numSelected === numRows;
3881
- }
3871
+ #onSelectableDataChangeEffect = effect(() => {
3872
+ const selectableData = this.$selectableData();
3873
+ untracked(() => {
3874
+ const selected = this.$selection()?.selected;
3875
+ if (!selected.length)
3876
+ return;
3877
+ const trackBy = this.$trackBy();
3878
+ const trackByFunc = trackBy ? (s) => selectableData.every(d => d[trackBy] !== s[trackBy]) : s => !selectableData.includes(s);
3879
+ const removed = selected.filter(trackByFunc);
3880
+ this.$selection().deselect(removed);
3881
+ });
3882
+ });
3882
3883
  /** Selects all rows if they are not all selected; otherwise clear selection. */
3883
3884
  masterToggle() {
3884
- if (this.isAllSelected()) {
3885
- this.selection.clear();
3885
+ if (this.$isAllSelected()) {
3886
+ this.$selection().clear();
3886
3887
  }
3887
3888
  else {
3888
- this.selection.select(...this.$selectableData());
3889
+ this.$selection().select(...this.$selectableData());
3889
3890
  }
3890
3891
  }
3891
- tableWidth = this.state.getUserDefinedTableSize$.pipe(previousAndCurrent(0), map(([previousUserDefinedWidth, currentUserDefinedWidth]) => {
3892
- if (currentUserDefinedWidth) {
3893
- return ({ width: `${currentUserDefinedWidth}px`, minWidth: 'initial' });
3894
- }
3895
- if (wasReset()) {
3896
- return ({ width: 'initial' });
3897
- }
3898
- return ({});
3899
- function wasReset() {
3900
- return (previousUserDefinedWidth ?? 0) >= 0 && currentUserDefinedWidth == null;
3892
+ $tableWidth = linkedSignal({
3893
+ source: this.state.$getUserDefinedTableWidth,
3894
+ computation: (currentUserDefinedWidth, { source: previousUserDefinedWidth } = { value: null, source: 0 }) => {
3895
+ if (currentUserDefinedWidth) {
3896
+ return ({ width: `${currentUserDefinedWidth}px`, minWidth: 'initial' });
3897
+ }
3898
+ if (wasReset()) {
3899
+ return ({ width: 'initial' });
3900
+ }
3901
+ return {};
3902
+ function wasReset() {
3903
+ return (previousUserDefinedWidth ?? 0) >= 0 && currentUserDefinedWidth == null;
3904
+ }
3901
3905
  }
3902
- }));
3906
+ });
3903
3907
  getTransform = (key, val) => {
3904
3908
  if (val == undefined || val === 'null')
3905
3909
  return '';
3906
3910
  try {
3907
- return this.transformCreator.createTransformer(this.$columns[key].metaData, true)({ [key]: val });
3911
+ return this.transformCreator.createTransformer(this.state.$getMetaData(key)(), true, true)(val);
3908
3912
  }
3909
3913
  catch (error) {
3910
3914
  return val;
3911
3915
  }
3912
3916
  };
3913
3917
  $rowHeight = this.state.selectSignal(s => {
3914
- if (this.state.$isVirtual() && s.notPersistedTableSettings.useVirtualScroll?.enforceRowHeight) {
3915
- const height = s.notPersistedTableSettings.useVirtualScroll.rowHeight;
3918
+ if (this.state.$isVirtual() && s.notPersistedTableSettings.virtualSettings?.enforceRowHeight) {
3919
+ const height = s.notPersistedTableSettings.virtualSettings.rowHeight;
3916
3920
  return height + 'px';
3917
3921
  }
3918
3922
  if (typeof s.notPersistedTableSettings.rowHeight === 'number') {
@@ -3921,8 +3925,8 @@ class GenericTableComponent {
3921
3925
  return s.notPersistedTableSettings.rowHeight;
3922
3926
  });
3923
3927
  $headerHeight = this.state.selectSignal(s => {
3924
- if (this.state.$isVirtual() && s.notPersistedTableSettings.useVirtualScroll?.enforceHeaderHeight) {
3925
- const height = s.notPersistedTableSettings.useVirtualScroll.headerHeight;
3928
+ if (this.state.$isVirtual() && s.notPersistedTableSettings.virtualSettings?.enforceHeaderHeight) {
3929
+ const height = s.notPersistedTableSettings.virtualSettings.headerHeight;
3926
3930
  return height + 'px';
3927
3931
  }
3928
3932
  if (typeof s.notPersistedTableSettings.headerHeight === 'number') {
@@ -3947,24 +3951,17 @@ class GenericTableComponent {
3947
3951
  return '0px';
3948
3952
  }
3949
3953
  });
3950
- $stickyFooter = computed(() => this.state.props().stickyFooter || this.state.$isVirtual());
3954
+ $stickyFooter = computed(() => this.state.$props().stickyFooter || this.state.$isVirtual());
3951
3955
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: GenericTableComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
3952
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.0", type: GenericTableComponent, isStandalone: true, selector: "tb-generic-table", inputs: { trackBy: { classPropertyName: "trackBy", publicName: "trackBy", isSignal: false, isRequired: false, transformFunction: null }, $displayData: { classPropertyName: "$displayData", publicName: "displayData", isSignal: true, isRequired: true, transformFunction: null }, $data: { classPropertyName: "$data", publicName: "data", isSignal: true, isRequired: true, transformFunction: null }, $rows: { classPropertyName: "$rows", publicName: "rows", isSignal: true, isRequired: false, transformFunction: null }, $columnInfos: { classPropertyName: "$columnInfos", publicName: "columnInfos", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { selection$: "selection$" }, viewQueries: [{ propertyName: "$headerRow", first: true, predicate: MatHeaderRowDef, descendants: true, isSignal: true }, { propertyName: "$footerRow", first: true, predicate: MatFooterRowDef, descendants: true, isSignal: true }, { propertyName: "$table", first: true, predicate: MatTable, descendants: true, isSignal: true }, { propertyName: "dropList", first: true, predicate: CdkDropList, descendants: true, static: true }], ngImport: i0, template: "<mat-table\r\n cdkDropList\r\n cdkDropListLockAxis='x'\r\n cdkDropListOrientation=\"horizontal\"\r\n (cdkDropListDropped)=\"drop($event)\"\r\n class=\"table-drag-list\"\r\n #table\r\n [dataSource]=\"state.props().dataSource!\"\r\n [trackBy]=\"trackByFunction\"\r\n [style]=\"tableWidth | async \"\r\n>\r\n\r\n <!-- select column -->\r\n <ng-container matColumnDef=\"select\">\r\n\r\n <mat-header-cell *matHeaderCellDef class=\"select-column\">\r\n <mat-checkbox (change)=\"$event ? masterToggle() : null\"\r\n [checked]=\"!!(masterToggleChecked$ | async)\"\r\n [indeterminate]=\"masterToggleIndeterminate$ | async\">\r\n </mat-checkbox>\r\n </mat-header-cell>\r\n\r\n <mat-cell *matCellDef=\"let row\" class=\"select-column\">\r\n <mat-checkbox\r\n (click)=\"$event.stopPropagation()\"\r\n (change)=\"$event ? selection.toggle(row) : null\"\r\n [checked]=\"selection.isSelected(row)\"/>\r\n </mat-cell>\r\n\r\n <mat-footer-cell *matFooterCellDef class=\"select-column\">\r\n {{ selection.selected.length }}\r\n </mat-footer-cell>\r\n </ng-container>\r\n\r\n\r\n <!-- index column -->\r\n <ng-container matColumnDef=\"index\">\r\n <mat-header-cell *matHeaderCellDef class=\"f-mat-header-cell\" class=\"index-column\">#\r\n </mat-header-cell>\r\n <mat-cell *matCellDef=\"let i = index;\" class=\"index-column\">\r\n {{ 1 + i + $offsetIndex() }}\r\n </mat-cell>\r\n <mat-footer-cell *matFooterCellDef class=\"index-column\"></mat-footer-cell>\r\n </ng-container>\r\n\r\n <!-- Grouping -->\r\n <ng-container matColumnDef=\"groupHeader\">\r\n <mat-cell *matCellDef=\"let row\">\r\n @let expanded = (state.getIsExpanded | func : row.key : row.groupName );\r\n <div [style.paddingLeft]=\"row.padding + 'px !important'\">\r\n <button mat-icon-button (click)=\"setExpanded(row.key, row.groupName, !expanded());\">\r\n @if (!expanded()) {\r\n <mat-icon>chevron_right</mat-icon>\r\n } @else {\r\n <mat-icon>expand_more</mat-icon>\r\n }\r\n </button>\r\n {{ getTransform | func : row.key : row.groupHeaderDisplay }} ({{ row.length }})\r\n </div>\r\n <div style=\"flex-grow: 1\">\r\n <ng-container *ngTemplateOutlet=\"state.props().groupHeaderTemplate!; context: { element: row }\"></ng-container>\r\n </div>\r\n </mat-cell>\r\n </ng-container>\r\n\r\n <mat-row [style.height]=\"$rowHeight()\" [style.min-height]=\"$rowHeight()\"\r\n *matRowDef=\"let row; columns: $keys(); let i = index\"/>\r\n <mat-row [style.height]=\"state.props().groupHeaderHeight ? state.props().groupHeaderHeight + 'px' : $groupHeaderHeight()\"\r\n [style.min-height]=\"state.props().groupHeaderHeight ? state.props().groupHeaderHeight + 'px' : $groupHeaderHeight()\"\r\n *matRowDef=\"let row; columns: ['groupHeader']; when: isGroupHeader\" style=\"background-color: white;\"/>\r\n</mat-table>\r\n\r\n<mat-header-row [style.height]=\"$headerHeight()\" [style.min-height]=\"$headerHeight()\"\r\n *matHeaderRowDef=\"$keys(); sticky: state.props().isSticky\" [style.top.px]=\"((offset$ | async)! * -1)\"/>\r\n<mat-footer-row [style.height]=\"$footerHeight()\" [style.min-height]=\"$footerHeight()\"\r\n *matFooterRowDef=\"$keys(); sticky: $stickyFooter() \"\r\n [style.bottom.px]=\"$stickyFooter() ? (offset$ | async) : undefined\"/>\r\n", styles: [":host{--mat-paginator-container-size: initial}.select-column{min-width:var(--tb-min-select-column-width, 42px)}.index-column{min-width:var(--tb-min-index-column-width, 42px)}.mat-mdc-row:nth-child(odd){background-color:var(--tb-odd-row-background-color, #cdeefe)}.page-amounts{color:#0000008a;font-family:Roboto,Helvetica Neue,sans-serif;font-size:12px;margin-right:.2rem}:host::ng-deep .table-drag-list.cdk-drop-list-dragging .drag-header:not(.cdk-drag-placeholder){transition:transform .25s cubic-bezier(0,0,.2,1)}:host::ng-deep .mdc-data-table__cell,:host::ng-deep .mdc-data-table__header-cell{padding:var(--tb-cell-padding, 0 0 0 .2rem);line-height:var(--tb-cell-line-height, normal)}::ng-deep .op-date-time-input{line-height:3rem;font-size:.9rem;font-family:Roboto,Helvetica Neue,sans-serif;padding-left:.2rem;width:12rem}\n"], dependencies: [{ kind: "ngmodule", type: MatTableModule }, { kind: "component", type: i1$5.MatTable, selector: "mat-table, table[mat-table]", exportAs: ["matTable"] }, { kind: "directive", type: i1$5.MatHeaderCellDef, selector: "[matHeaderCellDef]" }, { kind: "directive", type: i1$5.MatHeaderRowDef, selector: "[matHeaderRowDef]", inputs: ["matHeaderRowDef", "matHeaderRowDefSticky"] }, { kind: "directive", type: i1$5.MatColumnDef, selector: "[matColumnDef]", inputs: ["matColumnDef"] }, { kind: "directive", type: i1$5.MatCellDef, selector: "[matCellDef]" }, { kind: "directive", type: i1$5.MatRowDef, selector: "[matRowDef]", inputs: ["matRowDefColumns", "matRowDefWhen"] }, { kind: "directive", type: i1$5.MatFooterCellDef, selector: "[matFooterCellDef]" }, { kind: "directive", type: i1$5.MatFooterRowDef, selector: "[matFooterRowDef]", inputs: ["matFooterRowDef", "matFooterRowDefSticky"] }, { kind: "directive", type: i1$5.MatHeaderCell, selector: "mat-header-cell, th[mat-header-cell]" }, { kind: "directive", type: i1$5.MatCell, selector: "mat-cell, td[mat-cell]" }, { kind: "directive", type: i1$5.MatFooterCell, selector: "mat-footer-cell, td[mat-footer-cell]" }, { kind: "component", type: i1$5.MatHeaderRow, selector: "mat-header-row, tr[mat-header-row]", exportAs: ["matHeaderRow"] }, { kind: "component", type: i1$5.MatRow, selector: "mat-row, tr[mat-row]", exportAs: ["matRow"] }, { kind: "component", type: i1$5.MatFooterRow, selector: "mat-footer-row, tr[mat-footer-row]", exportAs: ["matFooterRow"] }, { kind: "ngmodule", type: DragDropModule }, { kind: "directive", type: i5.CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "ngmodule", type: MatCheckboxModule }, { kind: "component", type: i1$2.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: i3$1.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "pipe", type: FunctionPipe, name: "func" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
3956
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.0", type: GenericTableComponent, isStandalone: true, selector: "tb-generic-table", inputs: { $displayDataLength: { classPropertyName: "$displayDataLength", publicName: "displayDataLength", isSignal: true, isRequired: true, transformFunction: null }, $data: { classPropertyName: "$data", publicName: "data", isSignal: true, isRequired: true, transformFunction: null }, $rows: { classPropertyName: "$rows", publicName: "rows", isSignal: true, isRequired: false, transformFunction: null }, $columnInfos: { classPropertyName: "$columnInfos", publicName: "columnInfos", isSignal: true, isRequired: true, transformFunction: null }, $dataSource: { classPropertyName: "$dataSource", publicName: "dataSource", isSignal: true, isRequired: true, transformFunction: null }, $trackBy: { classPropertyName: "$trackBy", publicName: "trackBy", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { selection$: "selection" }, viewQueries: [{ propertyName: "$headerRow", first: true, predicate: MatHeaderRowDef, descendants: true, isSignal: true }, { propertyName: "$footerRow", first: true, predicate: MatFooterRowDef, descendants: true, isSignal: true }, { propertyName: "$table", first: true, predicate: MatTable, descendants: true, isSignal: true }, { propertyName: "$dropList", first: true, predicate: CdkDropList, descendants: true, isSignal: true }], ngImport: i0, template: "<mat-table\r\n cdkDropList\r\n cdkDropListLockAxis='x'\r\n cdkDropListOrientation=\"horizontal\"\r\n (cdkDropListDropped)=\"drop($event)\"\r\n class=\"table-drag-list\"\r\n #table\r\n [dataSource]=\"$dataSource()\"\r\n [trackBy]=\"$trackByFunction()\"\r\n [style]=\"$tableWidth()\"\r\n>\r\n\r\n <!-- select column -->\r\n <ng-container matColumnDef=\"select\">\r\n @let selection = $selection();\r\n <mat-header-cell *matHeaderCellDef class=\"select-column\">\r\n <mat-checkbox (change)=\"$event ? masterToggle() : null\"\r\n [checked]=\"!!($masterToggleChecked())\"\r\n [indeterminate]=\"$masterToggleIndeterminate()\">\r\n </mat-checkbox>\r\n </mat-header-cell>\r\n\r\n <mat-cell *matCellDef=\"let row\" class=\"select-column\">\r\n <mat-checkbox\r\n (click)=\"$event.stopPropagation()\"\r\n (change)=\"$event ? selection.toggle(row) : null\"\r\n [checked]=\"selection.isSelected(row)\"/>\r\n </mat-cell>\r\n\r\n <mat-footer-cell *matFooterCellDef class=\"select-column\">\r\n {{ selection.selected.length }}\r\n </mat-footer-cell>\r\n </ng-container>\r\n\r\n\r\n <!-- index column -->\r\n <ng-container matColumnDef=\"index\">\r\n <mat-header-cell *matHeaderCellDef class=\"f-mat-header-cell\" class=\"index-column\">#\r\n </mat-header-cell>\r\n <mat-cell *matCellDef=\"let i = index;\" class=\"index-column\">\r\n {{ 1 + i + $offsetIndex() }}\r\n </mat-cell>\r\n <mat-footer-cell *matFooterCellDef class=\"index-column\"></mat-footer-cell>\r\n </ng-container>\r\n\r\n <!-- Grouping -->\r\n <ng-container matColumnDef=\"groupHeader\">\r\n <mat-cell *matCellDef=\"let row\">\r\n @let expanded = (state.$getIsExpanded | func : row.key : row.groupName );\r\n <div [style.paddingLeft]=\"row.padding + 'px !important'\">\r\n <button mat-icon-button (click)=\"setExpanded(row.key, row.groupName, !expanded());\">\r\n @if (!expanded()) {\r\n <mat-icon>chevron_right</mat-icon>\r\n } @else {\r\n <mat-icon>expand_more</mat-icon>\r\n }\r\n </button>\r\n {{ getTransform | func : row.key : row.groupHeaderDisplay }} ({{ row.length }})\r\n </div>\r\n <div style=\"flex-grow: 1\">\r\n <ng-container *ngTemplateOutlet=\"state.$props().groupHeaderTemplate!; context: { element: row }\"></ng-container>\r\n </div>\r\n </mat-cell>\r\n </ng-container>\r\n\r\n <mat-row [style.height]=\"$rowHeight()\" [style.min-height]=\"$rowHeight()\"\r\n *matRowDef=\"let row; columns: $keys(); let i = index\"/>\r\n <mat-row [style.height]=\"state.$props().groupHeaderHeight ? state.$props().groupHeaderHeight + 'px' : $groupHeaderHeight()\"\r\n [style.min-height]=\"state.$props().groupHeaderHeight ? state.$props().groupHeaderHeight + 'px' : $groupHeaderHeight()\"\r\n *matRowDef=\"let row; columns: ['groupHeader']; when: isGroupHeader\" style=\"background-color: white;\"/>\r\n</mat-table>\r\n\r\n<mat-header-row [style.height]=\"$headerHeight()\" [style.min-height]=\"$headerHeight()\"\r\n *matHeaderRowDef=\"$keys(); sticky: state.$props().isSticky\" [style.top.px]=\"($offset()! * -1)\"/>\r\n<mat-footer-row [style.height]=\"$footerHeight()\" [style.min-height]=\"$footerHeight()\"\r\n *matFooterRowDef=\"$keys(); sticky: $stickyFooter() \"\r\n [style.bottom.px]=\"$stickyFooter() ? ($offset()) : undefined\"/>\r\n", styles: [":host{--mat-paginator-container-size: initial}.select-column{min-width:var(--tb-min-select-column-width, 42px)}.index-column{min-width:var(--tb-min-index-column-width, 42px)}.mat-mdc-row:nth-child(odd){background-color:var(--tb-odd-row-background-color, #cdeefe)}.page-amounts{color:#0000008a;font-family:Roboto,Helvetica Neue,sans-serif;font-size:12px;margin-right:.2rem}:host::ng-deep .table-drag-list.cdk-drop-list-dragging .drag-header:not(.cdk-drag-placeholder){transition:transform .25s cubic-bezier(0,0,.2,1)}:host::ng-deep .mdc-data-table__cell,:host::ng-deep .mdc-data-table__header-cell{padding:var(--tb-cell-padding, 0 0 0 .2rem);line-height:var(--tb-cell-line-height, normal)}::ng-deep .op-date-time-input{line-height:3rem;font-size:.9rem;font-family:Roboto,Helvetica Neue,sans-serif;padding-left:.2rem;width:12rem}\n"], dependencies: [{ kind: "ngmodule", type: MatTableModule }, { kind: "component", type: i1$5.MatTable, selector: "mat-table, table[mat-table]", exportAs: ["matTable"] }, { kind: "directive", type: i1$5.MatHeaderCellDef, selector: "[matHeaderCellDef]" }, { kind: "directive", type: i1$5.MatHeaderRowDef, selector: "[matHeaderRowDef]", inputs: ["matHeaderRowDef", "matHeaderRowDefSticky"] }, { kind: "directive", type: i1$5.MatColumnDef, selector: "[matColumnDef]", inputs: ["matColumnDef"] }, { kind: "directive", type: i1$5.MatCellDef, selector: "[matCellDef]" }, { kind: "directive", type: i1$5.MatRowDef, selector: "[matRowDef]", inputs: ["matRowDefColumns", "matRowDefWhen"] }, { kind: "directive", type: i1$5.MatFooterCellDef, selector: "[matFooterCellDef]" }, { kind: "directive", type: i1$5.MatFooterRowDef, selector: "[matFooterRowDef]", inputs: ["matFooterRowDef", "matFooterRowDefSticky"] }, { kind: "directive", type: i1$5.MatHeaderCell, selector: "mat-header-cell, th[mat-header-cell]" }, { kind: "directive", type: i1$5.MatCell, selector: "mat-cell, td[mat-cell]" }, { kind: "directive", type: i1$5.MatFooterCell, selector: "mat-footer-cell, td[mat-footer-cell]" }, { kind: "component", type: i1$5.MatHeaderRow, selector: "mat-header-row, tr[mat-header-row]", exportAs: ["matHeaderRow"] }, { kind: "component", type: i1$5.MatRow, selector: "mat-row, tr[mat-row]", exportAs: ["matRow"] }, { kind: "component", type: i1$5.MatFooterRow, selector: "mat-footer-row, tr[mat-footer-row]", exportAs: ["matFooterRow"] }, { kind: "ngmodule", type: DragDropModule }, { kind: "directive", type: i5.CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "ngmodule", type: MatCheckboxModule }, { kind: "component", type: i1$2.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: i3$1.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "pipe", type: FunctionPipe, name: "func" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
3953
3957
  }
3954
3958
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: GenericTableComponent, decorators: [{
3955
3959
  type: Component,
3956
- args: [{ selector: 'tb-generic-table', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [
3960
+ args: [{ selector: 'tb-generic-table', changeDetection: ChangeDetectionStrategy.OnPush, imports: [
3957
3961
  MatTableModule, DragDropModule, MatCheckboxModule, MatButtonModule, MatIconModule, NgTemplateOutlet,
3958
- MatTooltipModule, AsyncPipe, FunctionPipe,
3959
- ], template: "<mat-table\r\n cdkDropList\r\n cdkDropListLockAxis='x'\r\n cdkDropListOrientation=\"horizontal\"\r\n (cdkDropListDropped)=\"drop($event)\"\r\n class=\"table-drag-list\"\r\n #table\r\n [dataSource]=\"state.props().dataSource!\"\r\n [trackBy]=\"trackByFunction\"\r\n [style]=\"tableWidth | async \"\r\n>\r\n\r\n <!-- select column -->\r\n <ng-container matColumnDef=\"select\">\r\n\r\n <mat-header-cell *matHeaderCellDef class=\"select-column\">\r\n <mat-checkbox (change)=\"$event ? masterToggle() : null\"\r\n [checked]=\"!!(masterToggleChecked$ | async)\"\r\n [indeterminate]=\"masterToggleIndeterminate$ | async\">\r\n </mat-checkbox>\r\n </mat-header-cell>\r\n\r\n <mat-cell *matCellDef=\"let row\" class=\"select-column\">\r\n <mat-checkbox\r\n (click)=\"$event.stopPropagation()\"\r\n (change)=\"$event ? selection.toggle(row) : null\"\r\n [checked]=\"selection.isSelected(row)\"/>\r\n </mat-cell>\r\n\r\n <mat-footer-cell *matFooterCellDef class=\"select-column\">\r\n {{ selection.selected.length }}\r\n </mat-footer-cell>\r\n </ng-container>\r\n\r\n\r\n <!-- index column -->\r\n <ng-container matColumnDef=\"index\">\r\n <mat-header-cell *matHeaderCellDef class=\"f-mat-header-cell\" class=\"index-column\">#\r\n </mat-header-cell>\r\n <mat-cell *matCellDef=\"let i = index;\" class=\"index-column\">\r\n {{ 1 + i + $offsetIndex() }}\r\n </mat-cell>\r\n <mat-footer-cell *matFooterCellDef class=\"index-column\"></mat-footer-cell>\r\n </ng-container>\r\n\r\n <!-- Grouping -->\r\n <ng-container matColumnDef=\"groupHeader\">\r\n <mat-cell *matCellDef=\"let row\">\r\n @let expanded = (state.getIsExpanded | func : row.key : row.groupName );\r\n <div [style.paddingLeft]=\"row.padding + 'px !important'\">\r\n <button mat-icon-button (click)=\"setExpanded(row.key, row.groupName, !expanded());\">\r\n @if (!expanded()) {\r\n <mat-icon>chevron_right</mat-icon>\r\n } @else {\r\n <mat-icon>expand_more</mat-icon>\r\n }\r\n </button>\r\n {{ getTransform | func : row.key : row.groupHeaderDisplay }} ({{ row.length }})\r\n </div>\r\n <div style=\"flex-grow: 1\">\r\n <ng-container *ngTemplateOutlet=\"state.props().groupHeaderTemplate!; context: { element: row }\"></ng-container>\r\n </div>\r\n </mat-cell>\r\n </ng-container>\r\n\r\n <mat-row [style.height]=\"$rowHeight()\" [style.min-height]=\"$rowHeight()\"\r\n *matRowDef=\"let row; columns: $keys(); let i = index\"/>\r\n <mat-row [style.height]=\"state.props().groupHeaderHeight ? state.props().groupHeaderHeight + 'px' : $groupHeaderHeight()\"\r\n [style.min-height]=\"state.props().groupHeaderHeight ? state.props().groupHeaderHeight + 'px' : $groupHeaderHeight()\"\r\n *matRowDef=\"let row; columns: ['groupHeader']; when: isGroupHeader\" style=\"background-color: white;\"/>\r\n</mat-table>\r\n\r\n<mat-header-row [style.height]=\"$headerHeight()\" [style.min-height]=\"$headerHeight()\"\r\n *matHeaderRowDef=\"$keys(); sticky: state.props().isSticky\" [style.top.px]=\"((offset$ | async)! * -1)\"/>\r\n<mat-footer-row [style.height]=\"$footerHeight()\" [style.min-height]=\"$footerHeight()\"\r\n *matFooterRowDef=\"$keys(); sticky: $stickyFooter() \"\r\n [style.bottom.px]=\"$stickyFooter() ? (offset$ | async) : undefined\"/>\r\n", styles: [":host{--mat-paginator-container-size: initial}.select-column{min-width:var(--tb-min-select-column-width, 42px)}.index-column{min-width:var(--tb-min-index-column-width, 42px)}.mat-mdc-row:nth-child(odd){background-color:var(--tb-odd-row-background-color, #cdeefe)}.page-amounts{color:#0000008a;font-family:Roboto,Helvetica Neue,sans-serif;font-size:12px;margin-right:.2rem}:host::ng-deep .table-drag-list.cdk-drop-list-dragging .drag-header:not(.cdk-drag-placeholder){transition:transform .25s cubic-bezier(0,0,.2,1)}:host::ng-deep .mdc-data-table__cell,:host::ng-deep .mdc-data-table__header-cell{padding:var(--tb-cell-padding, 0 0 0 .2rem);line-height:var(--tb-cell-line-height, normal)}::ng-deep .op-date-time-input{line-height:3rem;font-size:.9rem;font-family:Roboto,Helvetica Neue,sans-serif;padding-left:.2rem;width:12rem}\n"] }]
3960
- }], ctorParameters: () => [], propDecorators: { trackBy: [{
3961
- type: Input
3962
- }], dropList: [{
3963
- type: ViewChild,
3964
- args: [CdkDropList, { static: true }]
3965
- }], selection$: [{
3966
- type: Output
3967
- }] } });
3962
+ MatTooltipModule, FunctionPipe,
3963
+ ], template: "<mat-table\r\n cdkDropList\r\n cdkDropListLockAxis='x'\r\n cdkDropListOrientation=\"horizontal\"\r\n (cdkDropListDropped)=\"drop($event)\"\r\n class=\"table-drag-list\"\r\n #table\r\n [dataSource]=\"$dataSource()\"\r\n [trackBy]=\"$trackByFunction()\"\r\n [style]=\"$tableWidth()\"\r\n>\r\n\r\n <!-- select column -->\r\n <ng-container matColumnDef=\"select\">\r\n @let selection = $selection();\r\n <mat-header-cell *matHeaderCellDef class=\"select-column\">\r\n <mat-checkbox (change)=\"$event ? masterToggle() : null\"\r\n [checked]=\"!!($masterToggleChecked())\"\r\n [indeterminate]=\"$masterToggleIndeterminate()\">\r\n </mat-checkbox>\r\n </mat-header-cell>\r\n\r\n <mat-cell *matCellDef=\"let row\" class=\"select-column\">\r\n <mat-checkbox\r\n (click)=\"$event.stopPropagation()\"\r\n (change)=\"$event ? selection.toggle(row) : null\"\r\n [checked]=\"selection.isSelected(row)\"/>\r\n </mat-cell>\r\n\r\n <mat-footer-cell *matFooterCellDef class=\"select-column\">\r\n {{ selection.selected.length }}\r\n </mat-footer-cell>\r\n </ng-container>\r\n\r\n\r\n <!-- index column -->\r\n <ng-container matColumnDef=\"index\">\r\n <mat-header-cell *matHeaderCellDef class=\"f-mat-header-cell\" class=\"index-column\">#\r\n </mat-header-cell>\r\n <mat-cell *matCellDef=\"let i = index;\" class=\"index-column\">\r\n {{ 1 + i + $offsetIndex() }}\r\n </mat-cell>\r\n <mat-footer-cell *matFooterCellDef class=\"index-column\"></mat-footer-cell>\r\n </ng-container>\r\n\r\n <!-- Grouping -->\r\n <ng-container matColumnDef=\"groupHeader\">\r\n <mat-cell *matCellDef=\"let row\">\r\n @let expanded = (state.$getIsExpanded | func : row.key : row.groupName );\r\n <div [style.paddingLeft]=\"row.padding + 'px !important'\">\r\n <button mat-icon-button (click)=\"setExpanded(row.key, row.groupName, !expanded());\">\r\n @if (!expanded()) {\r\n <mat-icon>chevron_right</mat-icon>\r\n } @else {\r\n <mat-icon>expand_more</mat-icon>\r\n }\r\n </button>\r\n {{ getTransform | func : row.key : row.groupHeaderDisplay }} ({{ row.length }})\r\n </div>\r\n <div style=\"flex-grow: 1\">\r\n <ng-container *ngTemplateOutlet=\"state.$props().groupHeaderTemplate!; context: { element: row }\"></ng-container>\r\n </div>\r\n </mat-cell>\r\n </ng-container>\r\n\r\n <mat-row [style.height]=\"$rowHeight()\" [style.min-height]=\"$rowHeight()\"\r\n *matRowDef=\"let row; columns: $keys(); let i = index\"/>\r\n <mat-row [style.height]=\"state.$props().groupHeaderHeight ? state.$props().groupHeaderHeight + 'px' : $groupHeaderHeight()\"\r\n [style.min-height]=\"state.$props().groupHeaderHeight ? state.$props().groupHeaderHeight + 'px' : $groupHeaderHeight()\"\r\n *matRowDef=\"let row; columns: ['groupHeader']; when: isGroupHeader\" style=\"background-color: white;\"/>\r\n</mat-table>\r\n\r\n<mat-header-row [style.height]=\"$headerHeight()\" [style.min-height]=\"$headerHeight()\"\r\n *matHeaderRowDef=\"$keys(); sticky: state.$props().isSticky\" [style.top.px]=\"($offset()! * -1)\"/>\r\n<mat-footer-row [style.height]=\"$footerHeight()\" [style.min-height]=\"$footerHeight()\"\r\n *matFooterRowDef=\"$keys(); sticky: $stickyFooter() \"\r\n [style.bottom.px]=\"$stickyFooter() ? ($offset()) : undefined\"/>\r\n", styles: [":host{--mat-paginator-container-size: initial}.select-column{min-width:var(--tb-min-select-column-width, 42px)}.index-column{min-width:var(--tb-min-index-column-width, 42px)}.mat-mdc-row:nth-child(odd){background-color:var(--tb-odd-row-background-color, #cdeefe)}.page-amounts{color:#0000008a;font-family:Roboto,Helvetica Neue,sans-serif;font-size:12px;margin-right:.2rem}:host::ng-deep .table-drag-list.cdk-drop-list-dragging .drag-header:not(.cdk-drag-placeholder){transition:transform .25s cubic-bezier(0,0,.2,1)}:host::ng-deep .mdc-data-table__cell,:host::ng-deep .mdc-data-table__header-cell{padding:var(--tb-cell-padding, 0 0 0 .2rem);line-height:var(--tb-cell-line-height, normal)}::ng-deep .op-date-time-input{line-height:3rem;font-size:.9rem;font-family:Roboto,Helvetica Neue,sans-serif;padding-left:.2rem;width:12rem}\n"] }]
3964
+ }] });
3968
3965
 
3969
3966
  function downloadData(data, filename, mimeType) {
3970
3967
  const url = URL.createObjectURL(new Blob([data], { type: mimeType }));
@@ -4018,8 +4015,9 @@ class ExportToCsvService {
4018
4015
  val = prepend + val;
4019
4016
  break;
4020
4017
  case FieldType.Array:
4021
- const additional = meta.additional;
4022
- val = val.slice(0, additional.limit).join(additional.arrayStyle === ArrayStyle.NewLine ? '\n' : ', ');
4018
+ const style = meta.additional.arrayStyle ?? this.config.arrayDefaults?.arrayStyle;
4019
+ const limit = meta.additional.limit ?? this.config.arrayDefaults?.limit;
4020
+ val = val.slice(0, limit).join(style === ArrayStyle.NewLine ? '\n' : ', ');
4023
4021
  break;
4024
4022
  case FieldType.Expression:
4025
4023
  val = meta.transform(row);
@@ -4044,11 +4042,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImpor
4044
4042
  type: Injectable
4045
4043
  }] });
4046
4044
 
4047
- const ArrayDefaults = {
4048
- limit: 3,
4049
- arrayStyle: ArrayStyle.CommaDelimited
4050
- };
4051
-
4052
4045
  function createLinkCreatorDict(metaDatas) {
4053
4046
  return metaDatas.reduce((acc, md) => {
4054
4047
  if (md.fieldType === FieldType.Link) {
@@ -4251,42 +4244,50 @@ const defaultStorageState = {
4251
4244
  class GroupByListComponent {
4252
4245
  tableStore = inject(TableStore);
4253
4246
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: GroupByListComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
4254
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.0", type: GroupByListComponent, isStandalone: true, selector: "group-by-list", ngImport: i0, template: "<mat-chip-set *ngrxLet=\"tableStore.groupByKeys$ as groupByKeys\">\r\n <span class=\"tb-group-label\">Group By:</span>\r\n @for (groupByKey of groupByKeys; track groupByKey) {\r\n @if($index > 0){\r\n <mat-icon class=\"nested-arrow\">arrow_right</mat-icon>\r\n }\r\n <mat-chip (removed)=\"tableStore.removeGroupByKey(groupByKey)\">\r\n {{groupByKey | spaceCase}}\r\n <mat-icon matChipRemove>cancel</mat-icon>\r\n </mat-chip>\r\n }\r\n</mat-chip-set>\r\n", styles: [".tb-group-label{padding-right:5px}.nested-arrow{margin-right:-8px;margin-left:-8px}\n"], dependencies: [{ kind: "ngmodule", type: MatChipsModule }, { kind: "component", type: i4$3.MatChip, selector: "mat-basic-chip, [mat-basic-chip], mat-chip, [mat-chip]", inputs: ["role", "id", "aria-label", "aria-description", "value", "color", "removable", "highlighted", "disableRipple", "disabled"], outputs: ["removed", "destroyed"], exportAs: ["matChip"] }, { kind: "directive", type: i4$3.MatChipRemove, selector: "[matChipRemove]" }, { kind: "component", type: i4$3.MatChipSet, selector: "mat-chip-set", inputs: ["disabled", "role", "tabIndex"] }, { kind: "directive", type: LetDirective, selector: "[ngrxLet]", inputs: ["ngrxLet", "ngrxLetSuspenseTpl"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "pipe", type: SpaceCasePipe, name: "spaceCase" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
4247
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.0", type: GroupByListComponent, isStandalone: true, selector: "group-by-list", ngImport: i0, template: "<mat-chip-set>\r\n <span class=\"tb-group-label\">Group By:</span>\r\n @for (groupByKey of tableStore.$groupByKeys(); track groupByKey) {\r\n @if($index > 0){\r\n <mat-icon class=\"nested-arrow\">arrow_right</mat-icon>\r\n }\r\n <mat-chip (removed)=\"tableStore.removeGroupByKey(groupByKey)\">\r\n {{groupByKey | spaceCase}}\r\n <mat-icon matChipRemove>cancel</mat-icon>\r\n </mat-chip>\r\n }\r\n</mat-chip-set>\r\n", styles: [".tb-group-label{padding-right:5px}.nested-arrow{margin-right:-8px;margin-left:-8px}\n"], dependencies: [{ kind: "ngmodule", type: MatChipsModule }, { kind: "component", type: i4$3.MatChip, selector: "mat-basic-chip, [mat-basic-chip], mat-chip, [mat-chip]", inputs: ["role", "id", "aria-label", "aria-description", "value", "color", "removable", "highlighted", "disableRipple", "disabled"], outputs: ["removed", "destroyed"], exportAs: ["matChip"] }, { kind: "directive", type: i4$3.MatChipRemove, selector: "[matChipRemove]" }, { kind: "component", type: i4$3.MatChipSet, selector: "mat-chip-set", inputs: ["disabled", "role", "tabIndex"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "pipe", type: SpaceCasePipe, name: "spaceCase" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
4255
4248
  }
4256
4249
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: GroupByListComponent, decorators: [{
4257
4250
  type: Component,
4258
- args: [{ selector: 'group-by-list', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [
4259
- MatChipsModule, LetDirective, MatIconModule, SpaceCasePipe
4260
- ], template: "<mat-chip-set *ngrxLet=\"tableStore.groupByKeys$ as groupByKeys\">\r\n <span class=\"tb-group-label\">Group By:</span>\r\n @for (groupByKey of groupByKeys; track groupByKey) {\r\n @if($index > 0){\r\n <mat-icon class=\"nested-arrow\">arrow_right</mat-icon>\r\n }\r\n <mat-chip (removed)=\"tableStore.removeGroupByKey(groupByKey)\">\r\n {{groupByKey | spaceCase}}\r\n <mat-icon matChipRemove>cancel</mat-icon>\r\n </mat-chip>\r\n }\r\n</mat-chip-set>\r\n", styles: [".tb-group-label{padding-right:5px}.nested-arrow{margin-right:-8px;margin-left:-8px}\n"] }]
4251
+ args: [{ selector: 'group-by-list', changeDetection: ChangeDetectionStrategy.OnPush, imports: [
4252
+ MatChipsModule, MatIconModule, SpaceCasePipe
4253
+ ], template: "<mat-chip-set>\r\n <span class=\"tb-group-label\">Group By:</span>\r\n @for (groupByKey of tableStore.$groupByKeys(); track groupByKey) {\r\n @if($index > 0){\r\n <mat-icon class=\"nested-arrow\">arrow_right</mat-icon>\r\n }\r\n <mat-chip (removed)=\"tableStore.removeGroupByKey(groupByKey)\">\r\n {{groupByKey | spaceCase}}\r\n <mat-icon matChipRemove>cancel</mat-icon>\r\n </mat-chip>\r\n }\r\n</mat-chip-set>\r\n", styles: [".tb-group-label{padding-right:5px}.nested-arrow{margin-right:-8px;margin-left:-8px}\n"] }]
4261
4254
  }] });
4262
4255
 
4263
4256
  class SortMenuComponentStore extends ComponentStore {
4264
4257
  tableState = inject(TableStore);
4258
+ setStoreStateEffect = effect(() => {
4259
+ const metaData = this.tableState.$metaData();
4260
+ if (!metaData)
4261
+ return;
4262
+ this.tableState.$selectSorted();
4263
+ untracked(() => this.setStateFromTableStore());
4264
+ });
4265
+ setStateFromTableStore = () => {
4266
+ const metaData = this.tableState.$metaData();
4267
+ const sorted = [...this.tableState.$selectSorted()].map(s => ({
4268
+ ...s,
4269
+ displayName: metaData[s.active]?.displayName
4270
+ }));
4271
+ const notSorted = this.tableState.$metaDataArray()
4272
+ .filter(md => md.fieldType !== FieldType.NotMapped && !md.noSort && !sorted.some(s => s.active === md.key))
4273
+ .map(meta => ({ active: meta.key, displayName: meta.displayName }));
4274
+ this.setState({ sorted, notSorted });
4275
+ };
4265
4276
  constructor() {
4266
4277
  super({ notSorted: [], sorted: [] });
4267
4278
  }
4268
- set = this.updater((state, data) => ({ ...data }));
4269
4279
  setSorted = this.updater((state, sorted) => ({ ...state, sorted }));
4270
4280
  setNotSorted = this.updater((state, notSorted) => ({ ...state, notSorted }));
4271
- sorted$ = this.select(state => state.sorted);
4272
- notSorted$ = this.select(state => state.notSorted);
4281
+ $sorted = this.selectSignal(state => state.sorted);
4282
+ $notSorted = this.selectSignal(state => state.notSorted);
4273
4283
  setDirection = this.updater((state, sort) => {
4274
4284
  const index = state.sorted.findIndex(s => s.active === sort.active);
4275
4285
  const sorted = [...state.sorted];
4276
4286
  sorted.splice(index, 1, sort);
4277
4287
  return ({ ...state, sorted });
4278
4288
  });
4279
- metaDataArr$ = toObservable(this.tableState.$metaDataArray);
4280
4289
  reset = () => {
4281
- const sorted = this.tableState.sort$.pipe(mergeMap(sort => this.tableState.metaData$.pipe(notNull(), map(meta => sort.map(s => {
4282
- return { ...s, displayName: meta[s.active]?.displayName };
4283
- })))));
4284
- const notSorted = this.metaDataArr$.pipe(mergeMap(metas => this.tableState.sort$.pipe(map(s => metas
4285
- .filter(meta => !s.some(s => s.active === meta.key) && meta.fieldType !== FieldType.NotMapped && !meta.noSort)
4286
- .map(meta => ({ active: meta.key, displayName: meta.displayName }))))));
4287
- this.set(combineLatest([
4288
- sorted.pipe(distinctSortArray), notSorted.pipe(distinctSortArray)
4289
- ]).pipe(map(([sorted, notSorted]) => ({ sorted, notSorted }))));
4290
+ this.setStateFromTableStore();
4290
4291
  };
4291
4292
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: SortMenuComponentStore, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
4292
4293
  static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: SortMenuComponentStore });
@@ -4294,38 +4295,31 @@ class SortMenuComponentStore extends ComponentStore {
4294
4295
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: SortMenuComponentStore, decorators: [{
4295
4296
  type: Injectable
4296
4297
  }], ctorParameters: () => [] });
4297
- const equalSortArray = (arr1, arr2) => arr1.length === arr2.length && arr2.every(s1 => arr1.some(s2 => s1.active === s2.active));
4298
- const distinctSortArray = distinctUntilChanged(equalSortArray);
4299
4298
 
4300
4299
  class SortMenuComponent {
4300
+ SortDirection = SortDirection;
4301
4301
  tableState = inject(TableStore);
4302
4302
  store = inject(SortMenuComponentStore);
4303
- sorted$;
4304
- notSorted$;
4305
- SortDirection = SortDirection;
4306
- dirty$ = new BehaviorSubject(false);
4307
- constructor() {
4308
- this.sorted$ = this.store.sorted$.pipe(map(data => [...data]));
4309
- this.notSorted$ = this.store.notSorted$.pipe(map(data => [...data]));
4310
- }
4303
+ $sorted = computed(() => [...this.store.$sorted()]);
4304
+ $notSorted = computed(() => [...this.store.$notSorted()]);
4305
+ $dirty = signal(false);
4311
4306
  reset() {
4312
- this.dirty$.next(false);
4313
- this.store.reset();
4314
- }
4315
- ngOnInit() {
4307
+ this.$dirty.set(false);
4316
4308
  this.store.reset();
4317
4309
  }
4318
4310
  dropIntoSorted(event) {
4319
- this.dirty$.next(true);
4311
+ this.$dirty.set(true);
4312
+ const sorted = [...event.container.data];
4320
4313
  if (event.previousContainer === event.container) {
4321
- moveItemInArray(event.container.data, event.previousIndex, event.currentIndex);
4322
- this.store.setSorted(event.container.data);
4314
+ moveItemInArray(sorted, event.previousIndex, event.currentIndex);
4315
+ this.store.setSorted(sorted);
4323
4316
  }
4324
4317
  else {
4325
- transferArrayItem(event.previousContainer.data, event.container.data, event.previousIndex, event.currentIndex);
4326
- event.container.data[event.currentIndex] = { ...event.container.data[event.currentIndex], direction: SortDirection.asc };
4327
- this.store.setSorted(event.container.data);
4328
- this.store.setNotSorted(event.previousContainer.data);
4318
+ const notSorted = [...event.previousContainer.data];
4319
+ transferArrayItem(notSorted, sorted, event.previousIndex, event.currentIndex);
4320
+ sorted[event.currentIndex] = { ...sorted[event.currentIndex], direction: SortDirection.asc };
4321
+ this.store.setSorted(sorted);
4322
+ this.store.setNotSorted(notSorted);
4329
4323
  }
4330
4324
  }
4331
4325
  dropIntoNotSorted(event) {
@@ -4333,37 +4327,38 @@ class SortMenuComponent {
4333
4327
  return;
4334
4328
  }
4335
4329
  else {
4336
- this.dirty$.next(true);
4337
- transferArrayItem(event.previousContainer.data, event.container.data, event.previousIndex, event.currentIndex);
4338
- event.container.data[event.currentIndex] = { ...event.container.data[event.currentIndex] };
4339
- this.store.setNotSorted(event.container.data);
4340
- this.store.setSorted(event.previousContainer.data);
4341
- }
4342
- }
4343
- apply = this.store.effect((obs) => obs.pipe(tap(() => {
4344
- this.dirty$.next(false);
4345
- this.tableState.setAllSort(this.store.sorted$.pipe(first$1()));
4346
- })));
4330
+ this.$dirty.set(true);
4331
+ const sorted = [...event.previousContainer.data];
4332
+ const notSorted = [...event.container.data];
4333
+ transferArrayItem(sorted, notSorted, event.previousIndex, event.currentIndex);
4334
+ notSorted[event.currentIndex] = { ...notSorted[event.currentIndex] };
4335
+ this.store.setNotSorted(notSorted);
4336
+ this.store.setSorted(sorted);
4337
+ }
4338
+ }
4339
+ apply = () => {
4340
+ this.$dirty.set(false);
4341
+ this.tableState.setAllSort(this.store.$sorted());
4342
+ };
4347
4343
  setDirection(sort) {
4348
- this.dirty$.next(true);
4344
+ this.$dirty.set(true);
4349
4345
  this.store.setDirection(sort);
4350
4346
  }
4351
4347
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: SortMenuComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
4352
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.0", type: SortMenuComponent, isStandalone: true, selector: "tb-sort-menu", providers: [SortMenuComponentStore], ngImport: i0, template: "<ng-container *ngrxLet=\"dirty$ as dirty\">\r\n @if(sorted$ | async; as sorted){\r\n @if (notSorted$ | async; as notSorted) {\r\n <!-- Menu Trigger -->\r\n <span matTooltip=\"Sort\">\r\n <button mat-icon-button [matMenuTriggerFor]=\"menu\">\r\n <mat-icon color=\"primary\">swap_vert</mat-icon>\r\n </button>\r\n </span>\r\n\r\n <!-- Menu -->\r\n <mat-menu #menu=\"matMenu\" class=\"my-mat-menu\" (closed)=\"reset()\">\r\n <div mat-menu-item class=\"menu-button\">\r\n <div class=\"close-button-wrapper\">\r\n <span matTooltip=\"Close\">\r\n <mat-icon>close</mat-icon>\r\n </span>\r\n @if(dirty){\r\n <span matTooltip=\"Undo\" stop-propagation (click)=\"reset()\">\r\n <mat-icon>undo</mat-icon>\r\n </span>\r\n }\r\n \r\n </div>\r\n </div>\r\n\r\n <!-- Apply Button -->\r\n <div class=\"apply-button-wrapper\">\r\n <button mat-button color=\"primary\" (click)=\"apply(null)\"\r\n stop-propagation [class.apply-border]=\"dirty\"\r\n [disabled]=\"!dirty\">\r\n Apply @if (dirty) { Unsaved Changes }\r\n </button>\r\n </div>\r\n\r\n <!-- Default Sorting Text -->\r\n @if (!sorted.length) {\r\n <div class=\"tip\" >\r\n Sorting List\r\n </div>\r\n }\r\n\r\n <!-- Sorted Menu List -->\r\n <div class=\"list\"\r\n cdkDropList\r\n #sortedGroup=\"cdkDropList\"\r\n [cdkDropListConnectedTo]=\"[notSortedGroup]\"\r\n [cdkDropListData]=\"sorted\"\r\n (cdkDropListDropped)=\"dropIntoSorted($event)\">\r\n\r\n <!-- Menu Item Wrapper -->\r\n @for (sort of sorted; track sort.active) {\r\n <!-- Menu Item Headers -->\r\n @if (sorted.length > 1) {\r\n <span class=\"description sort-header\">{{$index === 0 ? 'First By' : 'Then By'}}</span>\r\n }\r\n \r\n <!-- Menu Item -->\r\n <div mat-menu-item cdkDrag class=\"menu-item\">\r\n <div class=\"sort-item\">\r\n <span class=\"sorted-name\">\r\n {{sort.displayName || (sort.active | spaceCase)}}\r\n <span class=\"direction-text\">{{sort.direction}}</span>\r\n </span>\r\n \r\n <!-- Sort Direction Buttons -->\r\n <div class=\"up-down-buttons-wrapper\">\r\n <button class=\"up-down-button up-button\" stop-propagation\r\n (click)=\"setDirection({active:sort.active,direction:SortDirection.asc,displayName:sort.displayName})\">\r\n <mat-icon [ngClass]=\"sort.direction !== SortDirection.asc ? 'light-arrow' : 'dark-arrow'\" class=\"up-down-icon\">\r\n arrow_upward\r\n </mat-icon>\r\n </button>\r\n \r\n <button class=\"up-down-button\" stop-propagation\r\n (click)=\"setDirection({active:sort.active,direction:SortDirection.desc,displayName:sort.displayName})\">\r\n <mat-icon [ngClass]=\"sort.direction === SortDirection.asc ? 'light-arrow' : 'dark-arrow'\" class=\"up-down-icon\">\r\n arrow_downward\r\n </mat-icon>\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n }\r\n\r\n </div>\r\n\r\n <!-- Default Not Sorted Text -->\r\n @if(!notSorted.length){\r\n <div class=\"tip\" >\r\n Not Sorted List\r\n </div>\r\n }\r\n\r\n <!-- Not Sorted Menu List -->\r\n <div class=\"list\"\r\n cdkDropList\r\n #notSortedGroup=\"cdkDropList\"\r\n [cdkDropListConnectedTo]=\"[sortedGroup]\"\r\n [cdkDropListData]=\"notSorted\"\r\n (cdkDropListDropped)=\"dropIntoNotSorted($event)\">\r\n @for (sort of notSorted; track sort.active) {\r\n <div mat-menu-item class=\"menu-item\" cdkDrag>\r\n <span class=\"not-sorted-name\">{{sort.displayName || (sort.active | spaceCase)}}</span>\r\n </div>\r\n }\r\n </div>\r\n </mat-menu>\r\n }\r\n }\r\n</ng-container>\r\n", styles: [".cdk-drag-preview{box-sizing:border-box;border-radius:4px;box-shadow:0 5px 5px -3px #0003,0 8px 10px 1px #00000024,0 3px 14px 2px #0000001f}.cdk-drag-placeholder{opacity:0}.cdk-drag-animating{transition:transform .25s cubic-bezier(0,0,.2,1)}.list{padding:5px 2px;border-bottom:solid 1px #ccc;color:#000000de;background:#fff}.light-arrow{color:#93b1ea78}.dark-arrow{color:#224e9c}.up-down-button{background-color:#fff;border-radius:30%;border-color:#0ff;padding:1px 1px 0;border-width:.5px;cursor:pointer;height:27px}.mat-icon.up-down-icon{margin-right:0;font-size:20px;font-weight:lighter}.sort-item{display:flex;align-items:center;justify-content:space-between}.up-down-buttons-wrapper{margin-left:2rem}.up-button{margin-right:.3rem}.mat-mdc-menu-item.menu-item,.mat-mdc-menu-item.menu-button{min-height:initial;padding:0 3px;line-height:25px;height:30px}.mat-mdc-menu-item.menu-item{cursor:move}.sorted-name{color:#224e9c;font-size:17px;font-weight:700}.not-sorted-name{color:#93b1ea;font-size:17px;font-weight:700}.apply-border{border:#224e9c solid .5px}.apply-border:hover{background-color:#faebd7}.apply-button-wrapper{display:grid;justify-content:center}.sort-header{font-size:10px;font-style:italic}.tip{padding:0 3px;color:#d3d3d3}.direction-text{font-size:small;font-weight:400}.close-button-wrapper{display:flex;flex-direction:row-reverse}\n"], dependencies: [{ kind: "directive", type: LetDirective, selector: "[ngrxLet]", inputs: ["ngrxLet", "ngrxLetSuspenseTpl"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i4$1.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i3$1.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "component", type: i3$1.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatMenuModule }, { kind: "component", type: i4$2.MatMenu, selector: "mat-menu", inputs: ["backdropClass", "aria-label", "aria-labelledby", "aria-describedby", "xPosition", "yPosition", "overlapTrigger", "hasBackdrop", "class", "classList"], outputs: ["closed", "close"], exportAs: ["matMenu"] }, { kind: "component", type: i4$2.MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i4$2.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }, { kind: "directive", type: StopPropagationDirective, selector: "[stop-propagation]" }, { kind: "ngmodule", type: DragDropModule }, { kind: "directive", type: i5.CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: i5.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"] }, { kind: "pipe", type: SpaceCasePipe, name: "spaceCase" }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "pipe", type: AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
4348
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.0", type: SortMenuComponent, isStandalone: true, selector: "tb-sort-menu", providers: [SortMenuComponentStore], ngImport: i0, template: "@let dirty = $dirty();\r\n@let sorted = $sorted();\r\n@let notSorted = $notSorted();\r\n\r\n<!-- Menu Trigger -->\r\n<span matTooltip=\"Sort\">\r\n <button mat-icon-button [matMenuTriggerFor]=\"menu\">\r\n <mat-icon color=\"primary\">swap_vert</mat-icon>\r\n </button>\r\n</span>\r\n\r\n<!-- Menu -->\r\n<mat-menu #menu=\"matMenu\" class=\"my-mat-menu\" (closed)=\"reset()\">\r\n <div mat-menu-item class=\"menu-button\">\r\n <div class=\"close-button-wrapper\">\r\n <span matTooltip=\"Close\">\r\n <mat-icon>close</mat-icon>\r\n </span>\r\n @if(dirty){\r\n <span matTooltip=\"Undo\" stop-propagation (click)=\"reset()\">\r\n <mat-icon>undo</mat-icon>\r\n </span>\r\n }\r\n \r\n </div>\r\n </div>\r\n\r\n <!-- Apply Button -->\r\n <div class=\"apply-button-wrapper\">\r\n <button mat-button color=\"primary\" (click)=\"apply()\"\r\n stop-propagation [class.apply-border]=\"dirty\"\r\n [disabled]=\"!dirty\">\r\n Apply @if (dirty) { Unsaved Changes }\r\n </button>\r\n </div>\r\n\r\n <!-- Default Sorting Text -->\r\n @if (!sorted.length) {\r\n <div class=\"tip\" >\r\n Sorting List\r\n </div>\r\n }\r\n\r\n <!-- Sorted Menu List -->\r\n <div class=\"list\"\r\n cdkDropList\r\n #sortedGroup=\"cdkDropList\"\r\n [cdkDropListConnectedTo]=\"[notSortedGroup]\"\r\n [cdkDropListData]=\"sorted\"\r\n (cdkDropListDropped)=\"dropIntoSorted($event)\">\r\n\r\n <!-- Menu Item Wrapper -->\r\n @for (sort of sorted; track sort.active) {\r\n <!-- Menu Item Headers -->\r\n @if (sorted.length > 1) {\r\n <span class=\"description sort-header\">{{$index === 0 ? 'First By' : 'Then By'}}</span>\r\n }\r\n\r\n <!-- Menu Item -->\r\n <div mat-menu-item cdkDrag class=\"menu-item\">\r\n <div class=\"sort-item\">\r\n <span class=\"sorted-name\">\r\n {{sort.displayName || (sort.active | spaceCase)}}\r\n <span class=\"direction-text\">{{sort.direction}}</span>\r\n </span>\r\n\r\n <!-- Sort Direction Buttons -->\r\n <div class=\"up-down-buttons-wrapper\">\r\n <button class=\"up-down-button up-button\" stop-propagation\r\n (click)=\"setDirection({active:sort.active,direction:SortDirection.asc,displayName:sort.displayName})\">\r\n <mat-icon [class]=\"sort.direction !== SortDirection.asc ? 'light-arrow' : 'dark-arrow'\" class=\"up-down-icon\">\r\n arrow_upward\r\n </mat-icon>\r\n </button>\r\n\r\n <button class=\"up-down-button\" stop-propagation\r\n (click)=\"setDirection({active:sort.active,direction:SortDirection.desc,displayName:sort.displayName})\">\r\n <mat-icon [class]=\"sort.direction === SortDirection.asc ? 'light-arrow' : 'dark-arrow'\" class=\"up-down-icon\">\r\n arrow_downward\r\n </mat-icon>\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n }\r\n\r\n </div>\r\n\r\n <!-- Default Not Sorted Text -->\r\n @if(!notSorted.length){\r\n <div class=\"tip\" >\r\n Not Sorted List\r\n </div>\r\n }\r\n\r\n <!-- Not Sorted Menu List -->\r\n <div class=\"list\"\r\n cdkDropList\r\n #notSortedGroup=\"cdkDropList\"\r\n [cdkDropListConnectedTo]=\"[sortedGroup]\"\r\n [cdkDropListData]=\"notSorted\"\r\n (cdkDropListDropped)=\"dropIntoNotSorted($event)\">\r\n @for (sort of notSorted; track sort.active) {\r\n <div mat-menu-item class=\"menu-item\" cdkDrag>\r\n <span class=\"not-sorted-name\">{{sort.displayName || (sort.active | spaceCase)}}</span>\r\n </div>\r\n }\r\n </div>\r\n</mat-menu>\r\n", styles: [".cdk-drag-preview{box-sizing:border-box;border-radius:4px;box-shadow:0 5px 5px -3px #0003,0 8px 10px 1px #00000024,0 3px 14px 2px #0000001f}.cdk-drag-placeholder{opacity:0}.cdk-drag-animating{transition:transform .25s cubic-bezier(0,0,.2,1)}.list{padding:5px 2px;border-bottom:solid 1px #ccc;color:#000000de;background:#fff}.light-arrow{color:#93b1ea78}.dark-arrow{color:#224e9c}.up-down-button{background-color:#fff;border-radius:30%;border-color:#0ff;padding:1px 1px 0;border-width:.5px;cursor:pointer;height:27px}.mat-icon.up-down-icon{margin-right:0;font-size:20px;font-weight:lighter}.sort-item{display:flex;align-items:center;justify-content:space-between}.up-down-buttons-wrapper{margin-left:2rem}.up-button{margin-right:.3rem}.mat-mdc-menu-item.menu-item,.mat-mdc-menu-item.menu-button{min-height:initial;padding:0 3px;line-height:25px;height:30px}.mat-mdc-menu-item.menu-item{cursor:move}.sorted-name{color:#224e9c;font-size:17px;font-weight:700}.not-sorted-name{color:#93b1ea;font-size:17px;font-weight:700}.apply-border{border:#224e9c solid .5px}.apply-border:hover{background-color:#faebd7}.apply-button-wrapper{display:grid;justify-content:center}.sort-header{font-size:10px;font-style:italic}.tip{padding:0 3px;color:#d3d3d3}.direction-text{font-size:small;font-weight:400}.close-button-wrapper{display:flex;flex-direction:row-reverse}\n"], dependencies: [{ kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i4$1.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i3$1.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "component", type: i3$1.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatMenuModule }, { kind: "component", type: i4$2.MatMenu, selector: "mat-menu", inputs: ["backdropClass", "aria-label", "aria-labelledby", "aria-describedby", "xPosition", "yPosition", "overlapTrigger", "hasBackdrop", "class", "classList"], outputs: ["closed", "close"], exportAs: ["matMenu"] }, { kind: "component", type: i4$2.MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i4$2.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }, { kind: "directive", type: StopPropagationDirective, selector: "[stop-propagation]" }, { kind: "ngmodule", type: DragDropModule }, { kind: "directive", type: i5.CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: i5.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"] }, { kind: "pipe", type: SpaceCasePipe, name: "spaceCase" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
4353
4349
  }
4354
4350
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: SortMenuComponent, decorators: [{
4355
4351
  type: Component,
4356
- args: [{ selector: 'tb-sort-menu', providers: [SortMenuComponentStore], changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [
4357
- LetDirective, MatTooltipModule, MatButtonModule, MatIconModule, MatMenuModule, StopPropagationDirective, DragDropModule,
4358
- SpaceCasePipe, NgClass, AsyncPipe
4359
- ], template: "<ng-container *ngrxLet=\"dirty$ as dirty\">\r\n @if(sorted$ | async; as sorted){\r\n @if (notSorted$ | async; as notSorted) {\r\n <!-- Menu Trigger -->\r\n <span matTooltip=\"Sort\">\r\n <button mat-icon-button [matMenuTriggerFor]=\"menu\">\r\n <mat-icon color=\"primary\">swap_vert</mat-icon>\r\n </button>\r\n </span>\r\n\r\n <!-- Menu -->\r\n <mat-menu #menu=\"matMenu\" class=\"my-mat-menu\" (closed)=\"reset()\">\r\n <div mat-menu-item class=\"menu-button\">\r\n <div class=\"close-button-wrapper\">\r\n <span matTooltip=\"Close\">\r\n <mat-icon>close</mat-icon>\r\n </span>\r\n @if(dirty){\r\n <span matTooltip=\"Undo\" stop-propagation (click)=\"reset()\">\r\n <mat-icon>undo</mat-icon>\r\n </span>\r\n }\r\n \r\n </div>\r\n </div>\r\n\r\n <!-- Apply Button -->\r\n <div class=\"apply-button-wrapper\">\r\n <button mat-button color=\"primary\" (click)=\"apply(null)\"\r\n stop-propagation [class.apply-border]=\"dirty\"\r\n [disabled]=\"!dirty\">\r\n Apply @if (dirty) { Unsaved Changes }\r\n </button>\r\n </div>\r\n\r\n <!-- Default Sorting Text -->\r\n @if (!sorted.length) {\r\n <div class=\"tip\" >\r\n Sorting List\r\n </div>\r\n }\r\n\r\n <!-- Sorted Menu List -->\r\n <div class=\"list\"\r\n cdkDropList\r\n #sortedGroup=\"cdkDropList\"\r\n [cdkDropListConnectedTo]=\"[notSortedGroup]\"\r\n [cdkDropListData]=\"sorted\"\r\n (cdkDropListDropped)=\"dropIntoSorted($event)\">\r\n\r\n <!-- Menu Item Wrapper -->\r\n @for (sort of sorted; track sort.active) {\r\n <!-- Menu Item Headers -->\r\n @if (sorted.length > 1) {\r\n <span class=\"description sort-header\">{{$index === 0 ? 'First By' : 'Then By'}}</span>\r\n }\r\n \r\n <!-- Menu Item -->\r\n <div mat-menu-item cdkDrag class=\"menu-item\">\r\n <div class=\"sort-item\">\r\n <span class=\"sorted-name\">\r\n {{sort.displayName || (sort.active | spaceCase)}}\r\n <span class=\"direction-text\">{{sort.direction}}</span>\r\n </span>\r\n \r\n <!-- Sort Direction Buttons -->\r\n <div class=\"up-down-buttons-wrapper\">\r\n <button class=\"up-down-button up-button\" stop-propagation\r\n (click)=\"setDirection({active:sort.active,direction:SortDirection.asc,displayName:sort.displayName})\">\r\n <mat-icon [ngClass]=\"sort.direction !== SortDirection.asc ? 'light-arrow' : 'dark-arrow'\" class=\"up-down-icon\">\r\n arrow_upward\r\n </mat-icon>\r\n </button>\r\n \r\n <button class=\"up-down-button\" stop-propagation\r\n (click)=\"setDirection({active:sort.active,direction:SortDirection.desc,displayName:sort.displayName})\">\r\n <mat-icon [ngClass]=\"sort.direction === SortDirection.asc ? 'light-arrow' : 'dark-arrow'\" class=\"up-down-icon\">\r\n arrow_downward\r\n </mat-icon>\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n }\r\n\r\n </div>\r\n\r\n <!-- Default Not Sorted Text -->\r\n @if(!notSorted.length){\r\n <div class=\"tip\" >\r\n Not Sorted List\r\n </div>\r\n }\r\n\r\n <!-- Not Sorted Menu List -->\r\n <div class=\"list\"\r\n cdkDropList\r\n #notSortedGroup=\"cdkDropList\"\r\n [cdkDropListConnectedTo]=\"[sortedGroup]\"\r\n [cdkDropListData]=\"notSorted\"\r\n (cdkDropListDropped)=\"dropIntoNotSorted($event)\">\r\n @for (sort of notSorted; track sort.active) {\r\n <div mat-menu-item class=\"menu-item\" cdkDrag>\r\n <span class=\"not-sorted-name\">{{sort.displayName || (sort.active | spaceCase)}}</span>\r\n </div>\r\n }\r\n </div>\r\n </mat-menu>\r\n }\r\n }\r\n</ng-container>\r\n", styles: [".cdk-drag-preview{box-sizing:border-box;border-radius:4px;box-shadow:0 5px 5px -3px #0003,0 8px 10px 1px #00000024,0 3px 14px 2px #0000001f}.cdk-drag-placeholder{opacity:0}.cdk-drag-animating{transition:transform .25s cubic-bezier(0,0,.2,1)}.list{padding:5px 2px;border-bottom:solid 1px #ccc;color:#000000de;background:#fff}.light-arrow{color:#93b1ea78}.dark-arrow{color:#224e9c}.up-down-button{background-color:#fff;border-radius:30%;border-color:#0ff;padding:1px 1px 0;border-width:.5px;cursor:pointer;height:27px}.mat-icon.up-down-icon{margin-right:0;font-size:20px;font-weight:lighter}.sort-item{display:flex;align-items:center;justify-content:space-between}.up-down-buttons-wrapper{margin-left:2rem}.up-button{margin-right:.3rem}.mat-mdc-menu-item.menu-item,.mat-mdc-menu-item.menu-button{min-height:initial;padding:0 3px;line-height:25px;height:30px}.mat-mdc-menu-item.menu-item{cursor:move}.sorted-name{color:#224e9c;font-size:17px;font-weight:700}.not-sorted-name{color:#93b1ea;font-size:17px;font-weight:700}.apply-border{border:#224e9c solid .5px}.apply-border:hover{background-color:#faebd7}.apply-button-wrapper{display:grid;justify-content:center}.sort-header{font-size:10px;font-style:italic}.tip{padding:0 3px;color:#d3d3d3}.direction-text{font-size:small;font-weight:400}.close-button-wrapper{display:flex;flex-direction:row-reverse}\n"] }]
4360
- }], ctorParameters: () => [] });
4352
+ args: [{ selector: 'tb-sort-menu', providers: [SortMenuComponentStore], changeDetection: ChangeDetectionStrategy.OnPush, imports: [
4353
+ MatTooltipModule, MatButtonModule, MatIconModule, MatMenuModule, StopPropagationDirective, DragDropModule,
4354
+ SpaceCasePipe
4355
+ ], template: "@let dirty = $dirty();\r\n@let sorted = $sorted();\r\n@let notSorted = $notSorted();\r\n\r\n<!-- Menu Trigger -->\r\n<span matTooltip=\"Sort\">\r\n <button mat-icon-button [matMenuTriggerFor]=\"menu\">\r\n <mat-icon color=\"primary\">swap_vert</mat-icon>\r\n </button>\r\n</span>\r\n\r\n<!-- Menu -->\r\n<mat-menu #menu=\"matMenu\" class=\"my-mat-menu\" (closed)=\"reset()\">\r\n <div mat-menu-item class=\"menu-button\">\r\n <div class=\"close-button-wrapper\">\r\n <span matTooltip=\"Close\">\r\n <mat-icon>close</mat-icon>\r\n </span>\r\n @if(dirty){\r\n <span matTooltip=\"Undo\" stop-propagation (click)=\"reset()\">\r\n <mat-icon>undo</mat-icon>\r\n </span>\r\n }\r\n \r\n </div>\r\n </div>\r\n\r\n <!-- Apply Button -->\r\n <div class=\"apply-button-wrapper\">\r\n <button mat-button color=\"primary\" (click)=\"apply()\"\r\n stop-propagation [class.apply-border]=\"dirty\"\r\n [disabled]=\"!dirty\">\r\n Apply @if (dirty) { Unsaved Changes }\r\n </button>\r\n </div>\r\n\r\n <!-- Default Sorting Text -->\r\n @if (!sorted.length) {\r\n <div class=\"tip\" >\r\n Sorting List\r\n </div>\r\n }\r\n\r\n <!-- Sorted Menu List -->\r\n <div class=\"list\"\r\n cdkDropList\r\n #sortedGroup=\"cdkDropList\"\r\n [cdkDropListConnectedTo]=\"[notSortedGroup]\"\r\n [cdkDropListData]=\"sorted\"\r\n (cdkDropListDropped)=\"dropIntoSorted($event)\">\r\n\r\n <!-- Menu Item Wrapper -->\r\n @for (sort of sorted; track sort.active) {\r\n <!-- Menu Item Headers -->\r\n @if (sorted.length > 1) {\r\n <span class=\"description sort-header\">{{$index === 0 ? 'First By' : 'Then By'}}</span>\r\n }\r\n\r\n <!-- Menu Item -->\r\n <div mat-menu-item cdkDrag class=\"menu-item\">\r\n <div class=\"sort-item\">\r\n <span class=\"sorted-name\">\r\n {{sort.displayName || (sort.active | spaceCase)}}\r\n <span class=\"direction-text\">{{sort.direction}}</span>\r\n </span>\r\n\r\n <!-- Sort Direction Buttons -->\r\n <div class=\"up-down-buttons-wrapper\">\r\n <button class=\"up-down-button up-button\" stop-propagation\r\n (click)=\"setDirection({active:sort.active,direction:SortDirection.asc,displayName:sort.displayName})\">\r\n <mat-icon [class]=\"sort.direction !== SortDirection.asc ? 'light-arrow' : 'dark-arrow'\" class=\"up-down-icon\">\r\n arrow_upward\r\n </mat-icon>\r\n </button>\r\n\r\n <button class=\"up-down-button\" stop-propagation\r\n (click)=\"setDirection({active:sort.active,direction:SortDirection.desc,displayName:sort.displayName})\">\r\n <mat-icon [class]=\"sort.direction === SortDirection.asc ? 'light-arrow' : 'dark-arrow'\" class=\"up-down-icon\">\r\n arrow_downward\r\n </mat-icon>\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n }\r\n\r\n </div>\r\n\r\n <!-- Default Not Sorted Text -->\r\n @if(!notSorted.length){\r\n <div class=\"tip\" >\r\n Not Sorted List\r\n </div>\r\n }\r\n\r\n <!-- Not Sorted Menu List -->\r\n <div class=\"list\"\r\n cdkDropList\r\n #notSortedGroup=\"cdkDropList\"\r\n [cdkDropListConnectedTo]=\"[sortedGroup]\"\r\n [cdkDropListData]=\"notSorted\"\r\n (cdkDropListDropped)=\"dropIntoNotSorted($event)\">\r\n @for (sort of notSorted; track sort.active) {\r\n <div mat-menu-item class=\"menu-item\" cdkDrag>\r\n <span class=\"not-sorted-name\">{{sort.displayName || (sort.active | spaceCase)}}</span>\r\n </div>\r\n }\r\n </div>\r\n</mat-menu>\r\n", styles: [".cdk-drag-preview{box-sizing:border-box;border-radius:4px;box-shadow:0 5px 5px -3px #0003,0 8px 10px 1px #00000024,0 3px 14px 2px #0000001f}.cdk-drag-placeholder{opacity:0}.cdk-drag-animating{transition:transform .25s cubic-bezier(0,0,.2,1)}.list{padding:5px 2px;border-bottom:solid 1px #ccc;color:#000000de;background:#fff}.light-arrow{color:#93b1ea78}.dark-arrow{color:#224e9c}.up-down-button{background-color:#fff;border-radius:30%;border-color:#0ff;padding:1px 1px 0;border-width:.5px;cursor:pointer;height:27px}.mat-icon.up-down-icon{margin-right:0;font-size:20px;font-weight:lighter}.sort-item{display:flex;align-items:center;justify-content:space-between}.up-down-buttons-wrapper{margin-left:2rem}.up-button{margin-right:.3rem}.mat-mdc-menu-item.menu-item,.mat-mdc-menu-item.menu-button{min-height:initial;padding:0 3px;line-height:25px;height:30px}.mat-mdc-menu-item.menu-item{cursor:move}.sorted-name{color:#224e9c;font-size:17px;font-weight:700}.not-sorted-name{color:#93b1ea;font-size:17px;font-weight:700}.apply-border{border:#224e9c solid .5px}.apply-border:hover{background-color:#faebd7}.apply-button-wrapper{display:grid;justify-content:center}.sort-header{font-size:10px;font-style:italic}.tip{padding:0 3px;color:#d3d3d3}.direction-text{font-size:small;font-weight:400}.close-button-wrapper{display:flex;flex-direction:row-reverse}\n"] }]
4356
+ }] });
4361
4357
 
4362
4358
  class PaginatorComponent {
4363
4359
  state = inject(TableStore);
4364
4360
  data = inject(DataStore);
4365
4361
  $paginator = viewChild(MatPaginator);
4366
- $tableElRef = input.required({ alias: 'tableElRef' });
4367
4362
  $dataLength = this.data.selectSignal(d => d.dataLen);
4368
4363
  pageEvent$ = toObservable(this.$paginator).pipe(notNull(), switchMap(p => p.page));
4369
4364
  $pageEvent = toSignal(this.pageEvent$);
@@ -4384,13 +4379,16 @@ class PaginatorComponent {
4384
4379
  });
4385
4380
  onPageIndexEffect = effect(() => {
4386
4381
  const index = this.$pageIndexChangeEvent();
4387
- untracked(() => this.state.updateState({ currentPage: index }));
4382
+ if (index === undefined)
4383
+ return;
4384
+ untracked(() => this.state.setCurrentPage(index));
4388
4385
  });
4389
4386
  onPageSizeEffect = effect(() => {
4390
4387
  const size = this.$pageSizeChangeEvent();
4391
- if (!size)
4388
+ const initialized = this.state.$initializationState() >= InitializationState.Ready;
4389
+ if (!size || !initialized)
4392
4390
  return;
4393
- untracked(() => this.state.setPageSize(size));
4391
+ untracked(() => this.state.setUserDefinedPageSize(size));
4394
4392
  });
4395
4393
  onMetaPageSizeEffect = effect(() => {
4396
4394
  const paginator = this.$paginator();
@@ -4409,14 +4407,13 @@ class PaginatorComponent {
4409
4407
  });
4410
4408
  });
4411
4409
  $collapseFooter = computed(() => this.state.selectSignal(state => state.persistedTableSettings.collapseFooter)() || this.$showAll());
4412
- $showAllOption = this.state.selectSignal(s => s.notPersistedTableSettings?.includeAllInPaginatorOptions);
4413
- $showAll = this.state.selectSignal(s => s.showAll);
4414
- updatePaginator = this.state.updater(state => ({ ...state, showAll: !state.showAll }));
4410
+ $showAllOption = this.state.selectSignal(s => s.notPersistedTableSettings?.paginatorSettings?.includeAllInOptions);
4411
+ $showAll = this.state.$showAll;
4415
4412
  showAll() {
4416
- this.updatePaginator();
4413
+ this.state.setUserDefinedShowAll(!this.$showAll());
4417
4414
  }
4418
4415
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: PaginatorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
4419
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.0", type: PaginatorComponent, isStandalone: true, selector: "tb-paginator", inputs: { $tableElRef: { classPropertyName: "$tableElRef", publicName: "tableElRef", isSignal: true, isRequired: true, transformFunction: null } }, viewQueries: [{ propertyName: "$paginator", first: true, predicate: MatPaginator, descendants: true, isSignal: true }], ngImport: i0, template: `
4416
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.0", type: PaginatorComponent, isStandalone: true, selector: "tb-paginator", viewQueries: [{ propertyName: "$paginator", first: true, predicate: MatPaginator, descendants: true, isSignal: true }], ngImport: i0, template: `
4420
4417
  <div class="paginator-row">
4421
4418
  @if($currentPageData(); as pageData){
4422
4419
  <div [class]="{ 'hide' : ! $collapseFooter(), 'page-amounts':true}">
@@ -4426,13 +4423,13 @@ class PaginatorComponent {
4426
4423
  <mat-paginator [pageSizeOptions]="[5, 10, 20, 50, 100, 500]" showFirstLastButtons
4427
4424
  [class]="{ 'hide' : $collapseFooter() }">
4428
4425
  </mat-paginator>
4429
- @if ($showAllOption()) {<button mat-button (click)="updatePaginator()"><span [style.text-decoration]="$showAll() ? 'line-through' : ''" >All</span></button>}
4426
+ @if ($showAllOption()) {<button mat-button (click)="showAll()"><span [style.text-decoration]="$showAll() ? 'line-through' : ''" >All</span></button>}
4430
4427
  </div>
4431
4428
  `, isInline: true, styles: [":host{--mat-paginator-container-size: initial}.select-column{min-width:var(--tb-min-select-column-width, 42px)}.index-column{min-width:var(--tb-min-index-column-width, 42px)}.mat-mdc-row:nth-child(odd){background-color:var(--tb-odd-row-background-color, #cdeefe)}.page-amounts{color:#0000008a;font-family:Roboto,Helvetica Neue,sans-serif;font-size:12px;margin-right:.2rem}:host::ng-deep .table-drag-list.cdk-drop-list-dragging .drag-header:not(.cdk-drag-placeholder){transition:transform .25s cubic-bezier(0,0,.2,1)}:host::ng-deep .mdc-data-table__cell,:host::ng-deep .mdc-data-table__header-cell{padding:var(--tb-cell-padding, 0 0 0 .2rem);line-height:var(--tb-cell-line-height, normal)}::ng-deep .op-date-time-input{line-height:3rem;font-size:.9rem;font-family:Roboto,Helvetica Neue,sans-serif;padding-left:.2rem;width:12rem}\n", ".collapse-icon{font-size:16px;height:16px;color:#3f51b5;align-self:flex-start}.collapse-icon:hover{cursor:pointer}.hide{display:none}.paginator-row{display:flex;align-items:center}\n"], dependencies: [{ kind: "ngmodule", type: MatPaginatorModule }, { kind: "component", type: i1$6.MatPaginator, selector: "mat-paginator", inputs: ["color", "pageIndex", "length", "pageSize", "pageSizeOptions", "hidePageSize", "showFirstLastButtons", "selectConfig", "disabled"], outputs: ["page"], exportAs: ["matPaginator"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i3$1.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
4432
4429
  }
4433
4430
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: PaginatorComponent, decorators: [{
4434
4431
  type: Component,
4435
- args: [{ selector: 'tb-paginator', standalone: true, imports: [MatPaginatorModule, MatButtonModule], template: `
4432
+ args: [{ selector: 'tb-paginator', imports: [MatPaginatorModule, MatButtonModule], template: `
4436
4433
  <div class="paginator-row">
4437
4434
  @if($currentPageData(); as pageData){
4438
4435
  <div [class]="{ 'hide' : ! $collapseFooter(), 'page-amounts':true}">
@@ -4442,7 +4439,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImpor
4442
4439
  <mat-paginator [pageSizeOptions]="[5, 10, 20, 50, 100, 500]" showFirstLastButtons
4443
4440
  [class]="{ 'hide' : $collapseFooter() }">
4444
4441
  </mat-paginator>
4445
- @if ($showAllOption()) {<button mat-button (click)="updatePaginator()"><span [style.text-decoration]="$showAll() ? 'line-through' : ''" >All</span></button>}
4442
+ @if ($showAllOption()) {<button mat-button (click)="showAll()"><span [style.text-decoration]="$showAll() ? 'line-through' : ''" >All</span></button>}
4446
4443
  </div>
4447
4444
  `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{--mat-paginator-container-size: initial}.select-column{min-width:var(--tb-min-select-column-width, 42px)}.index-column{min-width:var(--tb-min-index-column-width, 42px)}.mat-mdc-row:nth-child(odd){background-color:var(--tb-odd-row-background-color, #cdeefe)}.page-amounts{color:#0000008a;font-family:Roboto,Helvetica Neue,sans-serif;font-size:12px;margin-right:.2rem}:host::ng-deep .table-drag-list.cdk-drop-list-dragging .drag-header:not(.cdk-drag-placeholder){transition:transform .25s cubic-bezier(0,0,.2,1)}:host::ng-deep .mdc-data-table__cell,:host::ng-deep .mdc-data-table__header-cell{padding:var(--tb-cell-padding, 0 0 0 .2rem);line-height:var(--tb-cell-line-height, normal)}::ng-deep .op-date-time-input{line-height:3rem;font-size:.9rem;font-family:Roboto,Helvetica Neue,sans-serif;padding-left:.2rem;width:12rem}\n", ".collapse-icon{font-size:16px;height:16px;color:#3f51b5;align-self:flex-start}.collapse-icon:hover{cursor:pointer}.hide{display:none}.paginator-row{display:flex;align-items:center}\n"] }]
4448
4445
  }] });
@@ -4514,13 +4511,18 @@ class VirtualScrollContainer {
4514
4511
  dataStore = inject(DataStore);
4515
4512
  viewport = viewChild(CdkVirtualScrollViewport);
4516
4513
  genericTable = contentChild(GenericTableComponent);
4514
+ tableContainer = inject(TableContainerComponent);
4517
4515
  defaultOptions = new VirtualScrollOptions();
4518
4516
  scrollStrategy = new TableVirtualScrollStrategy(this.computedRowHeight(), this.computedHeaderHeight());
4519
4517
  $usePaginator = this.state.selectSignal(s => s.notPersistedTableSettings.usePaginator);
4520
4518
  $pageSize = this.state.$pageSize;
4521
4519
  $currentPage = this.state.$currentPage;
4522
- $showAll = this.state.selectSignal(s => s.showAll);
4520
+ $showAll = this.state.$showAll;
4523
4521
  $stateDataLength = this.dataStore.selectSignal(s => s.dataLen);
4522
+ viewPort$ = toObservable(this.viewport).pipe(notNull());
4523
+ $scrolledIndexChange = toSignal(this.viewPort$.pipe(switchMap$1(v => v.scrolledIndexChange)));
4524
+ $renderedRange = toSignal(this.viewPort$.pipe(switchMap$1(v => v.renderedRangeStream)));
4525
+ $virtualScrollOptions = computed(() => this.state.$tableSettings().virtualSettings);
4524
4526
  $dataLength = computed(() => {
4525
4527
  const paginated = this.$usePaginator() && !this.$showAll();
4526
4528
  const pageSize = this.$pageSize();
@@ -4569,9 +4571,6 @@ class VirtualScrollContainer {
4569
4571
  this.dataStore.patchState({ virtualScrollOffset: offset });
4570
4572
  });
4571
4573
  });
4572
- viewPort$ = toObservable(this.viewport).pipe(notNull());
4573
- $scrolledIndexChange = toSignal(this.viewPort$.pipe(switchMap$1(v => v.scrolledIndexChange)));
4574
- $renderedRange = toSignal(this.viewPort$.pipe(switchMap$1(v => v.renderedRangeStream)));
4575
4574
  $offset = computed(() => {
4576
4575
  const viewport = this.viewport();
4577
4576
  const scrolledIndexChange = this.$scrolledIndexChange();
@@ -4583,40 +4582,78 @@ class VirtualScrollContainer {
4583
4582
  removeEventListener('resize', this.resizeHandler);
4584
4583
  }
4585
4584
  setSize(el) {
4586
- const vsViewport = el.nativeElement;
4587
- const virtualScrollOptions = this.state.tableSettings().useVirtualScroll;
4585
+ const virtualScrollOptions = this.$virtualScrollOptions();
4586
+ if (virtualScrollOptions.dynamicHeight) {
4587
+ this.calcDynamic(el);
4588
+ return;
4589
+ }
4588
4590
  const rowHeight = this.computedRowHeight();
4589
4591
  let amountOfVisibleItems = virtualScrollOptions?.amountOfVisibleItems || this.defaultOptions.amountOfVisibleItems;
4590
- virtualScrollOptions?.amountOfVisibleItems || this.defaultOptions.amountOfVisibleItems;
4591
4592
  amountOfVisibleItems = Math.min(amountOfVisibleItems, this.$dataLength());
4592
4593
  let height = (rowHeight * amountOfVisibleItems);
4593
- height += parseFloat(this.genericTable()?.$footerHeight()?.replace('px', '') || '0');
4594
- if (!this.state.tableSettings().hideHeader) {
4595
- const headerHeight = this.computedHeaderHeight();
4596
- height += headerHeight;
4597
- }
4594
+ const footerHeight = this.computedFooterHeight();
4595
+ const headerHeight = this.computedHeaderHeight();
4596
+ height += (footerHeight + headerHeight);
4598
4597
  if (virtualScrollOptions?.maxViewPortHeight && virtualScrollOptions.maxViewPortHeight < height)
4599
4598
  height = virtualScrollOptions.maxViewPortHeight;
4599
+ this.setHeight(height, el);
4600
+ }
4601
+ calcDynamic$ = new Subject();
4602
+ $calcDynamic = toSignal(this.calcDynamic$.pipe(debounceTime(300)));
4603
+ #onCalcDynamicEffect = effect(() => {
4604
+ const el = this.$calcDynamic();
4605
+ if (!el)
4606
+ return;
4607
+ this.calcDynamic(el);
4608
+ });
4609
+ calcDynamic(el) {
4610
+ const virtualScrollOptions = this.$virtualScrollOptions();
4611
+ const t = this.tableContainer.elementRef.nativeElement.querySelector(`#${TableContainerComponent.headerId}`);
4612
+ const rect = t?.getBoundingClientRect();
4613
+ const viewportHeight = window.innerHeight;
4614
+ const distanceFromBottom = viewportHeight - rect.bottom;
4615
+ const rowHeight = this.computedRowHeight();
4616
+ const footerHeight = this.computedFooterHeight();
4617
+ const headerHeight = this.computedHeaderHeight();
4618
+ let tableSize = distanceFromBottom;
4619
+ if (virtualScrollOptions?.maxViewPortHeight && virtualScrollOptions.maxViewPortHeight < tableSize) {
4620
+ tableSize = virtualScrollOptions.maxViewPortHeight;
4621
+ }
4622
+ const available = (distanceFromBottom - footerHeight) - headerHeight;
4623
+ const amountOfRowsThatWillFit = Math.floor(available / rowHeight);
4624
+ const minAmountOfRows = virtualScrollOptions?.amountOfVisibleItems || this.defaultOptions.amountOfVisibleItems;
4625
+ const amountOfVisibleItems = Math.min(Math.max(amountOfRowsThatWillFit, minAmountOfRows), this.$dataLength());
4626
+ let height = (rowHeight * amountOfVisibleItems);
4627
+ height += (footerHeight + headerHeight) - 10;
4628
+ this.setHeight(height, el);
4629
+ }
4630
+ setHeight(height, el) {
4631
+ const vsViewport = el.nativeElement;
4600
4632
  vsViewport.setAttribute('style', `height: ${height}px !important;`);
4601
4633
  this.viewport()?.checkViewportSize();
4602
4634
  const virtualScrollOffset = this.viewport()?.getOffsetToRenderedContentStart() ?? 0;
4603
4635
  this.dataStore.patchState({ virtualScrollOffset });
4604
4636
  }
4605
4637
  resizeHandler = () => {
4606
- if (this.viewport()) {
4638
+ if (this.viewport() && this.$virtualScrollOptions().dynamicHeight) {
4607
4639
  this.setSize(this.viewport().elementRef);
4608
4640
  }
4609
4641
  };
4610
4642
  computedRowHeight() {
4611
- const virtualScrollOptions = this.state.tableSettings().useVirtualScroll;
4612
- const rowHeight = virtualScrollOptions?.rowHeight || (typeof this.state.tableSettings().rowHeight === 'number' && this.state.tableSettings().rowHeight) || this.defaultOptions.rowHeight;
4643
+ const virtualScrollOptions = this.state.$tableSettings().virtualSettings;
4644
+ const rowHeight = virtualScrollOptions?.rowHeight || (typeof this.state.$tableSettings().rowHeight === 'number' && this.state.$tableSettings().rowHeight) || this.defaultOptions.rowHeight;
4613
4645
  return rowHeight;
4614
4646
  }
4615
4647
  computedHeaderHeight() {
4616
- const virtualScrollOptions = this.state.tableSettings().useVirtualScroll;
4617
- const headerHeight = virtualScrollOptions?.headerHeight || (typeof this.state.tableSettings().headerHeight === 'number' && this.state.tableSettings().headerHeight) || this.defaultOptions.headerHeight;
4648
+ if (this.state.$tableSettings().hideHeader)
4649
+ return 0;
4650
+ const virtualScrollOptions = this.state.$tableSettings().virtualSettings;
4651
+ const headerHeight = virtualScrollOptions?.headerHeight || (typeof this.state.$tableSettings().headerHeight === 'number' && this.state.$tableSettings().headerHeight) || this.defaultOptions.headerHeight;
4618
4652
  return headerHeight;
4619
4653
  }
4654
+ computedFooterHeight() {
4655
+ return parseFloat(this.genericTable()?.$footerHeight()?.replace('px', '') || '0');
4656
+ }
4620
4657
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: VirtualScrollContainer, deps: [], target: i0.ɵɵFactoryTarget.Component });
4621
4658
  static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "19.0.0", type: VirtualScrollContainer, isStandalone: true, selector: "tb-virtual-scroll-container", queries: [{ propertyName: "genericTable", first: true, predicate: GenericTableComponent, descendants: true, isSignal: true }], viewQueries: [{ propertyName: "viewport", first: true, predicate: CdkVirtualScrollViewport, descendants: true, isSignal: true }], ngImport: i0, template: `
4622
4659
  <cdk-virtual-scroll-viewport>
@@ -4640,7 +4677,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImpor
4640
4677
  </cdk-virtual-scroll-viewport>
4641
4678
  `,
4642
4679
  changeDetection: ChangeDetectionStrategy.OnPush,
4643
- standalone: true,
4644
4680
  imports: [ScrollingModule],
4645
4681
  viewProviders: [
4646
4682
  {
@@ -4664,12 +4700,12 @@ class ProfilesMenuComponent {
4664
4700
  $defaultProfile = computed(() => this.stateService.$selectLocalProfileDefaultKey(this.$tableId())());
4665
4701
  $keys = computed(() => this.stateService.$selectLocalProfileKeys(this.$tableId())());
4666
4702
  saveState(key) {
4667
- const tableState = this.tableStore.getSavableStateSignal();
4703
+ const tableState = this.tableStore.$savableState();
4668
4704
  this.onSaveState.emit(null);
4669
4705
  this.stateService.saveTableSettingsToLocalAndStorage(this.$tableId(), key, tableState);
4670
4706
  }
4671
4707
  addState(key, asDefault) {
4672
- const tableState = this.tableStore.getSavableStateSignal();
4708
+ const tableState = this.tableStore.$savableState();
4673
4709
  this.stateService.addNewStateToLocalAndStorage(this.$tableId(), key, tableState, asDefault);
4674
4710
  }
4675
4711
  setDefault(key) {
@@ -4691,19 +4727,18 @@ class ProfilesMenuComponent {
4691
4727
  return a;
4692
4728
  };
4693
4729
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: ProfilesMenuComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
4694
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.0", type: ProfilesMenuComponent, isStandalone: true, selector: "tb-profiles-menu", inputs: { $tableId: { classPropertyName: "$tableId", publicName: "$tableId", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { onSaveState: "onSaveState" }, viewQueries: [{ propertyName: "trigger", first: true, predicate: ["trigger"], descendants: true, isSignal: true }], ngImport: i0, template: "<button mat-icon-button [matMenuTriggerFor]=\"menu\" #trigger=\"matMenuTrigger\" [matTooltip]=\"'Profiles'\">\r\n <mat-icon color=\"primary\">people</mat-icon>\r\n</button>\r\n<mat-menu #menu=\"matMenu\" (closed)=\"addedKey.value = null; allProfilesPanelOpened.set(false); newProfilePanelOpened.set(false)\">\r\n @if(!!$currentProfile())\r\n {\r\n <div mat-menu-item [matTooltip]=\"'Save Profile'\" mat-stroked-button (click)=\"saveState($currentProfile()!)\">\r\n <mat-icon color=\"primary\">save</mat-icon>\r\n <span>{{$currentProfile()}}</span>\r\n </div>\r\n }\r\n @else\r\n {\r\n <div class=\"profile-line\">\r\n <button class=\"first-in-line first-button\" mat-stroked-button (click)=\"addState(defaultName, m.checked);\">\r\n <mat-icon class=\"save-for-default-icon button-save-icon\" color=\"primary\">save</mat-icon>\r\n <span>Save as <span class=\"current-name\">{{defaultName}}</span> </span>\r\n </button>\r\n <button [matTooltip]=\"'Toggle Profile Being Created As Default'\" stop-propagation mat-icon-button (click)=\"m.toggle()\" >\r\n <mat-icon style=\"color: green;\">{{m.checked ? 'star' : 'star_border'}}</mat-icon>\r\n </button>\r\n <mat-checkbox class=\"display-none\" [checked]=\"true\" #m />\r\n </div>\r\n }\r\n @if (allProfilesPanelOpened()) {<hr class=\"divider\"/>}\r\n <div [class]=\"{ hide: !$keys().length, 'all-profile-row': true }\" mat-menu-item stop-propagation (click)=\"allProfilesPanelOpened.set(!allProfilesPanelOpened())\">\r\n <div class=\"all-profiles\">\r\n <span>All Profiles</span>\r\n <span [class]=\"(allProfilesPanelOpened() ? 'all-profile-arrow-close' : 'all-profile-arrow-open') + ' all-profile-arrow'\" class=\"arrow\"></span>\r\n </div>\r\n </div>\r\n <div [class]=\"{ hide: !allProfilesPanelOpened(), panel: true }\">\r\n @for (key of $keys() ; track key) {\r\n <div class=\"profile-line\" [class]=\"key === $currentProfile() ? 'current-in-list' : 'not-current-in-list'\">\r\n <button [matTooltip]=\"'Select Profile'\" class=\"menu-item first-in-line\" mat-stroked-button (click)='stateService.setLocalCurrentState({ tableId: $tableId(), currentStateKey: key})'>\r\n <span>{{key}}</span>\r\n </button>\r\n @if(key !== $defaultProfile())\r\n {\r\n <button [matTooltip]=\"'Toggle Profile Being Default'\" stop-propagation mat-icon-button (click)=\"setDefault(key)\">\r\n <mat-icon style=\"color: green;\">star_border</mat-icon>\r\n </button>\r\n }\r\n @else\r\n {\r\n <button [matTooltip]=\"'Toggle Profile Being Default'\" stop-propagation mat-icon-button (click)=\"unsetDefault()\">\r\n <mat-icon style=\"color: green;\">star</mat-icon>\r\n </button>\r\n }\r\n <button [matTooltip]=\"'Delete Profile'\" class=\"last-in-line\" stop-propagation mat-icon-button (click)='stateService.deleteProfileFromLocalAndStorage($tableId(), key)'>\r\n <mat-icon color='warn'>delete_forever</mat-icon>\r\n </button>\r\n </div>\r\n }\r\n <hr class=\"divider\"/>\r\n </div>\r\n <div class=\"add-new-profile-row\" mat-menu-item stop-propagation (click)=\"newProfilePanelOpened.set(!newProfilePanelOpened()); addedKey.focus()\">Add New Profile</div>\r\n <div [class]=\"{ hide: !newProfilePanelOpened(), panel: true }\" >\r\n <div class=\"profile-line\" stop-propagation>\r\n <div class=\"new-name-input\">\r\n <i class=\"input-hint\">Enter New Name</i>\r\n <input matInput #addedKey=\"matInput\" [name]=\"'key'\" />\r\n </div>\r\n <button [matTooltip]=\"'Toggle Profile Being Created As Default'\" stop-propagation mat-icon-button (click)=\"m2.toggle()\" >\r\n <mat-icon style=\"color: green;\">{{m2.checked ? 'star' : 'star_border'}}</mat-icon>\r\n </button>\r\n <mat-checkbox class=\"display-none\" [ngModel]=\"!$defaultProfile()\" #m2 />\r\n </div>\r\n <button class=\"add-button\" color=\"primary\" [matTooltip]=\"'Create New Profile'\" mat-raised-button (click)=\"addState(addedKey.value, m2.checked); addedKey.value = null\" [disabled]=\"!addedKey.value\">\r\n Add\r\n </button>\r\n </div>\r\n</mat-menu>\r\n\r\n<ng-template #line let-key>\r\n\r\n\r\n</ng-template>\r\n", styles: [":host ::ng-deep .mat-expansion-panel-header{padding:0}.current-name{color:#00f}.menu-item{display:inline-flex;width:initial;flex-grow:1}.profile-line{display:flex;justify-content:space-between;align-items:center}.first-in-line{--f-b: 2rem;margin-left:var(--mat-menu-item-with-icon-leading-spacing)}.first-in-line.first-button{height:var(--f-b);margin:.2rem}.first-in-line .button-save-icon{height:var(--f-b);width:var(--f-b);font-size:var(--f-b)}.main-save-button{height:4rem;width:4rem;padding:.5rem}.main-save-button mat-icon{height:3rem;width:3rem;font-size:3rem}.save-for-default-icon{margin:0}.display-none{display:none}.last-in-line{padding-right:var(--mat-menu-item-with-icon-trailing-spacing)}.default-cursor{cursor:default}.as-def{padding-left:var(--mat-menu-item-with-icon-leading-spacing)}.divider{margin:.2px 0}.add-key{max-width:8.5rem;margin-left:2px}.add-key ::ng-deep .mdc-text-field{padding:0}.panel{transition:height .1s}.hide{height:0;min-height:0;overflow:hidden}.open-panel-button{width:100%;height:2.5rem}.current-in-list{border-left:3px solid blue;background-color:#0000ff0d}.not-current-in-list{border-left:3px solid rgba(255,255,255,0)}.add-new-profile-row,.all-profile-row{border-top:rgba(128,128,128,.25) solid 1px}.all-profiles{display:flex;justify-content:space-between}.all-profiles:has(.all-profile-arrow-close){align-items:center}.all-profile-arrow{display:inline-block;height:.7rem;width:.7rem;border-color:#000;transform:rotate(-45deg)}.all-profile-arrow-open{border-left:solid 2px;border-bottom:solid 2px}.all-profile-arrow-close{border-right:solid 2px;border-top:solid 2px}.new-name-input{margin-left:3px;display:flex;flex-direction:column}.new-name-input .input-hint{font-size:smaller;font-weight:200;color:gray}.add-button{height:20px;line-height:20px;margin:3px 0 0 3px}\n"], dependencies: [{ kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "ngmodule", type: MatMenuModule }, { kind: "component", type: i4$2.MatMenu, selector: "mat-menu", inputs: ["backdropClass", "aria-label", "aria-labelledby", "aria-describedby", "xPosition", "yPosition", "overlapTrigger", "hasBackdrop", "class", "classList"], outputs: ["closed", "close"], exportAs: ["matMenu"] }, { kind: "component", type: i4$2.MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i4$2.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }, { kind: "component", type: MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "directive", type: MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "component", type: 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: "directive", type: StopPropagationDirective, selector: "[stop-propagation]" }, { kind: "ngmodule", type: MatInputModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }] });
4730
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.0", type: ProfilesMenuComponent, isStandalone: true, selector: "tb-profiles-menu", inputs: { $tableId: { classPropertyName: "$tableId", publicName: "$tableId", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { onSaveState: "onSaveState" }, viewQueries: [{ propertyName: "trigger", first: true, predicate: ["trigger"], descendants: true, isSignal: true }], ngImport: i0, template: "<button mat-icon-button [matMenuTriggerFor]=\"menu\" #trigger=\"matMenuTrigger\" [matTooltip]=\"'Profiles'\">\r\n <mat-icon color=\"primary\">people</mat-icon>\r\n</button>\r\n<mat-menu #menu=\"matMenu\" (closed)=\"addedKey.value = null; allProfilesPanelOpened.set(false); newProfilePanelOpened.set(false)\">\r\n @if(!!$currentProfile())\r\n {\r\n <div mat-menu-item [matTooltip]=\"'Save Profile'\" mat-stroked-button (click)=\"saveState($currentProfile()!)\">\r\n <mat-icon color=\"primary\">save</mat-icon>\r\n <span>{{$currentProfile()}}</span>\r\n </div>\r\n }\r\n @else\r\n {\r\n <div class=\"profile-line\">\r\n <button class=\"first-in-line first-button\" mat-stroked-button (click)=\"addState(defaultName, m.checked);\">\r\n <mat-icon class=\"save-for-default-icon button-save-icon\" color=\"primary\">save</mat-icon>\r\n <span>Save as <span class=\"current-name\">{{defaultName}}</span> </span>\r\n </button>\r\n <button [matTooltip]=\"'Toggle Profile Being Created As Default'\" stop-propagation mat-icon-button (click)=\"m.toggle()\" >\r\n <mat-icon style=\"color: green;\">{{m.checked ? 'star' : 'star_border'}}</mat-icon>\r\n </button>\r\n <mat-checkbox class=\"display-none\" [checked]=\"true\" #m />\r\n </div>\r\n }\r\n @if (allProfilesPanelOpened()) {<hr class=\"divider\"/>}\r\n <div [class]=\"{ hide: !$keys().length, 'all-profile-row': true }\" mat-menu-item stop-propagation (click)=\"allProfilesPanelOpened.set(!allProfilesPanelOpened())\">\r\n <div class=\"all-profiles\">\r\n <span>All Profiles</span>\r\n <span [class]=\"(allProfilesPanelOpened() ? 'all-profile-arrow-close' : 'all-profile-arrow-open') + ' all-profile-arrow'\" class=\"arrow\"></span>\r\n </div>\r\n </div>\r\n <div [class]=\"{ hide: !allProfilesPanelOpened(), panel: true }\">\r\n @for (key of $keys() ; track key) {\r\n <div class=\"profile-line\" [class]=\"key === $currentProfile() ? 'current-in-list' : 'not-current-in-list'\">\r\n <button [matTooltip]=\"'Select Profile'\" class=\"menu-item first-in-line\" mat-stroked-button (click)='stateService.setLocalCurrentState({ tableId: $tableId(), currentStateKey: key})'>\r\n <span>{{key}}</span>\r\n </button>\r\n @if(key !== $defaultProfile())\r\n {\r\n <button [matTooltip]=\"'Toggle Profile Being Default'\" stop-propagation mat-icon-button (click)=\"setDefault(key)\">\r\n <mat-icon style=\"color: green;\">star_border</mat-icon>\r\n </button>\r\n }\r\n @else\r\n {\r\n <button [matTooltip]=\"'Toggle Profile Being Default'\" stop-propagation mat-icon-button (click)=\"unsetDefault()\">\r\n <mat-icon style=\"color: green;\">star</mat-icon>\r\n </button>\r\n }\r\n <button [matTooltip]=\"'Delete Profile'\" class=\"last-in-line\" stop-propagation mat-icon-button (click)='stateService.deleteProfileFromLocalAndStorage($tableId(), key)'>\r\n <mat-icon color='warn'>delete_forever</mat-icon>\r\n </button>\r\n </div>\r\n }\r\n <hr class=\"divider\"/>\r\n </div>\r\n <div class=\"add-new-profile-row\" mat-menu-item stop-propagation (click)=\"newProfilePanelOpened.set(!newProfilePanelOpened()); addedKey.focus()\">Add New Profile</div>\r\n <div [class]=\"{ hide: !newProfilePanelOpened(), panel: true }\" >\r\n <div class=\"profile-line\" stop-propagation>\r\n <div class=\"new-name-input\">\r\n <i class=\"input-hint\">Enter New Name</i>\r\n <input matInput #addedKey=\"matInput\" [name]=\"'key'\" />\r\n </div>\r\n <button [matTooltip]=\"'Toggle Profile Being Created As Default'\" stop-propagation mat-icon-button (click)=\"m2.toggle()\" >\r\n <mat-icon style=\"color: green;\">{{m2.checked ? 'star' : 'star_border'}}</mat-icon>\r\n </button>\r\n <mat-checkbox class=\"display-none\" [ngModel]=\"!$defaultProfile()\" #m2 />\r\n </div>\r\n <button class=\"add-button\" color=\"primary\" [matTooltip]=\"'Create New Profile'\" mat-raised-button (click)=\"addState(addedKey.value, m2.checked); addedKey.value = null\" [disabled]=\"!addedKey.value\">\r\n Add\r\n </button>\r\n </div>\r\n</mat-menu>\r\n", styles: [":host ::ng-deep .mat-expansion-panel-header{padding:0}.current-name{color:#00f}.menu-item{display:inline-flex;width:initial;flex-grow:1}.profile-line{display:flex;justify-content:space-between;align-items:center}.first-in-line{--f-b: 2rem;margin-left:var(--mat-menu-item-with-icon-leading-spacing)}.first-in-line.first-button{height:var(--f-b);margin:.2rem}.first-in-line .button-save-icon{height:var(--f-b);width:var(--f-b);font-size:var(--f-b)}.main-save-button{height:4rem;width:4rem;padding:.5rem}.main-save-button mat-icon{height:3rem;width:3rem;font-size:3rem}.save-for-default-icon{margin:0}.display-none{display:none}.last-in-line{padding-right:var(--mat-menu-item-with-icon-trailing-spacing)}.default-cursor{cursor:default}.as-def{padding-left:var(--mat-menu-item-with-icon-leading-spacing)}.divider{margin:.2px 0}.add-key{max-width:8.5rem;margin-left:2px}.add-key ::ng-deep .mdc-text-field{padding:0}.panel{transition:height .1s}.hide{height:0;min-height:0;overflow:hidden}.open-panel-button{width:100%;height:2.5rem}.current-in-list{border-left:3px solid blue;background-color:#0000ff0d}.not-current-in-list{border-left:3px solid rgba(255,255,255,0)}.add-new-profile-row,.all-profile-row{border-top:rgba(128,128,128,.25) solid 1px}.all-profiles{display:flex;justify-content:space-between}.all-profiles:has(.all-profile-arrow-close){align-items:center}.all-profile-arrow{display:inline-block;height:.7rem;width:.7rem;border-color:#000;transform:rotate(-45deg)}.all-profile-arrow-open{border-left:solid 2px;border-bottom:solid 2px}.all-profile-arrow-close{border-right:solid 2px;border-top:solid 2px}.new-name-input{margin-left:3px;display:flex;flex-direction:column}.new-name-input .input-hint{font-size:smaller;font-weight:200;color:gray}.add-button{height:20px;line-height:20px;margin:3px 0 0 3px}\n"], dependencies: [{ kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "ngmodule", type: MatMenuModule }, { kind: "component", type: i4$2.MatMenu, selector: "mat-menu", inputs: ["backdropClass", "aria-label", "aria-labelledby", "aria-describedby", "xPosition", "yPosition", "overlapTrigger", "hasBackdrop", "class", "classList"], outputs: ["closed", "close"], exportAs: ["matMenu"] }, { kind: "component", type: i4$2.MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i4$2.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }, { kind: "component", type: MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "directive", type: MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "component", type: 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: "directive", type: StopPropagationDirective, selector: "[stop-propagation]" }, { kind: "ngmodule", type: MatInputModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }] });
4695
4731
  }
4696
4732
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: ProfilesMenuComponent, decorators: [{
4697
4733
  type: Component,
4698
- args: [{ selector: 'tb-profiles-menu', standalone: true, imports: [MatIcon, MatTooltip, MatIconButton, MatMenuModule, MatButton, MatInput, DialogDirective, ClickEmitterDirective, NgTemplateOutlet,
4699
- MatCheckbox, StopPropagationDirective, FunctionPipe, MatInputModule, AsyncPipe, FormsModule
4700
- ], template: "<button mat-icon-button [matMenuTriggerFor]=\"menu\" #trigger=\"matMenuTrigger\" [matTooltip]=\"'Profiles'\">\r\n <mat-icon color=\"primary\">people</mat-icon>\r\n</button>\r\n<mat-menu #menu=\"matMenu\" (closed)=\"addedKey.value = null; allProfilesPanelOpened.set(false); newProfilePanelOpened.set(false)\">\r\n @if(!!$currentProfile())\r\n {\r\n <div mat-menu-item [matTooltip]=\"'Save Profile'\" mat-stroked-button (click)=\"saveState($currentProfile()!)\">\r\n <mat-icon color=\"primary\">save</mat-icon>\r\n <span>{{$currentProfile()}}</span>\r\n </div>\r\n }\r\n @else\r\n {\r\n <div class=\"profile-line\">\r\n <button class=\"first-in-line first-button\" mat-stroked-button (click)=\"addState(defaultName, m.checked);\">\r\n <mat-icon class=\"save-for-default-icon button-save-icon\" color=\"primary\">save</mat-icon>\r\n <span>Save as <span class=\"current-name\">{{defaultName}}</span> </span>\r\n </button>\r\n <button [matTooltip]=\"'Toggle Profile Being Created As Default'\" stop-propagation mat-icon-button (click)=\"m.toggle()\" >\r\n <mat-icon style=\"color: green;\">{{m.checked ? 'star' : 'star_border'}}</mat-icon>\r\n </button>\r\n <mat-checkbox class=\"display-none\" [checked]=\"true\" #m />\r\n </div>\r\n }\r\n @if (allProfilesPanelOpened()) {<hr class=\"divider\"/>}\r\n <div [class]=\"{ hide: !$keys().length, 'all-profile-row': true }\" mat-menu-item stop-propagation (click)=\"allProfilesPanelOpened.set(!allProfilesPanelOpened())\">\r\n <div class=\"all-profiles\">\r\n <span>All Profiles</span>\r\n <span [class]=\"(allProfilesPanelOpened() ? 'all-profile-arrow-close' : 'all-profile-arrow-open') + ' all-profile-arrow'\" class=\"arrow\"></span>\r\n </div>\r\n </div>\r\n <div [class]=\"{ hide: !allProfilesPanelOpened(), panel: true }\">\r\n @for (key of $keys() ; track key) {\r\n <div class=\"profile-line\" [class]=\"key === $currentProfile() ? 'current-in-list' : 'not-current-in-list'\">\r\n <button [matTooltip]=\"'Select Profile'\" class=\"menu-item first-in-line\" mat-stroked-button (click)='stateService.setLocalCurrentState({ tableId: $tableId(), currentStateKey: key})'>\r\n <span>{{key}}</span>\r\n </button>\r\n @if(key !== $defaultProfile())\r\n {\r\n <button [matTooltip]=\"'Toggle Profile Being Default'\" stop-propagation mat-icon-button (click)=\"setDefault(key)\">\r\n <mat-icon style=\"color: green;\">star_border</mat-icon>\r\n </button>\r\n }\r\n @else\r\n {\r\n <button [matTooltip]=\"'Toggle Profile Being Default'\" stop-propagation mat-icon-button (click)=\"unsetDefault()\">\r\n <mat-icon style=\"color: green;\">star</mat-icon>\r\n </button>\r\n }\r\n <button [matTooltip]=\"'Delete Profile'\" class=\"last-in-line\" stop-propagation mat-icon-button (click)='stateService.deleteProfileFromLocalAndStorage($tableId(), key)'>\r\n <mat-icon color='warn'>delete_forever</mat-icon>\r\n </button>\r\n </div>\r\n }\r\n <hr class=\"divider\"/>\r\n </div>\r\n <div class=\"add-new-profile-row\" mat-menu-item stop-propagation (click)=\"newProfilePanelOpened.set(!newProfilePanelOpened()); addedKey.focus()\">Add New Profile</div>\r\n <div [class]=\"{ hide: !newProfilePanelOpened(), panel: true }\" >\r\n <div class=\"profile-line\" stop-propagation>\r\n <div class=\"new-name-input\">\r\n <i class=\"input-hint\">Enter New Name</i>\r\n <input matInput #addedKey=\"matInput\" [name]=\"'key'\" />\r\n </div>\r\n <button [matTooltip]=\"'Toggle Profile Being Created As Default'\" stop-propagation mat-icon-button (click)=\"m2.toggle()\" >\r\n <mat-icon style=\"color: green;\">{{m2.checked ? 'star' : 'star_border'}}</mat-icon>\r\n </button>\r\n <mat-checkbox class=\"display-none\" [ngModel]=\"!$defaultProfile()\" #m2 />\r\n </div>\r\n <button class=\"add-button\" color=\"primary\" [matTooltip]=\"'Create New Profile'\" mat-raised-button (click)=\"addState(addedKey.value, m2.checked); addedKey.value = null\" [disabled]=\"!addedKey.value\">\r\n Add\r\n </button>\r\n </div>\r\n</mat-menu>\r\n\r\n<ng-template #line let-key>\r\n\r\n\r\n</ng-template>\r\n", styles: [":host ::ng-deep .mat-expansion-panel-header{padding:0}.current-name{color:#00f}.menu-item{display:inline-flex;width:initial;flex-grow:1}.profile-line{display:flex;justify-content:space-between;align-items:center}.first-in-line{--f-b: 2rem;margin-left:var(--mat-menu-item-with-icon-leading-spacing)}.first-in-line.first-button{height:var(--f-b);margin:.2rem}.first-in-line .button-save-icon{height:var(--f-b);width:var(--f-b);font-size:var(--f-b)}.main-save-button{height:4rem;width:4rem;padding:.5rem}.main-save-button mat-icon{height:3rem;width:3rem;font-size:3rem}.save-for-default-icon{margin:0}.display-none{display:none}.last-in-line{padding-right:var(--mat-menu-item-with-icon-trailing-spacing)}.default-cursor{cursor:default}.as-def{padding-left:var(--mat-menu-item-with-icon-leading-spacing)}.divider{margin:.2px 0}.add-key{max-width:8.5rem;margin-left:2px}.add-key ::ng-deep .mdc-text-field{padding:0}.panel{transition:height .1s}.hide{height:0;min-height:0;overflow:hidden}.open-panel-button{width:100%;height:2.5rem}.current-in-list{border-left:3px solid blue;background-color:#0000ff0d}.not-current-in-list{border-left:3px solid rgba(255,255,255,0)}.add-new-profile-row,.all-profile-row{border-top:rgba(128,128,128,.25) solid 1px}.all-profiles{display:flex;justify-content:space-between}.all-profiles:has(.all-profile-arrow-close){align-items:center}.all-profile-arrow{display:inline-block;height:.7rem;width:.7rem;border-color:#000;transform:rotate(-45deg)}.all-profile-arrow-open{border-left:solid 2px;border-bottom:solid 2px}.all-profile-arrow-close{border-right:solid 2px;border-top:solid 2px}.new-name-input{margin-left:3px;display:flex;flex-direction:column}.new-name-input .input-hint{font-size:smaller;font-weight:200;color:gray}.add-button{height:20px;line-height:20px;margin:3px 0 0 3px}\n"] }]
4734
+ args: [{ selector: 'tb-profiles-menu', imports: [MatIcon, MatTooltip, MatIconButton, MatMenuModule, MatButton, MatInput,
4735
+ MatCheckbox, StopPropagationDirective, MatInputModule, FormsModule
4736
+ ], template: "<button mat-icon-button [matMenuTriggerFor]=\"menu\" #trigger=\"matMenuTrigger\" [matTooltip]=\"'Profiles'\">\r\n <mat-icon color=\"primary\">people</mat-icon>\r\n</button>\r\n<mat-menu #menu=\"matMenu\" (closed)=\"addedKey.value = null; allProfilesPanelOpened.set(false); newProfilePanelOpened.set(false)\">\r\n @if(!!$currentProfile())\r\n {\r\n <div mat-menu-item [matTooltip]=\"'Save Profile'\" mat-stroked-button (click)=\"saveState($currentProfile()!)\">\r\n <mat-icon color=\"primary\">save</mat-icon>\r\n <span>{{$currentProfile()}}</span>\r\n </div>\r\n }\r\n @else\r\n {\r\n <div class=\"profile-line\">\r\n <button class=\"first-in-line first-button\" mat-stroked-button (click)=\"addState(defaultName, m.checked);\">\r\n <mat-icon class=\"save-for-default-icon button-save-icon\" color=\"primary\">save</mat-icon>\r\n <span>Save as <span class=\"current-name\">{{defaultName}}</span> </span>\r\n </button>\r\n <button [matTooltip]=\"'Toggle Profile Being Created As Default'\" stop-propagation mat-icon-button (click)=\"m.toggle()\" >\r\n <mat-icon style=\"color: green;\">{{m.checked ? 'star' : 'star_border'}}</mat-icon>\r\n </button>\r\n <mat-checkbox class=\"display-none\" [checked]=\"true\" #m />\r\n </div>\r\n }\r\n @if (allProfilesPanelOpened()) {<hr class=\"divider\"/>}\r\n <div [class]=\"{ hide: !$keys().length, 'all-profile-row': true }\" mat-menu-item stop-propagation (click)=\"allProfilesPanelOpened.set(!allProfilesPanelOpened())\">\r\n <div class=\"all-profiles\">\r\n <span>All Profiles</span>\r\n <span [class]=\"(allProfilesPanelOpened() ? 'all-profile-arrow-close' : 'all-profile-arrow-open') + ' all-profile-arrow'\" class=\"arrow\"></span>\r\n </div>\r\n </div>\r\n <div [class]=\"{ hide: !allProfilesPanelOpened(), panel: true }\">\r\n @for (key of $keys() ; track key) {\r\n <div class=\"profile-line\" [class]=\"key === $currentProfile() ? 'current-in-list' : 'not-current-in-list'\">\r\n <button [matTooltip]=\"'Select Profile'\" class=\"menu-item first-in-line\" mat-stroked-button (click)='stateService.setLocalCurrentState({ tableId: $tableId(), currentStateKey: key})'>\r\n <span>{{key}}</span>\r\n </button>\r\n @if(key !== $defaultProfile())\r\n {\r\n <button [matTooltip]=\"'Toggle Profile Being Default'\" stop-propagation mat-icon-button (click)=\"setDefault(key)\">\r\n <mat-icon style=\"color: green;\">star_border</mat-icon>\r\n </button>\r\n }\r\n @else\r\n {\r\n <button [matTooltip]=\"'Toggle Profile Being Default'\" stop-propagation mat-icon-button (click)=\"unsetDefault()\">\r\n <mat-icon style=\"color: green;\">star</mat-icon>\r\n </button>\r\n }\r\n <button [matTooltip]=\"'Delete Profile'\" class=\"last-in-line\" stop-propagation mat-icon-button (click)='stateService.deleteProfileFromLocalAndStorage($tableId(), key)'>\r\n <mat-icon color='warn'>delete_forever</mat-icon>\r\n </button>\r\n </div>\r\n }\r\n <hr class=\"divider\"/>\r\n </div>\r\n <div class=\"add-new-profile-row\" mat-menu-item stop-propagation (click)=\"newProfilePanelOpened.set(!newProfilePanelOpened()); addedKey.focus()\">Add New Profile</div>\r\n <div [class]=\"{ hide: !newProfilePanelOpened(), panel: true }\" >\r\n <div class=\"profile-line\" stop-propagation>\r\n <div class=\"new-name-input\">\r\n <i class=\"input-hint\">Enter New Name</i>\r\n <input matInput #addedKey=\"matInput\" [name]=\"'key'\" />\r\n </div>\r\n <button [matTooltip]=\"'Toggle Profile Being Created As Default'\" stop-propagation mat-icon-button (click)=\"m2.toggle()\" >\r\n <mat-icon style=\"color: green;\">{{m2.checked ? 'star' : 'star_border'}}</mat-icon>\r\n </button>\r\n <mat-checkbox class=\"display-none\" [ngModel]=\"!$defaultProfile()\" #m2 />\r\n </div>\r\n <button class=\"add-button\" color=\"primary\" [matTooltip]=\"'Create New Profile'\" mat-raised-button (click)=\"addState(addedKey.value, m2.checked); addedKey.value = null\" [disabled]=\"!addedKey.value\">\r\n Add\r\n </button>\r\n </div>\r\n</mat-menu>\r\n", styles: [":host ::ng-deep .mat-expansion-panel-header{padding:0}.current-name{color:#00f}.menu-item{display:inline-flex;width:initial;flex-grow:1}.profile-line{display:flex;justify-content:space-between;align-items:center}.first-in-line{--f-b: 2rem;margin-left:var(--mat-menu-item-with-icon-leading-spacing)}.first-in-line.first-button{height:var(--f-b);margin:.2rem}.first-in-line .button-save-icon{height:var(--f-b);width:var(--f-b);font-size:var(--f-b)}.main-save-button{height:4rem;width:4rem;padding:.5rem}.main-save-button mat-icon{height:3rem;width:3rem;font-size:3rem}.save-for-default-icon{margin:0}.display-none{display:none}.last-in-line{padding-right:var(--mat-menu-item-with-icon-trailing-spacing)}.default-cursor{cursor:default}.as-def{padding-left:var(--mat-menu-item-with-icon-leading-spacing)}.divider{margin:.2px 0}.add-key{max-width:8.5rem;margin-left:2px}.add-key ::ng-deep .mdc-text-field{padding:0}.panel{transition:height .1s}.hide{height:0;min-height:0;overflow:hidden}.open-panel-button{width:100%;height:2.5rem}.current-in-list{border-left:3px solid blue;background-color:#0000ff0d}.not-current-in-list{border-left:3px solid rgba(255,255,255,0)}.add-new-profile-row,.all-profile-row{border-top:rgba(128,128,128,.25) solid 1px}.all-profiles{display:flex;justify-content:space-between}.all-profiles:has(.all-profile-arrow-close){align-items:center}.all-profile-arrow{display:inline-block;height:.7rem;width:.7rem;border-color:#000;transform:rotate(-45deg)}.all-profile-arrow-open{border-left:solid 2px;border-bottom:solid 2px}.all-profile-arrow-close{border-right:solid 2px;border-top:solid 2px}.new-name-input{margin-left:3px;display:flex;flex-direction:column}.new-name-input .input-hint{font-size:smaller;font-weight:200;color:gray}.add-button{height:20px;line-height:20px;margin:3px 0 0 3px}\n"] }]
4701
4737
  }] });
4702
4738
 
4703
4739
  const containerImports = [
4704
- AsyncPipe, NgTemplateOutlet,
4740
+ NgTemplateOutlet,
4705
4741
  PaginatorComponent,
4706
- LetDirective,
4707
4742
  MultiSortDirective, GroupByListComponent, FilterChipsComponent, GenFilterDisplayerComponent, GenColDisplayerComponent,
4708
4743
  SortMenuComponent, GenericTableComponent, StopPropagationDirective, ProfilesMenuComponent,
4709
4744
  MatButtonModule, MatMenuModule, MatIconModule, MatTooltipModule, VirtualScrollContainer
@@ -4712,7 +4747,7 @@ const containerImports = [
4712
4747
  //The idea of this is that if filters were only added, and none were removed or changed, then we only need to tag more rows to not be shown. We don't need to remove any 'dont show' tags.
4713
4748
  // So if filters were only added this method will return the added filters, if filters were removed or changed this method will return undefined.
4714
4749
  const updateFilterInfoState = (previousState, filterInfos) => {
4715
- filterInfos = filterNonActiveFilters(filterInfos);
4750
+ filterInfos = filterNonActiveOrNotReadyFilters(filterInfos);
4716
4751
  const currentState = {
4717
4752
  allFilters: filterInfos,
4718
4753
  onlyAddedFilters: filterInfoOnlyAdded(previousState.allFilters, filterInfos)
@@ -4720,11 +4755,18 @@ const updateFilterInfoState = (previousState, filterInfos) => {
4720
4755
  return currentState;
4721
4756
  };
4722
4757
  const mapFilterInfoStateToPredicateState = (s) => {
4723
- const mappedAddOnly = s.onlyAddedFilters ? Object.entries(s.onlyAddedFilters).reduce((obj, [key, value]) => {
4724
- obj[key] = createFilterFunc(value);
4725
- return obj;
4726
- }, {}) : {};
4727
- const mappedAll = Object.entries(s.allFilters).map(([key, value]) => mappedAddOnly[key] || createFilterFunc(value));
4758
+ const mappedAddOnly = s.onlyAddedFilters
4759
+ ?
4760
+ Object.entries(s.onlyAddedFilters).filter(([, v]) => needsFilterCreation(v)).reduce((obj, [key, value]) => {
4761
+ obj[key] = createFilterFunc(value);
4762
+ return obj;
4763
+ }, {})
4764
+ : {};
4765
+ const mappedAll = Object.entries(s.allFilters).filter(([, v]) => needsFilterCreation(v))
4766
+ .filter(([, v]) => !isCustomFilter(v) || !!v.predicate)
4767
+ .map(([key, value]) => {
4768
+ return mappedAddOnly[key] || createFilterFunc(value);
4769
+ });
4728
4770
  return ({
4729
4771
  allFilters: mappedAll,
4730
4772
  onlyAddedFilters: s.onlyAddedFilters ? Object.values(mappedAddOnly) : undefined
@@ -4750,8 +4792,8 @@ const updateFilterState = (filterInfos, predicates) => {
4750
4792
  }
4751
4793
  return filtersState;
4752
4794
  };
4753
- const filterNonActiveFilters = (filtersDict) => Object.entries(filtersDict).reduce((obj, [key, value]) => {
4754
- if (value.active !== false) {
4795
+ const filterNonActiveOrNotReadyFilters = (filtersDict) => Object.entries(filtersDict).reduce((obj, [key, value]) => {
4796
+ if (value.active !== false && (!isCustomFilter(value) || !!value.predicate)) {
4755
4797
  obj[key] = value;
4756
4798
  }
4757
4799
  ;
@@ -4789,6 +4831,16 @@ function filtersInfosUpdated(previousFilterInfos, currentFilterInfos) {
4789
4831
  return currentFilterInfos[key].filterType === val.filterType && currentFilterInfos[key].filterValue === val.filterValue;
4790
4832
  });
4791
4833
  }
4834
+ function patchDirectiveFromState(directive, stateFilter) {
4835
+ if (isFilterInfo(stateFilter)) {
4836
+ const filterDirective = directive;
4837
+ filterDirective.setFilterValue(stateFilter.filterValue);
4838
+ filterDirective.update();
4839
+ }
4840
+ if (isCustomFilter(stateFilter)) {
4841
+ directive.active = stateFilter.active ?? false;
4842
+ }
4843
+ }
4792
4844
 
4793
4845
  function getGroupedData(data, groupByKeys) {
4794
4846
  return tbGroupBy(data, groupByKeys);
@@ -4902,6 +4954,7 @@ const createDataCleaners = (metadatas, mutate = false) => {
4902
4954
  };
4903
4955
  const createCleaners = (metadatas) => {
4904
4956
  return metadatas.reduce((transforms, metaData) => {
4957
+ const notNestedKey = metaData.key;
4905
4958
  switch (metaData.fieldType) {
4906
4959
  case FieldType.Currency:
4907
4960
  case FieldType.Number: {
@@ -4911,14 +4964,13 @@ const createCleaners = (metadatas) => {
4911
4964
  const val = get(t, metaData.key);
4912
4965
  const num = Number(val);
4913
4966
  set(t, metaData.key, isNaN(num) || val == null ? null : num);
4914
- t[metaData.key] = (isNaN(num) || val == null ? null : num);
4915
4967
  });
4916
4968
  }
4917
4969
  else {
4918
4970
  transforms.push((t) => {
4919
- const val = t[metaData.key];
4971
+ const val = t[notNestedKey];
4920
4972
  const num = Number(val);
4921
- t[metaData.key] = (isNaN(num) || val == null ? null : num);
4973
+ t[notNestedKey] = (isNaN(num) || val == null ? null : num);
4922
4974
  });
4923
4975
  }
4924
4976
  break;
@@ -4940,15 +4992,15 @@ const createCleaners = (metadatas) => {
4940
4992
  }
4941
4993
  else {
4942
4994
  transforms.push((t) => {
4943
- const val = t[metaData.key];
4995
+ const val = t[notNestedKey];
4944
4996
  const date = Date.parse(val);
4945
4997
  if (isNaN(date)) {
4946
- t[metaData.key] = null;
4998
+ t[notNestedKey] = null;
4947
4999
  return;
4948
5000
  }
4949
5001
  const d = new Date(date);
4950
5002
  d.setHours(0, 0, 0, 0);
4951
- t[metaData.key] = d;
5003
+ t[notNestedKey] = d;
4952
5004
  });
4953
5005
  }
4954
5006
  break;
@@ -4979,24 +5031,24 @@ const createCleaners = (metadatas) => {
4979
5031
  }
4980
5032
  else {
4981
5033
  transforms.push((t) => {
4982
- const val = t[metaData.key];
5034
+ const val = t[notNestedKey];
4983
5035
  const dateTime = Date.parse(val);
4984
5036
  if (isNaN(dateTime)) {
4985
- t[metaData.key] = null;
5037
+ t[notNestedKey] = null;
4986
5038
  return;
4987
5039
  }
4988
5040
  const dt = new Date(dateTime);
4989
5041
  if (metaData.additional?.dateTimeOptions?.includeMilliseconds) {
4990
- t[metaData.key] = dt;
5042
+ t[notNestedKey] = dt;
4991
5043
  return;
4992
5044
  }
4993
5045
  if (metaData.additional?.dateTimeOptions?.includeSeconds) {
4994
5046
  dt.setMilliseconds(0);
4995
- t[metaData.key] = dt;
5047
+ t[notNestedKey] = dt;
4996
5048
  return;
4997
5049
  }
4998
5050
  dt.setSeconds(0, 0);
4999
- t[metaData.key] = dt;
5051
+ t[notNestedKey] = dt;
5000
5052
  });
5001
5053
  }
5002
5054
  }
@@ -5005,24 +5057,26 @@ const createCleaners = (metadatas) => {
5005
5057
  }, []);
5006
5058
  };
5007
5059
 
5008
- const defaultProps = {
5009
- indexColumn: false,
5010
- selectionColumn: false,
5011
- isSticky: true,
5012
- stickyFooter: false,
5013
- groupHeaderHeight: undefined,
5014
- };
5015
-
5016
5060
  class TableBuilderDataSource extends MatTableDataSource {
5017
- dataSrc;
5018
5061
  subscription;
5019
- constructor(dataSrc, state, data) {
5062
+ #$dataSrc = signal([]);
5063
+ $dataSize = signal({ start: 0, end: 0 }, {
5064
+ equal: (a, b) => a.start === b.start && a.end === b.end
5065
+ });
5066
+ _ = effect(() => {
5067
+ const data = this.#$dataSrc();
5068
+ const dataSize = this.$dataSize();
5069
+ untracked(() => this.data = data.slice(dataSize.start, dataSize.end));
5070
+ });
5071
+ setData(data) {
5072
+ this.#$dataSrc.set(data);
5073
+ }
5074
+ constructor(state, data) {
5020
5075
  super([]);
5021
- this.dataSrc = dataSrc;
5022
5076
  const $currentPage = state.$currentPage;
5023
5077
  const $pageSize = state.$pageSize;
5024
5078
  const $virtualEnds = data.selectSignal(d => d.virtualEnds);
5025
- const $dataLength = computed(() => dataSrc().length);
5079
+ const $dataLength = computed(() => this.#$dataSrc().length);
5026
5080
  const $dataSize = computed(() => {
5027
5081
  const viewType = state.$viewType();
5028
5082
  const dataLength = $dataLength();
@@ -5041,11 +5095,7 @@ class TableBuilderDataSource extends MatTableDataSource {
5041
5095
  }
5042
5096
  return ({ start: virtualEnds.start, end: virtualEnds.end });
5043
5097
  });
5044
- const $dataToShow = computed(() => dataSrc().slice($dataSize().start, $dataSize().end));
5045
- effect(() => {
5046
- const dataToShow = $dataToShow();
5047
- untracked(() => this.data = dataToShow);
5048
- });
5098
+ this.$dataSize = $dataSize;
5049
5099
  }
5050
5100
  connect() {
5051
5101
  return super.connect();
@@ -5059,118 +5109,182 @@ class TableBuilderDataSource extends MatTableDataSource {
5059
5109
  }
5060
5110
  }
5061
5111
 
5112
+ function mergeCustomCellMetaData(metaData1, metaData2) {
5113
+ if (!metaData2) {
5114
+ metaData1.noExport = true;
5115
+ return metaData1;
5116
+ }
5117
+ if (!metaData1.displayName)
5118
+ metaData1.displayName = metaData2.displayName;
5119
+ if (!metaData1.preSort)
5120
+ metaData1.preSort = metaData2.preSort;
5121
+ if (!metaData1.order)
5122
+ metaData1.order = metaData2.order;
5123
+ if (!metaData1.width)
5124
+ metaData1.width = metaData2.width;
5125
+ if (metaData2.fieldType)
5126
+ metaData1.fieldType = metaData2.fieldType;
5127
+ metaData1.noExport = metaData2.noExport;
5128
+ return metaData1;
5129
+ }
5130
+
5062
5131
  class TableContainerComponent {
5063
- props = { ...defaultProps };
5064
- data = new BehaviorSubject([]);
5065
5132
  state = inject(TableStore);
5066
5133
  dataStore = inject(DataStore);
5067
- config = inject(TableBuilderConfigToken);
5068
5134
  exportToCsvService = inject((ExportToCsvService));
5069
5135
  wrapper = inject(TableWrapperDirective, { optional: true });
5070
5136
  stateService = inject(TableBuilderStateStore);
5071
5137
  injector = inject(Injector);
5072
- filterDirectives = contentChildren(TableFilterDirective, { descendants: true });
5073
- customFilterDirectives = contentChildren(TableCustomFilterDirective, { descendants: true });
5074
- $allFilterDirectives = computed(() => {
5075
- if (this.wrapper) {
5076
- return [...this.filterDirectives(), ...this.customFilterDirectives(), ...this.wrapper.$registrations()];
5077
- }
5078
- {
5079
- return [...this.filterDirectives(), ...this.customFilterDirectives()];
5080
- }
5081
- });
5082
- $isInitializationState = (state) => computed(() => this.state.selectSignal(s => s.initializationState >= state)());
5083
- allFilterDirectivesEffect = effect(() => {
5084
- const loaded = this.$isInitializationState(InitializationState.LoadedFromStore)();
5085
- const stateFilters = this.state.$filters();
5086
- const filterDirectives = this.$allFilterDirectives();
5087
- untracked(() => {
5088
- if (loaded) {
5089
- filterDirectives.filter(f => !f.used).forEach(f => {
5090
- f.used = true;
5091
- if (f.savable) {
5092
- var filter = stateFilters[f.filterId];
5093
- if (isFilterInfo(filter)) {
5094
- const filterDirective = f;
5095
- filterDirective.fieldType = filter.fieldType;
5096
- filterDirective.filterType = filter.filterType;
5097
- filterDirective.setFilterValue(filter.filterValue);
5098
- filterDirective.key = filter.key;
5099
- filterDirective.update();
5100
- }
5101
- if (isCustomFilter(filter)) {
5102
- f.active = filter.active ?? false;
5103
- }
5104
- this.state.addFilter(f.filter$);
5105
- }
5106
- });
5107
- }
5108
- });
5109
- });
5110
- paginatorComponent;
5111
- genericTable;
5138
+ elementRef = inject(ElementRef);
5139
+ dataSource = new TableBuilderDataSource(this.state, this.dataStore);
5140
+ $filterDirectives = contentChildren(TableFilterDirective, { descendants: true });
5141
+ $customFilterDirectives = contentChildren(TableCustomFilterDirective, { descendants: true });
5142
+ $paginatorComponent = viewChild(PaginatorComponent);
5143
+ $genericTable = viewChild(GenericTableComponent);
5112
5144
  _$customRows = contentChildren((MatRowDef));
5113
5145
  $customRows = computed(() => [...this._$customRows()]);
5114
5146
  $customCells = contentChildren(CustomCellDirective);
5115
- $myColumns = computed(() => {
5116
- return this.state.$metaDataArray().map(metaData => ({ metaData, customCell: this.$customCells().find(cc => cc.customCell === metaData.key) }));
5117
- });
5118
- tableElRef;
5119
- tableBuilder;
5147
+ $tableBuilder = input.required({ alias: 'tableBuilder' });
5120
5148
  $tableId = input(undefined, { alias: 'tableId' });
5121
- set indexColumn(val) {
5122
- this.props.indexColumn = val;
5123
- }
5124
- set selectionColumn(val) {
5125
- this.props.selectionColumn = val;
5126
- }
5127
- set isSticky(val) {
5128
- this.props.isSticky = val;
5129
- }
5130
- set stickyFooter(val) {
5131
- this.props.stickyFooter = val;
5132
- }
5133
- set pageSize(value) {
5134
- this.state.setPageSize(value);
5135
- }
5136
- set groupHeaderTemplate(template) {
5137
- this.props.groupHeaderTemplate = template;
5138
- }
5139
- set groupHeaderHeight(value) {
5140
- this.props.groupHeaderHeight = value;
5141
- }
5142
- trackBy;
5143
- inputFilters;
5144
- selection$ = new EventEmitter();
5145
- $data = toSignal(this.data, { initialValue: [] });
5146
- onStateReset = new EventEmitter();
5147
- onSaveState = new EventEmitter();
5148
- state$ = this.state.getSavableState().pipe(map(state => cloneDeep(state)), defaultShareReplay());
5149
+ $trackBy = input(undefined, { alias: 'trackBy' });
5150
+ $inputFilters = model([], { alias: 'inputFilters' });
5151
+ predicateInputFilters$ = toObservable(computed(() => this.$inputFilters().filter(isFunction$1)));
5152
+ $filterInfoInputs = computed(() => this.$inputFilters().filter(i => !isFunction$1(i)));
5153
+ $indexColumn = input(false, { alias: 'indexColumn' });
5154
+ $selectionColumn = input(false, { alias: 'selectionColumn' });
5155
+ $isSticky = input(true, { alias: 'isSticky' });
5156
+ $stickyFooter = input(false, { alias: 'stickyFooter' });
5157
+ $groupHeaderTemplate = input(undefined, { alias: 'groupHeaderTemplate' });
5158
+ $groupHeaderHeight = input(undefined, { alias: 'groupHeaderHeight' });
5159
+ $pageSize = input(undefined, { alias: 'pageSize' });
5160
+ $props = computed(() => {
5161
+ const indexColumn = this.$indexColumn();
5162
+ const selectionColumn = this.$selectionColumn();
5163
+ const isSticky = this.$isSticky();
5164
+ const stickyFooter = this.$stickyFooter();
5165
+ const groupHeaderTemplate = this.$groupHeaderTemplate();
5166
+ const groupHeaderHeight = this.$groupHeaderHeight();
5167
+ return ({ indexColumn, selectionColumn, isSticky, stickyFooter, groupHeaderTemplate, groupHeaderHeight });
5168
+ });
5169
+ selection$ = output({ alias: 'selection' });
5170
+ onStateReset$ = output({ alias: 'onStateReset' });
5171
+ onSaveState$ = output({ alias: 'onSaveState' });
5172
+ _state$ = toObservable(this.state.$savableState);
5173
+ state$ = outputFromObservable(this._state$, { alias: 'state' });
5174
+ _data$ = new BehaviorSubject([]);
5175
+ data$ = outputFromObservable(this._data$, { alias: 'data' });
5176
+ $data = toSignal(this._data$, { initialValue: [] });
5149
5177
  clearSelections() {
5150
- this.genericTable?.selection.clear(true);
5151
- }
5152
- displayData = new ReplaySubject(1);
5153
- $displayData = toSignal(this.displayData, { initialValue: [] });
5154
- $collapseFooter = this.state.$collapseFooter;
5155
- $collapseHeader = this.state.$collapseHeader;
5156
- ngOnDestroy() {
5157
- const tableId = this.$tableId();
5158
- if (tableId) {
5159
- this.stateService.saveTableStateToLocal({ tableId, tableState: this.state.getSavableStateSignal() });
5160
- }
5178
+ this.$genericTable()?.$selection().clear(true);
5161
5179
  }
5162
5180
  firstPage() {
5163
- this.paginatorComponent?.$paginator()?.firstPage();
5181
+ this.$paginatorComponent()?.$paginator()?.firstPage();
5164
5182
  }
5165
5183
  lastPage() {
5166
- this.paginatorComponent?.$paginator()?.lastPage();
5184
+ this.$paginatorComponent()?.$paginator()?.lastPage();
5167
5185
  }
5186
+ expandAllGroups = () => {
5187
+ const groupHeaders = getAllGroupHeaderNames(this.$displayData());
5188
+ this.state.expandAllOfGroup({ groupHeadersByKey: groupHeaders });
5189
+ };
5190
+ collapseAllGroups = () => this.state.collapseAll();
5191
+ $myColumns = computed(() => {
5192
+ return this.state.$metaDataArray().map(metaData => ({
5193
+ metaData,
5194
+ customCell: this.$customCells().filter(cc => cc.$inited()).find(cc => cc.$customCell() === metaData.key)
5195
+ }));
5196
+ });
5197
+ $useVirtual = this.state.$isVirtual;
5198
+ $collapsedFooter = this.state.$footerCollapsed;
5199
+ $collapsedHeader = this.state.$headerCollapsed;
5200
+ $displayDataLength = computed(() => this.$displayData().length);
5168
5201
  resetState() {
5169
- this.customFilterDirectives().forEach(cf => cf.reset());
5170
- this.filterDirectives().forEach(cf => cf.reset());
5202
+ this.$customFilterDirectives().forEach(cf => cf.reset());
5203
+ this.$filterDirectives().forEach(cf => cf.reset());
5171
5204
  this.state.resetState();
5172
- this.onStateReset.next(null);
5205
+ this.onStateReset$.emit(null);
5206
+ }
5207
+ exportToCsv() {
5208
+ this.exportToCsvService.exportToCsv(this.$data());
5173
5209
  }
5210
+ #initializeTableSettingsFromTableBuilderAndPersistedStateEffect = effect(() => {
5211
+ const metaLoaded = this.$isInitializationState(InitializationState.MetaDataLoaded)();
5212
+ if (!metaLoaded)
5213
+ return;
5214
+ const persistedState = this.$persistedState();
5215
+ untracked(() => {
5216
+ this.state.setTableSettings(this.$tableBuilder().settings$);
5217
+ if (persistedState) {
5218
+ persistedState.persistedTableSettings = new PersistedTableSettings(persistedState.persistedTableSettings);
5219
+ this.state.updateStateFromPersistedState(persistedState);
5220
+ }
5221
+ this.state.setInitializationState(InitializationState.LoadedFromStore);
5222
+ });
5223
+ });
5224
+ #setPageSizeFromInputEffect = effect(() => {
5225
+ const pageSize = this.$pageSize();
5226
+ if (pageSize) {
5227
+ untracked(() => this.state.setPageSize(pageSize));
5228
+ }
5229
+ });
5230
+ #patchedFilters = [];
5231
+ #patchSavableFilterDirectivesFromPersistedStateEffect = effect(() => {
5232
+ const loaded = this.$isInitializationState(InitializationState.LoadedFromStore)();
5233
+ const filterDirectives = this.$allFilterDirectives();
5234
+ if (!loaded || !filterDirectives.length)
5235
+ return;
5236
+ const stateFilters = this.state.$filters();
5237
+ untracked(() => {
5238
+ filterDirectives.filter(f => f.savable && !this.#patchedFilters.includes(f.filterId)).forEach(f => {
5239
+ this.#patchedFilters.push(f.filterId);
5240
+ const filter = stateFilters[f.filterId];
5241
+ patchDirectiveFromState(f, filter);
5242
+ this.state.addFilter(f.filter$);
5243
+ });
5244
+ });
5245
+ });
5246
+ #patchSavableFilterInputsFromPersistedStateEffect = effect(() => {
5247
+ const loaded = this.$isInitializationState(InitializationState.LoadedFromStore)();
5248
+ const inputFilters = this.$filterInfoInputs();
5249
+ if (!loaded || !inputFilters.length)
5250
+ return;
5251
+ untracked(() => {
5252
+ const stateFilters = this.state.$filters();
5253
+ inputFilters.filter(f => f.filterId).forEach(f => {
5254
+ const patched = this.#patchedFilters.includes(f.filterId);
5255
+ const stateFilter = stateFilters[f.filterId];
5256
+ if (patched || !stateFilter) {
5257
+ this.state.addFilter(f);
5258
+ }
5259
+ else if (isCustomFilter(f)) {
5260
+ stateFilter.predicate = f.predicate;
5261
+ this.state.addFilter(stateFilter);
5262
+ }
5263
+ this.#patchedFilters.push(f.filterId);
5264
+ });
5265
+ });
5266
+ });
5267
+ #addPropsToStoreFromInputsEffect = effect(() => {
5268
+ const props = this.$props();
5269
+ untracked(() => this.state.setProps(props));
5270
+ });
5271
+ #addMetaDataToStoreEffect = effect(() => {
5272
+ const allMetaDatas = this.$allMetaDatas();
5273
+ if (!allMetaDatas)
5274
+ return;
5275
+ untracked(() => {
5276
+ this.state.setMetaData(allMetaDatas);
5277
+ this.state.setLinkMaps(createLinkCreatorDict(allMetaDatas));
5278
+ });
5279
+ });
5280
+ #initializeDataEffect = effect(() => {
5281
+ const tableBuilder = this.$tableBuilder();
5282
+ if (!tableBuilder)
5283
+ return;
5284
+ untracked(() => {
5285
+ this.initializeData();
5286
+ });
5287
+ });
5174
5288
  $persistedState = computed(() => {
5175
5289
  const tableId = this.$tableId();
5176
5290
  if (tableId) {
@@ -5178,27 +5292,35 @@ class TableContainerComponent {
5178
5292
  }
5179
5293
  return undefined;
5180
5294
  });
5181
- initializeStateEffect = effect(() => {
5182
- const metaLoaded = this.$isInitializationState(InitializationState.MetaDataLoaded)();
5183
- const tableId = this.$tableId();
5184
- const persistedState = this.$persistedState();
5185
- untracked(() => {
5186
- if (metaLoaded) {
5187
- this.state.setTableSettings(this.tableBuilder.settings);
5188
- if (tableId) {
5189
- if (persistedState) {
5190
- persistedState.persistedTableSettings = new PersistedTableSettings(persistedState.persistedTableSettings);
5191
- this.state.updateStateFromPersistedState(persistedState);
5192
- return;
5193
- }
5194
- }
5195
- this.state.setInitializationState(InitializationState.LoadedFromStore);
5196
- }
5197
- });
5295
+ $allFilterDirectives = computed(() => {
5296
+ if (this.wrapper) {
5297
+ return [...this.$filterDirectives(), ...this.$customFilterDirectives(), ...this.wrapper.$registrations()];
5298
+ }
5299
+ return [...this.$filterDirectives(), ...this.$customFilterDirectives()];
5300
+ });
5301
+ allNotSavableFilterDirectivesFilters$ = toObservable(this.$allFilterDirectives).pipe(filterArray(d => !d.savable), switchMap(d => {
5302
+ const a = d.map(d => d.filter$);
5303
+ return combineLatest(a).pipe(startWith([]));
5304
+ }), map(createFilterFuncs));
5305
+ tableBuilderMetaData$ = toObservable(this.$tableBuilder).pipe(notNull(), switchMap(tb => tb.metaData$));
5306
+ $tableBuilderMetaData = toSignal(this.tableBuilderMetaData$);
5307
+ $allMetaDatas = computed(() => {
5308
+ const tableBuilderMetaData = this.$tableBuilderMetaData();
5309
+ if (!tableBuilderMetaData)
5310
+ return;
5311
+ const customCellMetaDatas = this.$customCells().filter(cc => cc.$inited()).map(cc => cc.$metaData()).filter(d => !!d);
5312
+ const mappedCustomCellMetaDatas = customCellMetaDatas.map(md => mergeCustomCellMetaData(md, tableBuilderMetaData.find(item => item.key === md.key)));
5313
+ return [...tableBuilderMetaData, ...mappedCustomCellMetaDatas];
5198
5314
  });
5199
- customFilters$ = new BehaviorSubject([]);
5315
+ $displayData = signal([]);
5316
+ ngOnDestroy() {
5317
+ const tableId = this.$tableId();
5318
+ if (tableId) {
5319
+ this.stateService.saveTableStateToLocal({ tableId, tableState: this.state.$savableState() });
5320
+ }
5321
+ }
5200
5322
  initializeData() {
5201
- const predicateFilters$ = combineLatest([this.inputFilters?.pipe(startWith([])) ?? of([]), this.customFilters$])
5323
+ const predicateFilters$ = combineLatest([this.predicateInputFilters$.pipe(), this.allNotSavableFilterDirectivesFilters$])
5202
5324
  .pipe(map(([a, b]) => [...a, ...b]));
5203
5325
  const filters$ = combineLatest([
5204
5326
  this.state.filters$.pipe(scan$1(updateFilterInfoState, { allFilters: {} }), timestamp$1()),
@@ -5206,144 +5328,27 @@ class TableContainerComponent {
5206
5328
  ])
5207
5329
  .pipe(map(([filterInfo, pred]) => updateFilterState(filterInfo, pred)));
5208
5330
  const sortsState$ = this.state.sort$.pipe(scan$1(updateSortState, initialSortState));
5209
- const sortedAndFilteredData$ = sortAndFilterData(this.tableBuilder.getData$(), sortsState$, filters$);
5331
+ const sortedAndFilteredData$ = sortAndFilterData(this.$tableBuilder().getData$(), sortsState$, filters$);
5210
5332
  const flatGrouped$ = combineLatest([sortedAndFilteredData$.pipe(timestamp$1()), this.state.groupByKeys$.pipe(timestamp$1()), this.state.expandedGroups$.pipe(timestamp$1())]).pipe(scan$1(updateGroupByState, initialGroupByState), map(({ displayData }) => displayData), defaultShareReplay());
5211
5333
  this.state.on(sortedAndFilteredData$, (data) => {
5212
- this.data.next(data);
5334
+ this._data$.next(data);
5213
5335
  this.dataStore.patchState({ dataLen: data.length });
5214
5336
  });
5215
5337
  this.state.on(flatGrouped$, (data) => {
5216
- this.displayData.next(data);
5217
- });
5218
- }
5219
- ngOnInit() {
5220
- const customCells$ = toObservable(this.$customCells, { injector: this.injector });
5221
- this.state.setLinkMaps(this.tableBuilder.metaData$.pipe(map(createLinkCreatorDict)));
5222
- const customCellMeta = customCells$.pipe(switchMap(c => c.length ? combineLatest(c.map(c => c.$metaData)) : of([])));
5223
- const metaForState = combineLatest([this.tableBuilder.metaData$, customCellMeta]).pipe(map(([mds, customCells]) => {
5224
- mds = mds.map(this.mapArrayFieldsMetaDatas);
5225
- return [
5226
- ...mds,
5227
- ...customCells.map(md => this.mergeMetaData(md, mds.find(item => item.key === md.key)))
5228
- ];
5229
- }));
5230
- this.state.setMetaData(metaForState);
5231
- runInInjectionContext(this.injector, () => {
5232
- const ds = new TableBuilderDataSource(this.$displayData, this.state, this.dataStore);
5233
- this.state.updateState({
5234
- props: {
5235
- dataSource: ds,
5236
- ...this.props
5237
- }
5238
- });
5338
+ this.dataSource.setData(data);
5339
+ this.$displayData.set(data);
5239
5340
  });
5240
- this.initializeData();
5241
- }
5242
- mergeMetaData(metaData1, metaData2) {
5243
- if (!metaData2) {
5244
- metaData1.noExport = true;
5245
- return metaData1;
5246
- }
5247
- if (!metaData1.displayName)
5248
- metaData1.displayName = metaData2.displayName;
5249
- if (!metaData1.preSort)
5250
- metaData1.preSort = metaData2.preSort;
5251
- if (!metaData1.order)
5252
- metaData1.order = metaData2.order;
5253
- if (!metaData1.width)
5254
- metaData1.width = metaData2.width;
5255
- if (metaData2.fieldType)
5256
- metaData1.fieldType = metaData2.fieldType;
5257
- metaData1.noExport = !metaData2;
5258
- return metaData1;
5259
5341
  }
5260
- exportToCsv() {
5261
- this.exportToCsvService.exportToCsv(this.$data());
5262
- }
5263
- expandAllGroups = () => {
5264
- const groupHeaders = getAllGroupHeaderNames(this.$displayData());
5265
- this.state.expandAllOfGroup({ groupHeadersByKey: groupHeaders });
5266
- };
5267
- collapseAllGroups = () => this.state.collapseAll();
5268
- ngAfterContentInit() {
5269
- this.state.runOnceWhen(stateIs(InitializationState.LoadedFromStore), state => {
5270
- this.addFilterDirectives(state);
5271
- this.state.updateState({ initializationState: InitializationState.Ready });
5272
- });
5273
- }
5274
- mapArrayFieldsMetaDatas = (meta) => {
5275
- if (meta.fieldType === FieldType.Array) {
5276
- const additional = { ...meta.additional };
5277
- additional.arrayStyle = additional?.arrayStyle ?? ArrayDefaults.arrayStyle;
5278
- additional.limit = additional.limit ?? this.config.arrayDefaults?.limit ?? ArrayDefaults.limit;
5279
- return { ...meta, additional };
5280
- }
5281
- return meta;
5282
- };
5283
- addFilterDirectives = (state) => {
5284
- const customFilters$ = toObservable(this.$allFilterDirectives, { injector: this.injector }).pipe(mergeMap(customerFilters => customerFilters
5285
- .filter(filter => !filter.savable)
5286
- .map(filter => filter.filter$)), mergeAll(), scan$1((a, b) => {
5287
- if (b.active) {
5288
- a[b.filterId] = isCustomFilter(b) ? b.predicate : createFilterFunc(b);
5289
- }
5290
- else {
5291
- delete a[b.filterId];
5292
- }
5293
- return a;
5294
- }, {}), map(f => Object.values(f)));
5295
- this.state.on(customFilters$, (f) => {
5296
- this.customFilters$.next(f);
5297
- });
5298
- };
5299
- $useVirtual = this.state.$isVirtual;
5342
+ $isInitializationState = (state) => computed(() => this.state.selectSignal(s => s.initializationState >= state)());
5343
+ static headerId = 'tb-header-wrapper';
5344
+ headerId = TableContainerComponent.headerId;
5300
5345
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: TableContainerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
5301
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.0", type: TableContainerComponent, isStandalone: true, selector: "tb-table-container", inputs: { tableBuilder: { classPropertyName: "tableBuilder", publicName: "tableBuilder", isSignal: false, isRequired: true, transformFunction: null }, $tableId: { classPropertyName: "$tableId", publicName: "tableId", isSignal: true, isRequired: false, transformFunction: null }, indexColumn: { classPropertyName: "indexColumn", publicName: "indexColumn", isSignal: false, isRequired: false, transformFunction: null }, selectionColumn: { classPropertyName: "selectionColumn", publicName: "selectionColumn", isSignal: false, isRequired: false, transformFunction: null }, isSticky: { classPropertyName: "isSticky", publicName: "isSticky", isSignal: false, isRequired: false, transformFunction: null }, stickyFooter: { classPropertyName: "stickyFooter", publicName: "stickyFooter", isSignal: false, isRequired: false, transformFunction: null }, pageSize: { classPropertyName: "pageSize", publicName: "pageSize", isSignal: false, isRequired: false, transformFunction: null }, groupHeaderTemplate: { classPropertyName: "groupHeaderTemplate", publicName: "groupHeaderTemplate", isSignal: false, isRequired: false, transformFunction: null }, groupHeaderHeight: { classPropertyName: "groupHeaderHeight", publicName: "groupHeaderHeight", isSignal: false, isRequired: false, transformFunction: null }, trackBy: { classPropertyName: "trackBy", publicName: "trackBy", isSignal: false, isRequired: false, transformFunction: null }, inputFilters: { classPropertyName: "inputFilters", publicName: "inputFilters", isSignal: false, isRequired: false, transformFunction: null } }, outputs: { data: "data", selection$: "selection$", onStateReset: "onStateReset", onSaveState: "onSaveState", state$: "state$" }, providers: [TableStore, ExportToCsvService, WrapperFilterStore, DataStore], queries: [{ propertyName: "filterDirectives", predicate: TableFilterDirective, descendants: true, isSignal: true }, { propertyName: "customFilterDirectives", predicate: TableCustomFilterDirective, descendants: true, isSignal: true }, { propertyName: "_$customRows", predicate: (MatRowDef), isSignal: true }, { propertyName: "$customCells", predicate: CustomCellDirective, isSignal: true }, { propertyName: "tableElRef", first: true, predicate: ["table"], descendants: true, read: ElementRef }], viewQueries: [{ propertyName: "paginatorComponent", first: true, predicate: PaginatorComponent, descendants: true }, { propertyName: "genericTable", first: true, predicate: GenericTableComponent, descendants: true }], ngImport: i0, template: "@let tableId = $tableId();\r\n\r\n<ng-content select=\"[before]\" />\r\n\r\n<ng-container multiSort *ngrxLet=\"state.tableSettings$ as tableSettings\">\r\n <div class=\"header-wrapper\">\r\n <div class=\"title\">\r\n @if ((!$collapseHeader()) || tableSettings.showTitleWhenHeaderCollapsed) {\r\n <ng-content select=\".tb-header-title\"/>\r\n }\r\n @if((state.groupByKeys$ | async)?.length){\r\n <group-by-list />\r\n }\r\n </div>\r\n <div class=\"flx-row-end\">\r\n <lib-filter-list />\r\n @if (!tableSettings.hideHeader) {\r\n @if (!$collapseHeader()) {\r\n <ng-container *ngTemplateOutlet=\"headerMenu\"/>\r\n <button mat-icon-button color='primary' [matMenuTriggerFor]=\"mainMenu\">\r\n <mat-icon>more_vert</mat-icon>\r\n </button>\r\n <mat-menu #mainMenu='matMenu'>\r\n <ng-container *ngTemplateOutlet=\"headerMenuExtra\"/>\r\n </mat-menu>\r\n }\r\n @else {\r\n <mat-icon color=\"primary\" [matMenuTriggerFor]=\"mainMenu\" class=\"flat-menu-button pointer\">more_horiz</mat-icon>\r\n <mat-menu #mainMenu='matMenu'>\r\n <div class=\"flex-column\">\r\n <ng-container *ngTemplateOutlet=\"headerMenu\"/>\r\n </div>\r\n <ng-container *ngTemplateOutlet=\"headerMenuExtra\"/>\r\n </mat-menu>\r\n }\r\n <mat-icon [matTooltip]=\"$collapseHeader() ? 'expand' : 'collapse'\" class=\"collapse-icon header\"\r\n (click)=\"state.toggleCollapseHeader()\">\r\n {{$collapseHeader() ? 'expand_less' : 'expand_more'}}\r\n </mat-icon>\r\n }\r\n\r\n </div>\r\n </div>\r\n @if($useVirtual())\r\n {\r\n <tb-virtual-scroll-container class=\"scrollable\">\r\n <tb-generic-table [rows]=\"$customRows()\" [data]=\"(data | async)!\" [displayData]=\"$displayData()\"\r\n (selection$)='selection$.emit($event)' [columnInfos]='$myColumns()' [trackBy]=\"trackBy\" />\r\n </tb-virtual-scroll-container>\r\n }\r\n @else\r\n {\r\n <tb-generic-table [rows]=\"$customRows()\" [data]=\"(data | async)!\" [displayData]=\"$displayData()\"\r\n (selection$)='selection$.emit($event)' [columnInfos]='$myColumns()' [trackBy]=\"trackBy\" />\r\n }\r\n @if(tableSettings.usePaginator)\r\n {\r\n <div class=\"paginator\">\r\n <tb-paginator #tbPaginator [tableElRef]=\"tableElRef\" />\r\n\r\n <mat-icon [matTooltip]=\"$collapseFooter() ? 'expand' : 'collapse'\" class=\"collapse-icon footer\"\r\n (click)=\"state.toggleCollapseFooter()\">\r\n {{$collapseFooter() ? 'expand_more' : 'expand_less'}}\r\n </mat-icon>\r\n </div>\r\n }\r\n\r\n <ng-template #headerMenu>\r\n @if (!tableSettings.hideFilter) {<tb-filter-displayer/>}\r\n @if (!tableSettings.hideColumnSettings) {<tb-col-displayer/>}\r\n @if (!tableSettings.hideSort) {<tb-sort-menu/>}\r\n @if (!!tableId) {<tb-profiles-menu [$tableId]=\"tableId\" (onSaveState)=\"onSaveState.emit($event)\"/>}\r\n </ng-template>\r\n\r\n <ng-template #headerMenuExtra>\r\n <button mat-menu-item (click)=\"resetState()\">\r\n <mat-icon color=\"primary\">autorenew</mat-icon>\r\n <span>Reset table</span>\r\n </button>\r\n @if (!tableSettings.hideExport) {\r\n <button mat-menu-item (click)=\"exportToCsv()\">\r\n <mat-icon color=\"primary\">file_download</mat-icon>\r\n <span>Export Table</span>\r\n </button>\r\n }\r\n @if (tableId) {\r\n <button stop-propagation mat-menu-item (click)=\"pm.trigger()?.toggleMenu()\">\r\n <mat-icon color=\"primary\">people</mat-icon>\r\n <span>Profiles</span>\r\n </button>\r\n <tb-profiles-menu class=\"profiles-menu\" #pm [$tableId]=\"tableId\" (onSaveState)=\"onSaveState.emit($event)\"/>\r\n }\r\n </ng-template>\r\n</ng-container>\r\n", styles: [".header-wrapper{display:flex;flex-direction:row;justify-content:space-between;width:100%}.flx-row-end{display:flex;flex-direction:row;justify-content:flex-end;align-items:center}.flat-menu{line-height:initial;height:initial}.pointer{cursor:pointer}.add-key{width:90%}.paginator{display:flex;flex-direction:row;justify-content:flex-end;align-items:center;background-color:#fff;bottom:0;position:sticky;border-top:.5px solid rgba(0,0,0,.12)}.profiles-menu{visibility:hidden;width:0px;height:0px;display:block;overflow:hidden;position:absolute;top:50px}\n", ".collapse-icon{font-size:16px;height:16px;color:#3f51b5;align-self:flex-start}.collapse-icon:hover{cursor:pointer}.hide{display:none}.paginator-row{display:flex;align-items:center}\n"], dependencies: [{ kind: "pipe", type: i1$8.AsyncPipe, name: "async" }, { kind: "directive", type: i1$8.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: PaginatorComponent, selector: "tb-paginator", inputs: ["tableElRef"] }, { kind: "directive", type: i3$3.LetDirective, selector: "[ngrxLet]", inputs: ["ngrxLet", "ngrxLetSuspenseTpl"] }, { kind: "directive", type: MultiSortDirective, selector: "[multiSort]", inputs: ["matSortDisabled"], exportAs: ["multiSort"] }, { kind: "component", type: GroupByListComponent, selector: "group-by-list" }, { kind: "component", type: FilterChipsComponent, selector: "lib-filter-list" }, { kind: "component", type: GenFilterDisplayerComponent, selector: "tb-filter-displayer" }, { kind: "component", type: GenColDisplayerComponent, selector: "tb-col-displayer" }, { kind: "component", type: SortMenuComponent, selector: "tb-sort-menu" }, { kind: "component", type: GenericTableComponent, selector: "tb-generic-table", inputs: ["trackBy", "displayData", "data", "rows", "columnInfos"], outputs: ["selection$"] }, { kind: "directive", type: StopPropagationDirective, selector: "[stop-propagation]" }, { kind: "component", type: ProfilesMenuComponent, selector: "tb-profiles-menu", inputs: ["$tableId"], outputs: ["onSaveState"] }, { kind: "ngmodule", type: i3$1.MatButtonModule }, { kind: "component", type: i3$1.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "ngmodule", type: i4$2.MatMenuModule }, { kind: "component", type: i4$2.MatMenu, selector: "mat-menu", inputs: ["backdropClass", "aria-label", "aria-labelledby", "aria-describedby", "xPosition", "yPosition", "overlapTrigger", "hasBackdrop", "class", "classList"], outputs: ["closed", "close"], exportAs: ["matMenu"] }, { kind: "component", type: i4$2.MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i4$2.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }, { kind: "ngmodule", type: i2.MatIconModule }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: i4$1.MatTooltipModule }, { kind: "directive", type: i4$1.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: VirtualScrollContainer, selector: "tb-virtual-scroll-container" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
5346
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.0", type: TableContainerComponent, isStandalone: true, selector: "tb-table-container", inputs: { $tableBuilder: { classPropertyName: "$tableBuilder", publicName: "tableBuilder", isSignal: true, isRequired: true, transformFunction: null }, $tableId: { classPropertyName: "$tableId", publicName: "tableId", isSignal: true, isRequired: false, transformFunction: null }, $trackBy: { classPropertyName: "$trackBy", publicName: "trackBy", isSignal: true, isRequired: false, transformFunction: null }, $inputFilters: { classPropertyName: "$inputFilters", publicName: "inputFilters", isSignal: true, isRequired: false, transformFunction: null }, $indexColumn: { classPropertyName: "$indexColumn", publicName: "indexColumn", isSignal: true, isRequired: false, transformFunction: null }, $selectionColumn: { classPropertyName: "$selectionColumn", publicName: "selectionColumn", isSignal: true, isRequired: false, transformFunction: null }, $isSticky: { classPropertyName: "$isSticky", publicName: "isSticky", isSignal: true, isRequired: false, transformFunction: null }, $stickyFooter: { classPropertyName: "$stickyFooter", publicName: "stickyFooter", isSignal: true, isRequired: false, transformFunction: null }, $groupHeaderTemplate: { classPropertyName: "$groupHeaderTemplate", publicName: "groupHeaderTemplate", isSignal: true, isRequired: false, transformFunction: null }, $groupHeaderHeight: { classPropertyName: "$groupHeaderHeight", publicName: "groupHeaderHeight", isSignal: true, isRequired: false, transformFunction: null }, $pageSize: { classPropertyName: "$pageSize", publicName: "pageSize", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { $inputFilters: "inputFiltersChange", selection$: "selection", onStateReset$: "onStateReset", onSaveState$: "onSaveState", state$: "state", data$: "data" }, providers: [TableStore, ExportToCsvService, WrapperFilterStore, DataStore], queries: [{ propertyName: "$filterDirectives", predicate: TableFilterDirective, descendants: true, isSignal: true }, { propertyName: "$customFilterDirectives", predicate: TableCustomFilterDirective, descendants: true, isSignal: true }, { propertyName: "_$customRows", predicate: (MatRowDef), isSignal: true }, { propertyName: "$customCells", predicate: CustomCellDirective, isSignal: true }], viewQueries: [{ propertyName: "$paginatorComponent", first: true, predicate: PaginatorComponent, descendants: true, isSignal: true }, { propertyName: "$genericTable", first: true, predicate: GenericTableComponent, descendants: true, isSignal: true }], ngImport: i0, template: "@let tableId = $tableId();\r\n@let tableSettings = state.$tableSettings();\r\n\r\n<ng-content select=\"[before]\" />\r\n<ng-container multiSort>\r\n <div class=\"tb-header-wrapper\" [id]=\"headerId\">\r\n <div class=\"title\">\r\n @if ((!$collapsedHeader()) || tableSettings.showTitleWhenHeaderCollapsed) {\r\n <ng-content select=\".tb-header-title\"/>\r\n }\r\n @if(state.$groupByKeys().length){\r\n <group-by-list />\r\n }\r\n </div>\r\n <div class=\"flx-row-end\">\r\n <lib-filter-list />\r\n @if (!tableSettings.hideHeader) {\r\n @if (!$collapsedHeader()) {\r\n <ng-container *ngTemplateOutlet=\"headerMenu\"/>\r\n <button mat-icon-button color='primary' [matMenuTriggerFor]=\"mainMenu\">\r\n <mat-icon>more_vert</mat-icon>\r\n </button>\r\n <mat-menu #mainMenu='matMenu'>\r\n <ng-container *ngTemplateOutlet=\"headerMenuExtra\"/>\r\n </mat-menu>\r\n }\r\n @else {\r\n <mat-icon color=\"primary\" [matMenuTriggerFor]=\"mainMenu\" class=\"flat-menu-button pointer\">more_horiz</mat-icon>\r\n <mat-menu #mainMenu='matMenu'>\r\n <div class=\"flex-column\">\r\n <ng-container *ngTemplateOutlet=\"headerMenu\"/>\r\n </div>\r\n <ng-container *ngTemplateOutlet=\"headerMenuExtra\"/>\r\n </mat-menu>\r\n }\r\n <mat-icon [matTooltip]=\"$collapsedHeader() ? 'expand' : 'collapse'\" class=\"collapse-icon header\"\r\n (click)=\"state.toggleCollapseHeader()\">\r\n {{$collapsedHeader() ? 'expand_less' : 'expand_more'}}\r\n </mat-icon>\r\n }\r\n\r\n </div>\r\n </div>\r\n\r\n @if($useVirtual())\r\n {\r\n <tb-virtual-scroll-container class=\"scrollable\">\r\n <tb-generic-table [rows]=\"$customRows()\" [data]=\"$data()!\" [displayDataLength]=\"$displayDataLength()\"\r\n (selection)='selection$.emit($event)' [columnInfos]='$myColumns()' [trackBy]=\"$trackBy()\" [dataSource]=\"dataSource\" />\r\n </tb-virtual-scroll-container>\r\n }\r\n @else\r\n {\r\n <tb-generic-table [rows]=\"$customRows()\" [data]=\"$data()!\" [displayDataLength]=\"$displayDataLength()\"\r\n (selection)='selection$.emit($event)' [columnInfos]='$myColumns()' [trackBy]=\"$trackBy()\" [dataSource]=\"dataSource\" />\r\n }\r\n @if(tableSettings.usePaginator)\r\n {\r\n <div class=\"paginator\">\r\n <tb-paginator #tbPaginator />\r\n\r\n <mat-icon [matTooltip]=\"$collapsedFooter() ? 'expand' : 'collapse'\" class=\"collapse-icon footer\"\r\n (click)=\"state.toggleCollapseFooter()\">\r\n {{$collapsedFooter() ? 'expand_more' : 'expand_less'}}\r\n </mat-icon>\r\n </div>\r\n }\r\n\r\n <ng-template #headerMenu>\r\n @if (!tableSettings.hideFilter) {<tb-filter-displayer/>}\r\n @if (!tableSettings.hideColumnSettings) {<tb-col-displayer/>}\r\n @if (!tableSettings.hideSort) {<tb-sort-menu/>}\r\n @if (!!tableId) {<tb-profiles-menu [$tableId]=\"tableId\" (onSaveState)=\"onSaveState$.emit($event)\"/>}\r\n </ng-template>\r\n\r\n <ng-template #headerMenuExtra>\r\n <button mat-menu-item (click)=\"resetState()\">\r\n <mat-icon color=\"primary\">autorenew</mat-icon>\r\n <span>Reset table</span>\r\n </button>\r\n @if (!tableSettings.hideExport) {\r\n <button mat-menu-item (click)=\"exportToCsv()\">\r\n <mat-icon color=\"primary\">file_download</mat-icon>\r\n <span>Export Table</span>\r\n </button>\r\n }\r\n @if (tableId) {\r\n <button stop-propagation mat-menu-item (click)=\"pm.trigger()?.toggleMenu()\">\r\n <mat-icon color=\"primary\">people</mat-icon>\r\n <span>Profiles</span>\r\n </button>\r\n <tb-profiles-menu class=\"profiles-menu\" #pm [$tableId]=\"tableId\" (onSaveState)=\"onSaveState$.emit($event)\"/>\r\n }\r\n </ng-template>\r\n</ng-container>\r\n", styles: [".tb-header-wrapper{display:flex;flex-direction:row;justify-content:space-between;width:100%}.flx-row-end{display:flex;flex-direction:row;justify-content:flex-end;align-items:center}.flat-menu{line-height:initial;height:initial}.pointer{cursor:pointer}.add-key{width:90%}.paginator{display:flex;flex-direction:row;justify-content:flex-end;align-items:center;background-color:#fff;bottom:0;position:sticky;border-top:.5px solid rgba(0,0,0,.12)}.profiles-menu{visibility:hidden;width:0px;height:0px;display:block;overflow:hidden;position:absolute;top:50px}\n", ".collapse-icon{font-size:16px;height:16px;color:#3f51b5;align-self:flex-start}.collapse-icon:hover{cursor:pointer}.hide{display:none}.paginator-row{display:flex;align-items:center}\n"], dependencies: [{ kind: "directive", type: i1$8.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: PaginatorComponent, selector: "tb-paginator" }, { kind: "directive", type: MultiSortDirective, selector: "[multiSort]", inputs: ["matSortDisabled"], exportAs: ["multiSort"] }, { kind: "component", type: GroupByListComponent, selector: "group-by-list" }, { kind: "component", type: FilterChipsComponent, selector: "lib-filter-list" }, { kind: "component", type: GenFilterDisplayerComponent, selector: "tb-filter-displayer" }, { kind: "component", type: GenColDisplayerComponent, selector: "tb-col-displayer" }, { kind: "component", type: SortMenuComponent, selector: "tb-sort-menu" }, { kind: "component", type: GenericTableComponent, selector: "tb-generic-table", inputs: ["displayDataLength", "data", "rows", "columnInfos", "dataSource", "trackBy"], outputs: ["selection"] }, { kind: "directive", type: StopPropagationDirective, selector: "[stop-propagation]" }, { kind: "component", type: ProfilesMenuComponent, selector: "tb-profiles-menu", inputs: ["$tableId"], outputs: ["onSaveState"] }, { kind: "ngmodule", type: i3$1.MatButtonModule }, { kind: "component", type: i3$1.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "ngmodule", type: i4$2.MatMenuModule }, { kind: "component", type: i4$2.MatMenu, selector: "mat-menu", inputs: ["backdropClass", "aria-label", "aria-labelledby", "aria-describedby", "xPosition", "yPosition", "overlapTrigger", "hasBackdrop", "class", "classList"], outputs: ["closed", "close"], exportAs: ["matMenu"] }, { kind: "component", type: i4$2.MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i4$2.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }, { kind: "ngmodule", type: i2.MatIconModule }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: i4$1.MatTooltipModule }, { kind: "directive", type: i4$1.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: VirtualScrollContainer, selector: "tb-virtual-scroll-container" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
5302
5347
  }
5303
5348
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: TableContainerComponent, decorators: [{
5304
5349
  type: Component,
5305
- args: [{ selector: 'tb-table-container', changeDetection: ChangeDetectionStrategy.OnPush, providers: [TableStore, ExportToCsvService, WrapperFilterStore, DataStore], standalone: true, imports: containerImports, template: "@let tableId = $tableId();\r\n\r\n<ng-content select=\"[before]\" />\r\n\r\n<ng-container multiSort *ngrxLet=\"state.tableSettings$ as tableSettings\">\r\n <div class=\"header-wrapper\">\r\n <div class=\"title\">\r\n @if ((!$collapseHeader()) || tableSettings.showTitleWhenHeaderCollapsed) {\r\n <ng-content select=\".tb-header-title\"/>\r\n }\r\n @if((state.groupByKeys$ | async)?.length){\r\n <group-by-list />\r\n }\r\n </div>\r\n <div class=\"flx-row-end\">\r\n <lib-filter-list />\r\n @if (!tableSettings.hideHeader) {\r\n @if (!$collapseHeader()) {\r\n <ng-container *ngTemplateOutlet=\"headerMenu\"/>\r\n <button mat-icon-button color='primary' [matMenuTriggerFor]=\"mainMenu\">\r\n <mat-icon>more_vert</mat-icon>\r\n </button>\r\n <mat-menu #mainMenu='matMenu'>\r\n <ng-container *ngTemplateOutlet=\"headerMenuExtra\"/>\r\n </mat-menu>\r\n }\r\n @else {\r\n <mat-icon color=\"primary\" [matMenuTriggerFor]=\"mainMenu\" class=\"flat-menu-button pointer\">more_horiz</mat-icon>\r\n <mat-menu #mainMenu='matMenu'>\r\n <div class=\"flex-column\">\r\n <ng-container *ngTemplateOutlet=\"headerMenu\"/>\r\n </div>\r\n <ng-container *ngTemplateOutlet=\"headerMenuExtra\"/>\r\n </mat-menu>\r\n }\r\n <mat-icon [matTooltip]=\"$collapseHeader() ? 'expand' : 'collapse'\" class=\"collapse-icon header\"\r\n (click)=\"state.toggleCollapseHeader()\">\r\n {{$collapseHeader() ? 'expand_less' : 'expand_more'}}\r\n </mat-icon>\r\n }\r\n\r\n </div>\r\n </div>\r\n @if($useVirtual())\r\n {\r\n <tb-virtual-scroll-container class=\"scrollable\">\r\n <tb-generic-table [rows]=\"$customRows()\" [data]=\"(data | async)!\" [displayData]=\"$displayData()\"\r\n (selection$)='selection$.emit($event)' [columnInfos]='$myColumns()' [trackBy]=\"trackBy\" />\r\n </tb-virtual-scroll-container>\r\n }\r\n @else\r\n {\r\n <tb-generic-table [rows]=\"$customRows()\" [data]=\"(data | async)!\" [displayData]=\"$displayData()\"\r\n (selection$)='selection$.emit($event)' [columnInfos]='$myColumns()' [trackBy]=\"trackBy\" />\r\n }\r\n @if(tableSettings.usePaginator)\r\n {\r\n <div class=\"paginator\">\r\n <tb-paginator #tbPaginator [tableElRef]=\"tableElRef\" />\r\n\r\n <mat-icon [matTooltip]=\"$collapseFooter() ? 'expand' : 'collapse'\" class=\"collapse-icon footer\"\r\n (click)=\"state.toggleCollapseFooter()\">\r\n {{$collapseFooter() ? 'expand_more' : 'expand_less'}}\r\n </mat-icon>\r\n </div>\r\n }\r\n\r\n <ng-template #headerMenu>\r\n @if (!tableSettings.hideFilter) {<tb-filter-displayer/>}\r\n @if (!tableSettings.hideColumnSettings) {<tb-col-displayer/>}\r\n @if (!tableSettings.hideSort) {<tb-sort-menu/>}\r\n @if (!!tableId) {<tb-profiles-menu [$tableId]=\"tableId\" (onSaveState)=\"onSaveState.emit($event)\"/>}\r\n </ng-template>\r\n\r\n <ng-template #headerMenuExtra>\r\n <button mat-menu-item (click)=\"resetState()\">\r\n <mat-icon color=\"primary\">autorenew</mat-icon>\r\n <span>Reset table</span>\r\n </button>\r\n @if (!tableSettings.hideExport) {\r\n <button mat-menu-item (click)=\"exportToCsv()\">\r\n <mat-icon color=\"primary\">file_download</mat-icon>\r\n <span>Export Table</span>\r\n </button>\r\n }\r\n @if (tableId) {\r\n <button stop-propagation mat-menu-item (click)=\"pm.trigger()?.toggleMenu()\">\r\n <mat-icon color=\"primary\">people</mat-icon>\r\n <span>Profiles</span>\r\n </button>\r\n <tb-profiles-menu class=\"profiles-menu\" #pm [$tableId]=\"tableId\" (onSaveState)=\"onSaveState.emit($event)\"/>\r\n }\r\n </ng-template>\r\n</ng-container>\r\n", styles: [".header-wrapper{display:flex;flex-direction:row;justify-content:space-between;width:100%}.flx-row-end{display:flex;flex-direction:row;justify-content:flex-end;align-items:center}.flat-menu{line-height:initial;height:initial}.pointer{cursor:pointer}.add-key{width:90%}.paginator{display:flex;flex-direction:row;justify-content:flex-end;align-items:center;background-color:#fff;bottom:0;position:sticky;border-top:.5px solid rgba(0,0,0,.12)}.profiles-menu{visibility:hidden;width:0px;height:0px;display:block;overflow:hidden;position:absolute;top:50px}\n", ".collapse-icon{font-size:16px;height:16px;color:#3f51b5;align-self:flex-start}.collapse-icon:hover{cursor:pointer}.hide{display:none}.paginator-row{display:flex;align-items:center}\n"] }]
5306
- }], propDecorators: { data: [{
5307
- type: Output
5308
- }], paginatorComponent: [{
5309
- type: ViewChild,
5310
- args: [PaginatorComponent]
5311
- }], genericTable: [{
5312
- type: ViewChild,
5313
- args: [GenericTableComponent]
5314
- }], tableElRef: [{
5315
- type: ContentChild,
5316
- args: ['table', { read: ElementRef }]
5317
- }], tableBuilder: [{
5318
- type: Input,
5319
- args: [{ required: true }]
5320
- }], indexColumn: [{
5321
- type: Input
5322
- }], selectionColumn: [{
5323
- type: Input
5324
- }], isSticky: [{
5325
- type: Input
5326
- }], stickyFooter: [{
5327
- type: Input
5328
- }], pageSize: [{
5329
- type: Input
5330
- }], groupHeaderTemplate: [{
5331
- type: Input
5332
- }], groupHeaderHeight: [{
5333
- type: Input
5334
- }], trackBy: [{
5335
- type: Input
5336
- }], inputFilters: [{
5337
- type: Input
5338
- }], selection$: [{
5339
- type: Output
5340
- }], onStateReset: [{
5341
- type: Output
5342
- }], onSaveState: [{
5343
- type: Output
5344
- }], state$: [{
5345
- type: Output
5346
- }] } });
5350
+ args: [{ selector: 'tb-table-container', changeDetection: ChangeDetectionStrategy.OnPush, providers: [TableStore, ExportToCsvService, WrapperFilterStore, DataStore], imports: containerImports, template: "@let tableId = $tableId();\r\n@let tableSettings = state.$tableSettings();\r\n\r\n<ng-content select=\"[before]\" />\r\n<ng-container multiSort>\r\n <div class=\"tb-header-wrapper\" [id]=\"headerId\">\r\n <div class=\"title\">\r\n @if ((!$collapsedHeader()) || tableSettings.showTitleWhenHeaderCollapsed) {\r\n <ng-content select=\".tb-header-title\"/>\r\n }\r\n @if(state.$groupByKeys().length){\r\n <group-by-list />\r\n }\r\n </div>\r\n <div class=\"flx-row-end\">\r\n <lib-filter-list />\r\n @if (!tableSettings.hideHeader) {\r\n @if (!$collapsedHeader()) {\r\n <ng-container *ngTemplateOutlet=\"headerMenu\"/>\r\n <button mat-icon-button color='primary' [matMenuTriggerFor]=\"mainMenu\">\r\n <mat-icon>more_vert</mat-icon>\r\n </button>\r\n <mat-menu #mainMenu='matMenu'>\r\n <ng-container *ngTemplateOutlet=\"headerMenuExtra\"/>\r\n </mat-menu>\r\n }\r\n @else {\r\n <mat-icon color=\"primary\" [matMenuTriggerFor]=\"mainMenu\" class=\"flat-menu-button pointer\">more_horiz</mat-icon>\r\n <mat-menu #mainMenu='matMenu'>\r\n <div class=\"flex-column\">\r\n <ng-container *ngTemplateOutlet=\"headerMenu\"/>\r\n </div>\r\n <ng-container *ngTemplateOutlet=\"headerMenuExtra\"/>\r\n </mat-menu>\r\n }\r\n <mat-icon [matTooltip]=\"$collapsedHeader() ? 'expand' : 'collapse'\" class=\"collapse-icon header\"\r\n (click)=\"state.toggleCollapseHeader()\">\r\n {{$collapsedHeader() ? 'expand_less' : 'expand_more'}}\r\n </mat-icon>\r\n }\r\n\r\n </div>\r\n </div>\r\n\r\n @if($useVirtual())\r\n {\r\n <tb-virtual-scroll-container class=\"scrollable\">\r\n <tb-generic-table [rows]=\"$customRows()\" [data]=\"$data()!\" [displayDataLength]=\"$displayDataLength()\"\r\n (selection)='selection$.emit($event)' [columnInfos]='$myColumns()' [trackBy]=\"$trackBy()\" [dataSource]=\"dataSource\" />\r\n </tb-virtual-scroll-container>\r\n }\r\n @else\r\n {\r\n <tb-generic-table [rows]=\"$customRows()\" [data]=\"$data()!\" [displayDataLength]=\"$displayDataLength()\"\r\n (selection)='selection$.emit($event)' [columnInfos]='$myColumns()' [trackBy]=\"$trackBy()\" [dataSource]=\"dataSource\" />\r\n }\r\n @if(tableSettings.usePaginator)\r\n {\r\n <div class=\"paginator\">\r\n <tb-paginator #tbPaginator />\r\n\r\n <mat-icon [matTooltip]=\"$collapsedFooter() ? 'expand' : 'collapse'\" class=\"collapse-icon footer\"\r\n (click)=\"state.toggleCollapseFooter()\">\r\n {{$collapsedFooter() ? 'expand_more' : 'expand_less'}}\r\n </mat-icon>\r\n </div>\r\n }\r\n\r\n <ng-template #headerMenu>\r\n @if (!tableSettings.hideFilter) {<tb-filter-displayer/>}\r\n @if (!tableSettings.hideColumnSettings) {<tb-col-displayer/>}\r\n @if (!tableSettings.hideSort) {<tb-sort-menu/>}\r\n @if (!!tableId) {<tb-profiles-menu [$tableId]=\"tableId\" (onSaveState)=\"onSaveState$.emit($event)\"/>}\r\n </ng-template>\r\n\r\n <ng-template #headerMenuExtra>\r\n <button mat-menu-item (click)=\"resetState()\">\r\n <mat-icon color=\"primary\">autorenew</mat-icon>\r\n <span>Reset table</span>\r\n </button>\r\n @if (!tableSettings.hideExport) {\r\n <button mat-menu-item (click)=\"exportToCsv()\">\r\n <mat-icon color=\"primary\">file_download</mat-icon>\r\n <span>Export Table</span>\r\n </button>\r\n }\r\n @if (tableId) {\r\n <button stop-propagation mat-menu-item (click)=\"pm.trigger()?.toggleMenu()\">\r\n <mat-icon color=\"primary\">people</mat-icon>\r\n <span>Profiles</span>\r\n </button>\r\n <tb-profiles-menu class=\"profiles-menu\" #pm [$tableId]=\"tableId\" (onSaveState)=\"onSaveState$.emit($event)\"/>\r\n }\r\n </ng-template>\r\n</ng-container>\r\n", styles: [".tb-header-wrapper{display:flex;flex-direction:row;justify-content:space-between;width:100%}.flx-row-end{display:flex;flex-direction:row;justify-content:flex-end;align-items:center}.flat-menu{line-height:initial;height:initial}.pointer{cursor:pointer}.add-key{width:90%}.paginator{display:flex;flex-direction:row;justify-content:flex-end;align-items:center;background-color:#fff;bottom:0;position:sticky;border-top:.5px solid rgba(0,0,0,.12)}.profiles-menu{visibility:hidden;width:0px;height:0px;display:block;overflow:hidden;position:absolute;top:50px}\n", ".collapse-icon{font-size:16px;height:16px;color:#3f51b5;align-self:flex-start}.collapse-icon:hover{cursor:pointer}.hide{display:none}.paginator-row{display:flex;align-items:center}\n"] }]
5351
+ }] });
5347
5352
 
5348
5353
  class TableBuilderModule {
5349
5354
  static forRoot(config) {
@@ -5480,14 +5485,14 @@ class MatTableObservableDataSource extends MatTableDataSource {
5480
5485
  class TableBuilder {
5481
5486
  metaData$;
5482
5487
  data$;
5483
- settings;
5488
+ settings$;
5484
5489
  constructor(data, metaData, settings = new GeneralTableSettings()) {
5485
- this.settings = this.coerceSettingsToObservable(settings)
5490
+ this.settings$ = this.coerceSettingsToObservable(settings)
5486
5491
  .pipe(defaultShareReplay());
5487
- this.data$ = this.coerceToObservable(data, this.settings)
5492
+ this.data$ = this.coerceToObservable(data, this.settings$)
5488
5493
  .pipe(notNull(), defaultShareReplay());
5489
5494
  this.metaData$ = metaData ?
5490
- this.coerceToObservable(metaData, this.settings).pipe(defaultShareReplay())
5495
+ this.coerceToObservable(metaData, this.settings$).pipe(defaultShareReplay())
5491
5496
  :
5492
5497
  this.data$.pipe(first$1(), map(d => this.createMetaData(d[0])), defaultShareReplay());
5493
5498
  }
@@ -5618,7 +5623,7 @@ class ActionStateSpinnerComponent {
5618
5623
  }
5619
5624
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: ActionStateSpinnerComponent, decorators: [{
5620
5625
  type: Component,
5621
- args: [{ selector: 'lib-action-state-spinner', standalone: true, imports: [AsyncPipe, MatProgressSpinnerModule], template: "@if((serverActionStatus$ | async)?.status === serverStatusTypes.inProgress){\r\n <div id=\"blocker\">\r\n <mat-spinner class=\"spinner\" [diameter]=\"200\" />\r\n </div>\r\n}\r\n\r\n", styles: ["#blocker{position:fixed;top:0;left:0;width:100%;height:100%;background-color:#0e0d0d69;z-index:999999}.spinner{position:absolute;top:50%;left:40%;transform:translate(-50%,-50%)}\n"] }]
5626
+ args: [{ selector: 'lib-action-state-spinner', imports: [AsyncPipe, MatProgressSpinnerModule], template: "@if((serverActionStatus$ | async)?.status === serverStatusTypes.inProgress){\r\n <div id=\"blocker\">\r\n <mat-spinner class=\"spinner\" [diameter]=\"200\" />\r\n </div>\r\n}\r\n\r\n", styles: ["#blocker{position:fixed;top:0;left:0;width:100%;height:100%;background-color:#0e0d0d69;z-index:999999}.spinner{position:absolute;top:50%;left:40%;transform:translate(-50%,-50%)}\n"] }]
5622
5627
  }], propDecorators: { status$: [{
5623
5628
  type: Input
5624
5629
  }] } });
@@ -5736,17 +5741,16 @@ const setEnvironmentInjector = (ei) => {
5736
5741
  };
5737
5742
  function provideActionableSelector() {
5738
5743
  return makeEnvironmentProviders([
5739
- { provide: APP_INITIALIZER, useFactory: setUpStoreFactory, multi: true, deps: [Store, EnvironmentInjector] },
5744
+ provideAppInitializer(setUpStoreFactory)
5740
5745
  ]);
5741
5746
  }
5742
- function setUpStoreFactory(store, env) {
5747
+ const setUpStoreFactory = () => {
5748
+ const store = inject(Store);
5749
+ const env = inject(EnvironmentInjector);
5743
5750
  _cache ??= new AppStoreCache();
5744
- return () => new Promise((resolve, reject) => {
5745
- setStore(store);
5746
- setEnvironmentInjector(env);
5747
- resolve(null);
5748
- });
5749
- }
5751
+ setStore(store);
5752
+ setEnvironmentInjector(env);
5753
+ };
5750
5754
 
5751
5755
  /*
5752
5756
  * Public API Surface of http-request-state
@@ -5756,5 +5760,5 @@ function setUpStoreFactory(store, env) {
5756
5760
  * Generated bundle index. Do not edit.
5757
5761
  */
5758
5762
 
5759
- export { ActionStateSpinnerComponent, ActionStateUiModule, ActionStatus, AppStatusState, ArrayStyle, AutoFocusDirective, CancellationToken, ClickEmitterDirective, ClickSubjectDirective, ConditionalClassesDirective, CreateTableBuilder, CustomCellDirective, DateFilterComponent, DefaultVirtualScrollOptions, DialogDirective, DialogService, DialogWrapper, FieldType, FilterChipsComponent, FilterComponent, FilterTypes, FunctionPipe, GenColDisplayerComponent, GenFilterDisplayerComponent, GeneralTableSettings, GenericTableComponent, GroupByListComponent, HttpErrorStateDirective, HttpInProgressStateDirective, HttpNotStartedStateDirective, HttpRequestModule, HttpRequestStateDirective, HttpRequestStateFactory, HttpRequestStateStore, HttpRequestStatus, HttpRequestStrategy, HttpSuccessStateDirective, MatButtonToggleFilterDirective, MatCheckboxTbFilterDirective, MatOptionTbFilterDirective, MatRadioButtonTbFilterDirective, MatSlideToggleGroupDirective, MatSlideToggleTbFilterDirective, MatTableObservableDataSource, MultiSortDirective, NgrxExtModule, NotPersistedTableSettings, PaginatorComponent, PersistedTableSettings, PhoneNumberPipe, PreventEnterDirective, ResizeColumnDirective, SortDirection, SpaceCasePipe, StopPropagationDirective, StylerDirective, Subjectifier, Subscriber, TableBuilder, TableBuilderConfigToken, TableBuilderModule, TableColumnHeaderSettings, TableContainerComponent, TableCustomFilterDirective, TableCustomFilterDirectiveBase, TableFilterDirective, TableFilterStringContainsDirective, TableSettings, TableWrapperDirective, TableWrapperFooterSettings, TableWrapperHeaderSettings, Target, TbSelectedFilterDirective, TrimWhitespaceDirective, UtilitiesModule, VirtualScrollOptions, actionStatusReducer, chainRequest, clearActionableSelectorRequestCache, combineArrays, createActionResultSelector, createActionSelector, createActionableResultSelector, createActionableSelector, createFailure, createRequestor, createSuccess, defaultFilter, defaultShareReplay, delayOn, filterArray, getRequestorBody, getRequestorStatus, getStatusState, httpRequest, httpRequestor, inProgress, initialState, isDifferent, isErrorState, isSuccessOrErrorState, isSuccessState, mapArray, mapError, metaDataArrToDict, notNull, notStarted, onWait, onceWhen, previousAndCurrent, provideActionableSelector, provideTableBuilder, selectAll, selectEntities, selectEntity, selectIds, selectTotal, serverStatusTypes, setUpStoreFactory, skipOneWhen, spaceCase, startWithIfEmpty, statusAdapter, statusIsSuccessOrInProgress, subscriber, switchOff, tapError, tapSuccess, wrapInArr };
5763
+ export { ActionStateSpinnerComponent, ActionStateUiModule, ActionStatus, AppStatusState, ArrayStyle, AutoFocusDirective, CancellationToken, ClickEmitterDirective, ClickSubjectDirective, ConditionalClassesDirective, CreateTableBuilder, CustomCellDirective, DateFilterComponent, DefaultVirtualScrollOptions, DialogDirective, DialogService, DialogWrapper, FieldType, FilterChipsComponent, FilterComponent, FilterTypes, FunctionPipe, GenColDisplayerComponent, GenFilterDisplayerComponent, GeneralTableSettings, GenericTableComponent, GroupByListComponent, HttpErrorStateDirective, HttpInProgressStateDirective, HttpNotStartedStateDirective, HttpRequestModule, HttpRequestStateDirective, HttpRequestStateFactory, HttpRequestStateStore, HttpRequestStatus, HttpRequestStrategy, HttpSuccessStateDirective, MatButtonToggleFilterDirective, MatCheckboxTbFilterDirective, MatOptionTbFilterDirective, MatRadioButtonTbFilterDirective, MatSlideToggleGroupDirective, MatSlideToggleTbFilterDirective, MatTableObservableDataSource, MultiSortDirective, NgrxExtModule, NotPersistedTableSettings, PaginatorComponent, PaginatorOptions, PersistedTableSettings, PhoneNumberPipe, PreventEnterDirective, ResizeColumnDirective, SortDirection, SpaceCasePipe, StopPropagationDirective, StylerDirective, Subjectifier, Subscriber, TableBuilder, TableBuilderConfigToken, TableBuilderModule, TableColumnHeaderSettings, TableContainerComponent, TableCustomFilterDirective, TableCustomFilterDirectiveBase, TableFilterDirective, TableFilterStringContainsDirective, TableSettings, TableWrapperDirective, TableWrapperFooterSettings, TableWrapperHeaderSettings, Target, TbSelectedFilterDirective, TrimWhitespaceDirective, UtilitiesModule, VirtualScrollOptions, actionStatusReducer, chainRequest, clearActionableSelectorRequestCache, combineArrays, createActionResultSelector, createActionSelector, createActionableResultSelector, createActionableSelector, createFailure, createRequestor, createSuccess, defaultFilter, defaultShareReplay, delayOn, filterArray, getRequestorBody, getRequestorStatus, getStatusState, httpRequest, httpRequestor, inProgress, initialState, isErrorState, isSuccessOrErrorState, isSuccessState, mapArray, mapError, metaDataArrToDict, notNull, notStarted, onWait, onceWhen, previousAndCurrent, provideActionableSelector, provideTableBuilder, selectAll, selectEntities, selectEntity, selectIds, selectTotal, serverStatusTypes, setUpStoreFactory, skipOneWhen, sortsAreSame, spaceCase, startWithIfEmpty, statusAdapter, statusIsSuccessOrInProgress, subscriber, switchOff, tapError, tapSuccess, wrapInArr };
5760
5764
  //# sourceMappingURL=one-paragon-angular-utilities.mjs.map