@one-paragon/angular-utilities 2.0.15 → 2.0.16

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,11 +1,10 @@
1
1
  import * as i0 from '@angular/core';
2
- import { Directive, Input, inject, Injector, TemplateRef, ViewContainerRef, NgModule, assertInInjectionContext, DestroyRef, computed, isSignal, Injectable, Pipe, input, signal, Renderer2, ElementRef, booleanAttribute, InjectionToken, makeEnvironmentProviders, Component, ChangeDetectionStrategy, HostListener, EventEmitter, untracked, Output, effect, ContentChildren, ChangeDetectorRef, output, viewChild, EnvironmentInjector, createComponent, 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, debounceTime, scan as scan$1, timestamp as timestamp$1, first as first$1 } from 'rxjs/operators';
2
+ import { Directive, Input, inject, Injector, TemplateRef, ViewContainerRef, NgModule, assertInInjectionContext, DestroyRef, computed, isSignal, Injectable, input, signal, Renderer2, ElementRef, booleanAttribute, Pipe, InjectionToken, makeEnvironmentProviders, Component, ChangeDetectionStrategy, HostListener, EventEmitter, untracked, Output, effect, ContentChildren, ChangeDetectorRef, output, viewChild, EnvironmentInjector, createComponent, linkedSignal, contentChild, forwardRef, contentChildren, runInInjectionContext, provideAppInitializer } from '@angular/core';
3
+ import { shareReplay, switchAll, map, filter, tap, catchError, startWith, switchMap, mergeMap, concatMap as concatMap$1, takeUntil, distinctUntilChanged, debounceTime } 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, takeUntil as takeUntil$1, tap as tap$1, switchMap as switchMap$1, scan, timestamp, animationFrameScheduler, debounceTime as debounceTime$1, BehaviorSubject } 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, timestamp } from 'rxjs';
6
6
  import { ComponentStore } from '@ngrx/component-store';
7
7
  import { toObservable, toSignal, outputFromObservable } from '@angular/core/rxjs-interop';
8
- import { DatePipe, CurrencyPipe, KeyValuePipe, NgTemplateOutlet, DecimalPipe, CommonModule, AsyncPipe } from '@angular/common';
9
8
  import * as i3$2 from '@angular/material/sort';
10
9
  import { MatSort, MatSortModule } from '@angular/material/sort';
11
10
  import { merge as merge$1, get, sumBy, difference, intersection, groupBy, orderBy, set, isFunction as isFunction$1 } from 'lodash';
@@ -20,11 +19,10 @@ import { MatCheckbox, MatCheckboxModule } from '@angular/material/checkbox';
20
19
  import * as i3 from '@angular/forms';
21
20
  import { NgControl, FormsModule, ControlContainer, NgForm, NG_VALUE_ACCESSOR } from '@angular/forms';
22
21
  import * as i9 from '@angular/material/core';
23
- import { MatOption, MatNativeDateModule } from '@angular/material/core';
22
+ import { MatOption } from '@angular/material/core';
23
+ import { DatePipe, CurrencyPipe, KeyValuePipe, NgTemplateOutlet, formatDate, formatCurrency, DecimalPipe, CommonModule, AsyncPipe } from '@angular/common';
24
24
  import * as i5 from '@angular/cdk/drag-drop';
25
25
  import { moveItemInArray, DragDropModule, CDK_DROP_LIST, CdkDropList, transferArrayItem } from '@angular/cdk/drag-drop';
26
- import * as i1$5 from '@angular/router';
27
- import { RouterModule } from '@angular/router';
28
26
  import * as i1$1 from '@angular/material/input';
29
27
  import { MatInputModule, MatInput } from '@angular/material/input';
30
28
  import * as i4 from '@angular/material/datepicker';
@@ -32,7 +30,7 @@ import { MatDatepickerModule } from '@angular/material/datepicker';
32
30
  import * as i6 from '@angular/material/form-field';
33
31
  import * as i1$3 from '@angular/material/card';
34
32
  import { MatCardModule } from '@angular/material/card';
35
- import { MatDialog, MAT_DIALOG_DEFAULT_OPTIONS, MatDialogModule } from '@angular/material/dialog';
33
+ import { MatDialog, MAT_DIALOG_DEFAULT_OPTIONS } from '@angular/material/dialog';
36
34
  import * as i3$1 from '@angular/material/button';
37
35
  import { MatButtonModule, MatIconButton, MatButton } from '@angular/material/button';
38
36
  import * as i4$1 from '@angular/material/tooltip';
@@ -48,6 +46,8 @@ import { MatChipsModule } from '@angular/material/chips';
48
46
  import * as i1$6 from '@angular/material/table';
49
47
  import { MatTable, MatColumnDef, MatTableModule, MatHeaderRowDef, MatFooterRowDef, MatTableDataSource, MatRowDef } from '@angular/material/table';
50
48
  import { SelectionModel } from '@angular/cdk/collections';
49
+ import * as i1$5 from '@angular/router';
50
+ import { RouterModule } from '@angular/router';
51
51
  import * as i1$7 from '@angular/material/paginator';
52
52
  import { MatPaginator, MatPaginatorModule } from '@angular/material/paginator';
53
53
  import * as i1$8 from '@angular/cdk/scrolling';
@@ -686,34 +686,6 @@ function getDestroyRef(options) {
686
686
  return destroyRef;
687
687
  }
688
688
 
689
- class SpaceCasePipe {
690
- transform(value) {
691
- return spaceCase(value);
692
- }
693
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: SpaceCasePipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
694
- static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "19.0.0", ngImport: i0, type: SpaceCasePipe, isStandalone: true, name: "spaceCase" });
695
- }
696
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: SpaceCasePipe, decorators: [{
697
- type: Pipe,
698
- args: [{ name: 'spaceCase' }]
699
- }] });
700
- /**
701
- * Adds a space before uppercase letters that either
702
- * 1. follows a lowercase letter or digit
703
- * 2. or precedes a lowercase letter and follows an alpha-numeric character
704
- *
705
- * Uppercases the first digit
706
- *
707
- * Turns underscores into spaces
708
- */
709
- function spaceCase(value) {
710
- const phrase = value?.replace(regex1, '$1$3 $2$4');
711
- // uppercase the first character of every word
712
- return phrase?.replace(regex2, x => x.toUpperCase());
713
- }
714
- const regex1 = /([a-z0-9])([A-Z])|([a-zA-Z0-9])([A-Z])(?=[a-z])|_/g;
715
- const regex2 = /(^| )(\w)/g;
716
-
717
689
  var FieldType;
718
690
  (function (FieldType) {
719
691
  FieldType[FieldType["Unknown"] = 0] = "Unknown";
@@ -771,8 +743,8 @@ class GeneralTableSettings {
771
743
  headerSettings = new TableWrapperHeaderSettings();
772
744
  footerSettings = new TableWrapperFooterSettings();
773
745
  columnHeaderSettings = new TableColumnHeaderSettings();
746
+ columnFooterSettings = new TableColumnFooterSettings();
774
747
  tableSettings = new TableSettings();
775
- injector;
776
748
  }
777
749
  class TableWrapperHeaderSettings {
778
750
  hideExport = false;
@@ -788,10 +760,18 @@ class TableWrapperFooterSettings {
788
760
  collapse = false;
789
761
  }
790
762
  class TableColumnHeaderSettings {
763
+ stickyHeaderRow = true;
791
764
  noFilters = false;
792
765
  noHeader = false;
793
766
  }
767
+ class TableColumnFooterSettings {
768
+ stickyFooterRow = false;
769
+ }
794
770
  class TableSettings {
771
+ tableId = undefined;
772
+ trackBy = undefined;
773
+ includeIndexColumn = false;
774
+ includeSelectionColumn = false;
795
775
  usePaginator = undefined;
796
776
  useVirtualScroll = undefined;
797
777
  paginatorSettings = undefined;
@@ -799,6 +779,8 @@ class TableSettings {
799
779
  rowHeight = undefined;
800
780
  groupHeaderHeight = undefined;
801
781
  minColumnWidth;
782
+ rowClasses;
783
+ rowStyles;
802
784
  }
803
785
  class PersistedTableSettings {
804
786
  constructor(tableSettings) {
@@ -838,6 +820,8 @@ class NotPersistedTableSettings {
838
820
  newNpts.headerHeight = tableSettings.headerSettings?.headerHeight ?? newNpts.headerHeight;
839
821
  newNpts.groupHeaderHeight = tableSettings.tableSettings?.groupHeaderHeight ?? newNpts.groupHeaderHeight;
840
822
  newNpts.minColumnWidth = tableSettings.tableSettings?.minColumnWidth ?? newNpts.minColumnWidth;
823
+ newNpts.rowClasses = tableSettings.tableSettings?.rowClasses ?? newNpts.rowClasses;
824
+ newNpts.rowStyles = tableSettings.tableSettings?.rowStyles ?? newNpts.rowStyles;
841
825
  if (tableSettings.tableSettings?.virtualScrollSettings) {
842
826
  const currVirt = tableSettings.tableSettings?.virtualScrollSettings || newNpts.virtualSettings;
843
827
  if (!currVirt.headerHeight) {
@@ -876,6 +860,8 @@ class NotPersistedTableSettings {
876
860
  rowHeight;
877
861
  headerHeight = undefined;
878
862
  minColumnWidth;
863
+ rowClasses;
864
+ rowStyles;
879
865
  }
880
866
  class VirtualScrollOptions {
881
867
  rowHeight = 48;
@@ -1192,6 +1178,7 @@ class TableFilterDirective {
1192
1178
  this.filterValue = undefined;
1193
1179
  }
1194
1180
  filter$ = new ReplaySubject(1);
1181
+ $filter = toSignal(this.filter$);
1195
1182
  filterType;
1196
1183
  key;
1197
1184
  fieldType;
@@ -1301,6 +1288,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImpor
1301
1288
  }], ctorParameters: () => [] });
1302
1289
  class TableCustomFilterDirectiveBase extends TableCustomFilterDirective {
1303
1290
  filter$ = new ReplaySubject(1);
1291
+ $filter = toSignal(this.filter$);
1304
1292
  filter;
1305
1293
  _predicate;
1306
1294
  set predicate(val) {
@@ -1532,13 +1520,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImpor
1532
1520
 
1533
1521
  class PhoneNumberPipe {
1534
1522
  transform(phoneNum) {
1535
- if (phoneNum) {
1536
- phoneNum = phoneNum.replace(/\D/g, '');
1537
- if (phoneNum[0] === '1') {
1538
- phoneNum = phoneNum.substring(1);
1539
- }
1540
- return '(' + phoneNum.slice(0, 3) + ') ' + phoneNum.slice(3, 6) + '-' + phoneNum.slice(6, 10) + ' ' + phoneNum.slice(10);
1541
- }
1523
+ return phoneFormatter(phoneNum);
1542
1524
  }
1543
1525
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: PhoneNumberPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
1544
1526
  static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "19.0.0", ngImport: i0, type: PhoneNumberPipe, isStandalone: true, name: "phone" });
@@ -1547,6 +1529,44 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImpor
1547
1529
  type: Pipe,
1548
1530
  args: [{ name: 'phone' }]
1549
1531
  }] });
1532
+ function phoneFormatter(phoneNum) {
1533
+ if (phoneNum) {
1534
+ phoneNum = phoneNum.replace(/\D/g, '');
1535
+ if (phoneNum[0] === '1') {
1536
+ phoneNum = phoneNum.substring(1);
1537
+ }
1538
+ return '(' + phoneNum.slice(0, 3) + ') ' + phoneNum.slice(3, 6) + '-' + phoneNum.slice(6, 10) + ' ' + phoneNum.slice(10);
1539
+ }
1540
+ return '';
1541
+ }
1542
+
1543
+ class SpaceCasePipe {
1544
+ transform(value) {
1545
+ return spaceCase(value);
1546
+ }
1547
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: SpaceCasePipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
1548
+ static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "19.0.0", ngImport: i0, type: SpaceCasePipe, isStandalone: true, name: "spaceCase" });
1549
+ }
1550
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: SpaceCasePipe, decorators: [{
1551
+ type: Pipe,
1552
+ args: [{ name: 'spaceCase' }]
1553
+ }] });
1554
+ /**
1555
+ * Adds a space before uppercase letters that either
1556
+ * 1. follows a lowercase letter or digit
1557
+ * 2. or precedes a lowercase letter and follows an alpha-numeric character
1558
+ *
1559
+ * Uppercases the first digit
1560
+ *
1561
+ * Turns underscores into spaces
1562
+ */
1563
+ function spaceCase(value) {
1564
+ const phrase = value?.replace(regex1, '$1$3 $2$4');
1565
+ // uppercase the first character of every word
1566
+ return phrase?.replace(regex2, x => x.toUpperCase());
1567
+ }
1568
+ const regex1 = /([a-z0-9])([A-Z])|([a-zA-Z0-9])([A-Z])(?=[a-z])|_/g;
1569
+ const regex2 = /(^| )(\w)/g;
1550
1570
 
1551
1571
  const defaultConfig = {
1552
1572
  defaultTableSettings: {
@@ -1920,8 +1940,8 @@ class TableStore extends ComponentStore {
1920
1940
  equal: sortsAreSame
1921
1941
  });
1922
1942
  selectSorted$ = this.select(state => state.sorted).pipe(distinctUntilChanged(sortsAreSame));
1923
- sort$ = this.select(state => state.initializationState).pipe(filter(i => i === InitializationState.Ready))
1924
- .pipe(switchMap(() => this.selectSorted$));
1943
+ $getSorts = this.selectSignal(() => this.$initializationState() !== InitializationState.Ready ? [] : this.$selectSorted());
1944
+ sort$ = toObservable(this.$getSorts);
1925
1945
  $getUserDefinedTableWidth = this.selectSignal(state => state.userDefined.table.width);
1926
1946
  getUserDefinedTableWidth$ = this.select(state => state.userDefined.table.width);
1927
1947
  $userDefinedRowHeight = this.selectSignal(state => (state.userDefined.rowHeight));
@@ -1940,6 +1960,11 @@ class TableStore extends ComponentStore {
1940
1960
  const bb = b.flatMap(g => g.expandedHeaders);
1941
1961
  return aa.length === bb.length && aa.every((k) => bb.includes(k));
1942
1962
  }));
1963
+ $expandGroups = this.selectSignal(state => state.groupBy, { equal: (a, b) => {
1964
+ const aa = a.flatMap(g => g.expandedHeaders);
1965
+ const bb = b.flatMap(g => g.expandedHeaders);
1966
+ return aa.length === bb.length && aa.every((k) => bb.includes(k));
1967
+ } });
1943
1968
  $getIsExpanded = (columnKey, groupHeaderKey) => {
1944
1969
  return this.selectSignal(state => !!state.groupBy.filter(g => g.key === columnKey && g.expandedHeaders.includes(groupHeaderKey)).length);
1945
1970
  };
@@ -3166,98 +3191,92 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImpor
3166
3191
  function isPipe(o) {
3167
3192
  return typeof (o.transform) === 'function';
3168
3193
  }
3169
- class TransformCreator {
3170
- datePipe = inject(DatePipe);
3171
- currencyPipe = inject(CurrencyPipe);
3172
- phonePipe = inject(PhoneNumberPipe);
3173
- config = inject(TableBuilderConfigToken);
3174
- createTransformer(metaData, noIcons = false, forItem = false) {
3175
- const nested = metaData.key.includes('.');
3176
- const defaultFunc = nested ? (value) => get(value, metaData.key) : (value) => value[metaData.key];
3177
- if (metaData.map && !forItem) {
3178
- return (value) => {
3179
- return metaData.map(value);
3180
- };
3181
- }
3182
- if (metaData.mapItem) {
3183
- return (value) => {
3184
- return metaData.mapItem(defaultFunc(value));
3185
- };
3186
- }
3187
- if (metaData.transform) {
3188
- if (isPipe(metaData.transform)) {
3189
- return (value) => metaData.transform.transform(defaultFunc(value));
3190
- }
3191
- return metaData.fieldType === FieldType.Expression ? metaData.transform : (value) => metaData.transform(defaultFunc(value), value);
3192
- }
3193
- if (this.config.transformers && this.config.transformers[metaData.fieldType]) {
3194
- var transformer = this.config.transformers[metaData.fieldType];
3195
- return (value) => transformer(defaultFunc(value));
3196
- }
3197
- const defaultDateFormat = this.config.dateFormats?.dateFormat ?? 'shortDate';
3198
- const defaultDateTimeFormat = this.config.dateFormats?.dateTimeFormat ?? 'short';
3199
- switch (metaData.fieldType) {
3200
- case FieldType.Date:
3201
- const dateFormat = metaData.additional?.dateFormat ?? defaultDateFormat;
3202
- return (value) => this.datePipe.transform(defaultFunc(value), dateFormat);
3203
- case FieldType.DateTime:
3204
- const dateTimeFormat = metaData.additional?.dateTimeOptions?.format ?? defaultDateTimeFormat;
3205
- return (value) => this.datePipe.transform(defaultFunc(value), dateTimeFormat);
3206
- case FieldType.Currency:
3207
- return (value) => this.currencyPipe.transform(defaultFunc(value));
3208
- case FieldType.PhoneNumber:
3209
- return (value) => this.phonePipe.transform(defaultFunc(value));
3210
- case FieldType.Enum:
3211
- return (value) => spaceCase(metaData.additional?.enumMap[defaultFunc(value)]);
3212
- case FieldType.Boolean:
3213
- if (noIcons) {
3214
- return defaultFunc;
3215
- }
3216
- let forTrue = 'check';
3217
- let forFalse = '';
3218
- if (metaData.additional?.boolean?.forTrue) {
3219
- forTrue = metaData?.additional.boolean.forTrue.icon;
3220
- }
3221
- if (metaData.additional?.boolean?.showForFalse === true) {
3222
- forFalse = 'clear';
3223
- }
3224
- else if (metaData.additional?.boolean?.showForFalse?.icon) {
3225
- forFalse = metaData.additional?.boolean?.showForFalse?.icon;
3226
- }
3227
- return (value) => defaultFunc(value) ? forTrue : forFalse;
3228
- }
3229
- return defaultFunc;
3194
+ function createTransformer(metaData, config, noIcons = false, forItem = false) {
3195
+ const nested = metaData.key.includes('.');
3196
+ const defaultFunc = nested ? (value) => get(value, metaData.key) : (value) => value[metaData.key];
3197
+ if (metaData.map && !forItem) {
3198
+ return (value) => {
3199
+ return metaData.map(value);
3200
+ };
3230
3201
  }
3231
- createItemTransformer = (metaData, noIcons = false, mutate = false) => {
3232
- const transform = this.createTransformer(metaData, noIcons);
3233
- return (t) => {
3234
- if (!mutate) {
3235
- t = { ...t };
3236
- }
3237
- t[metaData.key] = transform(t);
3202
+ if (metaData.mapItem) {
3203
+ return (value) => {
3204
+ return metaData.mapItem(defaultFunc(value));
3238
3205
  };
3239
- };
3240
- createItemTransformers = (metaDatas, noIcons = false, mutate = false) => {
3241
- const transformers = metaDatas.map(meta => this.createItemTransformer(meta, noIcons, true));
3242
- return (t) => {
3243
- if (!t)
3244
- return t;
3245
- if (!mutate) {
3246
- t = { ...t };
3206
+ }
3207
+ if (metaData.transform) {
3208
+ if (isPipe(metaData.transform)) {
3209
+ return (value) => metaData.transform.transform(defaultFunc(value));
3210
+ }
3211
+ return metaData.fieldType === FieldType.Expression ? metaData.transform : (value) => metaData.transform(defaultFunc(value), value);
3212
+ }
3213
+ if (config.transformers && config.transformers[metaData.fieldType]) {
3214
+ var transformer = config.transformers[metaData.fieldType];
3215
+ return (value) => transformer(defaultFunc(value));
3216
+ }
3217
+ const defaultDateFormat = config.dateFormats?.dateFormat ?? 'shortDate';
3218
+ const defaultDateTimeFormat = config.dateFormats?.dateTimeFormat ?? 'short';
3219
+ switch (metaData.fieldType) {
3220
+ case FieldType.Date:
3221
+ const dateFormat = metaData.additional?.dateFormat ?? defaultDateFormat;
3222
+ return (value) => dateFormatter(defaultFunc(value), dateFormat);
3223
+ case FieldType.DateTime:
3224
+ const dateTimeFormat = metaData.additional?.dateTimeOptions?.format ?? defaultDateTimeFormat;
3225
+ return (value) => dateFormatter(defaultFunc(value), dateTimeFormat);
3226
+ case FieldType.Currency:
3227
+ return (value) => currencyFormatter(defaultFunc(value));
3228
+ case FieldType.PhoneNumber:
3229
+ return (value) => phoneFormatter(defaultFunc(value));
3230
+ case FieldType.Enum:
3231
+ return (value) => spaceCase(metaData.additional?.enumMap[defaultFunc(value)]);
3232
+ case FieldType.Boolean:
3233
+ if (noIcons) {
3234
+ return defaultFunc;
3235
+ }
3236
+ let forTrue = 'check';
3237
+ let forFalse = '';
3238
+ if (metaData.additional?.boolean?.forTrue) {
3239
+ forTrue = metaData?.additional.boolean.forTrue.icon;
3240
+ }
3241
+ if (metaData.additional?.boolean?.showForFalse === true) {
3242
+ forFalse = 'clear';
3247
3243
  }
3248
- transformers.forEach(m => m(t));
3244
+ else if (metaData.additional?.boolean?.showForFalse?.icon) {
3245
+ forFalse = metaData.additional?.boolean?.showForFalse?.icon;
3246
+ }
3247
+ return (value) => defaultFunc(value) ? forTrue : forFalse;
3248
+ }
3249
+ return defaultFunc;
3250
+ }
3251
+ function createItemTransformer(metaData, config, noIcons = false, mutate = false) {
3252
+ const transform = createTransformer(metaData, config, noIcons);
3253
+ return (t) => {
3254
+ if (!mutate) {
3255
+ t = { ...t };
3256
+ }
3257
+ t[metaData.key] = transform(t);
3258
+ };
3259
+ }
3260
+ function createItemTransformers(metaDatas, config, noIcons = false, mutate = false) {
3261
+ const transformers = metaDatas.map(meta => createItemTransformer(meta, config, noIcons, true));
3262
+ return (t) => {
3263
+ if (!t)
3249
3264
  return t;
3250
- };
3265
+ if (!mutate) {
3266
+ t = { ...t };
3267
+ }
3268
+ transformers.forEach(m => m(t));
3269
+ return t;
3251
3270
  };
3252
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: TransformCreator, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
3253
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: TransformCreator, providedIn: 'root' });
3254
3271
  }
3255
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: TransformCreator, decorators: [{
3256
- type: Injectable,
3257
- args: [{
3258
- providedIn: 'root',
3259
- }]
3260
- }] });
3272
+ function dateFormatter(date, format) {
3273
+ if (!date)
3274
+ return;
3275
+ return formatDate(date, format, 'en-US');
3276
+ }
3277
+ function currencyFormatter(amt) {
3278
+ return formatCurrency(amt, 'en-US', '$');
3279
+ }
3261
3280
 
3262
3281
  class RouterLinkColumnComponent {
3263
3282
  additional = input.required();
@@ -3488,14 +3507,14 @@ class ColumnHeaderMenuComponent {
3488
3507
  }
3489
3508
  }
3490
3509
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: ColumnHeaderMenuComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
3491
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.0", type: ColumnHeaderMenuComponent, 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@let currentFilterType = $currentFilterType();\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 <div (keydown)=\"$event.stopImmediatePropagation()\">\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]=\"currentFilterType\" />\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(currentFilterType === FilterType.Or || currentFilterType === 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>{{currentFilterType === FilterType.StringDoesNotContain ? 'Does Not Contain...' : 'Contains...'}}</mat-label>\r\n <input matInput name=\"filterValue\" [ngModel]=\"undefined\"/>\r\n <span matSuffix [matTooltip]=\"currentFilterType === 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': currentFilterType === 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>{{currentFilterType === FilterType.NumberEquals ? 'Equals...' : currentFilterType === 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': currentFilterType === 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': currentFilterType === 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': currentFilterType === 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': currentFilterType === 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': currentFilterType === 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': currentFilterType === FilterType.DateIsOn }\">\r\n <span class=\"suffix-icons underline\"> =</span>\r\n </button>\r\n </span>\r\n <mat-label>{{currentFilterType === FilterType.DateIsOn ? 'On...' :\r\n currentFilterType === 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 </div>\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: i1$4.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: i1$4.MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i1$4.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 });
3510
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.0", type: ColumnHeaderMenuComponent, 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@let currentFilterType = $currentFilterType();\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 <div (keydown)=\"$event.stopImmediatePropagation()\">\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]=\"currentFilterType\" />\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(currentFilterType === FilterType.Or || currentFilterType === 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>{{currentFilterType === FilterType.StringDoesNotContain ? 'Does Not Contain...' : 'Contains...'}}</mat-label>\r\n <input matInput name=\"filterValue\" [ngModel]=\"undefined\"/>\r\n <span matSuffix [matTooltip]=\"currentFilterType === 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': currentFilterType === 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>{{currentFilterType === FilterType.NumberEquals ? 'Equals...' : currentFilterType === 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': currentFilterType === 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': currentFilterType === 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': currentFilterType === 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': currentFilterType === 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': currentFilterType === 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': currentFilterType === FilterType.DateIsOn }\">\r\n <span class=\"suffix-icons underline\"> =</span>\r\n </button>\r\n </span>\r\n <mat-label>{{currentFilterType === FilterType.DateIsOn ? 'On...' :\r\n currentFilterType === 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 </div>\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;width: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: i1$4.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: i1$4.MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i1$4.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 });
3492
3511
  }
3493
3512
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: ColumnHeaderMenuComponent, decorators: [{
3494
3513
  type: Component,
3495
3514
  args: [{ selector: 'tb-header-menu', changeDetection: ChangeDetectionStrategy.OnPush, imports: [
3496
3515
  MatMenuModule, MatIconModule, MatButtonModule, FormsModule, InListFilterComponent,
3497
3516
  MatInputModule, MatTooltipModule, StopPropagationDirective, MatRadioModule, MatDatepickerModule
3498
- ], template: "@let metaData = $metaData();\r\n@let currentFilterType = $currentFilterType();\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 <div (keydown)=\"$event.stopImmediatePropagation()\">\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]=\"currentFilterType\" />\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(currentFilterType === FilterType.Or || currentFilterType === 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>{{currentFilterType === FilterType.StringDoesNotContain ? 'Does Not Contain...' : 'Contains...'}}</mat-label>\r\n <input matInput name=\"filterValue\" [ngModel]=\"undefined\"/>\r\n <span matSuffix [matTooltip]=\"currentFilterType === 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': currentFilterType === 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>{{currentFilterType === FilterType.NumberEquals ? 'Equals...' : currentFilterType === 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': currentFilterType === 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': currentFilterType === 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': currentFilterType === 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': currentFilterType === 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': currentFilterType === 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': currentFilterType === FilterType.DateIsOn }\">\r\n <span class=\"suffix-icons underline\"> =</span>\r\n </button>\r\n </span>\r\n <mat-label>{{currentFilterType === FilterType.DateIsOn ? 'On...' :\r\n currentFilterType === 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 </div>\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"] }]
3517
+ ], template: "@let metaData = $metaData();\r\n@let currentFilterType = $currentFilterType();\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 <div (keydown)=\"$event.stopImmediatePropagation()\">\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]=\"currentFilterType\" />\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(currentFilterType === FilterType.Or || currentFilterType === 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>{{currentFilterType === FilterType.StringDoesNotContain ? 'Does Not Contain...' : 'Contains...'}}</mat-label>\r\n <input matInput name=\"filterValue\" [ngModel]=\"undefined\"/>\r\n <span matSuffix [matTooltip]=\"currentFilterType === 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': currentFilterType === 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>{{currentFilterType === FilterType.NumberEquals ? 'Equals...' : currentFilterType === 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': currentFilterType === 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': currentFilterType === 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': currentFilterType === 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': currentFilterType === 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': currentFilterType === 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': currentFilterType === FilterType.DateIsOn }\">\r\n <span class=\"suffix-icons underline\"> =</span>\r\n </button>\r\n </span>\r\n <mat-label>{{currentFilterType === FilterType.DateIsOn ? 'On...' :\r\n currentFilterType === 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 </div>\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;width: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"] }]
3499
3518
  }] });
3500
3519
 
3501
3520
  class ColumnTotalPipe {
@@ -3563,7 +3582,7 @@ const columnsStyles = (metaDatas, userDefinedWidths) => {
3563
3582
 
3564
3583
  class ColumnBuilderComponent {
3565
3584
  FieldType = FieldType;
3566
- transformCreator = inject(TransformCreator);
3585
+ config = inject(TableBuilderConfigToken);
3567
3586
  table = inject(MatTable);
3568
3587
  state = inject(TableStore);
3569
3588
  templateService = inject(TableTemplateService);
@@ -3594,7 +3613,7 @@ class ColumnBuilderComponent {
3594
3613
  const metaData = this.$metaData();
3595
3614
  if (!metaData)
3596
3615
  return;
3597
- return this.transformCreator.createTransformer(metaData);
3616
+ return createTransformer(metaData, this.config);
3598
3617
  });
3599
3618
  $innerTemplate = computed(() => {
3600
3619
  const metaData = this.$metaData();
@@ -3725,7 +3744,7 @@ class GenericTableComponent {
3725
3744
  state = inject(TableStore);
3726
3745
  dataStore = inject(DataStore);
3727
3746
  viewContainer = inject(ViewContainerRef);
3728
- transformCreator = inject(TransformCreator);
3747
+ config = inject(TableBuilderConfigToken);
3729
3748
  _injector = inject(Injector);
3730
3749
  smallFooter = 10;
3731
3750
  $headerRow = viewChild(MatHeaderRowDef);
@@ -3836,8 +3855,9 @@ class GenericTableComponent {
3836
3855
  });
3837
3856
  $usePaginator = computed(() => this.state.$tableSettings().usePaginator);
3838
3857
  $useVirtualScroll = computed(() => this.state.$viewType().includes('virtual'));
3858
+ $virtualStart = this.dataStore.selectSignal(d => d.virtualEnds.start);
3839
3859
  $offsetIndex = computed(() => {
3840
- const virtualStart = this.dataStore.selectSignal(d => d.virtualEnds.start)();
3860
+ const virtualStart = this.$virtualStart();
3841
3861
  const pageSize = this.state.$pageSize();
3842
3862
  const currentPage = this.state.$currentPage();
3843
3863
  if (this.$useVirtualScroll()) {
@@ -3953,7 +3973,7 @@ class GenericTableComponent {
3953
3973
  if (val == undefined || val === 'null')
3954
3974
  return '';
3955
3975
  try {
3956
- return this.transformCreator.createTransformer(this.state.$getMetaData(key)(), true, true)({ [`${key}`]: val });
3976
+ return createTransformer(this.state.$getMetaData(key)(), this.config, true, true)({ [`${key}`]: val });
3957
3977
  }
3958
3978
  catch (error) {
3959
3979
  return val;
@@ -4006,15 +4026,17 @@ class GenericTableComponent {
4006
4026
  }
4007
4027
  });
4008
4028
  $stickyFooter = computed(() => this.state.$props().stickyFooter || this.state.$isVirtual());
4029
+ $rowStyles = computed(() => this.state.$tableSettings().rowStyles || {});
4030
+ $rowClasses = computed(() => this.state.$tableSettings().rowClasses || {});
4009
4031
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: GenericTableComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
4010
- 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$6.MatTable, selector: "mat-table, table[mat-table]", exportAs: ["matTable"] }, { kind: "directive", type: i1$6.MatHeaderCellDef, selector: "[matHeaderCellDef]" }, { kind: "directive", type: i1$6.MatHeaderRowDef, selector: "[matHeaderRowDef]", inputs: ["matHeaderRowDef", "matHeaderRowDefSticky"] }, { kind: "directive", type: i1$6.MatColumnDef, selector: "[matColumnDef]", inputs: ["matColumnDef"] }, { kind: "directive", type: i1$6.MatCellDef, selector: "[matCellDef]" }, { kind: "directive", type: i1$6.MatRowDef, selector: "[matRowDef]", inputs: ["matRowDefColumns", "matRowDefWhen"] }, { kind: "directive", type: i1$6.MatFooterCellDef, selector: "[matFooterCellDef]" }, { kind: "directive", type: i1$6.MatFooterRowDef, selector: "[matFooterRowDef]", inputs: ["matFooterRowDef", "matFooterRowDefSticky"] }, { kind: "directive", type: i1$6.MatHeaderCell, selector: "mat-header-cell, th[mat-header-cell]" }, { kind: "directive", type: i1$6.MatCell, selector: "mat-cell, td[mat-cell]" }, { kind: "directive", type: i1$6.MatFooterCell, selector: "mat-footer-cell, td[mat-footer-cell]" }, { kind: "component", type: i1$6.MatHeaderRow, selector: "mat-header-row, tr[mat-header-row]", exportAs: ["matHeaderRow"] }, { kind: "component", type: i1$6.MatRow, selector: "mat-row, tr[mat-row]", exportAs: ["matRow"] }, { kind: "component", type: i1$6.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 });
4032
+ 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; let t\" 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\r\n *matRowDef=\"let row; columns: $keys(); let i = index\"\r\n [style.height]=\"$rowHeight()\"\r\n [style.min-height]=\"$rowHeight()\"\r\n [styler]=\"$rowStyles()\"\r\n [element]=\"row\"\r\n [conditionalClasses]=\"$rowClasses()\"\r\n />\r\n\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$6.MatTable, selector: "mat-table, table[mat-table]", exportAs: ["matTable"] }, { kind: "directive", type: i1$6.MatHeaderCellDef, selector: "[matHeaderCellDef]" }, { kind: "directive", type: i1$6.MatHeaderRowDef, selector: "[matHeaderRowDef]", inputs: ["matHeaderRowDef", "matHeaderRowDefSticky"] }, { kind: "directive", type: i1$6.MatColumnDef, selector: "[matColumnDef]", inputs: ["matColumnDef"] }, { kind: "directive", type: i1$6.MatCellDef, selector: "[matCellDef]" }, { kind: "directive", type: i1$6.MatRowDef, selector: "[matRowDef]", inputs: ["matRowDefColumns", "matRowDefWhen"] }, { kind: "directive", type: i1$6.MatFooterCellDef, selector: "[matFooterCellDef]" }, { kind: "directive", type: i1$6.MatFooterRowDef, selector: "[matFooterRowDef]", inputs: ["matFooterRowDef", "matFooterRowDefSticky"] }, { kind: "directive", type: i1$6.MatHeaderCell, selector: "mat-header-cell, th[mat-header-cell]" }, { kind: "directive", type: i1$6.MatCell, selector: "mat-cell, td[mat-cell]" }, { kind: "directive", type: i1$6.MatFooterCell, selector: "mat-footer-cell, td[mat-footer-cell]" }, { kind: "component", type: i1$6.MatHeaderRow, selector: "mat-header-row, tr[mat-header-row]", exportAs: ["matHeaderRow"] }, { kind: "component", type: i1$6.MatRow, selector: "mat-row, tr[mat-row]", exportAs: ["matRow"] }, { kind: "component", type: i1$6.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" }, { kind: "directive", type: StylerDirective, selector: "[styler]", inputs: ["element", "styler"] }, { kind: "directive", type: ConditionalClassesDirective, selector: "[conditionalClasses]", inputs: ["element", "conditionalClasses"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
4011
4033
  }
4012
4034
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: GenericTableComponent, decorators: [{
4013
4035
  type: Component,
4014
4036
  args: [{ selector: 'tb-generic-table', changeDetection: ChangeDetectionStrategy.OnPush, imports: [
4015
4037
  MatTableModule, DragDropModule, MatCheckboxModule, MatButtonModule, MatIconModule, NgTemplateOutlet,
4016
- MatTooltipModule, FunctionPipe,
4017
- ], 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"] }]
4038
+ MatTooltipModule, FunctionPipe, StylerDirective, ConditionalClassesDirective
4039
+ ], 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; let t\" 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\r\n *matRowDef=\"let row; columns: $keys(); let i = index\"\r\n [style.height]=\"$rowHeight()\"\r\n [style.min-height]=\"$rowHeight()\"\r\n [styler]=\"$rowStyles()\"\r\n [element]=\"row\"\r\n [conditionalClasses]=\"$rowClasses()\"\r\n />\r\n\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"] }]
4018
4040
  }] });
4019
4041
 
4020
4042
  function downloadData(data, filename, mimeType) {
@@ -4421,17 +4443,20 @@ const tbGroupBy = (data, groupByKeys, parentGroupName) => {
4421
4443
  };
4422
4444
  });
4423
4445
  };
4424
- function updateGroupByState({ groupedData }, [data, groups, expandedGroups], index) {
4425
- if (index === 0
4426
- || dataUpdated(data, groups, expandedGroups)
4427
- || groupsUpdated(groups, expandedGroups)) {
4446
+ function updateGroupByState(groupedData, { data, groups, expanded }, firstRun) {
4447
+ if (firstRun
4448
+ || dataUpdated(data, groups, expanded)
4449
+ || groupsUpdated(groups, expanded)) {
4428
4450
  groupedData = groups.value.length ? getGroupedData(data.value, groups.value) : data.value;
4429
4451
  }
4430
- const newDisplayData = expandedGroups.value.length === 0
4452
+ const newDisplayData = expanded.value.length === 0
4431
4453
  ? groupedData
4432
- : groupedData.map(group => mapGroupHeader(group, expandedGroups.value)).flat();
4454
+ : groupedData.map(group => mapGroupHeader(group, expanded.value)).flat();
4433
4455
  return ({ displayData: newDisplayData, groupedData });
4434
4456
  }
4457
+ function _updateGroupByState({ groupedData }, [data, groups, expanded], index) {
4458
+ return updateGroupByState(groupedData, { data, groups, expanded }, index === 0);
4459
+ }
4435
4460
  function mapGroupHeader(obj, data) {
4436
4461
  const showChildren = data.find(a => a.expandedHeaders.includes(obj.groupName));
4437
4462
  const children = !showChildren ? [] :
@@ -4468,6 +4493,15 @@ function sortData(data, sorted) {
4468
4493
  return ordered;
4469
4494
  }
4470
4495
  function filterData(data, filters, resetAll = false) {
4496
+ if (filters.length === 0) {
4497
+ if (resetAll) {
4498
+ for (let index = 0; index < data.length; index++) {
4499
+ const element = data[index];
4500
+ element[tbNoShowSymbol] = false;
4501
+ }
4502
+ }
4503
+ return data;
4504
+ }
4471
4505
  for (let index = 0; index < data.length; index++) {
4472
4506
  const element = data[index];
4473
4507
  const hide = !filters.every(filter => filter(element));
@@ -4479,19 +4513,33 @@ function filterData(data, filters, resetAll = false) {
4479
4513
  }
4480
4514
  const tbNoShowSymbol = Symbol('tb_no_show');
4481
4515
 
4482
- const sortAndFilterData = (data, sortState, filterState) => combineLatest([
4516
+ const _sortAndFilterData = (data, sortState, filterState) => combineLatest([
4483
4517
  data.pipe(timestamp()),
4484
4518
  sortState.pipe(timestamp()),
4485
4519
  filterState.pipe(timestamp())
4486
- ]).pipe(scan(({ mappedData: resultData }, [data, sort, f], index) => {
4487
- if (index === 0 || (data.timestamp > sort.timestamp && data.timestamp > f.timestamp)) {
4488
- return ({ mappedData: filterData(sortData(data.value, sort.value.sortsToRun), f.value.allFilters) });
4489
- }
4490
- if (sort.timestamp > f.timestamp) {
4491
- return ({ mappedData: sortData(resultData, sort.value.sortsToRun) });
4492
- }
4493
- return ({ mappedData: filterData(resultData, f.value.onlyAddedFilters || f.value.allFilters, !f.value.onlyAddedFilters) });
4494
- }, { mappedData: [] })).pipe(map$1(({ mappedData: resultData }) => resultData.filter(item => !item[tbNoShowSymbol])), defaultShareReplay());
4520
+ ]).pipe(scan((mappedData, [data, sort, f], index) => {
4521
+ return mapDataSortsAndFilters(data, f, sort, index === 0, mappedData);
4522
+ }, [])).pipe(map$1((resultData) => resultData.filter(item => !item[tbNoShowSymbol])), defaultShareReplay());
4523
+ const mapDataSortsAndFilters = (allData, filters, sort, firstRun, filteredData) => {
4524
+ const fresh = firstRun || (allData.timestamp > sort.timestamp && allData.timestamp > filters.timestamp);
4525
+ const sortChanged = !fresh && sort.timestamp > filters.timestamp;
4526
+ const filterRemoved = !fresh && !sortChanged && !filters.value.onlyAddedFilters;
4527
+ const runAllOnAllData = fresh || filterRemoved;
4528
+ const resetFilters = !fresh && filterRemoved;
4529
+ if (runAllOnAllData) {
4530
+ const filteredData = filterData(sortData(allData.value, sort.value.sortsToRun), filters.value.allFilters, resetFilters);
4531
+ return filteredData;
4532
+ }
4533
+ if (sortChanged) {
4534
+ return (sortData(filteredData, sort.value.sortsToRun));
4535
+ }
4536
+ return (filterData(filteredData, filters.value.onlyAddedFilters || filters.value.allFilters, resetFilters));
4537
+ };
4538
+ const sortAndFilterData = (data, filters, sort, firstRun, resultData) => {
4539
+ const markedAndSortedData = mapDataSortsAndFilters(data, filters, sort, firstRun, resultData);
4540
+ const filteredData = markedAndSortedData.filter(item => !item[tbNoShowSymbol]);
4541
+ return filteredData;
4542
+ };
4495
4543
  const createDataCleaners = (metadatas, mutate = false) => {
4496
4544
  const transforms = createCleaners(metadatas);
4497
4545
  return (data) => {
@@ -4724,7 +4772,7 @@ class TableBuilderDataSource extends MatTableDataSource {
4724
4772
  const $pageSize = state.$pageSize;
4725
4773
  const $virtualEnds = data.selectSignal(d => d.virtualEnds);
4726
4774
  const $dataLength = computed(() => this.#$dataSrc().length);
4727
- const $dataSize = computed(() => {
4775
+ this.$dataSize = computed(() => {
4728
4776
  const viewType = state.$viewType();
4729
4777
  const dataLength = $dataLength();
4730
4778
  const currentPage = $currentPage();
@@ -4742,7 +4790,6 @@ class TableBuilderDataSource extends MatTableDataSource {
4742
4790
  }
4743
4791
  return ({ start: virtualEnds.start, end: virtualEnds.end });
4744
4792
  });
4745
- this.$dataSize = $dataSize;
4746
4793
  }
4747
4794
  connect() {
4748
4795
  return super.connect();
@@ -4778,13 +4825,13 @@ function mergeCustomCellMetaData(metaData1, metaData2) {
4778
4825
  class GroupByListComponent {
4779
4826
  tableStore = inject(TableStore);
4780
4827
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: GroupByListComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
4781
- 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$2.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$2.MatChipRemove, selector: "[matChipRemove]" }, { kind: "component", type: i4$2.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 });
4828
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.0", type: GroupByListComponent, isStandalone: true, selector: "group-by-list", ngImport: i0, template: "<span class=\"tb-group-label\">Group By:</span>\r\n<mat-chip-set>\r\n @for (groupByKey of tableStore.$groupByKeys(); track groupByKey)\r\n {\r\n @if($index > 0)\r\n {\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{font-weight:bolder;padding-right:15px}:host{display:flex;padding-left:8px;align-items:center}:host mat-chip-set mat-chip{margin:0}:host mat-chip-set .nested-arrow{display:flex;width:15px;justify-content:center}\n"], dependencies: [{ kind: "ngmodule", type: MatChipsModule }, { kind: "component", type: i4$2.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$2.MatChipRemove, selector: "[matChipRemove]" }, { kind: "component", type: i4$2.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 });
4782
4829
  }
4783
4830
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: GroupByListComponent, decorators: [{
4784
4831
  type: Component,
4785
4832
  args: [{ selector: 'group-by-list', changeDetection: ChangeDetectionStrategy.OnPush, imports: [
4786
4833
  MatChipsModule, MatIconModule, SpaceCasePipe
4787
- ], 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"] }]
4834
+ ], template: "<span class=\"tb-group-label\">Group By:</span>\r\n<mat-chip-set>\r\n @for (groupByKey of tableStore.$groupByKeys(); track groupByKey)\r\n {\r\n @if($index > 0)\r\n {\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{font-weight:bolder;padding-right:15px}:host{display:flex;padding-left:8px;align-items:center}:host mat-chip-set mat-chip{margin:0}:host mat-chip-set .nested-arrow{display:flex;width:15px;justify-content:center}\n"] }]
4788
4835
  }] });
4789
4836
 
4790
4837
  class ProfilesMenuComponent {
@@ -4968,7 +5015,7 @@ class ResetMenuComponent {
4968
5015
  $widthsSet = computed(() => Object.keys(this.state.$getUserDefinedWidths()).length);
4969
5016
  $rowHeightSet = this.state.$userDefinedRowHeight;
4970
5017
  headerHeightSet = this.state.$userDefinedHeaderHeight;
4971
- pageSizeSet = this.state.$userDefinedPageSize;
5018
+ pageSizeSet = computed(() => this.state.$userDefinedPageSize() && this.state.$userDefinedPageSize() !== this.state.selectSignal(s => s.pageSize)());
4972
5019
  showAllSet = this.state.selectSignal(s => s.userDefined.showAll);
4973
5020
  $set = computed(() => {
4974
5021
  const arr = [];
@@ -5045,93 +5092,120 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImpor
5045
5092
  }] });
5046
5093
 
5047
5094
  class TableVirtualScrollStrategy {
5048
- scrolledIndexChange;
5049
- dataLength = 0;
5095
+ constructor(scrollContainer, dataStore) {
5096
+ this.$rowHeight = scrollContainer.computedRowHeight;
5097
+ this.$headerHeight = scrollContainer.computedHeaderHeight;
5098
+ this.viewport = scrollContainer.viewport;
5099
+ this.dataStore = dataStore;
5100
+ this.$dataLength = scrollContainer.$dataLength;
5101
+ }
5102
+ dataStore;
5050
5103
  indexChange = new Subject();
5104
+ scrolledIndexChange = this.indexChange.pipe(distinctUntilChanged());
5051
5105
  viewport;
5106
+ $dataLength;
5107
+ $dataLengthChange = linkedSignal({
5108
+ source: () => this.$dataLength(),
5109
+ computation: (curr, previous) => ({ curr, previous: previous == undefined ? curr : previous.source })
5110
+ });
5052
5111
  $rowHeight;
5053
5112
  $rowHeightChange = linkedSignal({
5054
5113
  source: () => this.$rowHeight(),
5055
- computation: (curr, previous) => ({ curr, previous: previous?.source || curr })
5114
+ computation: (curr, previous) => {
5115
+ return ({ curr, previous: previous == undefined ? curr : previous.source });
5116
+ }
5056
5117
  });
5057
5118
  $headerHeight;
5058
- constructor(scrollContainer) {
5059
- this.scrolledIndexChange = this.indexChange.pipe(distinctUntilChanged());
5060
- this.$rowHeight = scrollContainer.computedRowHeight;
5061
- this.$headerHeight = scrollContainer.computedHeaderHeight;
5062
- }
5063
- attach(viewport) {
5064
- this.viewport = viewport;
5065
- this.onDataLengthChanged();
5066
- }
5119
+ $headerHeightChange = linkedSignal({
5120
+ source: () => this.$headerHeight(),
5121
+ computation: (curr, previous) => ({ curr, previous: previous == undefined ? curr : previous.source })
5122
+ });
5067
5123
  contentScrolled$ = new Subject();
5068
- sub = subscriber(this.contentScrolled$.pipe(observeOn(animationFrameScheduler), debounceTime(20)), () => {
5124
+ sub = subscriber(this.contentScrolled$.pipe(debounceTime(20), distinctUntilChanged()), offset => {
5069
5125
  this.updateContent('scroll');
5070
5126
  });
5071
5127
  onContentScrolled() {
5072
- this.contentScrolled$.next();
5073
- }
5074
- onDataLengthChanged() {
5075
- }
5076
- setDataLength(length) {
5077
- this.dataLength = length;
5078
- if (this.viewport && this.$rowHeight) {
5079
- this.viewport.setTotalContentSize(this.dataLength * this.$rowHeight());
5080
- // this.updateContent('data ' + dataTrigger);
5081
- }
5082
- this.updateContent('data ');
5083
- }
5084
- detach() { }
5085
- onContentRendered() { }
5086
- onRenderedOffsetChanged() {
5087
- }
5088
- scrollToIndex(index, behavior) {
5128
+ this.contentScrolled$.next(this.viewport().measureScrollOffset());
5089
5129
  }
5130
+ #onDataLengthChange = effect(() => {
5131
+ const dataLengthChange = this.$dataLengthChange();
5132
+ untracked(() => {
5133
+ if (dataLengthChange.curr === dataLengthChange.previous)
5134
+ return;
5135
+ this.updateContent('data length');
5136
+ });
5137
+ });
5090
5138
  #onHeaderChange = effect(() => {
5091
- this.$headerHeight && this.$headerHeight();
5092
- this.updateContent('header height');
5139
+ const headerHeightChange = this.$headerHeightChange();
5140
+ untracked(() => {
5141
+ if (headerHeightChange.curr === headerHeightChange.previous)
5142
+ return;
5143
+ this.updateContent('header height');
5144
+ });
5093
5145
  });
5094
5146
  #onRowChange = effect(() => {
5095
- this.$rowHeight && this.$rowHeight();
5096
- this.updateContent('row height');
5147
+ const rowHeightChange = this.$rowHeightChange();
5148
+ untracked(() => {
5149
+ if (rowHeightChange.curr === rowHeightChange.previous)
5150
+ return;
5151
+ this.updateContent('row height');
5152
+ });
5097
5153
  });
5154
+ $currentRange = signal({ start: 0, end: 0 });
5098
5155
  updateContent(trigger) {
5099
- if (!this.viewport || !this.$rowHeight) {
5156
+ const viewport = this.viewport && this.viewport();
5157
+ if (!viewport || !this.$rowHeight) {
5100
5158
  return;
5101
5159
  }
5102
- const currentContentHeight = +this.viewport._totalContentHeight.replace('px', '');
5103
- const newContentHeight = this.dataLength * this.$rowHeight();
5160
+ const currentContentHeight = +viewport._totalContentHeight.replace('px', '');
5161
+ const newContentHeight = this.$dataLength() * this.$rowHeight();
5104
5162
  if (currentContentHeight !== newContentHeight) {
5105
- this.viewport.setTotalContentSize(newContentHeight);
5106
- setTimeout(() => {
5107
- this.update(trigger);
5108
- }, 0);
5163
+ viewport.setTotalContentSize(newContentHeight);
5164
+ this.update(trigger, viewport, true);
5109
5165
  return;
5110
5166
  }
5111
- this.update(trigger);
5167
+ this.update(trigger, viewport);
5112
5168
  }
5113
- update(trigger) {
5114
- if (!this.viewport || !this.$rowHeight) {
5169
+ update(trigger, viewport, needsScroll = false) {
5170
+ if (!viewport.getViewportSize())
5115
5171
  return;
5116
- }
5117
5172
  const rowHeightChangeEvent = this.$rowHeightChange();
5118
5173
  const rowHeight = rowHeightChangeEvent.curr;
5119
5174
  const rowHeightAdjustment = trigger === 'row height' ? rowHeightChangeEvent.curr / rowHeightChangeEvent.previous : 1;
5120
- const amountOfRows = Math.ceil((this.viewport.getViewportSize() - this.$headerHeight()) / rowHeight);
5121
- const f = this.viewport.measureScrollOffset();
5122
- const offset = this.viewport.measureScrollOffset() * rowHeightAdjustment;
5123
- if (offset !== f) {
5124
- this.viewport.scrollToOffset(offset);
5125
- }
5126
- const buffer = 35;
5175
+ const amountOfRows = Math.ceil((viewport.getViewportSize() - this.$headerHeight()) / rowHeight);
5176
+ const f = viewport.measureScrollOffset();
5177
+ const offset = viewport.measureScrollOffset() * rowHeightAdjustment;
5178
+ const buffer = 35 + Math.round((40 - rowHeight) / 10);
5127
5179
  const skip = Math.round(offset / rowHeight);
5128
5180
  const index = skip % 2 === 0 ? skip : skip - 1;
5129
5181
  const start = Math.max(0, index - buffer);
5130
- const end = Math.min(this.dataLength, index + amountOfRows + buffer);
5131
- this.viewport.setRenderedContentOffset(rowHeight * start);
5132
- this.viewport.setRenderedRange({ start, end });
5182
+ const end = Math.min(this.$dataLength(), index + amountOfRows + buffer);
5183
+ if (start > this.$dataLength()) {
5184
+ this.viewport().scrollToOffset(0);
5185
+ }
5186
+ else if (f !== offset) {
5187
+ if (offset < f)
5188
+ viewport.scrollToOffset(offset);
5189
+ else
5190
+ setTimeout(() => {
5191
+ viewport.scrollToOffset(offset);
5192
+ }, 0);
5193
+ }
5194
+ if (this.$currentRange().start === start && this.$currentRange().end === end) {
5195
+ return;
5196
+ }
5197
+ this.$currentRange.set({ start, end });
5198
+ viewport.setRenderedContentOffset(rowHeight * start);
5199
+ this.dataStore.patchState({ virtualScrollOffset: offset });
5200
+ viewport.setRenderedRange({ start, end });
5133
5201
  this.indexChange.next(index);
5134
5202
  }
5203
+ attach(viewport) { }
5204
+ onDataLengthChanged() { }
5205
+ detach() { }
5206
+ onContentRendered() { }
5207
+ onRenderedOffsetChanged() { }
5208
+ scrollToIndex(index, behavior) { }
5135
5209
  }
5136
5210
 
5137
5211
  class VirtualScrollContainer {
@@ -5149,7 +5223,13 @@ class VirtualScrollContainer {
5149
5223
  viewPort$ = toObservable(this.viewport).pipe(notNull());
5150
5224
  $scrolledIndexChange = toSignal(this.viewPort$.pipe(switchMap$1(v => v.scrolledIndexChange)));
5151
5225
  $renderedRange = toSignal(this.viewPort$.pipe(switchMap$1(v => v.renderedRangeStream)));
5152
- $virtualScrollOptions = computed(() => this.state.$tableSettings().virtualSettings);
5226
+ $virtualScrollOptions = computed(() => {
5227
+ if (this.state.$initializationState() >= InitializationState.Ready)
5228
+ return this.state.$tableSettings().virtualSettings;
5229
+ else
5230
+ return undefined;
5231
+ });
5232
+ $optionsSet = computed(() => !!this.$virtualScrollOptions());
5153
5233
  $dataLength = computed(() => {
5154
5234
  const paginated = this.$usePaginator() && !this.$showAll();
5155
5235
  const pageSize = this.$pageSize();
@@ -5162,58 +5242,40 @@ class VirtualScrollContainer {
5162
5242
  constructor() {
5163
5243
  addEventListener('resize', this.resizeHandler);
5164
5244
  }
5165
- setViewportEffect = effect(() => {
5245
+ #setViewportEffect = effect(() => {
5166
5246
  const viewport = this.viewport();
5247
+ const options = this.$optionsSet();
5167
5248
  untracked(() => {
5168
- if (!!viewport) {
5169
- this.setSize(this.viewport().elementRef);
5249
+ if (!!viewport && !!options) {
5250
+ this.setSize(this.viewport().elementRef, 'initial');
5170
5251
  }
5171
5252
  ;
5172
5253
  });
5173
5254
  });
5174
- subscriber = subscriber();
5175
5255
  #onRenderedRangeEffect = effect(() => {
5176
5256
  const renderedRange = this.$renderedRange();
5257
+ const viewport = this.viewport();
5177
5258
  if (!renderedRange)
5178
5259
  return;
5179
5260
  untracked(() => {
5180
5261
  this.dataStore.patchState({
5181
5262
  virtualEnds: {
5182
5263
  start: renderedRange.start,
5183
- end: renderedRange.end + 25,
5264
+ end: renderedRange.end,
5184
5265
  }
5185
5266
  });
5186
- this.setSize(this.viewport().elementRef);
5187
- });
5188
- });
5189
- #onDataLengthEffect = effect(() => {
5190
- const dataLength = this.$dataLength();
5191
- untracked(() => {
5192
- const renderedRange = this.$renderedRange();
5193
- this.scrollStrategy.setDataLength(dataLength);
5194
- if ((renderedRange?.start || 0) > dataLength) {
5195
- this.viewport().scrollToOffset(0);
5196
- }
5197
- });
5198
- });
5199
- #onOffsetEffect = effect(() => {
5200
- const offset = this.$offset();
5201
- untracked(() => {
5202
- this.dataStore.patchState({ virtualScrollOffset: offset });
5267
+ if (!viewport)
5268
+ return;
5269
+ this.setSize(viewport.elementRef, 'rendered range');
5203
5270
  });
5204
5271
  });
5205
- $offset = computed(() => {
5206
- const viewport = this.viewport();
5207
- const scrolledIndexChange = this.$scrolledIndexChange();
5208
- if (!scrolledIndexChange || !viewport)
5209
- return 0;
5210
- return viewport.getOffsetToRenderedContentStart() ?? 0;
5211
- });
5212
5272
  ngOnDestroy() {
5213
5273
  removeEventListener('resize', this.resizeHandler);
5214
5274
  }
5215
- setSize(el) {
5275
+ setSize(el, trigger) {
5216
5276
  const virtualScrollOptions = this.$virtualScrollOptions();
5277
+ if (!virtualScrollOptions)
5278
+ return;
5217
5279
  if (virtualScrollOptions.dynamicHeight) {
5218
5280
  this.calcDynamic(el);
5219
5281
  return;
@@ -5230,18 +5292,10 @@ class VirtualScrollContainer {
5230
5292
  height = maxViewPortHeightPx;
5231
5293
  this.setHeight(height, el);
5232
5294
  }
5233
- calcDynamic$ = new Subject();
5234
- $calcDynamic = toSignal(this.calcDynamic$.pipe(debounceTime$1(300)));
5235
- #onCalcDynamicEffect = effect(() => {
5236
- const el = this.$calcDynamic();
5237
- if (!el)
5238
- return;
5239
- untracked(() => {
5240
- this.calcDynamic(el);
5241
- });
5242
- });
5243
5295
  calcDynamic(el) {
5244
5296
  const virtualScrollOptions = this.$virtualScrollOptions();
5297
+ if (!virtualScrollOptions)
5298
+ return;
5245
5299
  const t = this.tableContainer.elementRef.nativeElement.querySelector(`#${TableContainerComponent.headerId}`);
5246
5300
  const rect = t?.getBoundingClientRect();
5247
5301
  const windowHeight = window.innerHeight;
@@ -5276,8 +5330,8 @@ class VirtualScrollContainer {
5276
5330
  this.dataStore.patchState({ virtualScrollOffset });
5277
5331
  }
5278
5332
  resizeHandler = () => {
5279
- if (this.viewport() && this.$virtualScrollOptions().dynamicHeight) {
5280
- this.setSize(this.viewport().elementRef);
5333
+ if (this.viewport() && this.$virtualScrollOptions()?.dynamicHeight) {
5334
+ this.setSize(this.viewport().elementRef, 'resize');
5281
5335
  }
5282
5336
  };
5283
5337
  computedRowHeight = computed(() => {
@@ -5301,7 +5355,7 @@ class VirtualScrollContainer {
5301
5355
  return 0;
5302
5356
  return parseTbSizeToPixels(virtualScrollOptions.dynamicalHeightBuffer) || 0;
5303
5357
  });
5304
- scrollStrategy = new TableVirtualScrollStrategy(this);
5358
+ scrollStrategy = new TableVirtualScrollStrategy(this, this.dataStore);
5305
5359
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: VirtualScrollContainer, deps: [], target: i0.ɵɵFactoryTarget.Component });
5306
5360
  static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "19.0.0", type: VirtualScrollContainer, isStandalone: true, selector: "tb-virtual-scroll-container", queries: [{ propertyName: "genericTable", first: true, predicate: GenericTableComponent, descendants: true, isSignal: true }], viewQueries: [{ propertyName: "viewport", first: true, predicate: CdkVirtualScrollViewport, descendants: true, isSignal: true }], ngImport: i0, template: `
5307
5361
  <cdk-virtual-scroll-viewport>
@@ -5357,35 +5411,24 @@ class TableContainerComponent {
5357
5411
  parent: this.injector
5358
5412
  });
5359
5413
  $tableBuilder = input.required({ alias: 'tableBuilder' });
5360
- $tableId = input(undefined, { alias: 'tableId' });
5361
- $trackBy = input(undefined, { alias: 'trackBy' });
5362
- $inputFilters = model([], { alias: 'inputFilters' });
5363
- predicateInputFilters$ = toObservable(computed(() => this.$inputFilters().filter(isFunction$1)));
5414
+ $tableIdInput = input(undefined, { alias: 'tableId' });
5415
+ $trackByInput = input(undefined, { alias: 'trackBy' });
5416
+ $inputFilters = input([], { alias: 'inputFilters' });
5364
5417
  $filterInfoInputs = computed(() => this.$inputFilters().filter(i => !isFunction$1(i)));
5365
- $indexColumn = input(false, { alias: 'indexColumn' });
5366
- $selectionColumn = input(false, { alias: 'selectionColumn' });
5367
- $isSticky = input(true, { alias: 'isSticky' });
5368
- $stickyFooter = input(false, { alias: 'stickyFooter' });
5418
+ $indexColumnInput = input(false, { alias: 'indexColumn' });
5419
+ $selectionColumnInput = input(false, { alias: 'selectionColumn' });
5420
+ $stickyHeaderInput = input(true, { alias: 'stickyHeader' });
5421
+ $stickyFooterInput = input(false, { alias: 'stickyFooter' });
5369
5422
  $groupHeaderTemplate = input(undefined, { alias: 'groupHeaderTemplate' });
5370
5423
  $groupHeaderHeight = input(undefined, { alias: 'groupHeaderHeight' });
5371
5424
  $pageSize = input(undefined, { alias: 'pageSize' });
5372
- $props = computed(() => {
5373
- const indexColumn = this.$indexColumn();
5374
- const selectionColumn = this.$selectionColumn();
5375
- const isSticky = this.$isSticky();
5376
- const stickyFooter = this.$stickyFooter();
5377
- const groupHeaderTemplate = this.$groupHeaderTemplate();
5378
- const groupHeaderHeight = this.$groupHeaderHeight();
5379
- return ({ indexColumn, selectionColumn, isSticky, stickyFooter, groupHeaderTemplate, groupHeaderHeight });
5380
- });
5381
5425
  selection$ = output({ alias: 'selection' });
5382
5426
  onStateReset$ = output({ alias: 'onStateReset' });
5383
5427
  onSaveState$ = output({ alias: 'onSaveState' });
5384
- _state$ = toObservable(this.state.$savableState);
5385
- state$ = outputFromObservable(this._state$, { alias: 'state' });
5386
- _data$ = new BehaviorSubject([]);
5387
- data$ = outputFromObservable(this._data$, { alias: 'data' });
5388
- $data = toSignal(this._data$, { initialValue: [] });
5428
+ state$ = outputFromObservable(toObservable(this.state.$savableState), { alias: 'state' });
5429
+ $data = computed(() => this.$sortedAndFilteredData()?.value || []);
5430
+ data$ = outputFromObservable(toObservable(this.$data), { alias: 'data' });
5431
+ $displayData = computed(() => this.$tableBuilder() && this.$filteredSortedAndGrouped()?.displayData);
5389
5432
  clearSelections() {
5390
5433
  this.$genericTable()?.$selection().clear(true);
5391
5434
  }
@@ -5409,14 +5452,44 @@ class TableContainerComponent {
5409
5452
  $useVirtual = this.state.$isVirtual;
5410
5453
  $collapsedFooter = this.state.$footerCollapsed;
5411
5454
  $collapsedHeader = this.state.$headerCollapsed;
5412
- $displayDataLength = computed(() => this.$displayData().length);
5455
+ $displayDataLength = computed(() => this.$displayData()?.length || 0);
5456
+ $tableBuilderSettings = computed(() => this.$tableBuilder().$settings());
5457
+ $trackBy = computed(() => this.$trackByInput() || this.$tableBuilderSettings()?.tableSettings?.trackBy);
5458
+ $tableId = computed(() => this.$tableIdInput() || this.$tableBuilderSettings()?.tableSettings?.tableId);
5459
+ $includeSelectionColumn = computed(() => this.$selectionColumnInput() || !!this.$tableBuilderSettings()?.tableSettings?.includeSelectionColumn);
5460
+ $includeIndexColumn = computed(() => this.$indexColumnInput() || !!this.$tableBuilderSettings()?.tableSettings?.includeIndexColumn);
5461
+ $stickyHeader = computed(() => {
5462
+ const settings = this.$tableBuilderSettings()?.columnHeaderSettings?.stickyHeaderRow;
5463
+ if (settings != null) {
5464
+ return settings;
5465
+ }
5466
+ return this.$stickyHeaderInput();
5467
+ });
5468
+ $stickyFooter = computed(() => this.$stickyFooterInput() || !!this.$tableBuilderSettings()?.columnFooterSettings?.stickyFooterRow);
5469
+ $props = computed(() => {
5470
+ const indexColumn = this.$includeIndexColumn();
5471
+ const selectionColumn = this.$includeSelectionColumn();
5472
+ const stickHeader = this.$stickyHeader();
5473
+ const stickyFooter = this.$stickyFooter();
5474
+ const groupHeaderTemplate = this.$groupHeaderTemplate();
5475
+ const groupHeaderHeight = this.$groupHeaderHeight();
5476
+ return ({ indexColumn, selectionColumn, isSticky: stickHeader, stickyFooter, groupHeaderTemplate, groupHeaderHeight });
5477
+ });
5478
+ #initTableBuilderIfNeeded = effect(() => {
5479
+ const tb = this.$tableBuilder();
5480
+ untracked(() => {
5481
+ if (tb)
5482
+ this.$tableBuilder()?.prep(this.injector);
5483
+ });
5484
+ });
5413
5485
  #initializeTableSettingsFromTableBuilderAndPersistedStateEffect = effect(() => {
5414
5486
  const metaLoaded = this.$isInitializationState(InitializationState.MetaDataLoaded)();
5415
5487
  if (!metaLoaded)
5416
5488
  return;
5417
5489
  const persistedState = this.$persistedState();
5490
+ const tbSettings = this.$tableBuilderSettings();
5418
5491
  untracked(() => {
5419
- this.state.setTableSettings(this.$tableBuilder().settings$);
5492
+ this.state.setTableSettings(tbSettings);
5420
5493
  if (persistedState) {
5421
5494
  persistedState.persistedTableSettings = new PersistedTableSettings(persistedState.persistedTableSettings);
5422
5495
  this.state.updateStateFromPersistedState(persistedState);
@@ -5481,14 +5554,32 @@ class TableContainerComponent {
5481
5554
  this.state.setLinkMaps(createLinkCreatorDict(allMetaDatas));
5482
5555
  });
5483
5556
  });
5484
- #initializeDataEffect = effect(() => {
5557
+ #setFilteredDataLengthEffect = effect(() => {
5485
5558
  const tableBuilder = this.$tableBuilder();
5486
- if (!tableBuilder)
5559
+ const data = this.$sortedAndFilteredData();
5560
+ if (!tableBuilder || !data)
5487
5561
  return;
5488
5562
  untracked(() => {
5489
- this.initializeData();
5563
+ this.dataStore.patchState({ sortedFilteredDataLength: data.value.length });
5490
5564
  });
5491
5565
  });
5566
+ #setDataSourceDataEffect = effect(() => {
5567
+ const tableBuilder = this.$tableBuilder();
5568
+ const flat = this.$filteredSortedAndGrouped();
5569
+ if (!tableBuilder || !flat)
5570
+ return;
5571
+ untracked(() => {
5572
+ const data = flat.displayData;
5573
+ this.dataSource.setData(data);
5574
+ this.dataStore.patchState({ sortedFilteredGroupedDataLength: data.length });
5575
+ });
5576
+ });
5577
+ #destroyRef = inject(DestroyRef).onDestroy(() => {
5578
+ const tableId = this.$tableId();
5579
+ if (tableId) {
5580
+ this.stateService.saveTableStateToLocal({ tableId, tableState: this.state.$savableState() });
5581
+ }
5582
+ });
5492
5583
  $persistedState = computed(() => {
5493
5584
  const tableId = this.$tableId();
5494
5585
  if (tableId) {
@@ -5502,12 +5593,7 @@ class TableContainerComponent {
5502
5593
  }
5503
5594
  return [...this.$filterDirectives(), ...this.$customFilterDirectives()];
5504
5595
  });
5505
- allNotSavableFilterDirectivesFilters$ = toObservable(this.$allFilterDirectives).pipe(filterArray(d => !d.savable), switchMap(d => {
5506
- const a = d.map(d => d.filter$);
5507
- return combineLatest(a).pipe(startWith([]));
5508
- }), map(createFilterFuncs));
5509
- tableBuilderMetaData$ = toObservable(this.$tableBuilder).pipe(notNull(), switchMap(tb => tb.metaData$));
5510
- $tableBuilderMetaData = toSignal(this.tableBuilderMetaData$);
5596
+ $tableBuilderMetaData = computed(() => this.$tableBuilder()?.$metaData());
5511
5597
  $allMetaDatas = computed(() => {
5512
5598
  const tableBuilderMetaData = this.$tableBuilderMetaData();
5513
5599
  if (!tableBuilderMetaData)
@@ -5516,47 +5602,118 @@ class TableContainerComponent {
5516
5602
  const mappedCustomCellMetaDatas = customCellMetaDatas.map(md => mergeCustomCellMetaData(md, tableBuilderMetaData.find(item => item.key === md.key)));
5517
5603
  return [...tableBuilderMetaData, ...mappedCustomCellMetaDatas];
5518
5604
  });
5519
- $displayData = signal([]);
5520
- ngOnDestroy() {
5521
- const tableId = this.$tableId();
5522
- if (tableId) {
5523
- this.stateService.saveTableStateToLocal({ tableId, tableState: this.state.$savableState() });
5605
+ $preds = computed(() => {
5606
+ const predicateInputFilters = this.$inputFilters().filter(isFunction$1);
5607
+ const notSavableFilterDirectives = this.$allFilterDirectives()
5608
+ .filter(d => !d.savable)
5609
+ .map(d => d.$filter())
5610
+ .filter(d => !!d && needsFilterCreation(d))
5611
+ .map(d => createFilterFunc(d));
5612
+ return [...predicateInputFilters, ...notSavableFilterDirectives];
5613
+ });
5614
+ $predicateFiltersState = linkedSignal({
5615
+ source: this.$preds,
5616
+ computation: (curr, previous) => {
5617
+ if (!previous?.value)
5618
+ return ({ value: updateFilterPredicateState({ allFilters: [] }, curr), timestamp: new Date().getTime() });
5619
+ return ({ value: updateFilterPredicateState(previous.value.value, curr), timestamp: new Date().getTime() });
5524
5620
  }
5525
- }
5526
- initializeData() {
5527
- const predicateFilters$ = combineLatest([this.predicateInputFilters$.pipe(), this.allNotSavableFilterDirectivesFilters$])
5528
- .pipe(map(([a, b]) => [...a, ...b]));
5529
- const filters$ = combineLatest([
5530
- this.state.filters$.pipe(scan$1(updateFilterInfoState, { allFilters: {} }), timestamp$1()),
5531
- predicateFilters$.pipe(scan$1(updateFilterPredicateState, { allFilters: [] }), timestamp$1())
5532
- ])
5533
- .pipe(map(([filterInfo, pred]) => updateFilterState(filterInfo, pred)));
5534
- const sortsState$ = this.state.sort$.pipe(scan$1(updateSortState, initialSortState));
5535
- const sortedAndFilteredData$ = sortAndFilterData(this.$tableBuilder().getData$(), sortsState$, filters$);
5536
- 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());
5537
- this.state.on(sortedAndFilteredData$, (data) => {
5538
- this._data$.next(data);
5539
- this.dataStore.patchState({ sortedFilteredDataLength: data.length });
5621
+ });
5622
+ $savableFiltersState = linkedSignal({
5623
+ source: this.state.$filters,
5624
+ computation: (curr, previous) => {
5625
+ if (!previous?.value)
5626
+ return ({ value: updateFilterInfoState({ allFilters: {} }, curr), timestamp: new Date().getTime() });
5627
+ return ({ value: updateFilterInfoState(previous.value.value, curr), timestamp: new Date().getTime() });
5628
+ }
5629
+ });
5630
+ $allFilterStatesTimeStamped = computed(() => {
5631
+ if (!this.$isInitializationState(InitializationState.Ready)())
5632
+ return undefined;
5633
+ return ({ value: updateFilterState(this.$savableFiltersState(), this.$predicateFiltersState()), timestamp: new Date().getTime() });
5634
+ });
5635
+ $sortStateTimeStamped = linkedSignal({
5636
+ source: computed(() => this.$isInitializationState(InitializationState.Ready)() && this.state.$getSorts()),
5637
+ computation: (curr, prev) => {
5638
+ if (!curr)
5639
+ return undefined;
5640
+ if (!prev?.value)
5641
+ return ({ value: updateSortState(initialSortState, curr), timestamp: new Date().getTime() });
5642
+ return ({ value: updateSortState(prev.value.value, curr), timestamp: new Date().getTime() });
5643
+ }
5644
+ });
5645
+ $allData = computed(() => this.$tableBuilder()?.$data() || []);
5646
+ $allDataTimeStamped = computed(() => {
5647
+ const data = this.$allData();
5648
+ if (!data)
5649
+ return undefined;
5650
+ return ({
5651
+ value: data,
5652
+ timestamp: new Date().getTime()
5540
5653
  });
5541
- this.state.on(flatGrouped$, (data) => {
5542
- this.dataSource.setData(data);
5543
- this.$displayData.set(data);
5544
- this.dataStore.patchState({ sortedFilteredGroupedDataLength: data.length });
5654
+ });
5655
+ $allTimeStamped = computed(() => {
5656
+ const data = this.$allDataTimeStamped();
5657
+ const sort = this.$sortStateTimeStamped();
5658
+ const filter = this.$allFilterStatesTimeStamped();
5659
+ if (!data?.value || !sort?.value || !filter?.value)
5660
+ return undefined;
5661
+ return ({
5662
+ data,
5663
+ sort,
5664
+ filter
5545
5665
  });
5546
- }
5666
+ });
5667
+ $sortedAndFilteredData = linkedSignal({
5668
+ source: this.$allTimeStamped,
5669
+ computation: (values, prev) => {
5670
+ const init = this.$isInitializationState(InitializationState.Ready);
5671
+ if (!values || !init)
5672
+ return undefined;
5673
+ const { data, filter, sort } = values;
5674
+ const val = prev?.value?.value || data.value;
5675
+ const filteredData = sortAndFilterData(data, filter, sort, !prev?.value, val);
5676
+ return ({ value: filteredData, timestamp: new Date().getTime() });
5677
+ }
5678
+ });
5679
+ $timestampedGroups = computed(() => ({ value: this.state.$groupByKeys(), timestamp: new Date().getTime() }));
5680
+ $timestampedExpanded = computed(() => ({ value: this.state.$expandGroups(), timestamp: new Date().getTime() }));
5681
+ $dataAndGroupsTimestamped = computed(() => {
5682
+ const data = this.$sortedAndFilteredData();
5683
+ const groups = this.$timestampedGroups();
5684
+ const expanded = this.$timestampedExpanded();
5685
+ if (!data)
5686
+ return undefined;
5687
+ return ({
5688
+ data,
5689
+ groups,
5690
+ expanded
5691
+ });
5692
+ });
5693
+ $filteredSortedAndGrouped = linkedSignal({
5694
+ source: this.$dataAndGroupsTimestamped,
5695
+ computation: (curr, prev) => {
5696
+ if (!curr)
5697
+ return undefined;
5698
+ const val = prev?.value?.groupedData || [];
5699
+ return updateGroupByState(val, curr, !prev?.value);
5700
+ }
5701
+ });
5547
5702
  $isInitializationState = (state) => computed(() => this.state.selectSignal(s => s.initializationState >= state)());
5548
5703
  static headerId = 'tb-header-wrapper';
5549
5704
  headerId = TableContainerComponent.headerId;
5550
5705
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: TableContainerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
5551
- 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 }, { propertyName: "$menu", first: true, predicate: MatMenu, descendants: true, isSignal: true }], ngImport: i0, template: "@let tableId = $tableId();\r\n@let tableSettings = state.$tableSettings();\r\n\r\n<ng-content select=\"[before]\" />\r\n<ng-container multiSort>\r\n <div class=\"tb-header-wrapper\" [id]=\"headerId\">\r\n <div class=\"title\">\r\n @if ((!$collapsedHeader()) || tableSettings.showTitleWhenHeaderCollapsed) {\r\n <ng-content select=\".tb-header-title\"/>\r\n }\r\n @if(state.$groupByKeys().length){\r\n <group-by-list />\r\n }\r\n </div>\r\n <div class=\"flx-row-end\">\r\n <lib-filter-list />\r\n @if (!tableSettings.hideHeader) {\r\n @if (!$collapsedHeader()) {\r\n <ng-container *ngTemplateOutlet=\"headerMenu\"/>\r\n <button mat-icon-button color='primary' [matMenuTriggerFor]=\"l.menu()\">\r\n <mat-icon>more_vert</mat-icon>\r\n </button>\r\n\r\n <lib-table-header-menu #l/>\r\n\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; injector menuInjector\"/>\r\n </div>\r\n <lib-table-header-menu />\r\n </mat-menu>\r\n }\r\n <mat-icon [matTooltip]=\"$collapsedHeader() ? 'expand' : 'collapse'\" class=\"collapse-icon header\"\r\n (click)=\"state.toggleCollapseHeader()\">\r\n {{$collapsedHeader() ? 'expand_less' : 'expand_more'}}\r\n </mat-icon>\r\n }\r\n\r\n </div>\r\n </div>\r\n\r\n @if($useVirtual())\r\n {\r\n <tb-virtual-scroll-container class=\"scrollable\">\r\n <tb-generic-table [rows]=\"$customRows()\" [data]=\"$data()!\" [displayDataLength]=\"$displayDataLength()\"\r\n (selection)='selection$.emit($event)' [columnInfos]='$myColumns()' [trackBy]=\"$trackBy()\" [dataSource]=\"dataSource\" />\r\n </tb-virtual-scroll-container>\r\n }\r\n @else\r\n {\r\n <tb-generic-table [rows]=\"$customRows()\" [data]=\"$data()!\" [displayDataLength]=\"$displayDataLength()\"\r\n (selection)='selection$.emit($event)' [columnInfos]='$myColumns()' [trackBy]=\"$trackBy()\" [dataSource]=\"dataSource\" />\r\n }\r\n @if(tableSettings.usePaginator)\r\n {\r\n <div class=\"paginator\">\r\n <tb-paginator #tbPaginator />\r\n\r\n <mat-icon [matTooltip]=\"$collapsedFooter() ? 'expand' : 'collapse'\" class=\"collapse-icon footer\"\r\n (click)=\"state.toggleCollapseFooter()\">\r\n {{$collapsedFooter() ? 'expand_more' : 'expand_less'}}\r\n </mat-icon>\r\n </div>\r\n }\r\n\r\n <ng-template #headerMenu>\r\n @if (!tableSettings.hideFilter) {<tb-filter-displayer/>}\r\n @if (!tableSettings.hideColumnSettings) {<tb-col-displayer/>}\r\n @if (!tableSettings.hideSort) {<tb-sort-menu/>}\r\n @if (!!tableId) {<tb-profiles-menu [tableId]=\"tableId\"/>}\r\n </ng-template>\r\n\r\n</ng-container>\r\n", styles: [".tb-header-wrapper{display:flex;flex-direction:row;justify-content:space-between;width:100%}.flx-row-end{display:flex;flex-direction:row;justify-content:flex-end;align-items:center}.flat-menu{line-height:initial;height:initial}.pointer{cursor:pointer}.add-key{width:90%}.paginator{display:flex;flex-direction:row;justify-content:flex-end;align-items:center;background-color:#fff;bottom:0;position:sticky;border-top:.5px solid rgba(0,0,0,.12)}.profiles-menu{visibility:hidden;width:0px;height:0px;display:block;overflow:hidden;position:absolute;top:50px}\n", ".collapse-icon{font-size:16px;height:16px;color:#3f51b5;align-self:flex-start}.collapse-icon:hover{cursor:pointer}.hide{display:none}.paginator-row{display:flex;align-items:center}\n"], dependencies: [{ kind: "directive", type: 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: "component", type: ProfilesMenuComponent, selector: "tb-profiles-menu", inputs: ["tableId", "isMatMenuChild"] }, { kind: "component", type: TableHeaderMenuComponent, selector: "lib-table-header-menu" }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i3$1.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "ngmodule", type: MatMenuModule }, { kind: "component", type: i1$4.MatMenu, selector: "mat-menu", inputs: ["backdropClass", "aria-label", "aria-labelledby", "aria-describedby", "xPosition", "yPosition", "overlapTrigger", "hasBackdrop", "class", "classList"], outputs: ["closed", "close"], exportAs: ["matMenu"] }, { kind: "directive", type: i1$4.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: 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 });
5706
+ 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 }, $tableIdInput: { classPropertyName: "$tableIdInput", publicName: "tableId", isSignal: true, isRequired: false, transformFunction: null }, $trackByInput: { classPropertyName: "$trackByInput", publicName: "trackBy", isSignal: true, isRequired: false, transformFunction: null }, $inputFilters: { classPropertyName: "$inputFilters", publicName: "inputFilters", isSignal: true, isRequired: false, transformFunction: null }, $indexColumnInput: { classPropertyName: "$indexColumnInput", publicName: "indexColumn", isSignal: true, isRequired: false, transformFunction: null }, $selectionColumnInput: { classPropertyName: "$selectionColumnInput", publicName: "selectionColumn", isSignal: true, isRequired: false, transformFunction: null }, $stickyHeaderInput: { classPropertyName: "$stickyHeaderInput", publicName: "stickyHeader", isSignal: true, isRequired: false, transformFunction: null }, $stickyFooterInput: { classPropertyName: "$stickyFooterInput", 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: { 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 }, { propertyName: "$menu", first: true, predicate: MatMenu, descendants: true, isSignal: true }], ngImport: i0, template: "@let tableId = $tableId();\r\n@let tableSettings = state.$tableSettings();\r\n\r\n<ng-content select=\"[before]\" />\r\n<ng-container multiSort>\r\n <div class=\"tb-header-wrapper\" [id]=\"headerId\">\r\n <div class=\"title\">\r\n @if ((!$collapsedHeader()) || tableSettings.showTitleWhenHeaderCollapsed)\r\n {\r\n <ng-content select=\".tb-header-title\"/>\r\n }\r\n </div>\r\n @if(state.$groupByKeys().length){\r\n <group-by-list />\r\n }\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]=\"l.menu()\">\r\n <mat-icon>more_vert</mat-icon>\r\n </button>\r\n\r\n <lib-table-header-menu #l/>\r\n\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; injector menuInjector\"/>\r\n </div>\r\n <lib-table-header-menu />\r\n </mat-menu>\r\n }\r\n <mat-icon [matTooltip]=\"$collapsedHeader() ? 'expand' : 'collapse'\" class=\"collapse-icon header\"\r\n (click)=\"state.toggleCollapseHeader()\">\r\n {{$collapsedHeader() ? 'expand_less' : 'expand_more'}}\r\n </mat-icon>\r\n }\r\n\r\n </div>\r\n </div>\r\n\r\n @if($useVirtual())\r\n {\r\n <tb-virtual-scroll-container class=\"scrollable\">\r\n <tb-generic-table [rows]=\"$customRows()\" [data]=\"$data()!\" [displayDataLength]=\"$displayDataLength()\"\r\n (selection)='selection$.emit($event)' [columnInfos]='$myColumns()' [trackBy]=\"$trackBy()\" [dataSource]=\"dataSource\" />\r\n </tb-virtual-scroll-container>\r\n }\r\n @else\r\n {\r\n <tb-generic-table [rows]=\"$customRows()\" [data]=\"$data()!\" [displayDataLength]=\"$displayDataLength()\"\r\n (selection)='selection$.emit($event)' [columnInfos]='$myColumns()' [trackBy]=\"$trackBy()\" [dataSource]=\"dataSource\" />\r\n }\r\n @if(tableSettings.usePaginator)\r\n {\r\n <div class=\"paginator\">\r\n <tb-paginator #tbPaginator />\r\n\r\n <mat-icon [matTooltip]=\"$collapsedFooter() ? 'expand' : 'collapse'\" class=\"collapse-icon footer\"\r\n (click)=\"state.toggleCollapseFooter()\">\r\n {{$collapsedFooter() ? 'expand_more' : 'expand_less'}}\r\n </mat-icon>\r\n </div>\r\n }\r\n\r\n <ng-template #headerMenu>\r\n @if (!tableSettings.hideFilter) {<tb-filter-displayer/>}\r\n @if (!tableSettings.hideColumnSettings) {<tb-col-displayer/>}\r\n @if (!tableSettings.hideSort) {<tb-sort-menu/>}\r\n @if (!!tableId) {<tb-profiles-menu [tableId]=\"tableId\"/>}\r\n </ng-template>\r\n\r\n</ng-container>\r\n", styles: [".tb-header-wrapper{display:flex;flex-direction:row;width:100%}.flx-row-end{display:flex;flex-direction:row;justify-content:flex-end;align-items:center;margin-left:auto}.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: 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: "component", type: ProfilesMenuComponent, selector: "tb-profiles-menu", inputs: ["tableId", "isMatMenuChild"] }, { kind: "component", type: TableHeaderMenuComponent, selector: "lib-table-header-menu" }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i3$1.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "ngmodule", type: MatMenuModule }, { kind: "component", type: i1$4.MatMenu, selector: "mat-menu", inputs: ["backdropClass", "aria-label", "aria-labelledby", "aria-describedby", "xPosition", "yPosition", "overlapTrigger", "hasBackdrop", "class", "classList"], outputs: ["closed", "close"], exportAs: ["matMenu"] }, { kind: "directive", type: i1$4.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: 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 });
5552
5707
  }
5553
5708
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: TableContainerComponent, decorators: [{
5554
5709
  type: Component,
5555
- args: [{ selector: 'tb-table-container', changeDetection: ChangeDetectionStrategy.OnPush, providers: [TableStore, ExportToCsvService, WrapperFilterStore, DataStore], imports: [NgTemplateOutlet,
5710
+ args: [{ selector: 'tb-table-container', changeDetection: ChangeDetectionStrategy.OnPush, providers: [TableStore, ExportToCsvService, WrapperFilterStore, DataStore], imports: [
5711
+ NgTemplateOutlet,
5556
5712
  PaginatorComponent,
5557
5713
  MultiSortDirective, GroupByListComponent, FilterChipsComponent, GenFilterDisplayerComponent, GenColDisplayerComponent,
5558
5714
  SortMenuComponent, GenericTableComponent, ProfilesMenuComponent, TableHeaderMenuComponent,
5559
- MatButtonModule, MatMenuModule, MatIconModule, MatTooltipModule, VirtualScrollContainer], template: "@let tableId = $tableId();\r\n@let tableSettings = state.$tableSettings();\r\n\r\n<ng-content select=\"[before]\" />\r\n<ng-container multiSort>\r\n <div class=\"tb-header-wrapper\" [id]=\"headerId\">\r\n <div class=\"title\">\r\n @if ((!$collapsedHeader()) || tableSettings.showTitleWhenHeaderCollapsed) {\r\n <ng-content select=\".tb-header-title\"/>\r\n }\r\n @if(state.$groupByKeys().length){\r\n <group-by-list />\r\n }\r\n </div>\r\n <div class=\"flx-row-end\">\r\n <lib-filter-list />\r\n @if (!tableSettings.hideHeader) {\r\n @if (!$collapsedHeader()) {\r\n <ng-container *ngTemplateOutlet=\"headerMenu\"/>\r\n <button mat-icon-button color='primary' [matMenuTriggerFor]=\"l.menu()\">\r\n <mat-icon>more_vert</mat-icon>\r\n </button>\r\n\r\n <lib-table-header-menu #l/>\r\n\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; injector menuInjector\"/>\r\n </div>\r\n <lib-table-header-menu />\r\n </mat-menu>\r\n }\r\n <mat-icon [matTooltip]=\"$collapsedHeader() ? 'expand' : 'collapse'\" class=\"collapse-icon header\"\r\n (click)=\"state.toggleCollapseHeader()\">\r\n {{$collapsedHeader() ? 'expand_less' : 'expand_more'}}\r\n </mat-icon>\r\n }\r\n\r\n </div>\r\n </div>\r\n\r\n @if($useVirtual())\r\n {\r\n <tb-virtual-scroll-container class=\"scrollable\">\r\n <tb-generic-table [rows]=\"$customRows()\" [data]=\"$data()!\" [displayDataLength]=\"$displayDataLength()\"\r\n (selection)='selection$.emit($event)' [columnInfos]='$myColumns()' [trackBy]=\"$trackBy()\" [dataSource]=\"dataSource\" />\r\n </tb-virtual-scroll-container>\r\n }\r\n @else\r\n {\r\n <tb-generic-table [rows]=\"$customRows()\" [data]=\"$data()!\" [displayDataLength]=\"$displayDataLength()\"\r\n (selection)='selection$.emit($event)' [columnInfos]='$myColumns()' [trackBy]=\"$trackBy()\" [dataSource]=\"dataSource\" />\r\n }\r\n @if(tableSettings.usePaginator)\r\n {\r\n <div class=\"paginator\">\r\n <tb-paginator #tbPaginator />\r\n\r\n <mat-icon [matTooltip]=\"$collapsedFooter() ? 'expand' : 'collapse'\" class=\"collapse-icon footer\"\r\n (click)=\"state.toggleCollapseFooter()\">\r\n {{$collapsedFooter() ? 'expand_more' : 'expand_less'}}\r\n </mat-icon>\r\n </div>\r\n }\r\n\r\n <ng-template #headerMenu>\r\n @if (!tableSettings.hideFilter) {<tb-filter-displayer/>}\r\n @if (!tableSettings.hideColumnSettings) {<tb-col-displayer/>}\r\n @if (!tableSettings.hideSort) {<tb-sort-menu/>}\r\n @if (!!tableId) {<tb-profiles-menu [tableId]=\"tableId\"/>}\r\n </ng-template>\r\n\r\n</ng-container>\r\n", styles: [".tb-header-wrapper{display:flex;flex-direction:row;justify-content:space-between;width:100%}.flx-row-end{display:flex;flex-direction:row;justify-content:flex-end;align-items:center}.flat-menu{line-height:initial;height:initial}.pointer{cursor:pointer}.add-key{width:90%}.paginator{display:flex;flex-direction:row;justify-content:flex-end;align-items:center;background-color:#fff;bottom:0;position:sticky;border-top:.5px solid rgba(0,0,0,.12)}.profiles-menu{visibility:hidden;width:0px;height:0px;display:block;overflow:hidden;position:absolute;top:50px}\n", ".collapse-icon{font-size:16px;height:16px;color:#3f51b5;align-self:flex-start}.collapse-icon:hover{cursor:pointer}.hide{display:none}.paginator-row{display:flex;align-items:center}\n"] }]
5715
+ MatButtonModule, MatMenuModule, MatIconModule, MatTooltipModule, VirtualScrollContainer
5716
+ ], template: "@let tableId = $tableId();\r\n@let tableSettings = state.$tableSettings();\r\n\r\n<ng-content select=\"[before]\" />\r\n<ng-container multiSort>\r\n <div class=\"tb-header-wrapper\" [id]=\"headerId\">\r\n <div class=\"title\">\r\n @if ((!$collapsedHeader()) || tableSettings.showTitleWhenHeaderCollapsed)\r\n {\r\n <ng-content select=\".tb-header-title\"/>\r\n }\r\n </div>\r\n @if(state.$groupByKeys().length){\r\n <group-by-list />\r\n }\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]=\"l.menu()\">\r\n <mat-icon>more_vert</mat-icon>\r\n </button>\r\n\r\n <lib-table-header-menu #l/>\r\n\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; injector menuInjector\"/>\r\n </div>\r\n <lib-table-header-menu />\r\n </mat-menu>\r\n }\r\n <mat-icon [matTooltip]=\"$collapsedHeader() ? 'expand' : 'collapse'\" class=\"collapse-icon header\"\r\n (click)=\"state.toggleCollapseHeader()\">\r\n {{$collapsedHeader() ? 'expand_less' : 'expand_more'}}\r\n </mat-icon>\r\n }\r\n\r\n </div>\r\n </div>\r\n\r\n @if($useVirtual())\r\n {\r\n <tb-virtual-scroll-container class=\"scrollable\">\r\n <tb-generic-table [rows]=\"$customRows()\" [data]=\"$data()!\" [displayDataLength]=\"$displayDataLength()\"\r\n (selection)='selection$.emit($event)' [columnInfos]='$myColumns()' [trackBy]=\"$trackBy()\" [dataSource]=\"dataSource\" />\r\n </tb-virtual-scroll-container>\r\n }\r\n @else\r\n {\r\n <tb-generic-table [rows]=\"$customRows()\" [data]=\"$data()!\" [displayDataLength]=\"$displayDataLength()\"\r\n (selection)='selection$.emit($event)' [columnInfos]='$myColumns()' [trackBy]=\"$trackBy()\" [dataSource]=\"dataSource\" />\r\n }\r\n @if(tableSettings.usePaginator)\r\n {\r\n <div class=\"paginator\">\r\n <tb-paginator #tbPaginator />\r\n\r\n <mat-icon [matTooltip]=\"$collapsedFooter() ? 'expand' : 'collapse'\" class=\"collapse-icon footer\"\r\n (click)=\"state.toggleCollapseFooter()\">\r\n {{$collapsedFooter() ? 'expand_more' : 'expand_less'}}\r\n </mat-icon>\r\n </div>\r\n }\r\n\r\n <ng-template #headerMenu>\r\n @if (!tableSettings.hideFilter) {<tb-filter-displayer/>}\r\n @if (!tableSettings.hideColumnSettings) {<tb-col-displayer/>}\r\n @if (!tableSettings.hideSort) {<tb-sort-menu/>}\r\n @if (!!tableId) {<tb-profiles-menu [tableId]=\"tableId\"/>}\r\n </ng-template>\r\n\r\n</ng-container>\r\n", styles: [".tb-header-wrapper{display:flex;flex-direction:row;width:100%}.flx-row-end{display:flex;flex-direction:row;justify-content:flex-end;align-items:center;margin-left:auto}.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"] }]
5560
5717
  }] });
5561
5718
 
5562
5719
  class TableBuilderModule {
@@ -5569,102 +5726,38 @@ class TableBuilderModule {
5569
5726
  };
5570
5727
  }
5571
5728
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: TableBuilderModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
5572
- static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "19.0.0", ngImport: i0, type: TableBuilderModule, imports: [CommonModule,
5573
- MatDialogModule,
5574
- MatNativeDateModule,
5575
- RouterModule,
5576
- TableContainerComponent,
5577
- GenericTableComponent,
5578
- TableContainerComponent,
5729
+ static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "19.0.0", ngImport: i0, type: TableBuilderModule, imports: [TableContainerComponent,
5579
5730
  CustomCellDirective,
5580
- FilterComponent,
5581
- MatSlideToggleTbFilterDirective,
5582
- MatRadioButtonTbFilterDirective,
5583
- MatOptionTbFilterDirective,
5584
- MatCheckboxTbFilterDirective,
5585
- MatButtonToggleFilterDirective,
5586
5731
  TableFilterDirective,
5587
5732
  TableFilterStringContainsDirective,
5588
- TableWrapperDirective,
5589
- ResizeColumnDirective,
5590
- UtilitiesModule], exports: [GenericTableComponent,
5591
- TableContainerComponent,
5733
+ TableWrapperDirective], exports: [TableContainerComponent,
5592
5734
  CustomCellDirective,
5593
- FilterComponent,
5594
- MatSlideToggleTbFilterDirective,
5595
- MatRadioButtonTbFilterDirective,
5596
- MatOptionTbFilterDirective,
5597
- MatCheckboxTbFilterDirective,
5598
- MatButtonToggleFilterDirective,
5599
- TableFilterDirective,
5600
5735
  TableFilterStringContainsDirective,
5601
5736
  TableWrapperDirective,
5602
- ResizeColumnDirective,
5603
5737
  UtilitiesModule] });
5604
5738
  static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: TableBuilderModule, providers: [
5605
- SpaceCasePipe,
5606
- DatePipe,
5607
- CurrencyPipe,
5608
- PhoneNumberPipe,
5609
5739
  MultiSortDirective,
5610
- TableBuilderStateStore,
5611
- ], imports: [CommonModule,
5612
- MatDialogModule,
5613
- MatNativeDateModule,
5614
- RouterModule,
5615
- TableContainerComponent,
5616
- GenericTableComponent,
5617
- TableContainerComponent,
5618
- FilterComponent,
5619
- UtilitiesModule, UtilitiesModule] });
5740
+ ], imports: [TableContainerComponent, UtilitiesModule] });
5620
5741
  }
5621
5742
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: TableBuilderModule, decorators: [{
5622
5743
  type: NgModule,
5623
5744
  args: [{
5624
5745
  imports: [
5625
- CommonModule,
5626
- MatDialogModule,
5627
- MatNativeDateModule,
5628
- RouterModule,
5629
- TableContainerComponent,
5630
- GenericTableComponent,
5631
5746
  TableContainerComponent,
5632
5747
  CustomCellDirective,
5633
- FilterComponent,
5634
- MatSlideToggleTbFilterDirective,
5635
- MatRadioButtonTbFilterDirective,
5636
- MatOptionTbFilterDirective,
5637
- MatCheckboxTbFilterDirective,
5638
- MatButtonToggleFilterDirective,
5639
5748
  TableFilterDirective,
5640
5749
  TableFilterStringContainsDirective,
5641
5750
  TableWrapperDirective,
5642
- ResizeColumnDirective,
5643
- UtilitiesModule,
5644
5751
  ],
5645
5752
  exports: [
5646
- GenericTableComponent,
5647
5753
  TableContainerComponent,
5648
5754
  CustomCellDirective,
5649
- FilterComponent,
5650
- MatSlideToggleTbFilterDirective,
5651
- MatRadioButtonTbFilterDirective,
5652
- MatOptionTbFilterDirective,
5653
- MatCheckboxTbFilterDirective,
5654
- MatButtonToggleFilterDirective,
5655
- TableFilterDirective,
5656
5755
  TableFilterStringContainsDirective,
5657
5756
  TableWrapperDirective,
5658
- ResizeColumnDirective,
5659
5757
  UtilitiesModule,
5660
5758
  ],
5661
5759
  providers: [
5662
- SpaceCasePipe,
5663
- DatePipe,
5664
- CurrencyPipe,
5665
- PhoneNumberPipe,
5666
5760
  MultiSortDirective,
5667
- TableBuilderStateStore,
5668
5761
  ]
5669
5762
  }]
5670
5763
  }] });
@@ -5692,66 +5785,86 @@ class MatTableObservableDataSource extends MatTableDataSource {
5692
5785
  }
5693
5786
 
5694
5787
  class TableBuilder {
5695
- metaData$;
5696
- data$;
5697
- settings$;
5788
+ data;
5789
+ metaData;
5790
+ settings;
5791
+ #$metaData;
5792
+ #$data;
5793
+ #$settings;
5794
+ $metaData = computed(() => this.$initialized() ? this.#$metaData() : undefined);
5795
+ $settings = computed(() => this.$initialized() ? this.#$settings() : undefined);
5796
+ metaNeedsPrep = false;
5797
+ dataIsObservable = false;
5798
+ settingsIsObservable = false;
5799
+ $initialized = signal(false);
5698
5800
  constructor(data, metaData, settings = new GeneralTableSettings()) {
5699
- this.settings$ = this.coerceSettingsToObservable(settings)
5700
- .pipe(defaultShareReplay());
5701
- this.data$ = this.coerceToObservable(data, this.settings$)
5702
- .pipe(notNull(), defaultShareReplay());
5703
- this.metaData$ = metaData ?
5704
- this.coerceToObservable(metaData, this.settings$).pipe(defaultShareReplay())
5705
- :
5706
- this.data$.pipe(first$1(), map(d => this.createMetaData(d[0])), defaultShareReplay());
5707
- }
5708
- getData$() {
5709
- return this.metaData$.pipe(map(md => createDataCleaners(md)), switchMap(cleaner => this.data$.pipe(map((datas, ii) => {
5710
- return datas.map((data, i) => {
5711
- const cleaned = cleaner(data);
5712
- cleaned[initIndexSymbol] = i * ((ii % 2) + 1);
5713
- return cleaned;
5714
- });
5715
- }))), defaultShareReplay());
5716
- }
5717
- createMetaData(obj) {
5718
- return Object.keys(obj ?? {})
5719
- .map(key => ({
5720
- key,
5721
- fieldType: FieldType.Unknown,
5722
- order: -1
5723
- }));
5724
- }
5725
- coerceToObservable(arg, settings) {
5726
- if (isObservable(arg)) {
5727
- return arg;
5801
+ this.data = data;
5802
+ this.metaData = metaData;
5803
+ this.settings = settings;
5804
+ if (isObservable(data)) {
5805
+ this.dataIsObservable = true;
5728
5806
  }
5729
- else if (isSignal(arg)) {
5730
- return settings.pipe(switchMap(s => {
5731
- this.assertInjector(s);
5732
- return toObservable(arg, { injector: s.injector });
5733
- }));
5807
+ else {
5808
+ this.#$data = isSignal(data) ? data : signal(data);
5809
+ }
5810
+ if (isObservable(metaData) || !metaData) {
5811
+ this.metaNeedsPrep = true;
5734
5812
  }
5735
5813
  else {
5736
- return of(arg);
5814
+ this.#$metaData = isSignal(metaData) ? metaData : signal(metaData);
5737
5815
  }
5738
- }
5739
- coerceSettingsToObservable(settings) {
5740
5816
  if (isObservable(settings)) {
5741
- return settings;
5742
- }
5743
- else if (isSignal(settings)) {
5744
- this.assertInjector(settings());
5745
- return toObservable(settings, { injector: settings().injector });
5817
+ this.settingsIsObservable = true;
5746
5818
  }
5747
5819
  else {
5748
- return of(settings);
5820
+ this.#$settings = isSignal(settings) ? settings : signal(settings);
5821
+ }
5822
+ if (!this.dataIsObservable && !this.settingsIsObservable && !this.metaNeedsPrep) {
5823
+ this.$initialized.set(true);
5749
5824
  }
5750
5825
  }
5751
- assertInjector(s) {
5752
- if (!s.injector) {
5753
- throw new Error('Injector must be provided when passing a signal to table builder');
5826
+ prep(injector) {
5827
+ if (this.settingsIsObservable) {
5828
+ this.#$settings = toSignal(this.settings, { injector, requireSync: true });
5829
+ }
5830
+ if (this.dataIsObservable) {
5831
+ this.#$data = toSignal(this.data, { injector, initialValue: [] });
5754
5832
  }
5833
+ if (this.metaNeedsPrep) {
5834
+ if (this.metaData) {
5835
+ this.#$metaData = toSignal(this.metaData, { injector, initialValue: [] });
5836
+ }
5837
+ else {
5838
+ this.#$metaData = computed(() => this.createMetaData(this.#$data()[0]));
5839
+ }
5840
+ }
5841
+ this.$initialized.set(true);
5842
+ }
5843
+ #dataCleaners = computed(() => {
5844
+ const metaData = this.$metaData();
5845
+ if (!metaData)
5846
+ return undefined;
5847
+ return createDataCleaners(metaData);
5848
+ });
5849
+ $data = computed(() => {
5850
+ const data = this.#$data();
5851
+ const cleaners = this.#dataCleaners();
5852
+ if (!data || !cleaners)
5853
+ return [];
5854
+ const cleanedData = data.map((data, i) => {
5855
+ const cleaned = cleaners(data);
5856
+ cleaned[initIndexSymbol] = i;
5857
+ return cleaned;
5858
+ });
5859
+ return cleanedData;
5860
+ });
5861
+ createMetaData(obj) {
5862
+ return Object.keys(obj ?? {})
5863
+ .map(key => ({
5864
+ key,
5865
+ fieldType: FieldType.Unknown,
5866
+ order: -1
5867
+ }));
5755
5868
  }
5756
5869
  }
5757
5870
  const CreateTableBuilder = (reportDef$) => {
@@ -5977,5 +6090,5 @@ function setUpStoreFactoryOld(store, env) {
5977
6090
  * Generated bundle index. Do not edit.
5978
6091
  */
5979
6092
 
5980
- export { ActionStateSpinnerComponent, ActionStateUiModule, ActionStatus, AppStatusState, ArrayStyle, AutoFocusDirective, CancellationToken, ClickEmitterDirective, ClickSubjectDirective, ConditionalClassesDirective, CreateTableBuilder, CustomCellDirective, DateFilterComponent, DefaultVirtualScrollOptions, DialogDirective, DialogService, DialogWrapper, FieldType, FilterChipsComponent, FilterComponent, FilterType, FunctionPipe, GenColDisplayerComponent, GenFilterDisplayerComponent, GeneralTableSettings, GenericTableComponent, GroupByListComponent, HttpErrorStateDirective, HttpInProgressStateDirective, HttpNotStartedStateDirective, HttpRequestModule, HttpRequestStateDirective, HttpRequestStateFactory, HttpRequestStateStore, HttpRequestStatus, HttpRequestStrategy, HttpSuccessStateDirective, MatButtonToggleFilterDirective, MatCheckboxTbFilterDirective, MatOptionTbFilterDirective, MatRadioButtonTbFilterDirective, MatSlideToggleGroupDirective, MatSlideToggleTbFilterDirective, MatTableObservableDataSource, MultiSortDirective, NgrxExtModule, NotPersistedTableSettings, PaginatorComponent, PaginatorOptions, PersistedTableSettings, PhoneNumberPipe, PreventEnterDirective, ResizeColumnDirective, SortDirection, SpaceCasePipe, StopPropagationDirective, StylerDirective, Subjectifier, Subscriber, TableBuilder, TableBuilderConfigToken, TableBuilderModule, TableColumnHeaderSettings, TableContainerComponent, TableCustomFilterDirective, TableCustomFilterDirectiveBase, TableFilterDirective, TableFilterStringContainsDirective, TableSettings, TableWrapperDirective, TableWrapperFooterSettings, TableWrapperHeaderSettings, Target, TbSelectedFilterDirective, TrimWhitespaceDirective, UtilitiesModule, VirtualScrollOptions, actionStatusReducer, chainRequest, clearActionableSelectorRequestCache, combineArrays, createActionResultSelector, createActionSelector, createActionableResultSelector, createActionableSelector, createFailure, createRequestor, createSuccess, defaultFilter, defaultShareReplay, delayOn, filterArray, getRequestorBody, getRequestorStatus, getStatusState, httpRequest, httpRequestor, inProgress, initialState, isErrorState, isSuccessOrErrorState, isSuccessState, mapArray, mapError, metaDataArrToDict, notNull, notStarted, onWait, onceWhen, parseTbSizeToPixels, previousAndCurrent, provideActionableSelector, provideTableBuilder, selectAll, selectEntities, selectEntity, selectIds, selectTotal, serverStatusTypes, setUpStoreFactory, setUpStoreFactoryOld, skipOneWhen, sortsAreSame, spaceCase, startWithIfEmpty, statusAdapter, statusIsSuccessOrInProgress, subscriber, switchOff, tapError, tapSuccess, wrapInArr };
6093
+ export { ActionStateSpinnerComponent, ActionStateUiModule, ActionStatus, AppStatusState, ArrayStyle, AutoFocusDirective, CancellationToken, ClickEmitterDirective, ClickSubjectDirective, ConditionalClassesDirective, CreateTableBuilder, CustomCellDirective, DateFilterComponent, DefaultVirtualScrollOptions, DialogDirective, DialogService, DialogWrapper, FieldType, FilterChipsComponent, FilterComponent, FilterType, FunctionPipe, GenColDisplayerComponent, GenFilterDisplayerComponent, GeneralTableSettings, GenericTableComponent, GroupByListComponent, HttpErrorStateDirective, HttpInProgressStateDirective, HttpNotStartedStateDirective, HttpRequestModule, HttpRequestStateDirective, HttpRequestStateFactory, HttpRequestStateStore, HttpRequestStatus, HttpRequestStrategy, HttpSuccessStateDirective, MatButtonToggleFilterDirective, MatCheckboxTbFilterDirective, MatOptionTbFilterDirective, MatRadioButtonTbFilterDirective, MatSlideToggleGroupDirective, MatSlideToggleTbFilterDirective, MatTableObservableDataSource, MultiSortDirective, NgrxExtModule, NotPersistedTableSettings, PaginatorComponent, PaginatorOptions, PersistedTableSettings, PhoneNumberPipe, PreventEnterDirective, ResizeColumnDirective, SortDirection, SpaceCasePipe, StopPropagationDirective, StylerDirective, Subjectifier, Subscriber, TableBuilder, TableBuilderConfigToken, TableBuilderModule, TableColumnFooterSettings, 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, parseTbSizeToPixels, phoneFormatter, previousAndCurrent, provideActionableSelector, provideTableBuilder, selectAll, selectEntities, selectEntity, selectIds, selectTotal, serverStatusTypes, setUpStoreFactory, setUpStoreFactoryOld, skipOneWhen, sortsAreSame, spaceCase, startWithIfEmpty, statusAdapter, statusIsSuccessOrInProgress, subscriber, switchOff, tapError, tapSuccess, wrapInArr };
5981
6094
  //# sourceMappingURL=one-paragon-angular-utilities.mjs.map