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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/fesm2022/one-paragon-angular-utilities.mjs +957 -1036
  2. package/fesm2022/one-paragon-angular-utilities.mjs.map +1 -1
  3. package/ngrx/actionable-selector.d.ts +3 -3
  4. package/package.json +7 -8
  5. package/table-builder/classes/TableBuilderDataSource.d.ts +8 -2
  6. package/table-builder/classes/filter-info.d.ts +3 -1
  7. package/table-builder/classes/table-builder.d.ts +1 -1
  8. package/table-builder/classes/table-store.d.ts +60 -68
  9. package/table-builder/classes/table-store.helpers.d.ts +28 -0
  10. package/table-builder/components/column-builder/column-builder.component.d.ts +19 -29
  11. package/table-builder/components/filter/filter.component.d.ts +3 -3
  12. package/table-builder/components/filter/in-list/in-list-filter.component.d.ts +9 -10
  13. package/table-builder/components/generic-table/generic-table.component.d.ts +26 -38
  14. package/table-builder/components/generic-table/paginator.component.d.ts +1 -3
  15. package/table-builder/components/header-menu/header-menu.component.d.ts +3 -5
  16. package/table-builder/components/in-filter/in-filter.component.d.ts +2 -2
  17. package/table-builder/components/number-filter/number-filter.component.d.ts +3 -3
  18. package/table-builder/components/sort-menu/sort-menu.component-store.d.ts +4 -4
  19. package/table-builder/components/sort-menu/sort-menu.component.d.ts +6 -11
  20. package/table-builder/components/table-container/table-container-imports.d.ts +2 -3
  21. package/table-builder/components/table-container/table-container.d.ts +53 -51
  22. package/table-builder/components/table-container/table-container.helpers/filter-state.helpers.d.ts +2 -0
  23. package/table-builder/components/table-container/table-container.helpers/meta-data.helpers.d.ts +2 -0
  24. package/table-builder/components/table-container/tableProps.d.ts +0 -2
  25. package/table-builder/components/table-container-filter/filter-list/filter-list.component.d.ts +1 -1
  26. package/table-builder/components/table-container-filter/table-wrapper-filter-store.d.ts +1 -1
  27. package/table-builder/directives/custom-cell-directive.d.ts +16 -17
  28. package/table-builder/directives/multi-sort.directive.d.ts +1 -1
  29. package/table-builder/directives/table-wrapper.directive.d.ts +1 -1
  30. package/table-builder/directives/tb-filter.directive.d.ts +13 -15
  31. package/table-builder/interfaces/report-def.d.ts +4 -0
  32. package/table-builder/pipes/format-filter-value.pipe.d.ts +1 -2
  33. package/table-builder/pipes/key-display.d.ts +1 -2
  34. package/table-builder/services/transform-creator.d.ts +0 -1
  35. package/utilities/pipes/function.pipe.d.ts +5 -1
@@ -1,15 +1,15 @@
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, Renderer2, ElementRef, booleanAttribute, signal, 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, 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
14
  import { MatSlideToggle } from '@angular/material/slide-toggle';
15
15
  import * as i10 from '@angular/material/radio';
@@ -29,10 +29,10 @@ import * as i1$1 from '@angular/material/input';
29
29
  import { MatInputModule, MatInput } from '@angular/material/input';
30
30
  import * as i4 from '@angular/material/datepicker';
31
31
  import { MatDatepickerModule } from '@angular/material/datepicker';
32
- import { MatDialog, MatDialogModule } from '@angular/material/dialog';
33
32
  import * as i6 from '@angular/material/form-field';
34
33
  import * as i1$3 from '@angular/material/card';
35
34
  import { MatCardModule } from '@angular/material/card';
35
+ import { MatDialog, MatDialogModule } from '@angular/material/dialog';
36
36
  import * as i3$1 from '@angular/material/button';
37
37
  import { MatButtonModule, MatIconButton, MatButton } from '@angular/material/button';
38
38
  import * as i4$1 from '@angular/material/tooltip';
@@ -43,8 +43,6 @@ import * as i8 from '@angular/material/select';
43
43
  import { MatSelectModule } from '@angular/material/select';
44
44
  import * as i4$2 from '@angular/material/menu';
45
45
  import { MatMenuModule, MatMenuTrigger } from '@angular/material/menu';
46
- import * as i3$3 from '@ngrx/component';
47
- import { LetDirective } from '@ngrx/component';
48
46
  import * as i4$3 from '@angular/material/chips';
49
47
  import { MatChipsModule } from '@angular/material/chips';
50
48
  import * as i1$5 from '@angular/material/table';
@@ -152,7 +150,7 @@ class HttpRequestStateDirective {
152
150
  }
153
151
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: HttpRequestStateDirective, decorators: [{
154
152
  type: Directive,
155
- args: [{ selector: '[httpRequestState]', standalone: true }]
153
+ args: [{ selector: '[httpRequestState]', }]
156
154
  }], ctorParameters: () => [{ type: i0.TemplateRef }, { type: i0.ViewContainerRef }], propDecorators: { stateStore: [{
157
155
  type: Input,
158
156
  args: ['httpRequestState']
@@ -201,7 +199,7 @@ class HttpErrorStateDirective extends HttpStateDirectiveBase {
201
199
  }
202
200
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: HttpErrorStateDirective, decorators: [{
203
201
  type: Directive,
204
- args: [{ selector: '[httpErrorState]', standalone: true }]
202
+ args: [{ selector: '[httpErrorState]', }]
205
203
  }] });
206
204
 
207
205
  class HttpInProgressStateDirective extends HttpStateDirectiveBase {
@@ -220,7 +218,7 @@ class HttpInProgressStateDirective extends HttpStateDirectiveBase {
220
218
  }
221
219
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: HttpInProgressStateDirective, decorators: [{
222
220
  type: Directive,
223
- args: [{ selector: '[httpInProgressState]', standalone: true }]
221
+ args: [{ selector: '[httpInProgressState]', }]
224
222
  }] });
225
223
 
226
224
  class HttpNotStartedStateDirective extends HttpStateDirectiveBase {
@@ -239,7 +237,7 @@ class HttpNotStartedStateDirective extends HttpStateDirectiveBase {
239
237
  }
240
238
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: HttpNotStartedStateDirective, decorators: [{
241
239
  type: Directive,
242
- args: [{ selector: '[httpNotStartedState]', standalone: true }]
240
+ args: [{ selector: '[httpNotStartedState]', }]
243
241
  }] });
244
242
 
245
243
  class HttpSuccessStateDirective extends HttpStateDirectiveBase {
@@ -262,7 +260,7 @@ class HttpSuccessStateDirective extends HttpStateDirectiveBase {
262
260
  }
263
261
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: HttpSuccessStateDirective, decorators: [{
264
262
  type: Directive,
265
- args: [{ selector: '[httpSuccessState]', standalone: true }]
263
+ args: [{ selector: '[httpSuccessState]', }]
266
264
  }], propDecorators: { httpSuccessStateTypeSafety: [{
267
265
  type: Input
268
266
  }] } });
@@ -694,7 +692,7 @@ class SpaceCasePipe {
694
692
  }
695
693
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: SpaceCasePipe, decorators: [{
696
694
  type: Pipe,
697
- args: [{ name: 'spaceCase', standalone: true }]
695
+ args: [{ name: 'spaceCase' }]
698
696
  }] });
699
697
  /**
700
698
  * Adds a space before uppercase letters that either
@@ -706,10 +704,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImpor
706
704
  * Turns underscores into spaces
707
705
  */
708
706
  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');
707
+ const phrase = value?.replace(regex1, '$1$3 $2$4');
710
708
  // uppercase the first character of every word
711
- return phrase?.replace(/(^| )(\w)/g, x => x.toUpperCase());
709
+ return phrase?.replace(regex2, x => x.toUpperCase());
712
710
  }
711
+ const regex1 = /([a-z0-9])([A-Z])|([a-zA-Z0-9])([A-Z])(?=[a-z])|_/g;
712
+ const regex2 = /(^| )(\w)/g;
713
713
 
714
714
  var FieldType;
715
715
  (function (FieldType) {
@@ -923,6 +923,11 @@ const defaultDataState = {
923
923
  },
924
924
  };
925
925
 
926
+ const ArrayDefaults = {
927
+ limit: 3,
928
+ arrayStyle: ArrayStyle.CommaDelimited
929
+ };
930
+
926
931
  // here is how to use it
927
932
  // <generic-table [report]="report">
928
933
  // <p *customCell="'column1'; let element = element" [class.makeMeRed]="element?.port">If Port, i will be red</p>
@@ -931,65 +936,47 @@ const defaultDataState = {
931
936
  class CustomCellDirective {
932
937
  templateRef = inject(TemplateRef, { optional: true });
933
938
  columnDef = inject(CdkColumnDef, { optional: true });
934
- customCell;
935
- displayName;
936
- preSort;
937
- TemplateRef;
938
- customCellOrder;
939
- customCellWidth;
940
- customCellTableRef;
939
+ $customCell = input.required({ alias: 'customCell' });
940
+ $displayName = input(undefined, { alias: 'displayName' });
941
+ $preSort = input(undefined, { alias: 'preSort' });
942
+ $templateRef = input(this.templateRef || undefined, { alias: 'templateRef' });
943
+ $customCellOrder = input(undefined, { alias: 'customCellOrder' });
944
+ $customCellWidth = input(undefined, { alias: 'customCellWidth' });
945
+ /**
946
+ * for type safety, this is a reference to the table builder instance.
947
+ */
948
+ $customCellTableRef = input(undefined, { alias: 'customCellTableRef' });
941
949
  /**
942
950
  * true if column not mapped to a property in the data source. Default is false.
943
951
  */
944
- customCellNotMapped = false;
945
- constructor() {
946
- if (this.templateRef !== null)
947
- this.TemplateRef = this.templateRef;
948
- }
949
- ngOnInit() {
950
- this.$metaData.next(this.getMetaData());
951
- }
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,
952
+ $customCellNotMapped = input(false, { alias: 'customCellNotMapped' });
953
+ $metaData = computed(() => {
954
+ const c = this.$customCell();
955
+ if (!c)
956
+ return;
957
+ return ({
958
+ key: this.$customCell(),
959
+ displayName: this.$displayName(),
960
+ preSort: this.$preSort(),
961
+ fieldType: this.$customCellNotMapped() ? FieldType.NotMapped : FieldType.Unknown,
962
+ order: this.$customCellOrder(),
963
+ width: this.$customCellWidth(),
961
964
  customCell: true,
962
- };
963
- };
965
+ noExport: true,
966
+ });
967
+ });
964
968
  static ngTemplateContextGuard(dir, ctx) {
965
969
  return true;
966
970
  }
967
971
  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 });
972
+ 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: "displayName", 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
973
  }
970
974
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: CustomCellDirective, decorators: [{
971
975
  type: Directive,
972
976
  args: [{
973
977
  selector: '[customCell]',
974
- standalone: true
975
978
  }]
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
- }] } });
979
+ }] });
993
980
 
994
981
  class ResizeColumnDirective {
995
982
  renderer = inject(Renderer2);
@@ -1063,7 +1050,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImpor
1063
1050
  type: Directive,
1064
1051
  args: [{
1065
1052
  selector: "[resizeColumn]",
1066
- standalone: true
1067
1053
  }]
1068
1054
  }], propDecorators: { resizable: [{
1069
1055
  type: Input,
@@ -1084,7 +1070,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImpor
1084
1070
  type: Directive,
1085
1071
  args: [{
1086
1072
  selector: '[tbWrapper]',
1087
- standalone: true,
1088
1073
  }]
1089
1074
  }] });
1090
1075
 
@@ -1124,14 +1109,13 @@ const inputs = [
1124
1109
  class TableCustomFilterDirective {
1125
1110
  filterId;
1126
1111
  savable = false;
1127
- used = false;
1128
1112
  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 });
1113
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.0.0", type: TableCustomFilterDirective, isStandalone: true, selector: "tb-abstract", ngImport: i0 });
1130
1114
  }
1131
1115
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: TableCustomFilterDirective, decorators: [{
1132
1116
  type: Directive,
1133
1117
  args: [{
1134
- selector: ' '
1118
+ selector: 'tb-abstract'
1135
1119
  }]
1136
1120
  }] });
1137
1121
  class TableFilterDirective {
@@ -1143,6 +1127,9 @@ class TableFilterDirective {
1143
1127
  }
1144
1128
  if (this.model) {
1145
1129
  subscriber(this.model.valueChanges, val => {
1130
+ if (this.filterType === FilterTypes.StringContains && val === '') {
1131
+ val = undefined;
1132
+ }
1146
1133
  this.filterValue = val;
1147
1134
  this.update();
1148
1135
  });
@@ -1151,7 +1138,7 @@ class TableFilterDirective {
1151
1138
  reset() {
1152
1139
  this.filterValue = undefined;
1153
1140
  }
1154
- filter$ = new Subject;
1141
+ filter$ = new ReplaySubject(1);
1155
1142
  filterType;
1156
1143
  key;
1157
1144
  fieldType;
@@ -1168,7 +1155,6 @@ class TableFilterDirective {
1168
1155
  this.filterValue = value;
1169
1156
  }
1170
1157
  }
1171
- used = false;
1172
1158
  savable = false;
1173
1159
  ready = false;
1174
1160
  _userActive = true;
@@ -1208,7 +1194,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImpor
1208
1194
  type: Directive,
1209
1195
  args: [{
1210
1196
  selector: "[tbFilter]",
1211
- standalone: true,
1212
1197
  }]
1213
1198
  }], ctorParameters: () => [], propDecorators: { filterType: [{
1214
1199
  type: Input
@@ -1259,11 +1244,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImpor
1259
1244
  'filterId: filterId',
1260
1245
  'active: active',
1261
1246
  ],
1262
- standalone: true,
1263
1247
  }]
1264
1248
  }], ctorParameters: () => [] });
1265
1249
  class TableCustomFilterDirectiveBase extends TableCustomFilterDirective {
1266
- filter$;
1250
+ filter$ = new ReplaySubject(1);
1267
1251
  filter;
1268
1252
  _predicate;
1269
1253
  set predicate(val) {
@@ -1301,7 +1285,7 @@ class TableCustomFilterDirectiveBase extends TableCustomFilterDirective {
1301
1285
  predicate: this._predicate,
1302
1286
  };
1303
1287
  this.ready = true;
1304
- this.filter$ = new BehaviorSubject(this.filter);
1288
+ this.filter$.next(this.filter);
1305
1289
  }
1306
1290
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: TableCustomFilterDirectiveBase, deps: null, target: i0.ɵɵFactoryTarget.Directive });
1307
1291
  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 +1356,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImpor
1372
1356
  ...inputs
1373
1357
  ],
1374
1358
  providers: [{ provide: TableCustomFilterDirective, useExisting: MatCheckboxTbFilterDirective }],
1375
- standalone: true,
1376
1359
  }]
1377
1360
  }], ctorParameters: () => [] });
1378
1361
  class MatSlideToggleTbFilterDirective extends TbSelectedFilterDirective {
@@ -1400,7 +1383,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImpor
1400
1383
  ...inputs
1401
1384
  ],
1402
1385
  providers: [{ provide: TableCustomFilterDirective, useExisting: MatSlideToggleTbFilterDirective }],
1403
- standalone: true,
1404
1386
  }]
1405
1387
  }], ctorParameters: () => [] });
1406
1388
  // Radio button
@@ -1427,7 +1409,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImpor
1427
1409
  selector: 'mat-radio-button[tbCustomFilter]',
1428
1410
  inputs: ['predicate: tbCustomFilter'],
1429
1411
  providers: [{ provide: TableCustomFilterDirective, useExisting: MatRadioButtonTbFilterDirective }],
1430
- standalone: true,
1431
1412
  }]
1432
1413
  }], ctorParameters: () => [] });
1433
1414
  // Option (select)
@@ -1465,7 +1446,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImpor
1465
1446
  ...inputs
1466
1447
  ],
1467
1448
  providers: [{ provide: TableCustomFilterDirective, useExisting: MatOptionTbFilterDirective }],
1468
- standalone: true,
1469
1449
  }]
1470
1450
  }], ctorParameters: () => [] });
1471
1451
  // Button toggle
@@ -1494,7 +1474,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImpor
1494
1474
  ...inputs
1495
1475
  ],
1496
1476
  providers: [{ provide: TableCustomFilterDirective, useExisting: MatButtonToggleFilterDirective }],
1497
- standalone: true,
1498
1477
  }]
1499
1478
  }], ctorParameters: () => [] });
1500
1479
 
@@ -1513,9 +1492,15 @@ class PhoneNumberPipe {
1513
1492
  }
1514
1493
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: PhoneNumberPipe, decorators: [{
1515
1494
  type: Pipe,
1516
- args: [{ name: 'phone', standalone: true }]
1495
+ args: [{ name: 'phone' }]
1517
1496
  }] });
1518
1497
 
1498
+ const defaultConfig = {
1499
+ defaultTableSettings: {
1500
+ pageSize: 10
1501
+ },
1502
+ arrayDefaults: ArrayDefaults
1503
+ };
1519
1504
  const TableBuilderConfigToken = new InjectionToken('TableBuilderConfig');
1520
1505
  function provideTableBuilder(config) {
1521
1506
  return makeEnvironmentProviders([
@@ -1524,7 +1509,7 @@ function provideTableBuilder(config) {
1524
1509
  DatePipe,
1525
1510
  CurrencyPipe,
1526
1511
  PhoneNumberPipe,
1527
- { provide: TableBuilderConfigToken, useValue: config || defaultTableState }
1512
+ { provide: TableBuilderConfigToken, useValue: config || defaultConfig }
1528
1513
  ]);
1529
1514
  }
1530
1515
 
@@ -1537,8 +1522,8 @@ const isNull = (filterInfo) => {
1537
1522
  };
1538
1523
 
1539
1524
  const stringEqualFunc = (filterInfo) => {
1540
- const equelsVal = prepareForStringCompare(filterInfo.filterValue);
1541
- return ((val) => prepareForStringCompare(val) === equelsVal);
1525
+ const equalsVal = prepareForStringCompare(filterInfo.filterValue);
1526
+ return ((val) => prepareForStringCompare(val) === equalsVal);
1542
1527
  };
1543
1528
  const stringContainsFunc = (filterInfo) => {
1544
1529
  const containsVal = prepareForStringCompare(filterInfo.filterValue);
@@ -1573,7 +1558,7 @@ const EnumFilterFuncs = {
1573
1558
  [FilterTypes.IsNull]: isNull,
1574
1559
  [FilterTypes.In]: multipleStringValuesEqualsFunc,
1575
1560
  };
1576
- const prepareForStringCompare = (val) => val?.toString().trim().toLowerCase();
1561
+ const prepareForStringCompare = (val) => (val?.toString().trim().toLowerCase());
1577
1562
 
1578
1563
  const numberEqalsFunc = (filterInfo) => (val) => {
1579
1564
  return val === filterInfo.filterValue;
@@ -1670,11 +1655,11 @@ const BooleanFilterFuncs = {
1670
1655
 
1671
1656
  const filterFactoryMap = {
1672
1657
  [FilterTypes.And]: (filter) => {
1673
- const filters = filter.filterValue.map(createFilterFunc);
1658
+ const filters = createFilterFuncs(filter.filterValue);
1674
1659
  return (obj) => filters.every(f => f(obj));
1675
1660
  },
1676
1661
  [FilterTypes.In]: (filter) => {
1677
- const filters = filter.filterValue.map(createFilterFunc);
1662
+ const filters = createFilterFuncs(filter.filterValue);
1678
1663
  return (obj) => filters.some(f => f(obj));
1679
1664
  },
1680
1665
  };
@@ -1699,11 +1684,20 @@ function isFilterInfo(filter) {
1699
1684
  return filter && typeof filter.key === 'string' && filter.filterType !== FilterTypes.Custom;
1700
1685
  }
1701
1686
  const defaultPredicate = () => true;
1687
+ function createFilterFuncs(filters) {
1688
+ return filters.filter(needsFilterCreation).map(createFilterFunc);
1689
+ }
1690
+ function needsFilterCreation(filter) {
1691
+ if (isCustomFilter(filter)) {
1692
+ return filter.active !== false;
1693
+ }
1694
+ return filter.filterValue != undefined && filter.active !== false;
1695
+ }
1702
1696
  function createFilterFunc(filter) {
1703
1697
  if (isCustomFilter(filter)) {
1704
1698
  return filter.active ? filter.predicate : defaultPredicate;
1705
1699
  }
1706
- if (filter.filterValue === undefined) {
1700
+ if (filter.filterValue == undefined) {
1707
1701
  return defaultPredicate;
1708
1702
  }
1709
1703
  const func = filterTypeFuncMap[filter.fieldType][filter.filterType](filter);
@@ -1720,7 +1714,12 @@ function createFilterFunc(filter) {
1720
1714
  : func(value);
1721
1715
  };
1722
1716
  }
1723
- const FalseyValueCanBeIncludedFilterTypes = [FilterTypes.IsNull, FilterTypes.NumberNotEqual, FilterTypes.DateIsNotOn, FilterTypes.StringDoesNotContain];
1717
+ const FalseyValueCanBeIncludedFilterTypes = [
1718
+ FilterTypes.IsNull,
1719
+ FilterTypes.NumberNotEqual,
1720
+ FilterTypes.DateIsNotOn,
1721
+ FilterTypes.StringDoesNotContain,
1722
+ ];
1724
1723
 
1725
1724
  const replaceInArrayWithClone = (arr, findMeth, actionOnClone = ((t) => { })) => {
1726
1725
  const index = arr.findIndex(findMeth);
@@ -1736,9 +1735,93 @@ const replaceInArrayWithClone = (arr, findMeth, actionOnClone = ((t) => { })) =>
1736
1735
  return clonedArray;
1737
1736
  };
1738
1737
 
1739
- function stateIs(initializationState) {
1740
- return (state) => state.initializationState === initializationState;
1738
+ const orderedStateVisibleMetaData = (state) => {
1739
+ const ordered = orderStateMetaData(state);
1740
+ const orderedVisible = ordered
1741
+ .filter(metaData => !state.hiddenKeys.includes(metaData.key) && state.metaData[metaData.key].fieldType !== FieldType.Hidden);
1742
+ return orderedVisible;
1743
+ };
1744
+ const orderedCodeVisibleMetaData = (state) => orderStateMetaData(state).filter(md => md.fieldType !== FieldType.Hidden);
1745
+ const orderStateMetaData = (state) => {
1746
+ return orderMetaData(state.metaData, state.userDefined.order);
1747
+ };
1748
+ const orderMetaData = (metaData, userDefined) => {
1749
+ const userOrderArr = Object.entries(userDefined);
1750
+ return userOrderArr.length ?
1751
+ Object.values(metaData).sort((a, b) => {
1752
+ const orderA = userDefined[a.key];
1753
+ const orderB = userDefined[b.key];
1754
+ return order(orderA, orderB);
1755
+ })
1756
+ :
1757
+ Object.values(metaData).sort((a, b) => {
1758
+ const orderA = a.order;
1759
+ const orderB = b.order;
1760
+ return order(orderA, orderB);
1761
+ });
1762
+ };
1763
+ function order(orderA, orderB) {
1764
+ if (orderA == null && orderB == null) {
1765
+ return 0;
1766
+ }
1767
+ if (orderA == null) {
1768
+ return 1;
1769
+ }
1770
+ if (orderB == null) {
1771
+ return -1;
1772
+ }
1773
+ return orderA - orderB;
1774
+ }
1775
+ function cleanPersistedState(state, pState) {
1776
+ const metas = Object.values(state.metaData);
1777
+ const filters = Object.values(pState.filters).filter(fltr => isCustomFilter(fltr) || metas.some(m => m.key === fltr.key)).reduce((obj, filter) => {
1778
+ obj[filter.filterId] = pState.filters[filter.filterId];
1779
+ return obj;
1780
+ }, {});
1781
+ const sorted = pState.sorted.filter(s => metas.some(m => m.key === s.active));
1782
+ return ({ ...pState, filters, sorted });
1741
1783
  }
1784
+ const mapSaveableState = (s) => {
1785
+ const savableState = { ...s };
1786
+ keysToDelete.forEach(key => delete savableState[key]);
1787
+ return savableState;
1788
+ };
1789
+ const createPreSort = (metaDatas) => {
1790
+ return Object.values(metaDatas).filter((metaData) => !!metaData.preSort)
1791
+ .sort(({ preSort: ps1 }, { preSort: ps2 }) => (ps1.precedence || Number.MAX_VALUE) - (ps2.precedence || Number.MAX_VALUE))
1792
+ .map(({ key, preSort: { direction } }) => ({ active: key, direction }));
1793
+ };
1794
+ const mergeMeta = (orig, merge) => {
1795
+ return {
1796
+ key: orig.key,
1797
+ displayName: merge.displayName ?? orig.displayName,
1798
+ fieldType: merge.fieldType || orig.fieldType,
1799
+ additional: { ...orig.additional, ...merge.additional },
1800
+ order: merge.order ?? orig.order,
1801
+ preSort: merge.preSort ?? orig.preSort,
1802
+ width: merge.width ?? orig.width,
1803
+ noExport: merge.noExport || orig.noExport,
1804
+ noFilter: merge.noFilter || orig.noFilter,
1805
+ customCell: merge.customCell ?? orig.customCell,
1806
+ transform: merge.transform ?? orig.transform,
1807
+ map: merge.map ?? orig.map,
1808
+ click: merge.click ?? orig.click,
1809
+ classes: merge.classes ?? orig.classes,
1810
+ noSort: merge.noSort ?? orig.noSort,
1811
+ template: merge.template ?? orig.template,
1812
+ toolTip: merge.toolTip ?? orig.toolTip,
1813
+ useIcon: merge.useIcon ?? orig.useIcon,
1814
+ };
1815
+ };
1816
+ const initializeOrder = (state, mds) => {
1817
+ const viewableMetaDataArr = Object.values(mds).filter(a => a.fieldType !== FieldType.Hidden);
1818
+ let userDefinedOrder = state.userDefined.order;
1819
+ if (viewableMetaDataArr.some(meta => userDefinedOrder[meta.key] == null)) {
1820
+ return {};
1821
+ }
1822
+ return userDefinedOrder;
1823
+ };
1824
+
1742
1825
  class TableStore extends ComponentStore {
1743
1826
  constructor() {
1744
1827
  const config = inject(TableBuilderConfigToken);
@@ -1751,41 +1834,122 @@ class TableStore extends ComponentStore {
1751
1834
  }
1752
1835
  super({ ...defaultTableState, ...settingsFromConfig });
1753
1836
  }
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
- }));
1759
- }
1760
1837
  getSavableStateSignal = computed(() => {
1761
1838
  const state = this.state();
1762
- return this.mapSaveableState(state);
1839
+ return mapSaveableState(state);
1763
1840
  });
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
- };
1841
+ $userDefinedOrder = this.selectSignal(state => state.userDefined.order);
1773
1842
  metaData$ = this.select(state => state.metaData);
1774
1843
  $metaData = this.selectSignal(state => state.metaData);
1775
- $userDefinedOrder = this.selectSignal(state => state.userDefined.order);
1776
- $hiddenKeys = this.selectSignal(state => state.hiddenKeys);
1777
1844
  $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]);
1845
+ $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) });
1846
+ $getMetaData = (key) => computed(() => {
1847
+ const metaData = this.state().metaData[key];
1848
+ if (!metaData)
1849
+ console.warn(`Meta data with key ${key} not found`);
1850
+ return metaData;
1851
+ });
1852
+ $hiddenKeys = this.selectSignal(state => state.hiddenKeys);
1853
+ $orderedVisibleColumns = this.selectSignal(this.$orderedCodeVisibleMetaDatas, this.$hiddenKeys, (cs, hiddenKeys) => cs.filter(m => !hiddenKeys.includes(m.key)).map(m => m.key));
1783
1854
  $getUserDefinedWidths = this.selectSignal(state => state.userDefined.widths);
1784
- tableSettingsMinWidth = this.selectSignal(state => state.notPersistedTableSettings.minColumnWidth);
1855
+ $tableSettingsMinWidth = this.selectSignal(state => state.notPersistedTableSettings.minColumnWidth);
1856
+ $getUserDefinedWidth = (key) => this.selectSignal(this.$getUserDefinedWidths, widths => widths[key]);
1857
+ $filters = this.selectSignal(state => state.filters);
1858
+ filters$ = this.select(state => state.filters);
1859
+ $getFilter = (filterId) => {
1860
+ return this.selectSignal(this.$filters, filters => filters[filterId]);
1861
+ };
1862
+ $selectSorted = this.selectSignal(state => state.sorted, {
1863
+ equal: sortsAreSame
1864
+ });
1865
+ selectSorted$ = this.select(state => state.sorted).pipe(distinctUntilChanged(sortsAreSame));
1866
+ sort$ = this.select(state => state.initializationState).pipe(filter(i => i === InitializationState.Ready))
1867
+ .pipe(switchMap(() => this.selectSorted$));
1868
+ $getUserDefinedTableWidth = this.selectSignal(state => state.userDefined.table.width);
1869
+ getUserDefinedTableWidth$ = this.select(state => state.userDefined.table.width);
1870
+ $getPageSize = this.selectSignal(state => state.userDefined.pageSize || state.pageSize);
1871
+ $footerCollapsed = this.selectSignal(state => state.persistedTableSettings.collapseFooter);
1872
+ $headerCollapsed = this.selectSignal(state => state.persistedTableSettings.collapseHeader);
1873
+ $groupBy = this.selectSignal(state => state.groupBy);
1874
+ $groupByKeys = this.selectSignal(this.$groupBy, gb => gb.map(gbk => gbk.key), {
1875
+ equal: (prev, curr) => prev.length === curr.length && curr.every((k, i) => prev[i] === k)
1876
+ });
1877
+ groupByKeys$ = this.select(state => state.groupBy.map(gbk => gbk.key))
1878
+ .pipe(distinctUntilChanged((prev, curr) => prev.length === curr.length && curr.every((k, i) => prev[i] === k)));
1879
+ expandedGroups$ = this.select(state => state.groupBy).pipe(distinctUntilChanged((a, b) => {
1880
+ const aa = a.flatMap(g => g.expandedHeaders);
1881
+ const bb = b.flatMap(g => g.expandedHeaders);
1882
+ return aa.length === bb.length && aa.every((k) => bb.includes(k));
1883
+ }));
1884
+ $getIsExpanded = (columnKey, groupHeaderKey) => {
1885
+ return this.selectSignal(state => !!state.groupBy.filter(g => g.key === columnKey && g.expandedHeaders.includes(groupHeaderKey)).length);
1886
+ };
1887
+ $currentPage = this.selectSignal(state => state.currentPage);
1888
+ $pageSize = this.selectSignal(s => s.userDefined?.pageSize || s.pageSize);
1889
+ $tableSettings = this.selectSignal(state => {
1890
+ const ts = { ...state.persistedTableSettings, ...state.notPersistedTableSettings };
1891
+ return ts;
1892
+ });
1893
+ tableSettings$ = toObservable(this.$tableSettings);
1894
+ $props = this.selectSignal(s => s.props);
1895
+ $getLinkInfo = (md) => this.selectSignal(state => state.linkMaps[md.key]);
1896
+ $isVirtual = this.selectSignal(state => state.notPersistedTableSettings.useVirtualScroll === true || state.notPersistedTableSettings.useVirtualScroll?.virtualAsDefault || state.showAll);
1897
+ $viewType = this.selectSignal(state => {
1898
+ const usePaginator = state.notPersistedTableSettings.usePaginator;
1899
+ if (state.showAll || (this.$isVirtual() && !usePaginator)) {
1900
+ return 'virtual all';
1901
+ }
1902
+ else if (this.$isVirtual() && usePaginator) {
1903
+ return 'virtual paginator';
1904
+ }
1905
+ else if (usePaginator) {
1906
+ return 'paginator';
1907
+ }
1908
+ else {
1909
+ return 'all';
1910
+ }
1911
+ });
1785
1912
  resetState = this.updater((state) => {
1786
- const sorted = this.createPreSort(state.metaData);
1913
+ const sorted = createPreSort(state.metaData);
1787
1914
  return ({ ...state, hiddenKeys: [], sorted, filters: {}, groupBy: [], userDefined: { widths: {}, order: {}, table: {} } });
1788
1915
  });
1916
+ updateStateFromPersistedState = this.updater((state, persistedState) => {
1917
+ const incomingTableState = cleanPersistedState(state, persistedState);
1918
+ const newState = this.updateStateFunc(state, incomingTableState);
1919
+ newState.initializationState = state.initializationState === InitializationState.MetaDataLoaded ? InitializationState.LoadedFromStore : state.initializationState;
1920
+ return newState;
1921
+ });
1922
+ updateStateFunc = (state, incomingTableState) => {
1923
+ const metaData = state.metaData;
1924
+ const sorted = incomingTableState.sorted?.length ? incomingTableState.sorted
1925
+ : state.initializationState === InitializationState.Created ? createPreSort(metaData) : state.sorted;
1926
+ return { ...state, ...incomingTableState, metaData, sorted };
1927
+ };
1928
+ setTableSettings = this.updater((state, settings) => {
1929
+ const s = {
1930
+ ...state,
1931
+ persistedTableSettings: state.persistedTableSettings.merge(settings),
1932
+ notPersistedTableSettings: state.notPersistedTableSettings.merge(settings)
1933
+ };
1934
+ return s;
1935
+ });
1936
+ setMetaData = this.updater((state, md) => {
1937
+ const metaData = md
1938
+ .reduce((prev, curr) => {
1939
+ if (prev[curr.key]) {
1940
+ prev[curr.key] = mergeMeta(prev[curr.key], curr);
1941
+ }
1942
+ else {
1943
+ prev[curr.key] = curr;
1944
+ }
1945
+ return prev;
1946
+ }, {});
1947
+ const sortedInitialized = state.sorted.length > 0;
1948
+ const sorted = sortedInitialized ? state.sorted : createPreSort(metaData);
1949
+ const order = initializeOrder(state, metaData);
1950
+ const initializationState = state.initializationState == InitializationState.Created ? InitializationState.MetaDataLoaded : state.initializationState;
1951
+ return { ...state, initializationState, metaData, sorted, userDefined: { ...state.userDefined, order: order } };
1952
+ });
1789
1953
  showColumn = this.updater((state, key) => ({
1790
1954
  ...state,
1791
1955
  hiddenKeys: state.hiddenKeys.filter(k => k !== key),
@@ -1814,17 +1978,29 @@ class TableStore extends ComponentStore {
1814
1978
  }, {});
1815
1979
  return ({ ...state, userDefined: { ...state.userDefined, order: userDefinedOrder } });
1816
1980
  });
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
1981
  addFilter = this.updater((state, filter) => {
1823
1982
  return this.addFiltersToState(state, [filter]);
1824
1983
  });
1984
+ // readonly patchPredicate = this.updater((state, {filterId, predicate}: {filterId: string, predicate: (data: any) => boolean}) => {
1985
+ // const filtersCopy = { ...state.filters };
1986
+ // const filter = filtersCopy[filterId] as CustomFilter;
1987
+ // filter.predicate = predicate;
1988
+ // return ({...state, filters: filtersCopy });
1989
+ // });
1825
1990
  addFilters = this.updater((state, filters) => {
1826
1991
  return this.addFiltersToState(state, filters);
1827
1992
  });
1993
+ removeFilter = this.updater((state, filterId) => {
1994
+ const filtersCopy = { ...state.filters };
1995
+ delete filtersCopy[filterId];
1996
+ return ({ ...state, filters: filtersCopy });
1997
+ });
1998
+ removeFilters = this.updater((state, filterIds) => {
1999
+ const filtersCopy = { ...state.filters };
2000
+ filterIds.forEach(id => { delete filtersCopy[id]; });
2001
+ return ({ ...state, filters: filtersCopy });
2002
+ });
2003
+ clearFilters = this.updater((state) => ({ ...state, filters: {} }));
1828
2004
  addFiltersToState = (state, filters) => {
1829
2005
  var customFilters = filters.filter(isCustomFilter);
1830
2006
  var filterInfos = filters.filter(isFilterInfo);
@@ -1848,24 +2024,6 @@ class TableStore extends ComponentStore {
1848
2024
  filters: { ...state.filters, ...filtersObj }
1849
2025
  };
1850
2026
  };
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
2027
  setSort = this.updater((state, { key, direction }) => {
1870
2028
  const sortArray = state.sorted.filter(s => s.active !== key);
1871
2029
  if (direction) {
@@ -1882,85 +2040,15 @@ class TableStore extends ComponentStore {
1882
2040
  sorted: sortArray,
1883
2041
  };
1884
2042
  });
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
- };
2043
+ setCurrentPage = this.updater((state, currentPage) => ({ ...state, currentPage }));
1891
2044
  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;
2045
+ setProps = this.updater((state, props) => {
2046
+ return ({ ...state, props });
1899
2047
  });
1900
- getUserDefinedTableSize = this.selectSignal(state => state.userDefined.table.width);
1901
- getUserDefinedTableSize$ = this.select(state => state.userDefined.table.width);
1902
2048
  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
2049
  setInitializationState = this.updater((state, initializationState) => {
1926
2050
  return { ...state, initializationState };
1927
2051
  });
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
2052
  toggleCollapseHeader = this.updater((state) => {
1965
2053
  const tableSettings = { ...state.persistedTableSettings };
1966
2054
  tableSettings.collapseHeader = !tableSettings.collapseHeader;
@@ -1971,8 +2059,6 @@ class TableStore extends ComponentStore {
1971
2059
  tableSettings.collapseFooter = !tableSettings.collapseFooter;
1972
2060
  return ({ ...state, persistedTableSettings: new PersistedTableSettings(tableSettings) });
1973
2061
  });
1974
- $collapseFooter = this.selectSignal(state => state.persistedTableSettings.collapseFooter);
1975
- $collapseHeader = this.selectSignal(state => state.persistedTableSettings.collapseHeader);
1976
2062
  addGroupByKey = this.updater((state, metaDataKey) => ({
1977
2063
  ...state,
1978
2064
  groupBy: [...state.groupBy, { key: metaDataKey, expandedHeaders: [] }]
@@ -2008,106 +2094,19 @@ class TableStore extends ComponentStore {
2008
2094
  expandedHeaders: data.keys.includes(gb.key) ? [] : gb.expandedHeaders
2009
2095
  }))
2010
2096
  }));
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
2097
  setLinkMaps = this.updater((state, maps) => {
2033
- return { ...state, linkMaps: maps };
2098
+ return ({ ...state, linkMaps: maps });
2034
2099
  });
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);
2100
+ on = (srcObservable, func) => {
2101
+ this.effect(() => srcObservable.pipe(tap(func)));
2102
+ return this;
2038
2103
  };
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
2104
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: TableStore, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
2060
2105
  static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: TableStore });
2061
2106
  }
2062
2107
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: TableStore, decorators: [{
2063
2108
  type: Injectable
2064
2109
  }], 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
2110
 
2112
2111
  class MultiSortDirective extends MatSort {
2113
2112
  state = inject(TableStore);
@@ -2139,21 +2138,38 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImpor
2139
2138
  providers: [
2140
2139
  { provide: MatSort, useExisting: MultiSortDirective }
2141
2140
  ],
2142
- standalone: true
2143
2141
  }]
2144
2142
  }], ctorParameters: () => [] });
2145
- function isDifferent(a, b) {
2143
+ function sortsAreSame(a, b) {
2146
2144
  if (a.length !== b.length) {
2147
- return true;
2145
+ return false;
2148
2146
  }
2149
2147
  for (let i = 0; i < a.length; i++) {
2150
2148
  if (a[i].active !== b[i].active || a[i].direction !== b[i].direction) {
2151
- return true;
2149
+ return false;
2152
2150
  }
2153
2151
  }
2154
- return false;
2152
+ return true;
2155
2153
  }
2156
2154
 
2155
+ class DateFilterComponent {
2156
+ FilterType = FilterTypes;
2157
+ info;
2158
+ CurrentFilterType;
2159
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: DateFilterComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
2160
+ 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 });
2161
+ }
2162
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: DateFilterComponent, decorators: [{
2163
+ type: Component,
2164
+ args: [{ selector: 'tb-date-filter', changeDetection: ChangeDetectionStrategy.OnPush, viewProviders: [{ provide: ControlContainer, useExisting: NgForm }], imports: [
2165
+ MatInputModule, FormsModule, MatDatepickerModule
2166
+ ], 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"] }]
2167
+ }], propDecorators: { info: [{
2168
+ type: Input
2169
+ }], CurrentFilterType: [{
2170
+ type: Input
2171
+ }] } });
2172
+
2157
2173
  class PreventEnterDirective {
2158
2174
  onKeyDown() {
2159
2175
  return false;
@@ -2165,7 +2181,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImpor
2165
2181
  type: Directive,
2166
2182
  args: [{
2167
2183
  selector: 'preventEnter',
2168
- standalone: true
2169
2184
  }]
2170
2185
  }], propDecorators: { onKeyDown: [{
2171
2186
  type: HostListener,
@@ -2186,7 +2201,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImpor
2186
2201
  type: Directive,
2187
2202
  args: [{
2188
2203
  selector: "[stop-propagation]",
2189
- standalone: true
2190
2204
  }]
2191
2205
  }], propDecorators: { onClick: [{
2192
2206
  type: HostListener,
@@ -2213,7 +2227,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImpor
2213
2227
  type: Directive,
2214
2228
  args: [{
2215
2229
  selector: '[autoFocus]',
2216
- standalone: true,
2217
2230
  }]
2218
2231
  }], propDecorators: { autoFocus: [{
2219
2232
  type: Input
@@ -2238,7 +2251,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImpor
2238
2251
  host: {
2239
2252
  '(click)': 'next(this._val)'
2240
2253
  },
2241
- standalone: true,
2242
2254
  }]
2243
2255
  }], ctorParameters: () => [], propDecorators: { clickSubject: [{
2244
2256
  type: Input,
@@ -2260,7 +2272,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImpor
2260
2272
  host: {
2261
2273
  '(click)': 'next(true)'
2262
2274
  },
2263
- standalone: true,
2264
2275
  }]
2265
2276
  }], ctorParameters: () => [] });
2266
2277
 
@@ -2311,7 +2322,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImpor
2311
2322
  args: [{
2312
2323
  selector: 'dialog-wrapper',
2313
2324
  template: ``,
2314
- standalone: true,
2315
2325
  changeDetection: ChangeDetectionStrategy.OnPush,
2316
2326
  }]
2317
2327
  }] });
@@ -2406,7 +2416,7 @@ class DialogDirective {
2406
2416
  }
2407
2417
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: DialogDirective, decorators: [{
2408
2418
  type: Directive,
2409
- args: [{ selector: '[opDialog]', standalone: true }]
2419
+ args: [{ selector: '[opDialog]', }]
2410
2420
  }], propDecorators: { opDialogClosed: [{
2411
2421
  type: Output
2412
2422
  }], opDialogAddDialogClass: [{
@@ -2452,7 +2462,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImpor
2452
2462
  type: Directive,
2453
2463
  args: [{
2454
2464
  selector: '[styler]',
2455
- standalone: true
2456
2465
  }]
2457
2466
  }], propDecorators: { element: [{
2458
2467
  type: Input
@@ -2504,7 +2513,6 @@ class MatSlideToggleGroupDirective {
2504
2513
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: MatSlideToggleGroupDirective, decorators: [{
2505
2514
  type: Directive,
2506
2515
  args: [{ selector: '[opMatSlideToggleGroup]',
2507
- standalone: true
2508
2516
  }]
2509
2517
  }], propDecorators: { allowMultiple: [{
2510
2518
  type: Input
@@ -2534,7 +2542,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImpor
2534
2542
  type: Directive,
2535
2543
  args: [{
2536
2544
  selector: 'input[trimWhitespace]',
2537
- standalone: true
2538
2545
  }]
2539
2546
  }], propDecorators: { onBlur: [{
2540
2547
  type: HostListener,
@@ -2557,7 +2564,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImpor
2557
2564
  type: Pipe,
2558
2565
  args: [{
2559
2566
  name: 'func',
2560
- standalone: true
2561
2567
  }]
2562
2568
  }] });
2563
2569
 
@@ -2586,7 +2592,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImpor
2586
2592
  type: Directive,
2587
2593
  args: [{
2588
2594
  selector: '[conditionalClasses]',
2589
- standalone: true
2590
2595
  }]
2591
2596
  }], propDecorators: { element: [{
2592
2597
  type: Input
@@ -2669,28 +2674,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImpor
2669
2674
  }]
2670
2675
  }] });
2671
2676
 
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
2677
  class InFilterComponent {
2691
2678
  ref = inject(ChangeDetectorRef);
2692
2679
  FieldType = FieldType;
2693
- type;
2680
+ $type = input.required({ alias: 'type' });
2694
2681
  value = [undefined];
2695
2682
  constructor() {
2696
2683
  this.value = [undefined];
@@ -2727,11 +2714,11 @@ class InFilterComponent {
2727
2714
  this.onChange(this.value);
2728
2715
  }
2729
2716
  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: [{
2717
+ 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
2718
  provide: NG_VALUE_ACCESSOR,
2732
2719
  useExisting: InFilterComponent,
2733
2720
  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 });
2721
+ }], 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
2722
  }
2736
2723
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: InFilterComponent, decorators: [{
2737
2724
  type: Component,
@@ -2739,31 +2726,25 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImpor
2739
2726
  provide: NG_VALUE_ACCESSOR,
2740
2727
  useExisting: InFilterComponent,
2741
2728
  multi: true
2742
- }], standalone: true, imports: [
2729
+ }], imports: [
2743
2730
  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
- }] } });
2731
+ ], 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"] }]
2732
+ }], ctorParameters: () => [] });
2748
2733
 
2749
2734
  class NumberFilterComponent {
2750
2735
  FilterType = FilterTypes;
2751
2736
  FieldType = FieldType;
2752
- CurrentFilterType;
2753
- info;
2737
+ $currentFilterType = input.required({ alias: 'CurrentFilterType' });
2738
+ $info = input.required({ alias: 'info' });
2754
2739
  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 });
2740
+ 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
2741
  }
2757
2742
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: NumberFilterComponent, decorators: [{
2758
2743
  type: Component,
2759
- args: [{ selector: 'tb-number-filter', changeDetection: ChangeDetectionStrategy.OnPush, viewProviders: [{ provide: ControlContainer, useExisting: NgForm }], standalone: true, imports: [
2744
+ args: [{ selector: 'tb-number-filter', changeDetection: ChangeDetectionStrategy.OnPush, viewProviders: [{ provide: ControlContainer, useExisting: NgForm }], imports: [
2760
2745
  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
- }] } });
2746
+ ], 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"] }]
2747
+ }] });
2767
2748
 
2768
2749
  class DateTimeFilterComponent {
2769
2750
  FilterType = FilterTypes;
@@ -2774,8 +2755,8 @@ class DateTimeFilterComponent {
2774
2755
  }
2775
2756
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: DateTimeFilterComponent, decorators: [{
2776
2757
  type: Component,
2777
- args: [{ selector: 'tb-date-time-filter', changeDetection: ChangeDetectionStrategy.OnPush, viewProviders: [{ provide: ControlContainer, useExisting: NgForm }], standalone: true, imports: [
2778
- FormsModule, PreventEnterDirective
2758
+ args: [{ selector: 'tb-date-time-filter', changeDetection: ChangeDetectionStrategy.OnPush, viewProviders: [{ provide: ControlContainer, useExisting: NgForm }], imports: [
2759
+ FormsModule
2779
2760
  ], 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
2761
  }], propDecorators: { info: [{
2781
2762
  type: Input
@@ -2791,7 +2772,7 @@ class InListFilterComponent {
2791
2772
  writeValue(obj) {
2792
2773
  this.value = obj;
2793
2774
  if (this.value) {
2794
- this.selectedKeys = this.value.map(f => f);
2775
+ this.$selectedKeys.set(this.value.map(f => f));
2795
2776
  }
2796
2777
  this.ref.markForCheck();
2797
2778
  }
@@ -2803,58 +2784,56 @@ class InListFilterComponent {
2803
2784
  registerOnTouched(fn) {
2804
2785
  this.onTouched = fn;
2805
2786
  }
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
- }
2787
+ $key = input.required({ alias: 'key' });
2788
+ $selectedKeys = signal([]);
2789
+ $metaData = computed(() => this.tableState.$getMetaData(this.$key())());
2790
+ $keyValues = computed(() => {
2791
+ const metaData = this.$metaData();
2792
+ if (metaData?.additional?.filterOptions?.filterableValues) {
2793
+ return metaData.additional.filterOptions.filterableValues.reduce((prev, cur) => { prev[cur] = cur; return prev; }, {});
2794
+ }
2795
+ else {
2796
+ if (metaData?.fieldType === FieldType.Enum) {
2797
+ return metaData.additional.enumMap;
2819
2798
  }
2820
- return {};
2821
- }));
2822
- }
2799
+ }
2800
+ return {};
2801
+ });
2823
2802
  selectFilterChanged($event, val) {
2824
2803
  if ($event.checked) {
2825
- this.selectedKeys = [...this.selectedKeys, val];
2804
+ this.$selectedKeys.update(keys => [...keys, val]);
2826
2805
  }
2827
2806
  else {
2828
- this.selectedKeys = this.selectedKeys.filter(item => item !== val);
2807
+ this.$selectedKeys.update(keys => keys.filter(item => item !== val));
2829
2808
  }
2830
- this.value = this.selectedKeys;
2809
+ this.value = this.$selectedKeys();
2831
2810
  this.onChange(this.value);
2832
2811
  }
2833
2812
  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: [{
2813
+ 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
2814
  provide: NG_VALUE_ACCESSOR,
2836
2815
  useExisting: InListFilterComponent,
2837
2816
  multi: true
2838
2817
  }], ngImport: i0, template: `
2839
- @for (item of keyValues$ | async| keyvalue; track item.key) {
2818
+ @for (item of $keyValues() | keyvalue; track item.key) {
2840
2819
  <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}}
2820
+ <mat-checkbox [checked]="'includes' | func : $selectedKeys() : item.key" stop-propagation (change)='selectFilterChanged($event, item.key)' >
2821
+ {{$metaData().fieldType === FieldType.Enum ? (item.value | spaceCase) : item.value}}
2843
2822
  </mat-checkbox>
2844
2823
  </div>
2845
2824
  }
2846
2825
 
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 });
2826
+ `, 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
2827
  }
2849
2828
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: InListFilterComponent, decorators: [{
2850
2829
  type: Component,
2851
2830
  args: [{
2852
2831
  selector: 'tb-in-list-filter , [tb-in-list-filter]',
2853
2832
  template: `
2854
- @for (item of keyValues$ | async| keyvalue; track item.key) {
2833
+ @for (item of $keyValues() | keyvalue; track item.key) {
2855
2834
  <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}}
2835
+ <mat-checkbox [checked]="'includes' | func : $selectedKeys() : item.key" stop-propagation (change)='selectFilterChanged($event, item.key)' >
2836
+ {{$metaData().fieldType === FieldType.Enum ? (item.value | spaceCase) : item.value}}
2858
2837
  </mat-checkbox>
2859
2838
  </div>
2860
2839
  }
@@ -2866,14 +2845,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImpor
2866
2845
  useExisting: InListFilterComponent,
2867
2846
  multi: true
2868
2847
  }],
2869
- standalone: true,
2870
2848
  imports: [
2871
- AsyncPipe, KeyValuePipe, MatCheckboxModule, StopPropagationDirective, SpaceCasePipe
2849
+ KeyValuePipe, MatCheckboxModule, StopPropagationDirective, SpaceCasePipe, FunctionPipe
2872
2850
  ]
2873
2851
  }]
2874
- }], propDecorators: { key: [{
2875
- type: Input
2876
- }] } });
2852
+ }] });
2877
2853
 
2878
2854
  class FilterComponent {
2879
2855
  state = inject(TableStore);
@@ -2900,7 +2876,7 @@ class FilterComponent {
2900
2876
  }
2901
2877
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: FilterComponent, decorators: [{
2902
2878
  type: Component,
2903
- args: [{ selector: 'tb-filter', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [
2879
+ args: [{ selector: 'tb-filter', changeDetection: ChangeDetectionStrategy.OnPush, imports: [
2904
2880
  MatCardModule, FormsModule, SpaceCasePipe, MatButtonModule, MatTooltipModule, MatIconModule,
2905
2881
  MatInputModule, MatSelectModule, NumberFilterComponent,
2906
2882
  DateFilterComponent, DateTimeFilterComponent, MatRadioModule, InFilterComponent, InListFilterComponent,
@@ -2934,8 +2910,8 @@ class GenColDisplayerComponent {
2934
2910
  }
2935
2911
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: GenColDisplayerComponent, decorators: [{
2936
2912
  type: Component,
2937
- args: [{ selector: 'tb-col-displayer', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [
2938
- AsyncPipe, MatTooltipModule, MatIconModule, MatButtonModule, MatMenuModule, StopPropagationDirective,
2913
+ args: [{ selector: 'tb-col-displayer', changeDetection: ChangeDetectionStrategy.OnPush, imports: [
2914
+ MatTooltipModule, MatIconModule, MatButtonModule, MatMenuModule, StopPropagationDirective,
2939
2915
  DragDropModule, SpaceCasePipe
2940
2916
  ], 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
2917
  }] });
@@ -2950,7 +2926,7 @@ class WrapperFilterStore extends ComponentStore {
2950
2926
  arr.splice(index, 1);
2951
2927
  return { filterInfo: arr };
2952
2928
  });
2953
- currentFilters$ = this.state$.pipe(map(state => state.filterInfo));
2929
+ $currentFilters = this.selectSignal(state => state.filterInfo);
2954
2930
  addFilter = this.updater((state, filter) => {
2955
2931
  return ({ ...state, filterInfo: [...state.filterInfo, filter] });
2956
2932
  });
@@ -2976,7 +2952,7 @@ class GenFilterDisplayerComponent {
2976
2952
  }
2977
2953
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: GenFilterDisplayerComponent, decorators: [{
2978
2954
  type: Component,
2979
- args: [{ selector: 'tb-filter-displayer', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [
2955
+ args: [{ selector: 'tb-filter-displayer', changeDetection: ChangeDetectionStrategy.OnPush, imports: [
2980
2956
  MatButtonModule, MatMenuModule, MatTooltipModule, StopPropagationDirective, MatIconModule,
2981
2957
  SpaceCasePipe
2982
2958
  ], 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 +2960,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImpor
2984
2960
 
2985
2961
  class KeyDisplayPipe {
2986
2962
  tableState = inject(TableStore);
2987
- transform(key) {
2988
- return this.tableState.getMetaData$(key).pipe(map(metaData => metaData.displayName || spaceCase(key)));
2989
- }
2963
+ transform = (key) => computed(() => this.tableState.$getMetaData(key)()?.displayName || spaceCase(key));
2990
2964
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: KeyDisplayPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
2991
2965
  static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "19.0.0", ngImport: i0, type: KeyDisplayPipe, isStandalone: true, name: "keyDisplay" });
2992
2966
  }
2993
2967
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: KeyDisplayPipe, decorators: [{
2994
2968
  type: Pipe,
2995
- args: [{ name: 'keyDisplay', standalone: true }]
2969
+ args: [{ name: 'keyDisplay' }]
2996
2970
  }] });
2997
2971
 
2998
2972
  class FormatFilterTypePipe {
@@ -3007,42 +2981,43 @@ class FormatFilterTypePipe {
3007
2981
  }
3008
2982
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: FormatFilterTypePipe, decorators: [{
3009
2983
  type: Pipe,
3010
- args: [{ name: 'formatFilterType', standalone: true }]
2984
+ args: [{ name: 'formatFilterType' }]
3011
2985
  }] });
3012
2986
 
3013
2987
  class FormatFilterValuePipe {
3014
2988
  tableState = inject(TableStore);
3015
2989
  datePipe = inject(DatePipe);
3016
2990
  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
- }));
2991
+ return computed(() => transform(value, this.tableState.$getMetaData(key)(), filterType));
3038
2992
  }
3039
2993
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: FormatFilterValuePipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
3040
2994
  static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "19.0.0", ngImport: i0, type: FormatFilterValuePipe, isStandalone: true, name: "formatFilterValue" });
3041
2995
  }
3042
2996
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: FormatFilterValuePipe, decorators: [{
3043
2997
  type: Pipe,
3044
- args: [{ name: 'formatFilterValue', standalone: true }]
2998
+ args: [{ name: 'formatFilterValue' }]
3045
2999
  }] });
3000
+ const transform = (value, meta, filterType) => {
3001
+ if (filterType === FilterTypes.IsNull) {
3002
+ return '';
3003
+ }
3004
+ if (value && (filterType === FilterTypes.In)) {
3005
+ if (meta.fieldType === FieldType.Enum) {
3006
+ return value.map((v) => spaceCase(meta.additional.enumMap[v])).join(', ') ?? value;
3007
+ }
3008
+ return value.join(', ') ?? value;
3009
+ }
3010
+ if (filterType === FilterTypes.NumberBetween) {
3011
+ return value.Start + ' - ' + value.End;
3012
+ }
3013
+ if (meta.fieldType === FieldType.Date) {
3014
+ return new DatePipe('en-US').transform(value, 'MM/dd/yy') || '';
3015
+ }
3016
+ if (meta.fieldType === FieldType.DateTime) {
3017
+ return (!!DateTimeFilterFuncs[filterType] ? new DatePipe('en-US').transform(value, 'short') : new DatePipe('en-US').transform(value, 'MM/dd/yy')) || '';
3018
+ }
3019
+ return value;
3020
+ };
3046
3021
 
3047
3022
  class FilterChipsComponent {
3048
3023
  tableState = inject(TableStore);
@@ -3057,16 +3032,16 @@ class FilterChipsComponent {
3057
3032
  clearAll() {
3058
3033
  this.filterStore.clearAll();
3059
3034
  }
3060
- currentFilters$ = this.filterStore.currentFilters$;
3035
+ $currentFilters = this.filterStore.$currentFilters;
3061
3036
  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 });
3037
+ 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
3038
  }
3064
3039
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: FilterChipsComponent, decorators: [{
3065
3040
  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"] }]
3041
+ args: [{ selector: 'lib-filter-list', changeDetection: ChangeDetectionStrategy.OnPush, imports: [
3042
+ MatButtonModule, MatTooltipModule, MatIconModule, FilterComponent,
3043
+ MatChipsModule, KeyDisplayPipe, FormatFilterTypePipe, FormatFilterValuePipe
3044
+ ], 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
3045
  }] });
3071
3046
 
3072
3047
  function isPipe(o) {
@@ -3076,7 +3051,6 @@ class TransformCreator {
3076
3051
  datePipe = inject(DatePipe);
3077
3052
  currencyPipe = inject(CurrencyPipe);
3078
3053
  phonePipe = inject(PhoneNumberPipe);
3079
- casePipe = inject(SpaceCasePipe);
3080
3054
  config = inject(TableBuilderConfigToken);
3081
3055
  createTransformer(metaData, noIcons = false) {
3082
3056
  const nested = metaData.key.includes('.');
@@ -3110,7 +3084,7 @@ class TransformCreator {
3110
3084
  case FieldType.PhoneNumber:
3111
3085
  return (value) => this.phonePipe.transform(defaultFunc(value));
3112
3086
  case FieldType.Enum:
3113
- return (value) => this.casePipe.transform(metaData.additional?.enumMap[defaultFunc(value)]);
3087
+ return (value) => spaceCase(metaData.additional?.enumMap[defaultFunc(value)]);
3114
3088
  case FieldType.Boolean:
3115
3089
  if (noIcons) {
3116
3090
  return defaultFunc;
@@ -3185,7 +3159,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImpor
3185
3159
  type: Component,
3186
3160
  args: [{
3187
3161
  selector: "tb-router-link-column",
3188
- standalone: true,
3189
3162
  changeDetection: ChangeDetectionStrategy.OnPush,
3190
3163
  imports: [
3191
3164
  RouterModule
@@ -3220,7 +3193,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImpor
3220
3193
  type: Component,
3221
3194
  args: [{
3222
3195
  selector: "tb-link-column",
3223
- standalone: true,
3224
3196
  changeDetection: ChangeDetectionStrategy.OnPush,
3225
3197
  template: `
3226
3198
  <a target="{{additional().target}}"
@@ -3246,7 +3218,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImpor
3246
3218
  type: Component,
3247
3219
  args: [{
3248
3220
  selector: 'tb-comma-array-column',
3249
- standalone: true,
3250
3221
  template: `
3251
3222
  @for(val of displayArray(); track $index){
3252
3223
  {{val + (!$last ? ',' : '')}}
@@ -3271,7 +3242,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImpor
3271
3242
  type: Component,
3272
3243
  args: [{
3273
3244
  selector: 'tb-new-line-array-column',
3274
- standalone: true,
3275
3245
  template: `
3276
3246
  @for(val of displayArray(); track $index){
3277
3247
  {{val}}
@@ -3295,8 +3265,8 @@ class InitializationComponent {
3295
3265
  }
3296
3266
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: InitializationComponent, decorators: [{
3297
3267
  type: Component,
3298
- args: [{ selector: 'initialization', standalone: true, imports: [
3299
- LinkColumnComponent, ArrayCommaColumnComponent, MatIconModule, FunctionPipe,
3268
+ args: [{ selector: 'initialization', imports: [
3269
+ LinkColumnComponent, ArrayCommaColumnComponent, MatIconModule,
3300
3270
  RouterLinkColumnComponent, ArrayNewLineColumnComponent
3301
3271
  ], 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
3272
  }], propDecorators: { linkTemplate: [{
@@ -3345,10 +3315,11 @@ class TableTemplateService {
3345
3315
  this.templates[FieldType.Enum] = this.instance.defaultTemplate;
3346
3316
  }
3347
3317
  getTemplate(metaData) {
3318
+ const arrayStyle = metaData.additional?.arrayStyle ?? this.tableConfig?.arrayDefaults?.arrayStyle;
3348
3319
  let tmp = metaData.fieldType === FieldType.Link && metaData.additional?.link?.useRouterLink
3349
3320
  ? this.templates[FieldType.Link + .5]
3350
3321
  :
3351
- metaData.fieldType === FieldType.Array && (metaData.additional?.arrayStyle === ArrayStyle.CommaDelimited || this.tableConfig?.arrayDefaults?.arrayStyle === ArrayStyle.CommaDelimited)
3322
+ metaData.fieldType === FieldType.Array && arrayStyle === ArrayStyle.CommaDelimited
3352
3323
  ? this.templates[FieldType.Array + .5]
3353
3324
  :
3354
3325
  this.templates[metaData.fieldType];
@@ -3381,23 +3352,20 @@ class HeaderMenuComponent {
3381
3352
  FieldType = FieldType;
3382
3353
  FilterType = FilterTypes;
3383
3354
  myFilterType;
3384
- myFilterValue;
3385
- filter;
3386
- metaData;
3387
- trigger;
3355
+ $metaData = input.required({ alias: 'metaData' });
3356
+ $trigger = viewChild(MatMenuTrigger);
3388
3357
  hideField(key) {
3389
3358
  this.tableState.hideColumn(key);
3390
3359
  }
3391
3360
  ngOnInit() {
3392
- this.filter = { key: this.metaData.key, fieldType: this.metaData.fieldType };
3393
3361
  this.resetFilterType();
3394
3362
  }
3395
3363
  resetFilterType() {
3396
- if (this.metaData.additional?.filterOptions?.filterableValues) {
3364
+ if (this.$metaData().additional?.filterOptions?.filterableValues) {
3397
3365
  this.myFilterType = FilterTypes.In;
3398
3366
  return;
3399
3367
  }
3400
- switch (this.metaData.fieldType) {
3368
+ switch (this.$metaData().fieldType) {
3401
3369
  case FieldType.String:
3402
3370
  case FieldType.Link:
3403
3371
  case FieldType.PhoneNumber:
@@ -3435,24 +3403,19 @@ class HeaderMenuComponent {
3435
3403
  onEnter(filter) {
3436
3404
  if (filter.filterValue != undefined && filter.filterType) {
3437
3405
  this.tableState.addFilter(filter);
3438
- this.trigger.closeMenu();
3406
+ this.$trigger().closeMenu();
3439
3407
  }
3440
3408
  }
3441
3409
  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 });
3410
+ 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
3411
  }
3444
3412
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: HeaderMenuComponent, decorators: [{
3445
3413
  type: Component,
3446
- args: [{ selector: 'tb-header-menu', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [
3414
+ args: [{ selector: 'tb-header-menu', changeDetection: ChangeDetectionStrategy.OnPush, imports: [
3447
3415
  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
- }] } });
3416
+ MatInputModule, MatTooltipModule, StopPropagationDirective, MatRadioModule, MatDatepickerModule
3417
+ ], 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"] }]
3418
+ }] });
3456
3419
 
3457
3420
  class ColumnTotalPipe {
3458
3421
  transform(data, metaData) {
@@ -3469,7 +3432,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImpor
3469
3432
  type: Pipe,
3470
3433
  args: [{
3471
3434
  name: 'columnTotal',
3472
- standalone: true
3473
3435
  }]
3474
3436
  }] });
3475
3437
 
@@ -3518,57 +3480,76 @@ const columnsStyles = (metaDatas, userDefinedWidths) => {
3518
3480
  };
3519
3481
 
3520
3482
  class ColumnBuilderComponent {
3483
+ FieldType = FieldType;
3521
3484
  transformCreator = inject(TransformCreator);
3522
3485
  table = inject(MatTable);
3523
3486
  state = inject(TableStore);
3524
3487
  templateService = inject(TableTemplateService);
3525
- injector = inject(Injector);
3526
- columnDef;
3527
- bodyTemplate;
3528
3488
  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();
3489
+ injector = inject(Injector);
3490
+ $columnDef = viewChild(MatColumnDef);
3491
+ $bodyTemplate = viewChild('body');
3492
+ $metaData = signal(undefined);
3493
+ $additional = computed(() => {
3494
+ const metaData = this.$metaData();
3495
+ if (!metaData)
3496
+ return;
3497
+ if (metaData.fieldType === FieldType.Link) {
3498
+ return this.state.$getLinkInfo(metaData)();
3540
3499
  }
3541
- else {
3542
- this._metaData = md;
3500
+ if (metaData.fieldType === FieldType.Array) {
3501
+ return metaData.additional?.limit || this.tableConfig?.arrayDefaults?.limit;
3543
3502
  }
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());
3503
+ return undefined;
3504
+ });
3505
+ setMetaData(md) {
3506
+ this.$metaData.set(md);
3507
+ }
3508
+ $customCell = signal(undefined);
3509
+ $data;
3510
+ $transform = computed(() => {
3511
+ const metaData = this.$metaData();
3512
+ if (!metaData)
3513
+ return;
3514
+ return this.transformCreator.createTransformer(metaData);
3515
+ });
3516
+ $innerTemplate = computed(() => {
3517
+ const metaData = this.$metaData();
3518
+ if (!metaData)
3519
+ return;
3520
+ return metaData.template || this.$customCell()?.$templateRef() || this.templateService.getTemplate(metaData);
3521
+ });
3522
+ $showFilters = computed(() => {
3523
+ const metaData = this.$metaData();
3524
+ if (!metaData)
3525
+ return;
3526
+ const settings = this.state.$tableSettings();
3527
+ return !(settings.hideColumnHeaderFilters || metaData.noFilter);
3528
+ });
3529
+ $outerTemplate = computed(() => {
3530
+ return this.$customCell()?.columnDef?.cell?.template ?? this.$bodyTemplate();
3531
+ });
3532
+ $classes = computed(() => {
3533
+ const metaData = this.$metaData();
3534
+ if (!metaData)
3535
+ return;
3536
+ if (metaData.fieldType === FieldType.Currency) {
3537
+ return ({
3538
+ ['negative-currency']: (element) => element[metaData.key] < 0,
3539
+ ...metaData.classes
3540
+ });
3541
+ }
3542
+ return metaData.classes;
3543
+ });
3544
+ $styles = computed(() => {
3545
+ const metaData = this.$metaData();
3546
+ if (!metaData)
3547
+ return;
3548
+ return columnStyles(metaData, this.state.$getUserDefinedWidth(metaData.key)(), this.state.$tableSettingsMinWidth());
3564
3549
  });
3565
- ngOnInit() {
3566
- this.initialSetUp();
3567
- }
3568
3550
  viewInited = false;
3569
3551
  ngAfterViewInit() {
3570
- this.furtherSetUp();
3571
- this.table.addColumnDef(this.columnDef);
3552
+ this.table.addColumnDef(this.$columnDef());
3572
3553
  this.onViewInit();
3573
3554
  this.viewInited = true;
3574
3555
  }
@@ -3580,44 +3561,23 @@ class ColumnBuilderComponent {
3580
3561
  }
3581
3562
  this.onViewInit = callback;
3582
3563
  };
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
3564
  cellClicked(element, key) {
3608
- if (this.metaData.click) {
3609
- this.metaData.click(element, key);
3565
+ const metaData = this.$metaData();
3566
+ if (metaData?.click) {
3567
+ metaData.click(element, key);
3610
3568
  }
3611
3569
  }
3612
3570
  getTooltip = (element) => {
3613
- if (typeof this.metaData.toolTip === 'string') {
3614
- return this.metaData.toolTip;
3571
+ const metaData = this.$metaData();
3572
+ if (!metaData?.toolTip)
3573
+ return;
3574
+ if (typeof metaData.toolTip === 'string') {
3575
+ return metaData.toolTip;
3615
3576
  }
3616
- return this.metaData.toolTip(element);
3577
+ return metaData.toolTip(element);
3617
3578
  };
3618
- additional;
3619
3579
  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: [
3580
+ 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
3581
  { provide: CDK_DROP_LIST, useExisting: CdkDropList },
3622
3582
  ], changeDetection: i0.ChangeDetectionStrategy.OnPush });
3623
3583
  }
@@ -3625,18 +3585,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImpor
3625
3585
  type: Component,
3626
3586
  args: [{ changeDetection: ChangeDetectionStrategy.OnPush, viewProviders: [
3627
3587
  { provide: CDK_DROP_LIST, useExisting: CdkDropList },
3628
- ], standalone: true, imports: [
3588
+ ], imports: [
3629
3589
  MatTableModule, NgTemplateOutlet, ResizeColumnDirective, FunctionPipe, StylerDirective,
3630
3590
  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
- }] } });
3591
+ MatTooltipModule, ColumnTotalPipe, CurrencyPipe, DecimalPipe
3592
+ ], 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"] }]
3593
+ }] });
3640
3594
 
3641
3595
  // 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
3596
  // 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 +3643,115 @@ class GenericTableComponent {
3689
3643
  dataStore = inject(DataStore);
3690
3644
  viewContainer = inject(ViewContainerRef);
3691
3645
  transformCreator = inject(TransformCreator);
3646
+ _injector = inject(Injector);
3692
3647
  smallFooter = 10;
3693
3648
  $headerRow = viewChild(MatHeaderRowDef);
3694
3649
  $footerRow = viewChild(MatFooterRowDef);
3695
3650
  $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));
3651
+ $dropList = viewChild(CdkDropList);
3652
+ selection$ = output({ alias: 'selection' });
3653
+ $displayDataLength = input.required({ alias: 'displayDataLength' });
3711
3654
  $data = input.required({ alias: 'data' });
3712
- data$ = toObservable(this.$data);
3713
3655
  $rows = input([], { alias: 'rows' });
3714
3656
  $columnInfos = input.required({ alias: 'columnInfos' });
3657
+ $dataSource = input.required({ alias: 'dataSource' });
3658
+ $keys = computed(() => {
3659
+ const displayed = this.state.$orderedVisibleColumns();
3660
+ const built = this.$columns();
3661
+ const keys = displayed.filter(d => !!built[d]);
3662
+ if (this.$hasSelectColumn()) {
3663
+ keys.unshift('select');
3664
+ }
3665
+ if (this.$hasIndexColumn()) {
3666
+ keys.unshift('index');
3667
+ }
3668
+ return keys;
3669
+ });
3670
+ keys$ = toObservable(this.$keys);
3671
+ $trackBy = input(undefined, { alias: 'trackBy' });
3672
+ $trackByFunction = computed(() => {
3673
+ const trackBy = this.$trackBy();
3674
+ if (!trackBy)
3675
+ return (index, item) => item[initIndexSymbol];
3676
+ return ((index, item) => item[trackBy]);
3677
+ });
3678
+ $hasFooterMeta = computed(() => this.state.$metaDataArray().some(md => !!md.additional?.footer));
3715
3679
  $hasCustomFooter = computed(() => this.$columnInfos()?.some(ci => !!ci.customCell?.columnDef?.footerCell));
3716
- dropList;
3717
3680
  $footerRowStyle = computed(() => {
3718
3681
  const hasData = !!this.$displayDataLength();
3719
3682
  const metaFooter = this.$hasFooterMeta();
3720
3683
  const customFooter = this.$hasCustomFooter();
3721
- const hasSelectionColumn = this.state.props().selectionColumn;
3684
+ const hasSelectionColumn = this.state.$props().selectionColumn;
3722
3685
  return customFooter || (hasData && (metaFooter || hasSelectionColumn)) ? 'regular-footer' : hasData ? 'no-footer' : 'small-footer';
3723
3686
  });
3724
3687
  $showFooterRow = computed(() => this.$footerRowStyle() !== 'no-footer');
3725
- _injector = inject(Injector);
3726
3688
  injector = Injector.create({
3727
3689
  providers: [
3728
3690
  { provide: MatTable, useFactory: () => this.$table() },
3729
- { provide: CdkDropList, useFactory: () => this.dropList },
3691
+ { provide: CdkDropList, useFactory: () => this.$dropList() },
3730
3692
  ],
3731
3693
  parent: this._injector
3732
3694
  });
3733
- $hasSelectColumn = computed(() => this.state.selectSignal(state => state.props.selectionColumn)());
3734
3695
  $hasIndexColumn = computed(() => this.state.selectSignal(state => state.props.indexColumn)());
3735
3696
  $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
- });
3697
+ $showHeader = computed(() => !this.state.$tableSettings().hideColumnHeader);
3698
+ $offset = this.dataStore.selectSignal(s => s.virtualScrollOffset);
3699
+ drop(event) {
3700
+ this.state.setUserDefinedOrder({ newOrder: event.currentIndex, oldOrder: event.previousIndex });
3701
+ }
3702
+ #buildColumnsEffect = effect(() => {
3703
+ const columnInfos = this.$columnInfos() || [];
3704
+ const table = this.$table();
3705
+ if (!table)
3706
+ return;
3707
+ untracked(() => {
3708
+ Object.entries(this.$columns()).forEach(([key, value]) => {
3709
+ const columnInfo = columnInfos.find(ci => ci.metaData.key === key);
3710
+ if (!columnInfo || columnInfo.customCell !== value.$customCell()) {
3711
+ delete this.$columns()[key];
3712
+ table?.removeColumnDef(value.$columnDef());
3713
+ }
3768
3714
  });
3715
+ columnInfos.forEach(ci => this.buildColumn(ci));
3769
3716
  });
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);
3717
+ });
3718
+ #buildRowsEffect = effect(() => {
3719
+ const table = this.$table();
3720
+ const rows = this.$rows();
3721
+ const keys = this.$keys();
3722
+ if (!table)
3723
+ return;
3724
+ untracked(() => {
3725
+ rows.forEach(row => {
3726
+ table.removeRowDef(row);
3727
+ row.columns = keys;
3728
+ table.addRowDef(row);
3779
3729
  });
3780
3730
  });
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
- });
3731
+ });
3732
+ #buildHeaderRowEffect = effect(() => {
3733
+ const headerRow = this.$headerRow();
3734
+ const showHeader = this.$showHeader();
3735
+ const table = this.$table();
3736
+ untracked(() => {
3737
+ if (headerRow && showHeader && table)
3738
+ table.addHeaderRowDef(headerRow);
3739
+ else if (headerRow && table)
3740
+ table.removeHeaderRowDef(headerRow);
3791
3741
  });
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
3742
  });
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
- }
3743
+ #buildFooterEffect = effect(() => {
3744
+ const footerRow = this.$footerRow();
3745
+ const showFooter = this.$showFooterRow();
3746
+ const table = this.$table();
3747
+ untracked(() => {
3748
+ if (footerRow && showFooter && table)
3749
+ table.addFooterRowDef(footerRow);
3750
+ else if (footerRow && table)
3751
+ table.removeFooterRowDef(footerRow);
3815
3752
  });
3816
- }
3817
- $usePaginator = computed(() => this.state.tableSettings().usePaginator);
3753
+ });
3754
+ $usePaginator = computed(() => this.state.$tableSettings().usePaginator);
3818
3755
  $useVirtualScroll = computed(() => this.state.$viewType().includes('virtual'));
3819
3756
  $offsetIndex = computed(() => {
3820
3757
  const virtualStart = this.dataStore.selectSignal(d => d.virtualEnds.start)();
@@ -3837,16 +3774,16 @@ class GenericTableComponent {
3837
3774
  buildColumn(column) {
3838
3775
  const alreadyBuiltColumn = this.$columns()[column.metaData.key];
3839
3776
  if (alreadyBuiltColumn) {
3840
- alreadyBuiltColumn.metaData = column.metaData;
3777
+ alreadyBuiltColumn.setMetaData(column.metaData);
3841
3778
  }
3842
3779
  else {
3843
3780
  const component = this.viewContainer.createComponent(ColumnBuilderComponent, {
3844
3781
  index: 0,
3845
3782
  injector: this.injector
3846
3783
  });
3847
- component.instance.customCell = column.customCell;
3848
- component.instance.metaData = column.metaData;
3849
- component.instance.data$ = this.data$;
3784
+ component.instance.$customCell.set(column.customCell);
3785
+ component.instance.setMetaData(column.metaData);
3786
+ component.instance.$data = this.$data;
3850
3787
  component.instance.whenViewInited(() => {
3851
3788
  this.$columns.update(columnsDict => ({
3852
3789
  ...columnsDict,
@@ -3855,14 +3792,34 @@ class GenericTableComponent {
3855
3792
  });
3856
3793
  }
3857
3794
  }
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
- }
3795
+ $hasSelectColumn = computed(() => this.state.selectSignal(state => state.props.selectionColumn)());
3796
+ $selection = computed(() => {
3797
+ const trackBy = this.$trackBy();
3798
+ if (trackBy) {
3799
+ return new SelectionModel(true, [], true, (a, b) => a[trackBy] === b[trackBy]);
3800
+ }
3801
+ return new SelectionModel(true, []);
3802
+ });
3803
+ selectionChange$ = toObservable(this.$selection).pipe(switchMap(s => s.changed));
3804
+ $selectionChange = toSignal(this.selectionChange$);
3805
+ onSelectionChangeEffect = effect(() => {
3806
+ const selectionChange = this.$selectionChange();
3807
+ if (!selectionChange)
3808
+ return;
3809
+ untracked(() => this.selection$.emit(selectionChange));
3810
+ });
3811
+ $isAllSelected = computed(() => {
3812
+ this.$selectionChange();
3813
+ const selected = this.$selection()?.selected;
3814
+ if (!selected)
3815
+ return false;
3816
+ return this.$selectableData()?.length === selected.length;
3817
+ });
3818
+ $masterToggleChecked = this.$isAllSelected;
3819
+ $masterToggleIndeterminate = computed(() => {
3820
+ this.$selectionChange();
3821
+ return !!this.$selection()?.selected.length && !this.$masterToggleChecked();
3822
+ });
3866
3823
  $selectableData = computed(() => {
3867
3824
  if (this.state.$viewType() === 'virtual paginator' || this.state.$viewType() === 'paginator') {
3868
3825
  const previousPageRecords = this.state.$currentPage() * this.state.$pageSize();
@@ -3873,33 +3830,42 @@ class GenericTableComponent {
3873
3830
  }
3874
3831
  return [];
3875
3832
  });
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
- }
3833
+ #onSelectableDataChangeEffect = effect(() => {
3834
+ const selectableData = this.$selectableData();
3835
+ untracked(() => {
3836
+ const selected = this.$selection()?.selected;
3837
+ if (!selected.length)
3838
+ return;
3839
+ const trackBy = this.$trackBy();
3840
+ const trackByFunc = trackBy ? (s) => selectableData.every(d => d[trackBy] !== s[trackBy]) : s => !selectableData.includes(s);
3841
+ const removed = selected.filter(trackByFunc);
3842
+ this.$selection().deselect(removed);
3843
+ });
3844
+ });
3882
3845
  /** Selects all rows if they are not all selected; otherwise clear selection. */
3883
3846
  masterToggle() {
3884
- if (this.isAllSelected()) {
3885
- this.selection.clear();
3847
+ if (this.$isAllSelected()) {
3848
+ this.$selection().clear();
3886
3849
  }
3887
3850
  else {
3888
- this.selection.select(...this.$selectableData());
3851
+ this.$selection().select(...this.$selectableData());
3889
3852
  }
3890
3853
  }
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;
3854
+ $tableWidth = linkedSignal({
3855
+ source: this.state.$getUserDefinedTableWidth,
3856
+ computation: (currentUserDefinedWidth, { source: previousUserDefinedWidth } = { value: null, source: 0 }) => {
3857
+ if (currentUserDefinedWidth) {
3858
+ return ({ width: `${currentUserDefinedWidth}px`, minWidth: 'initial' });
3859
+ }
3860
+ if (wasReset()) {
3861
+ return ({ width: 'initial' });
3862
+ }
3863
+ return {};
3864
+ function wasReset() {
3865
+ return (previousUserDefinedWidth ?? 0) >= 0 && currentUserDefinedWidth == null;
3866
+ }
3901
3867
  }
3902
- }));
3868
+ });
3903
3869
  getTransform = (key, val) => {
3904
3870
  if (val == undefined || val === 'null')
3905
3871
  return '';
@@ -3947,24 +3913,17 @@ class GenericTableComponent {
3947
3913
  return '0px';
3948
3914
  }
3949
3915
  });
3950
- $stickyFooter = computed(() => this.state.props().stickyFooter || this.state.$isVirtual());
3916
+ $stickyFooter = computed(() => this.state.$props().stickyFooter || this.state.$isVirtual());
3951
3917
  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 });
3918
+ 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
3919
  }
3954
3920
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: GenericTableComponent, decorators: [{
3955
3921
  type: Component,
3956
- args: [{ selector: 'tb-generic-table', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [
3922
+ args: [{ selector: 'tb-generic-table', changeDetection: ChangeDetectionStrategy.OnPush, imports: [
3957
3923
  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
- }] } });
3924
+ MatTooltipModule, FunctionPipe,
3925
+ ], 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"] }]
3926
+ }] });
3968
3927
 
3969
3928
  function downloadData(data, filename, mimeType) {
3970
3929
  const url = URL.createObjectURL(new Blob([data], { type: mimeType }));
@@ -4018,8 +3977,9 @@ class ExportToCsvService {
4018
3977
  val = prepend + val;
4019
3978
  break;
4020
3979
  case FieldType.Array:
4021
- const additional = meta.additional;
4022
- val = val.slice(0, additional.limit).join(additional.arrayStyle === ArrayStyle.NewLine ? '\n' : ', ');
3980
+ const style = meta.additional.arrayStyle ?? this.config.arrayDefaults?.arrayStyle;
3981
+ const limit = meta.additional.limit ?? this.config.arrayDefaults?.limit;
3982
+ val = val.slice(0, limit).join(style === ArrayStyle.NewLine ? '\n' : ', ');
4023
3983
  break;
4024
3984
  case FieldType.Expression:
4025
3985
  val = meta.transform(row);
@@ -4044,11 +4004,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImpor
4044
4004
  type: Injectable
4045
4005
  }] });
4046
4006
 
4047
- const ArrayDefaults = {
4048
- limit: 3,
4049
- arrayStyle: ArrayStyle.CommaDelimited
4050
- };
4051
-
4052
4007
  function createLinkCreatorDict(metaDatas) {
4053
4008
  return metaDatas.reduce((acc, md) => {
4054
4009
  if (md.fieldType === FieldType.Link) {
@@ -4251,42 +4206,50 @@ const defaultStorageState = {
4251
4206
  class GroupByListComponent {
4252
4207
  tableStore = inject(TableStore);
4253
4208
  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 });
4209
+ 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
4210
  }
4256
4211
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: GroupByListComponent, decorators: [{
4257
4212
  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"] }]
4213
+ args: [{ selector: 'group-by-list', changeDetection: ChangeDetectionStrategy.OnPush, imports: [
4214
+ MatChipsModule, MatIconModule, SpaceCasePipe
4215
+ ], 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
4216
  }] });
4262
4217
 
4263
4218
  class SortMenuComponentStore extends ComponentStore {
4264
4219
  tableState = inject(TableStore);
4220
+ setStoreStateEffect = effect(() => {
4221
+ const metaData = this.tableState.$metaData();
4222
+ if (!metaData)
4223
+ return;
4224
+ this.tableState.$selectSorted();
4225
+ untracked(() => this.setStateFromTableStore());
4226
+ });
4227
+ setStateFromTableStore = () => {
4228
+ const metaData = this.tableState.$metaData();
4229
+ const sorted = [...this.tableState.$selectSorted()].map(s => ({
4230
+ ...s,
4231
+ displayName: metaData[s.active]?.displayName
4232
+ }));
4233
+ const notSorted = this.tableState.$metaDataArray()
4234
+ .filter(md => md.fieldType !== FieldType.NotMapped && !md.noSort && !sorted.some(s => s.active === md.key))
4235
+ .map(meta => ({ active: meta.key, displayName: meta.displayName }));
4236
+ this.setState({ sorted, notSorted });
4237
+ };
4265
4238
  constructor() {
4266
4239
  super({ notSorted: [], sorted: [] });
4267
4240
  }
4268
- set = this.updater((state, data) => ({ ...data }));
4269
4241
  setSorted = this.updater((state, sorted) => ({ ...state, sorted }));
4270
4242
  setNotSorted = this.updater((state, notSorted) => ({ ...state, notSorted }));
4271
- sorted$ = this.select(state => state.sorted);
4272
- notSorted$ = this.select(state => state.notSorted);
4243
+ $sorted = this.selectSignal(state => state.sorted);
4244
+ $notSorted = this.selectSignal(state => state.notSorted);
4273
4245
  setDirection = this.updater((state, sort) => {
4274
4246
  const index = state.sorted.findIndex(s => s.active === sort.active);
4275
4247
  const sorted = [...state.sorted];
4276
4248
  sorted.splice(index, 1, sort);
4277
4249
  return ({ ...state, sorted });
4278
4250
  });
4279
- metaDataArr$ = toObservable(this.tableState.$metaDataArray);
4280
4251
  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 }))));
4252
+ this.setStateFromTableStore();
4290
4253
  };
4291
4254
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: SortMenuComponentStore, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
4292
4255
  static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: SortMenuComponentStore });
@@ -4294,38 +4257,31 @@ class SortMenuComponentStore extends ComponentStore {
4294
4257
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: SortMenuComponentStore, decorators: [{
4295
4258
  type: Injectable
4296
4259
  }], 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
4260
 
4300
4261
  class SortMenuComponent {
4262
+ SortDirection = SortDirection;
4301
4263
  tableState = inject(TableStore);
4302
4264
  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
- }
4265
+ $sorted = computed(() => [...this.store.$sorted()]);
4266
+ $notSorted = computed(() => [...this.store.$notSorted()]);
4267
+ $dirty = signal(false);
4311
4268
  reset() {
4312
- this.dirty$.next(false);
4313
- this.store.reset();
4314
- }
4315
- ngOnInit() {
4269
+ this.$dirty.set(false);
4316
4270
  this.store.reset();
4317
4271
  }
4318
4272
  dropIntoSorted(event) {
4319
- this.dirty$.next(true);
4273
+ this.$dirty.set(true);
4274
+ const sorted = [...event.container.data];
4320
4275
  if (event.previousContainer === event.container) {
4321
- moveItemInArray(event.container.data, event.previousIndex, event.currentIndex);
4322
- this.store.setSorted(event.container.data);
4276
+ moveItemInArray(sorted, event.previousIndex, event.currentIndex);
4277
+ this.store.setSorted(sorted);
4323
4278
  }
4324
4279
  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);
4280
+ const notSorted = [...event.previousContainer.data];
4281
+ transferArrayItem(notSorted, sorted, event.previousIndex, event.currentIndex);
4282
+ sorted[event.currentIndex] = { ...sorted[event.currentIndex], direction: SortDirection.asc };
4283
+ this.store.setSorted(sorted);
4284
+ this.store.setNotSorted(notSorted);
4329
4285
  }
4330
4286
  }
4331
4287
  dropIntoNotSorted(event) {
@@ -4333,37 +4289,38 @@ class SortMenuComponent {
4333
4289
  return;
4334
4290
  }
4335
4291
  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
- })));
4292
+ this.$dirty.set(true);
4293
+ const sorted = [...event.previousContainer.data];
4294
+ const notSorted = [...event.container.data];
4295
+ transferArrayItem(sorted, notSorted, event.previousIndex, event.currentIndex);
4296
+ notSorted[event.currentIndex] = { ...notSorted[event.currentIndex] };
4297
+ this.store.setNotSorted(notSorted);
4298
+ this.store.setSorted(sorted);
4299
+ }
4300
+ }
4301
+ apply = () => {
4302
+ this.$dirty.set(false);
4303
+ this.tableState.setAllSort(this.store.$sorted());
4304
+ };
4347
4305
  setDirection(sort) {
4348
- this.dirty$.next(true);
4306
+ this.$dirty.set(true);
4349
4307
  this.store.setDirection(sort);
4350
4308
  }
4351
4309
  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 });
4310
+ 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
4311
  }
4354
4312
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: SortMenuComponent, decorators: [{
4355
4313
  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: () => [] });
4314
+ args: [{ selector: 'tb-sort-menu', providers: [SortMenuComponentStore], changeDetection: ChangeDetectionStrategy.OnPush, imports: [
4315
+ MatTooltipModule, MatButtonModule, MatIconModule, MatMenuModule, StopPropagationDirective, DragDropModule,
4316
+ SpaceCasePipe
4317
+ ], 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"] }]
4318
+ }] });
4361
4319
 
4362
4320
  class PaginatorComponent {
4363
4321
  state = inject(TableStore);
4364
4322
  data = inject(DataStore);
4365
4323
  $paginator = viewChild(MatPaginator);
4366
- $tableElRef = input.required({ alias: 'tableElRef' });
4367
4324
  $dataLength = this.data.selectSignal(d => d.dataLen);
4368
4325
  pageEvent$ = toObservable(this.$paginator).pipe(notNull(), switchMap(p => p.page));
4369
4326
  $pageEvent = toSignal(this.pageEvent$);
@@ -4384,7 +4341,9 @@ class PaginatorComponent {
4384
4341
  });
4385
4342
  onPageIndexEffect = effect(() => {
4386
4343
  const index = this.$pageIndexChangeEvent();
4387
- untracked(() => this.state.updateState({ currentPage: index }));
4344
+ if (index === undefined)
4345
+ return;
4346
+ untracked(() => this.state.setCurrentPage(index));
4388
4347
  });
4389
4348
  onPageSizeEffect = effect(() => {
4390
4349
  const size = this.$pageSizeChangeEvent();
@@ -4416,7 +4375,7 @@ class PaginatorComponent {
4416
4375
  this.updatePaginator();
4417
4376
  }
4418
4377
  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: `
4378
+ 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
4379
  <div class="paginator-row">
4421
4380
  @if($currentPageData(); as pageData){
4422
4381
  <div [class]="{ 'hide' : ! $collapseFooter(), 'page-amounts':true}">
@@ -4432,7 +4391,7 @@ class PaginatorComponent {
4432
4391
  }
4433
4392
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: PaginatorComponent, decorators: [{
4434
4393
  type: Component,
4435
- args: [{ selector: 'tb-paginator', standalone: true, imports: [MatPaginatorModule, MatButtonModule], template: `
4394
+ args: [{ selector: 'tb-paginator', imports: [MatPaginatorModule, MatButtonModule], template: `
4436
4395
  <div class="paginator-row">
4437
4396
  @if($currentPageData(); as pageData){
4438
4397
  <div [class]="{ 'hide' : ! $collapseFooter(), 'page-amounts':true}">
@@ -4584,14 +4543,14 @@ class VirtualScrollContainer {
4584
4543
  }
4585
4544
  setSize(el) {
4586
4545
  const vsViewport = el.nativeElement;
4587
- const virtualScrollOptions = this.state.tableSettings().useVirtualScroll;
4546
+ const virtualScrollOptions = this.state.$tableSettings().useVirtualScroll;
4588
4547
  const rowHeight = this.computedRowHeight();
4589
4548
  let amountOfVisibleItems = virtualScrollOptions?.amountOfVisibleItems || this.defaultOptions.amountOfVisibleItems;
4590
4549
  virtualScrollOptions?.amountOfVisibleItems || this.defaultOptions.amountOfVisibleItems;
4591
4550
  amountOfVisibleItems = Math.min(amountOfVisibleItems, this.$dataLength());
4592
4551
  let height = (rowHeight * amountOfVisibleItems);
4593
4552
  height += parseFloat(this.genericTable()?.$footerHeight()?.replace('px', '') || '0');
4594
- if (!this.state.tableSettings().hideHeader) {
4553
+ if (!this.state.$tableSettings().hideHeader) {
4595
4554
  const headerHeight = this.computedHeaderHeight();
4596
4555
  height += headerHeight;
4597
4556
  }
@@ -4608,13 +4567,13 @@ class VirtualScrollContainer {
4608
4567
  }
4609
4568
  };
4610
4569
  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;
4570
+ const virtualScrollOptions = this.state.$tableSettings().useVirtualScroll;
4571
+ const rowHeight = virtualScrollOptions?.rowHeight || (typeof this.state.$tableSettings().rowHeight === 'number' && this.state.$tableSettings().rowHeight) || this.defaultOptions.rowHeight;
4613
4572
  return rowHeight;
4614
4573
  }
4615
4574
  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;
4575
+ const virtualScrollOptions = this.state.$tableSettings().useVirtualScroll;
4576
+ const headerHeight = virtualScrollOptions?.headerHeight || (typeof this.state.$tableSettings().headerHeight === 'number' && this.state.$tableSettings().headerHeight) || this.defaultOptions.headerHeight;
4618
4577
  return headerHeight;
4619
4578
  }
4620
4579
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: VirtualScrollContainer, deps: [], target: i0.ɵɵFactoryTarget.Component });
@@ -4640,7 +4599,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImpor
4640
4599
  </cdk-virtual-scroll-viewport>
4641
4600
  `,
4642
4601
  changeDetection: ChangeDetectionStrategy.OnPush,
4643
- standalone: true,
4644
4602
  imports: [ScrollingModule],
4645
4603
  viewProviders: [
4646
4604
  {
@@ -4691,19 +4649,18 @@ class ProfilesMenuComponent {
4691
4649
  return a;
4692
4650
  };
4693
4651
  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"] }] });
4652
+ 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
4653
  }
4696
4654
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: ProfilesMenuComponent, decorators: [{
4697
4655
  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"] }]
4656
+ args: [{ selector: 'tb-profiles-menu', imports: [MatIcon, MatTooltip, MatIconButton, MatMenuModule, MatButton, MatInput,
4657
+ MatCheckbox, StopPropagationDirective, MatInputModule, FormsModule
4658
+ ], 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
4659
  }] });
4702
4660
 
4703
4661
  const containerImports = [
4704
- AsyncPipe, NgTemplateOutlet,
4662
+ NgTemplateOutlet,
4705
4663
  PaginatorComponent,
4706
- LetDirective,
4707
4664
  MultiSortDirective, GroupByListComponent, FilterChipsComponent, GenFilterDisplayerComponent, GenColDisplayerComponent,
4708
4665
  SortMenuComponent, GenericTableComponent, StopPropagationDirective, ProfilesMenuComponent,
4709
4666
  MatButtonModule, MatMenuModule, MatIconModule, MatTooltipModule, VirtualScrollContainer
@@ -4712,7 +4669,7 @@ const containerImports = [
4712
4669
  //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
4670
  // 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
4671
  const updateFilterInfoState = (previousState, filterInfos) => {
4715
- filterInfos = filterNonActiveFilters(filterInfos);
4672
+ filterInfos = filterNonActiveOrNotReadyFilters(filterInfos);
4716
4673
  const currentState = {
4717
4674
  allFilters: filterInfos,
4718
4675
  onlyAddedFilters: filterInfoOnlyAdded(previousState.allFilters, filterInfos)
@@ -4720,11 +4677,18 @@ const updateFilterInfoState = (previousState, filterInfos) => {
4720
4677
  return currentState;
4721
4678
  };
4722
4679
  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));
4680
+ const mappedAddOnly = s.onlyAddedFilters
4681
+ ?
4682
+ Object.entries(s.onlyAddedFilters).filter(([, v]) => needsFilterCreation(v)).reduce((obj, [key, value]) => {
4683
+ obj[key] = createFilterFunc(value);
4684
+ return obj;
4685
+ }, {})
4686
+ : {};
4687
+ const mappedAll = Object.entries(s.allFilters).filter(([, v]) => needsFilterCreation(v))
4688
+ .filter(([, v]) => !isCustomFilter(v) || !!v.predicate)
4689
+ .map(([key, value]) => {
4690
+ return mappedAddOnly[key] || createFilterFunc(value);
4691
+ });
4728
4692
  return ({
4729
4693
  allFilters: mappedAll,
4730
4694
  onlyAddedFilters: s.onlyAddedFilters ? Object.values(mappedAddOnly) : undefined
@@ -4750,8 +4714,8 @@ const updateFilterState = (filterInfos, predicates) => {
4750
4714
  }
4751
4715
  return filtersState;
4752
4716
  };
4753
- const filterNonActiveFilters = (filtersDict) => Object.entries(filtersDict).reduce((obj, [key, value]) => {
4754
- if (value.active !== false) {
4717
+ const filterNonActiveOrNotReadyFilters = (filtersDict) => Object.entries(filtersDict).reduce((obj, [key, value]) => {
4718
+ if (value.active !== false && (!isCustomFilter(value) || !!value.predicate)) {
4755
4719
  obj[key] = value;
4756
4720
  }
4757
4721
  ;
@@ -4789,6 +4753,16 @@ function filtersInfosUpdated(previousFilterInfos, currentFilterInfos) {
4789
4753
  return currentFilterInfos[key].filterType === val.filterType && currentFilterInfos[key].filterValue === val.filterValue;
4790
4754
  });
4791
4755
  }
4756
+ function patchDirectiveFromState(directive, stateFilter) {
4757
+ if (isFilterInfo(stateFilter)) {
4758
+ const filterDirective = directive;
4759
+ filterDirective.setFilterValue(stateFilter.filterValue);
4760
+ filterDirective.update();
4761
+ }
4762
+ if (isCustomFilter(stateFilter)) {
4763
+ directive.active = stateFilter.active ?? false;
4764
+ }
4765
+ }
4792
4766
 
4793
4767
  function getGroupedData(data, groupByKeys) {
4794
4768
  return tbGroupBy(data, groupByKeys);
@@ -5005,24 +4979,26 @@ const createCleaners = (metadatas) => {
5005
4979
  }, []);
5006
4980
  };
5007
4981
 
5008
- const defaultProps = {
5009
- indexColumn: false,
5010
- selectionColumn: false,
5011
- isSticky: true,
5012
- stickyFooter: false,
5013
- groupHeaderHeight: undefined,
5014
- };
5015
-
5016
4982
  class TableBuilderDataSource extends MatTableDataSource {
5017
- dataSrc;
5018
4983
  subscription;
5019
- constructor(dataSrc, state, data) {
4984
+ #$dataSrc = signal([]);
4985
+ $dataSize = signal({ start: 0, end: 0 }, {
4986
+ equal: (a, b) => a.start === b.start && a.end === b.end
4987
+ });
4988
+ _ = effect(() => {
4989
+ const data = this.#$dataSrc();
4990
+ const dataSize = this.$dataSize();
4991
+ untracked(() => this.data = data.slice(dataSize.start, dataSize.end));
4992
+ });
4993
+ setData(data) {
4994
+ this.#$dataSrc.set(data);
4995
+ }
4996
+ constructor(state, data) {
5020
4997
  super([]);
5021
- this.dataSrc = dataSrc;
5022
4998
  const $currentPage = state.$currentPage;
5023
4999
  const $pageSize = state.$pageSize;
5024
5000
  const $virtualEnds = data.selectSignal(d => d.virtualEnds);
5025
- const $dataLength = computed(() => dataSrc().length);
5001
+ const $dataLength = computed(() => this.#$dataSrc().length);
5026
5002
  const $dataSize = computed(() => {
5027
5003
  const viewType = state.$viewType();
5028
5004
  const dataLength = $dataLength();
@@ -5041,11 +5017,7 @@ class TableBuilderDataSource extends MatTableDataSource {
5041
5017
  }
5042
5018
  return ({ start: virtualEnds.start, end: virtualEnds.end });
5043
5019
  });
5044
- const $dataToShow = computed(() => dataSrc().slice($dataSize().start, $dataSize().end));
5045
- effect(() => {
5046
- const dataToShow = $dataToShow();
5047
- untracked(() => this.data = dataToShow);
5048
- });
5020
+ this.$dataSize = $dataSize;
5049
5021
  }
5050
5022
  connect() {
5051
5023
  return super.connect();
@@ -5059,9 +5031,26 @@ class TableBuilderDataSource extends MatTableDataSource {
5059
5031
  }
5060
5032
  }
5061
5033
 
5034
+ function mergeCustomCellMetaData(metaData1, metaData2) {
5035
+ if (!metaData2) {
5036
+ metaData1.noExport = true;
5037
+ return metaData1;
5038
+ }
5039
+ if (!metaData1.displayName)
5040
+ metaData1.displayName = metaData2.displayName;
5041
+ if (!metaData1.preSort)
5042
+ metaData1.preSort = metaData2.preSort;
5043
+ if (!metaData1.order)
5044
+ metaData1.order = metaData2.order;
5045
+ if (!metaData1.width)
5046
+ metaData1.width = metaData2.width;
5047
+ if (metaData2.fieldType)
5048
+ metaData1.fieldType = metaData2.fieldType;
5049
+ metaData1.noExport = metaData2.noExport;
5050
+ return metaData1;
5051
+ }
5052
+
5062
5053
  class TableContainerComponent {
5063
- props = { ...defaultProps };
5064
- data = new BehaviorSubject([]);
5065
5054
  state = inject(TableStore);
5066
5055
  dataStore = inject(DataStore);
5067
5056
  config = inject(TableBuilderConfigToken);
@@ -5069,108 +5058,152 @@ class TableContainerComponent {
5069
5058
  wrapper = inject(TableWrapperDirective, { optional: true });
5070
5059
  stateService = inject(TableBuilderStateStore);
5071
5060
  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;
5061
+ dataSource = new TableBuilderDataSource(this.state, this.dataStore);
5062
+ $filterDirectives = contentChildren(TableFilterDirective, { descendants: true });
5063
+ $customFilterDirectives = contentChildren(TableCustomFilterDirective, { descendants: true });
5064
+ $paginatorComponent = viewChild(PaginatorComponent);
5065
+ $genericTable = viewChild(GenericTableComponent);
5112
5066
  _$customRows = contentChildren((MatRowDef));
5113
5067
  $customRows = computed(() => [...this._$customRows()]);
5114
5068
  $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;
5069
+ $tableBuilder = input.required({ alias: 'tableBuilder' });
5120
5070
  $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());
5071
+ $trackBy = input(undefined, { alias: 'trackBy' });
5072
+ $inputFilters = model([], { alias: 'inputFilters' });
5073
+ predicateInputFilters$ = toObservable(computed(() => this.$inputFilters().filter(isFunction$1)));
5074
+ $filterInfoInputs = computed(() => this.$inputFilters().filter(i => !isFunction$1(i)));
5075
+ $indexColumn = input(false, { alias: 'indexColumn' });
5076
+ $selectionColumn = input(false, { alias: 'selectionColumn' });
5077
+ $isSticky = input(true, { alias: 'isSticky' });
5078
+ $stickyFooter = input(false, { alias: 'stickyFooter' });
5079
+ $groupHeaderTemplate = input(undefined, { alias: 'groupHeaderTemplate' });
5080
+ $groupHeaderHeight = input(undefined, { alias: 'groupHeaderHeight' });
5081
+ $pageSize = input(undefined, { alias: 'pageSize' });
5082
+ $props = computed(() => {
5083
+ const indexColumn = this.$indexColumn();
5084
+ const selectionColumn = this.$selectionColumn();
5085
+ const isSticky = this.$isSticky();
5086
+ const stickyFooter = this.$stickyFooter();
5087
+ const groupHeaderTemplate = this.$groupHeaderTemplate();
5088
+ const groupHeaderHeight = this.$groupHeaderHeight();
5089
+ return ({ indexColumn, selectionColumn, isSticky, stickyFooter, groupHeaderTemplate, groupHeaderHeight });
5090
+ });
5091
+ selection$ = output({ alias: 'selection' });
5092
+ onStateReset$ = output({ alias: 'onStateReset' });
5093
+ onSaveState$ = output({ alias: 'onSaveState' });
5094
+ _state$ = toObservable(this.state.getSavableStateSignal);
5095
+ state$ = outputFromObservable(this._state$, { alias: 'state' });
5096
+ data$ = new BehaviorSubject([]);
5097
+ _data$ = outputFromObservable(this.data$, { alias: 'data' });
5098
+ $data = toSignal(this.data$, { initialValue: [] });
5149
5099
  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
- }
5100
+ this.$genericTable()?.$selection().clear(true);
5161
5101
  }
5162
5102
  firstPage() {
5163
- this.paginatorComponent?.$paginator()?.firstPage();
5103
+ this.$paginatorComponent()?.$paginator()?.firstPage();
5164
5104
  }
5165
5105
  lastPage() {
5166
- this.paginatorComponent?.$paginator()?.lastPage();
5106
+ this.$paginatorComponent()?.$paginator()?.lastPage();
5167
5107
  }
5108
+ expandAllGroups = () => {
5109
+ const groupHeaders = getAllGroupHeaderNames(this.$displayData());
5110
+ this.state.expandAllOfGroup({ groupHeadersByKey: groupHeaders });
5111
+ };
5112
+ collapseAllGroups = () => this.state.collapseAll();
5113
+ $myColumns = computed(() => {
5114
+ return this.state.$metaDataArray().map(metaData => ({ metaData, customCell: this.$customCells().find(cc => cc.$customCell() === metaData.key) }));
5115
+ });
5116
+ $useVirtual = this.state.$isVirtual;
5117
+ $collapsedFooter = this.state.$footerCollapsed;
5118
+ $collapsedHeader = this.state.$headerCollapsed;
5119
+ $displayDataLength = computed(() => this.$displayData().length);
5168
5120
  resetState() {
5169
- this.customFilterDirectives().forEach(cf => cf.reset());
5170
- this.filterDirectives().forEach(cf => cf.reset());
5121
+ this.$customFilterDirectives().forEach(cf => cf.reset());
5122
+ this.$filterDirectives().forEach(cf => cf.reset());
5171
5123
  this.state.resetState();
5172
- this.onStateReset.next(null);
5124
+ this.onStateReset$.emit(null);
5173
5125
  }
5126
+ exportToCsv() {
5127
+ this.exportToCsvService.exportToCsv(this.$data());
5128
+ }
5129
+ #initializeTableSettingsFromTableBuilderAndPersistedStateEffect = effect(() => {
5130
+ const metaLoaded = this.$isInitializationState(InitializationState.MetaDataLoaded)();
5131
+ if (!metaLoaded)
5132
+ return;
5133
+ const persistedState = this.$persistedState();
5134
+ untracked(() => {
5135
+ this.state.setTableSettings(this.$tableBuilder().settings$);
5136
+ if (persistedState) {
5137
+ persistedState.persistedTableSettings = new PersistedTableSettings(persistedState.persistedTableSettings);
5138
+ this.state.updateStateFromPersistedState(persistedState);
5139
+ }
5140
+ this.state.setInitializationState(InitializationState.Ready);
5141
+ });
5142
+ });
5143
+ #setPageSizeFromInputEffect = effect(() => {
5144
+ const pageSize = this.$pageSize();
5145
+ if (pageSize) {
5146
+ untracked(() => this.state.setPageSize(pageSize));
5147
+ }
5148
+ });
5149
+ #patchedFilters = [];
5150
+ #patchSavableFilterDirectivesFromPersistedStateEffect = effect(() => {
5151
+ const loaded = this.$isInitializationState(InitializationState.LoadedFromStore)();
5152
+ const filterDirectives = this.$allFilterDirectives();
5153
+ if (!loaded || !filterDirectives.length)
5154
+ return;
5155
+ const stateFilters = this.state.$filters();
5156
+ untracked(() => {
5157
+ filterDirectives.filter(f => f.savable && !this.#patchedFilters.includes(f.filterId)).forEach(f => {
5158
+ this.#patchedFilters.push(f.filterId);
5159
+ const filter = stateFilters[f.filterId];
5160
+ patchDirectiveFromState(f, filter);
5161
+ this.state.addFilter(f.filter$);
5162
+ });
5163
+ });
5164
+ });
5165
+ #patchSavableFilterInputsFromPersistedStateEffect = effect(() => {
5166
+ const loaded = this.$isInitializationState(InitializationState.LoadedFromStore)();
5167
+ const inputFilters = this.$filterInfoInputs();
5168
+ if (!loaded || !inputFilters.length)
5169
+ return;
5170
+ untracked(() => {
5171
+ const stateFilters = this.state.$filters();
5172
+ inputFilters.filter(f => f.filterId).forEach(f => {
5173
+ const patched = this.#patchedFilters.includes(f.filterId);
5174
+ const stateFilter = stateFilters[f.filterId];
5175
+ if (patched || !stateFilter) {
5176
+ this.state.addFilter(f);
5177
+ }
5178
+ else if (isCustomFilter(f)) {
5179
+ stateFilter.predicate = f.predicate;
5180
+ this.state.addFilter(stateFilter);
5181
+ }
5182
+ this.#patchedFilters.push(f.filterId);
5183
+ });
5184
+ });
5185
+ });
5186
+ #addPropsToStoreFromInputsEffect = effect(() => {
5187
+ const props = this.$props();
5188
+ untracked(() => this.state.setProps(props));
5189
+ });
5190
+ #addMetaDataToStoreEffect = effect(() => {
5191
+ const allMetaDatas = this.$allMetaDatas();
5192
+ if (!allMetaDatas)
5193
+ return;
5194
+ untracked(() => {
5195
+ this.state.setMetaData(allMetaDatas);
5196
+ this.state.setLinkMaps(createLinkCreatorDict(allMetaDatas));
5197
+ });
5198
+ });
5199
+ #initializeDataEffect = effect(() => {
5200
+ const tableBuilder = this.$tableBuilder();
5201
+ if (!tableBuilder)
5202
+ return;
5203
+ untracked(() => {
5204
+ this.initializeData();
5205
+ });
5206
+ });
5174
5207
  $persistedState = computed(() => {
5175
5208
  const tableId = this.$tableId();
5176
5209
  if (tableId) {
@@ -5178,27 +5211,35 @@ class TableContainerComponent {
5178
5211
  }
5179
5212
  return undefined;
5180
5213
  });
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
- });
5214
+ $allFilterDirectives = computed(() => {
5215
+ if (this.wrapper) {
5216
+ return [...this.$filterDirectives(), ...this.$customFilterDirectives(), ...this.wrapper.$registrations()];
5217
+ }
5218
+ return [...this.$filterDirectives(), ...this.$customFilterDirectives()];
5219
+ });
5220
+ allNotSavableFilterDirectivesFilters$ = toObservable(this.$allFilterDirectives).pipe(filterArray(d => !d.savable), switchMap(d => {
5221
+ const a = d.map(d => d.filter$);
5222
+ return combineLatest(a).pipe(startWith([]));
5223
+ }), map(createFilterFuncs));
5224
+ tableBuilderMetaData$ = toObservable(this.$tableBuilder).pipe(notNull(), switchMap(tb => tb.metaData$));
5225
+ $tableBuilderMetaData = toSignal(this.tableBuilderMetaData$);
5226
+ $allMetaDatas = computed(() => {
5227
+ const tableBuilderMetaData = this.$tableBuilderMetaData();
5228
+ if (!tableBuilderMetaData)
5229
+ return;
5230
+ const customCellMetaDatas = this.$customCells().map(cc => cc.$metaData()).filter(d => !!d);
5231
+ const mappedCustomCellMetaDatas = customCellMetaDatas.map(md => mergeCustomCellMetaData(md, tableBuilderMetaData.find(item => item.key === md.key)));
5232
+ return [...tableBuilderMetaData, ...mappedCustomCellMetaDatas];
5198
5233
  });
5199
- customFilters$ = new BehaviorSubject([]);
5234
+ $displayData = signal([]);
5235
+ ngOnDestroy() {
5236
+ const tableId = this.$tableId();
5237
+ if (tableId) {
5238
+ this.stateService.saveTableStateToLocal({ tableId, tableState: this.state.getSavableStateSignal() });
5239
+ }
5240
+ }
5200
5241
  initializeData() {
5201
- const predicateFilters$ = combineLatest([this.inputFilters?.pipe(startWith([])) ?? of([]), this.customFilters$])
5242
+ const predicateFilters$ = combineLatest([this.predicateInputFilters$.pipe(), this.allNotSavableFilterDirectivesFilters$])
5202
5243
  .pipe(map(([a, b]) => [...a, ...b]));
5203
5244
  const filters$ = combineLatest([
5204
5245
  this.state.filters$.pipe(scan$1(updateFilterInfoState, { allFilters: {} }), timestamp$1()),
@@ -5206,144 +5247,25 @@ class TableContainerComponent {
5206
5247
  ])
5207
5248
  .pipe(map(([filterInfo, pred]) => updateFilterState(filterInfo, pred)));
5208
5249
  const sortsState$ = this.state.sort$.pipe(scan$1(updateSortState, initialSortState));
5209
- const sortedAndFilteredData$ = sortAndFilterData(this.tableBuilder.getData$(), sortsState$, filters$);
5250
+ const sortedAndFilteredData$ = sortAndFilterData(this.$tableBuilder().getData$(), sortsState$, filters$);
5210
5251
  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
5252
  this.state.on(sortedAndFilteredData$, (data) => {
5212
- this.data.next(data);
5253
+ this.data$.next(data);
5213
5254
  this.dataStore.patchState({ dataLen: data.length });
5214
5255
  });
5215
5256
  this.state.on(flatGrouped$, (data) => {
5216
- this.displayData.next(data);
5257
+ this.dataSource.setData(data);
5258
+ this.$displayData.set(data);
5217
5259
  });
5218
5260
  }
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
- });
5239
- });
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
- }
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;
5261
+ $isInitializationState = (state) => computed(() => this.state.selectSignal(s => s.initializationState >= state)());
5300
5262
  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 });
5263
+ 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=\"header-wrapper\">\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 @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: [".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
5264
  }
5303
5265
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: TableContainerComponent, decorators: [{
5304
5266
  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
- }] } });
5267
+ 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=\"header-wrapper\">\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 @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: [".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"] }]
5268
+ }] });
5347
5269
 
5348
5270
  class TableBuilderModule {
5349
5271
  static forRoot(config) {
@@ -5480,14 +5402,14 @@ class MatTableObservableDataSource extends MatTableDataSource {
5480
5402
  class TableBuilder {
5481
5403
  metaData$;
5482
5404
  data$;
5483
- settings;
5405
+ settings$;
5484
5406
  constructor(data, metaData, settings = new GeneralTableSettings()) {
5485
- this.settings = this.coerceSettingsToObservable(settings)
5407
+ this.settings$ = this.coerceSettingsToObservable(settings)
5486
5408
  .pipe(defaultShareReplay());
5487
- this.data$ = this.coerceToObservable(data, this.settings)
5409
+ this.data$ = this.coerceToObservable(data, this.settings$)
5488
5410
  .pipe(notNull(), defaultShareReplay());
5489
5411
  this.metaData$ = metaData ?
5490
- this.coerceToObservable(metaData, this.settings).pipe(defaultShareReplay())
5412
+ this.coerceToObservable(metaData, this.settings$).pipe(defaultShareReplay())
5491
5413
  :
5492
5414
  this.data$.pipe(first$1(), map(d => this.createMetaData(d[0])), defaultShareReplay());
5493
5415
  }
@@ -5618,7 +5540,7 @@ class ActionStateSpinnerComponent {
5618
5540
  }
5619
5541
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: ActionStateSpinnerComponent, decorators: [{
5620
5542
  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"] }]
5543
+ 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
5544
  }], propDecorators: { status$: [{
5623
5545
  type: Input
5624
5546
  }] } });
@@ -5736,17 +5658,16 @@ const setEnvironmentInjector = (ei) => {
5736
5658
  };
5737
5659
  function provideActionableSelector() {
5738
5660
  return makeEnvironmentProviders([
5739
- { provide: APP_INITIALIZER, useFactory: setUpStoreFactory, multi: true, deps: [Store, EnvironmentInjector] },
5661
+ provideAppInitializer(setUpStoreFactory)
5740
5662
  ]);
5741
5663
  }
5742
- function setUpStoreFactory(store, env) {
5664
+ const setUpStoreFactory = () => {
5665
+ const store = inject(Store);
5666
+ const env = inject(EnvironmentInjector);
5743
5667
  _cache ??= new AppStoreCache();
5744
- return () => new Promise((resolve, reject) => {
5745
- setStore(store);
5746
- setEnvironmentInjector(env);
5747
- resolve(null);
5748
- });
5749
- }
5668
+ setStore(store);
5669
+ setEnvironmentInjector(env);
5670
+ };
5750
5671
 
5751
5672
  /*
5752
5673
  * Public API Surface of http-request-state
@@ -5756,5 +5677,5 @@ function setUpStoreFactory(store, env) {
5756
5677
  * Generated bundle index. Do not edit.
5757
5678
  */
5758
5679
 
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 };
5680
+ 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, 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
5681
  //# sourceMappingURL=one-paragon-angular-utilities.mjs.map