@one-paragon/angular-utilities 2.0.0-beta.13 → 2.0.0-beta.15

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, ContentChildren, ChangeDetectorRef, output, ViewChild, EnvironmentInjector, createComponent, viewChild, effect, linkedSignal, contentChild, forwardRef, contentChildren, model, runInInjectionContext, provideAppInitializer } 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, ContentChildren, ChangeDetectorRef, output, ViewChild, EnvironmentInjector, createComponent, viewChild, linkedSignal, effect, contentChild, forwardRef, contentChildren, model, runInInjectionContext, provideAppInitializer } from '@angular/core';
3
3
  import { shareReplay, switchAll, map, filter, tap, catchError, startWith, switchMap, mergeMap, concatMap as concatMap$1, takeUntil, distinctUntilChanged, observeOn, scan as scan$1, timestamp as timestamp$1, first as first$1 } from 'rxjs/operators';
4
4
  import * as i1 from 'rxjs';
5
- import { Subject, isObservable, of, ReplaySubject, filter as filter$1, first, map as map$1, Observable, combineLatest, Subscription, startWith as startWith$1, pairwise, concatMap, merge, delay, fromEvent, takeUntil as takeUntil$1, tap as tap$1, switchMap as switchMap$1, scan, animationFrameScheduler, debounceTime, timestamp, 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, animationFrameScheduler, debounceTime, BehaviorSubject } from 'rxjs';
6
6
  import { ComponentStore } from '@ngrx/component-store';
7
7
  import { toObservable, toSignal, outputFromObservable } from '@angular/core/rxjs-interop';
8
- import * as i1$8 from '@angular/common';
9
8
  import { DatePipe, CurrencyPipe, KeyValuePipe, NgTemplateOutlet, DecimalPipe, CommonModule, AsyncPipe } from '@angular/common';
10
9
  import * as i3$2 from '@angular/material/sort';
11
10
  import { MatSort, MatSortModule } from '@angular/material/sort';
@@ -24,7 +23,7 @@ import * as i9 from '@angular/material/core';
24
23
  import { MatOption, MatNativeDateModule } from '@angular/material/core';
25
24
  import * as i5 from '@angular/cdk/drag-drop';
26
25
  import { moveItemInArray, DragDropModule, CDK_DROP_LIST, CdkDropList, transferArrayItem } from '@angular/cdk/drag-drop';
27
- import * as i1$4 from '@angular/router';
26
+ import * as i1$5 from '@angular/router';
28
27
  import { RouterModule } from '@angular/router';
29
28
  import * as i1$1 from '@angular/material/input';
30
29
  import { MatInputModule, MatInput } from '@angular/material/input';
@@ -42,16 +41,16 @@ import * as i2 from '@angular/material/icon';
42
41
  import { MatIconModule, MatIcon } from '@angular/material/icon';
43
42
  import * as i8 from '@angular/material/select';
44
43
  import { MatSelectModule } from '@angular/material/select';
45
- import * as i4$2 from '@angular/material/menu';
46
- import { MatMenuModule, MatMenuTrigger } from '@angular/material/menu';
47
- import * as i4$3 from '@angular/material/chips';
44
+ import * as i1$4 from '@angular/material/menu';
45
+ import { MatMenuModule, MatMenuTrigger, MatMenu } from '@angular/material/menu';
46
+ import * as i4$2 from '@angular/material/chips';
48
47
  import { MatChipsModule } from '@angular/material/chips';
49
- import * as i1$5 from '@angular/material/table';
48
+ import * as i1$6 from '@angular/material/table';
50
49
  import { MatTable, MatColumnDef, MatTableModule, MatHeaderRowDef, MatFooterRowDef, MatTableDataSource, MatRowDef } from '@angular/material/table';
51
50
  import { SelectionModel } from '@angular/cdk/collections';
52
- import * as i1$6 from '@angular/material/paginator';
51
+ import * as i1$7 from '@angular/material/paginator';
53
52
  import { MatPaginator, MatPaginatorModule } from '@angular/material/paginator';
54
- import * as i1$7 from '@angular/cdk/scrolling';
53
+ import * as i1$8 from '@angular/cdk/scrolling';
55
54
  import { CdkVirtualScrollViewport, ScrollingModule, VIRTUAL_SCROLL_STRATEGY } from '@angular/cdk/scrolling';
56
55
  import * as i1$9 from '@ngrx/store';
57
56
  import { createFeatureSelector, createSelector, StoreModule, Store } from '@ngrx/store';
@@ -898,6 +897,22 @@ const DefaultVirtualScrollOptions = {
898
897
  rowHeight: 48,
899
898
  headerHeight: 56,
900
899
  };
900
+ function parseTbSizeToPixels(size) {
901
+ if (!size)
902
+ return undefined;
903
+ if (typeof size === 'number')
904
+ return size;
905
+ if (size.endsWith('px'))
906
+ return Number(size.replace('px', ''));
907
+ if (size.endsWith('rem')) {
908
+ const htmlElement = document.documentElement;
909
+ const remSize = window.getComputedStyle(htmlElement).getPropertyValue('font-size');
910
+ const remSizeNum = Number(remSize.replace('px', ''));
911
+ const num = Number(size.replace('rem', ''));
912
+ return num * remSizeNum;
913
+ }
914
+ return undefined;
915
+ }
901
916
 
902
917
  class KeysToDelete {
903
918
  initializationState = null;
@@ -1100,7 +1115,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImpor
1100
1115
  }]
1101
1116
  }] });
1102
1117
 
1103
- const FilterTypes = {
1118
+ const FilterType = {
1104
1119
  NumberEquals: 'Equals',
1105
1120
  NumberNotEqual: 'Does Not Equal',
1106
1121
  NumberGreaterThan: 'Greater Than',
@@ -1154,7 +1169,7 @@ class TableFilterDirective {
1154
1169
  }
1155
1170
  if (this.model) {
1156
1171
  subscriber(this.model.valueChanges, val => {
1157
- if (this.filterType === FilterTypes.StringContains && val === '') {
1172
+ if (this.filterType === FilterType.StringContains && val === '') {
1158
1173
  val = undefined;
1159
1174
  }
1160
1175
  this.filterValue = val;
@@ -1238,7 +1253,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImpor
1238
1253
  class TableFilterStringContainsDirective extends TableFilterDirective {
1239
1254
  constructor() {
1240
1255
  super();
1241
- this.filterType = FilterTypes.StringContains;
1256
+ this.filterType = FilterType.StringContains;
1242
1257
  this.fieldType = FieldType.String;
1243
1258
  }
1244
1259
  reset() {
@@ -1306,7 +1321,7 @@ class TableCustomFilterDirectiveBase extends TableCustomFilterDirective {
1306
1321
  this.savable = true;
1307
1322
  }
1308
1323
  this.filter = {
1309
- filterType: FilterTypes.Custom,
1324
+ filterType: FilterType.Custom,
1310
1325
  filterId: this.filterId,
1311
1326
  active: this._active,
1312
1327
  predicate: this._predicate,
@@ -1573,17 +1588,17 @@ const multipleStringValuesEqualsFunc = (filterInfo) => {
1573
1588
  return ((val) => filterVals.some((s) => prepareForStringCompare(val) === s));
1574
1589
  };
1575
1590
  const StringFilterFuncs = {
1576
- [FilterTypes.StringEquals]: stringEqualFunc,
1577
- [FilterTypes.StringContains]: stringContainsFunc,
1578
- [FilterTypes.StringDoesNotContain]: stringDoesNotContainFunc,
1579
- [FilterTypes.StringStartWith]: stringStartsWithFunc,
1580
- [FilterTypes.StringEndsWith]: stringEndsWithFunc,
1581
- [FilterTypes.IsNull]: isNull,
1582
- [FilterTypes.In]: multipleStringValuesEqualsFunc,
1591
+ [FilterType.StringEquals]: stringEqualFunc,
1592
+ [FilterType.StringContains]: stringContainsFunc,
1593
+ [FilterType.StringDoesNotContain]: stringDoesNotContainFunc,
1594
+ [FilterType.StringStartWith]: stringStartsWithFunc,
1595
+ [FilterType.StringEndsWith]: stringEndsWithFunc,
1596
+ [FilterType.IsNull]: isNull,
1597
+ [FilterType.In]: multipleStringValuesEqualsFunc,
1583
1598
  };
1584
1599
  const EnumFilterFuncs = {
1585
- [FilterTypes.IsNull]: isNull,
1586
- [FilterTypes.In]: multipleStringValuesEqualsFunc,
1600
+ [FilterType.IsNull]: isNull,
1601
+ [FilterType.In]: multipleStringValuesEqualsFunc,
1587
1602
  };
1588
1603
  const prepareForStringCompare = (val) => (val?.toString().trim().toLowerCase());
1589
1604
 
@@ -1608,13 +1623,13 @@ const multipleNumberValuesEqualsFunc = (filterInfo) => {
1608
1623
  return ((val) => filterInfo.filterValue.some((value) => val === value));
1609
1624
  };
1610
1625
  const NumberFilterFuncs = {
1611
- [FilterTypes.NumberEquals]: numberEqalsFunc,
1612
- [FilterTypes.NumberNotEqual]: numberNotEqualFunc,
1613
- [FilterTypes.NumberGreaterThan]: numberGreaterThanFunc,
1614
- [FilterTypes.NumberLessThan]: numberLessThanFunc,
1615
- [FilterTypes.NumberBetween]: numberBetweenFunc,
1616
- [FilterTypes.IsNull]: isNull,
1617
- [FilterTypes.In]: multipleNumberValuesEqualsFunc,
1626
+ [FilterType.NumberEquals]: numberEqalsFunc,
1627
+ [FilterType.NumberNotEqual]: numberNotEqualFunc,
1628
+ [FilterType.NumberGreaterThan]: numberGreaterThanFunc,
1629
+ [FilterType.NumberLessThan]: numberLessThanFunc,
1630
+ [FilterType.NumberBetween]: numberBetweenFunc,
1631
+ [FilterType.IsNull]: isNull,
1632
+ [FilterType.In]: multipleNumberValuesEqualsFunc,
1618
1633
  };
1619
1634
 
1620
1635
  const dateIsOnFunc = (filterInfo) => {
@@ -1655,37 +1670,37 @@ const cleanDateTime = (filterInfo, val) => {
1655
1670
  return val;
1656
1671
  };
1657
1672
  const DateFilterFuncs = {
1658
- [FilterTypes.DateIsOn]: dateIsOnFunc,
1659
- [FilterTypes.DateIsNotOn]: dateIsNotOnFunc,
1660
- [FilterTypes.DateOnOrAfter]: dateIsOnOrAfterFunc,
1661
- [FilterTypes.DateOnOrBefore]: dateIsOnOrBeforeFunc,
1662
- [FilterTypes.DateBetween]: dateBetweenFunc,
1663
- [FilterTypes.IsNull]: isNull,
1673
+ [FilterType.DateIsOn]: dateIsOnFunc,
1674
+ [FilterType.DateIsNotOn]: dateIsNotOnFunc,
1675
+ [FilterType.DateOnOrAfter]: dateIsOnOrAfterFunc,
1676
+ [FilterType.DateOnOrBefore]: dateIsOnOrBeforeFunc,
1677
+ [FilterType.DateBetween]: dateBetweenFunc,
1678
+ [FilterType.IsNull]: isNull,
1664
1679
  };
1665
1680
  const DateTimeFilterFuncs = {
1666
1681
  ...DateFilterFuncs,
1667
- [FilterTypes.DateTimeIsAt]: dateIsOnFunc,
1668
- [FilterTypes.DateTimeIsNotAt]: dateIsNotOnFunc,
1669
- [FilterTypes.DateTimeAtOrAfter]: dateIsOnOrAfterFunc,
1670
- [FilterTypes.DateTimeAtOrBefore]: dateIsOnOrBeforeFunc,
1671
- [FilterTypes.DateTimeBetween]: dateBetweenFunc,
1672
- [FilterTypes.IsNull]: isNull,
1682
+ [FilterType.DateTimeIsAt]: dateIsOnFunc,
1683
+ [FilterType.DateTimeIsNotAt]: dateIsNotOnFunc,
1684
+ [FilterType.DateTimeAtOrAfter]: dateIsOnOrAfterFunc,
1685
+ [FilterType.DateTimeAtOrBefore]: dateIsOnOrBeforeFunc,
1686
+ [FilterType.DateTimeBetween]: dateBetweenFunc,
1687
+ [FilterType.IsNull]: isNull,
1673
1688
  };
1674
1689
 
1675
1690
  const booleanEqualsFunc = (filterInfo) => (val) => {
1676
1691
  return filterInfo.filterValue === val;
1677
1692
  };
1678
1693
  const BooleanFilterFuncs = {
1679
- [FilterTypes.BooleanEquals]: booleanEqualsFunc,
1680
- [FilterTypes.IsNull]: isNull,
1694
+ [FilterType.BooleanEquals]: booleanEqualsFunc,
1695
+ [FilterType.IsNull]: isNull,
1681
1696
  };
1682
1697
 
1683
1698
  const filterFactoryMap = {
1684
- [FilterTypes.And]: (filter) => {
1699
+ [FilterType.And]: (filter) => {
1685
1700
  const filters = createFilterFuncs(filter.filterValue);
1686
1701
  return (obj) => filters.every(f => f(obj));
1687
1702
  },
1688
- [FilterTypes.In]: (filter) => {
1703
+ [FilterType.In]: (filter) => {
1689
1704
  const filters = createFilterFuncs(filter.filterValue);
1690
1705
  return (obj) => filters.some(f => f(obj));
1691
1706
  },
@@ -1705,10 +1720,10 @@ const filterTypeFuncMap = {
1705
1720
  };
1706
1721
  const filterTypeMap = Object.entries(filterTypeFuncMap).reduce((acc, [key, value]) => ({ ...acc, [key]: Object.keys(value) }), {});
1707
1722
  function isCustomFilter(filter) {
1708
- return filter && filter.filterType === FilterTypes.Custom;
1723
+ return filter && filter.filterType === FilterType.Custom;
1709
1724
  }
1710
1725
  function isFilterInfo(filter) {
1711
- return filter && typeof filter.key === 'string' && filter.filterType !== FilterTypes.Custom;
1726
+ return filter && typeof filter.key === 'string' && filter.filterType !== FilterType.Custom;
1712
1727
  }
1713
1728
  const defaultPredicate = () => true;
1714
1729
  function createFilterFuncs(filters) {
@@ -1742,10 +1757,10 @@ function createFilterFunc(filter) {
1742
1757
  };
1743
1758
  }
1744
1759
  const FalseyValueCanBeIncludedFilterTypes = [
1745
- FilterTypes.IsNull,
1746
- FilterTypes.NumberNotEqual,
1747
- FilterTypes.DateIsNotOn,
1748
- FilterTypes.StringDoesNotContain,
1760
+ FilterType.IsNull,
1761
+ FilterType.NumberNotEqual,
1762
+ FilterType.DateIsNotOn,
1763
+ FilterType.StringDoesNotContain,
1749
1764
  ];
1750
1765
 
1751
1766
  const replaceInArrayWithClone = (arr, findMeth, actionOnClone = ((t) => { })) => {
@@ -1882,13 +1897,14 @@ class TableStore extends ComponentStore {
1882
1897
  $hiddenKeys = this.selectSignal(state => state.hiddenKeys);
1883
1898
  $orderedVisibleColumns = this.selectSignal(this.$orderedCodeVisibleMetaDatas, this.$hiddenKeys, (cs, hiddenKeys) => cs.filter(m => !hiddenKeys.includes(m.key)).map(m => m.key));
1884
1899
  $getUserDefinedWidths = this.selectSignal(state => state.userDefined.widths);
1885
- $tableSettingsMinWidth = this.selectSignal(state => state.notPersistedTableSettings.minColumnWidth);
1900
+ $tableSettingsMinWidth = this.selectSignal(state => parseTbSizeToPixels(state.notPersistedTableSettings.minColumnWidth));
1886
1901
  $getUserDefinedWidth = (key) => this.selectSignal(this.$getUserDefinedWidths, widths => widths[key]);
1887
1902
  $filters = this.selectSignal(state => state.filters);
1888
1903
  filters$ = this.select(state => state.filters);
1889
1904
  $getFilter = (filterId) => {
1890
1905
  return this.selectSignal(this.$filters, filters => filters[filterId]);
1891
1906
  };
1907
+ $preSort = computed(() => createPreSort(this.$metaData()));
1892
1908
  $selectSorted = this.selectSignal(state => state.sorted, {
1893
1909
  equal: sortsAreSame
1894
1910
  });
@@ -1897,6 +1913,8 @@ class TableStore extends ComponentStore {
1897
1913
  .pipe(switchMap(() => this.selectSorted$));
1898
1914
  $getUserDefinedTableWidth = this.selectSignal(state => state.userDefined.table.width);
1899
1915
  getUserDefinedTableWidth$ = this.select(state => state.userDefined.table.width);
1916
+ $userDefinedRowHeight = this.selectSignal(state => (state.userDefined.rowHeight));
1917
+ $userDefinedHeaderHeight = this.selectSignal(state => (state.userDefined.headerHeight));
1900
1918
  $footerCollapsed = this.selectSignal(state => state.persistedTableSettings.collapseFooter);
1901
1919
  $headerCollapsed = this.selectSignal(state => state.persistedTableSettings.collapseHeader);
1902
1920
  $groupBy = this.selectSignal(state => state.groupBy);
@@ -1920,6 +1938,7 @@ class TableStore extends ComponentStore {
1920
1938
  const ts = { ...state.persistedTableSettings, ...state.notPersistedTableSettings };
1921
1939
  return ts;
1922
1940
  });
1941
+ $notPersistedTableSettings = this.selectSignal(state => state.notPersistedTableSettings);
1923
1942
  tableSettings$ = toObservable(this.$tableSettings);
1924
1943
  $props = this.selectSignal(s => s.props);
1925
1944
  $getLinkInfo = (md) => this.selectSignal(state => state.linkMaps[md.key]);
@@ -1944,9 +1963,46 @@ class TableStore extends ComponentStore {
1944
1963
  }
1945
1964
  });
1946
1965
  resetState = this.updater((state) => {
1947
- const sorted = createPreSort(state.metaData);
1966
+ const sorted = this.$preSort();
1948
1967
  return ({ ...state, hiddenKeys: [], sorted, filters: {}, groupBy: [], userDefined: { widths: {}, order: {}, table: {} } });
1949
1968
  });
1969
+ resetPart = this.updater((state, part) => {
1970
+ const newState = { ...state };
1971
+ switch (part) {
1972
+ case 'Sorting':
1973
+ newState.sorted = this.$preSort();
1974
+ return newState;
1975
+ case 'Filters':
1976
+ newState.filters = {};
1977
+ return newState;
1978
+ case 'Group By':
1979
+ newState.groupBy = [];
1980
+ return newState;
1981
+ case 'Hidden Columns':
1982
+ newState.hiddenKeys = [];
1983
+ return newState;
1984
+ case 'Column Widths':
1985
+ newState.userDefined.widths = {};
1986
+ newState.userDefined.table = {};
1987
+ return newState;
1988
+ case 'Column Order':
1989
+ newState.userDefined.order = {};
1990
+ return newState;
1991
+ case 'Page Size':
1992
+ delete newState.userDefined.pageSize;
1993
+ return newState;
1994
+ case 'Show All':
1995
+ delete newState.userDefined.showAll;
1996
+ return newState;
1997
+ case 'Row Height':
1998
+ delete newState.userDefined.rowHeight;
1999
+ return newState;
2000
+ case 'Header Height':
2001
+ delete newState.userDefined.headerHeight;
2002
+ return newState;
2003
+ }
2004
+ return newState;
2005
+ });
1950
2006
  updateStateFromPersistedState = this.updater((state, persistedState) => {
1951
2007
  const incomingTableState = cleanPersistedState(state, persistedState);
1952
2008
  const newState = this.updateStateFunc(state, incomingTableState);
@@ -1956,7 +2012,7 @@ class TableStore extends ComponentStore {
1956
2012
  updateStateFunc = (state, incomingTableState) => {
1957
2013
  const metaData = state.metaData;
1958
2014
  const sorted = incomingTableState.sorted?.length ? incomingTableState.sorted
1959
- : state.initializationState === InitializationState.Created ? createPreSort(metaData) : state.sorted;
2015
+ : state.initializationState === InitializationState.Created ? this.$preSort() : state.sorted;
1960
2016
  return { ...state, ...incomingTableState, metaData, sorted };
1961
2017
  };
1962
2018
  setTableSettings = this.updater((state, settings) => {
@@ -1982,7 +2038,7 @@ class TableStore extends ComponentStore {
1982
2038
  return prev;
1983
2039
  }, {});
1984
2040
  const sortedInitialized = state.sorted.length > 0;
1985
- const sorted = sortedInitialized ? state.sorted : createPreSort(metaData);
2041
+ const sorted = sortedInitialized ? state.sorted : this.$preSort();
1986
2042
  const order = initializeOrder(state, metaData);
1987
2043
  const initializationState = state.initializationState == InitializationState.Created ? InitializationState.MetaDataLoaded : state.initializationState;
1988
2044
  return { ...state, initializationState, metaData, sorted, userDefined: { ...state.userDefined, order: order } };
@@ -2015,6 +2071,12 @@ class TableStore extends ComponentStore {
2015
2071
  }, {});
2016
2072
  return ({ ...state, userDefined: { ...state.userDefined, order: userDefinedOrder } });
2017
2073
  });
2074
+ setUserDefinedRowHeight = this.updater((state, rowHeight) => {
2075
+ return ({ ...state, userDefined: { ...state.userDefined, rowHeight } });
2076
+ });
2077
+ setUserDefinedHeaderHeight = this.updater((state, headerHeight) => {
2078
+ return ({ ...state, userDefined: { ...state.userDefined, headerHeight } });
2079
+ });
2018
2080
  addFilter = this.updater((state, filter) => {
2019
2081
  return this.addFiltersToState(state, [filter]);
2020
2082
  });
@@ -2140,6 +2202,18 @@ class TableStore extends ComponentStore {
2140
2202
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: TableStore, decorators: [{
2141
2203
  type: Injectable
2142
2204
  }], ctorParameters: () => [] });
2205
+ const resetable = [
2206
+ 'Sorting',
2207
+ 'Filters',
2208
+ 'Group By',
2209
+ 'Hidden Columns',
2210
+ 'Column Widths',
2211
+ 'Column Order',
2212
+ 'Row Height',
2213
+ 'Header Height',
2214
+ 'Page Size',
2215
+ 'Show All',
2216
+ ];
2143
2217
 
2144
2218
  class MultiSortDirective extends MatSort {
2145
2219
  state = inject(TableStore);
@@ -2186,7 +2260,7 @@ function sortsAreSame(a, b) {
2186
2260
  }
2187
2261
 
2188
2262
  class DateFilterComponent {
2189
- FilterType = FilterTypes;
2263
+ FilterType = FilterType;
2190
2264
  info;
2191
2265
  CurrentFilterType;
2192
2266
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: DateFilterComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
@@ -2765,7 +2839,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImpor
2765
2839
  }], ctorParameters: () => [] });
2766
2840
 
2767
2841
  class NumberFilterComponent {
2768
- FilterType = FilterTypes;
2842
+ FilterType = FilterType;
2769
2843
  FieldType = FieldType;
2770
2844
  $currentFilterType = input.required({ alias: 'CurrentFilterType' });
2771
2845
  $info = input.required({ alias: 'info' });
@@ -2780,7 +2854,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImpor
2780
2854
  }] });
2781
2855
 
2782
2856
  class DateTimeFilterComponent {
2783
- FilterType = FilterTypes;
2857
+ FilterType = FilterType;
2784
2858
  info;
2785
2859
  CurrentFilterType;
2786
2860
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: DateTimeFilterComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
@@ -2887,7 +2961,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImpor
2887
2961
  class FilterComponent {
2888
2962
  state = inject(TableStore);
2889
2963
  filterTypes = filterTypeMap;
2890
- FilterType = FilterTypes;
2964
+ FilterType = FilterType;
2891
2965
  FieldType = FieldType;
2892
2966
  $filter = input.required({
2893
2967
  alias: 'filter',
@@ -2939,7 +3013,7 @@ class GenColDisplayerComponent {
2939
3013
  this.tableState.setHiddenColumns(displayCols.map(c => ({ key: c.key, visible: c.isVisible })));
2940
3014
  }
2941
3015
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: GenColDisplayerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
2942
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.0", type: GenColDisplayerComponent, isStandalone: true, selector: "tb-col-displayer", ngImport: i0, template: "@if($columns(); as displayCols){\r\n <span matTooltip=\"Show/hide columns\">\r\n <button mat-icon-button [matMenuTriggerFor]=\"menu\">\r\n <mat-icon color=\"primary\">visibility_off</mat-icon>\r\n </button>\r\n </span>\r\n <mat-menu #menu=\"matMenu\" class=\"my-mat-menu\">\r\n\r\n <button mat-menu-item>\r\n <span matTooltip=\"Close\">\r\n <button class=\"filter-button\" mat-icon-button>\r\n <mat-icon>close</mat-icon>\r\n </button>\r\n </span>\r\n </button>\r\n\r\n <button mat-menu-item stop-propagation>\r\n <span matTooltip=\"Show all columns\">\r\n <button mat-icon-button (click)=\"reset(displayCols)\">\r\n <mat-icon color=\"primary\">done_all</mat-icon>\r\n </button>\r\n </span>\r\n\r\n <span matTooltip=\"Hide all columns\">\r\n <button mat-icon-button (click)=\"unset(displayCols)\">\r\n <mat-icon color=\"primary\">cancel</mat-icon>\r\n </button>\r\n </span>\r\n </button>\r\n\r\n <div cdkDropList (cdkDropListDropped)=\"drop($event)\" stop-propagation [cdkDropListLockAxis]=\"'y'\">\r\n @for (col of displayCols; track col.key) {\r\n <button [class.isHidden]=\"!col.isVisible\" stop-propagation mat-menu-item cdkDrag [cdkDragData]=\"col\">\r\n <div (click)=\"col.isVisible = !col.isVisible; emit(displayCols)\" style=\"display: flex; align-items: center;\">\r\n @if(col.isVisible){\r\n <button mat-icon-button matTooltip=\"Hide Column\" class=\"show-hide\">\r\n <mat-icon color=\"primary\">check_box</mat-icon>\r\n </button>\r\n } @else {\r\n <button mat-icon-button matTooltip=\"Show Column\" class=\"show-hide\">\r\n <mat-icon>indeterminate_check_box</mat-icon>\r\n </button>\r\n }\r\n \r\n <p class=\"label\">\r\n {{col.displayName || (col.key | spaceCase) }}\r\n </p>\r\n\r\n </div>\r\n </button>\r\n }\r\n\r\n </div>\r\n </mat-menu>\r\n}", styles: [".show-hide{margin-right:15px;height:24px;width:24px;padding:4px}.label{color:#6495ed;text-overflow:ellipsis;overflow:hidden;white-space:nowrap;text-align:left;margin:0;font-size:17px;font-weight:700;display:inline-block;width:66%}.row{margin:0;padding:0}.isHidden{background-color:#d3d3d3;color:#a9a9a9;font-weight:700;font-size:17px;white-space:nowrap}.filter-button{margin-top:10px}.cdk-drag-preview{box-sizing:border-box;border-radius:4px;box-shadow:0 5px 5px -3px #0003,0 8px 10px 1px #00000024,0 3px 14px 2px #0000001f}.cdk-drag-placeholder{opacity:0}.cdk-drag-animating{transition:transform .25s cubic-bezier(0,0,.2,1)}.mdc-list-item__primary-text{display:inline-block;width:100%}\n"], dependencies: [{ kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i4$1.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: 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.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "ngmodule", type: MatMenuModule }, { kind: "component", type: i4$2.MatMenu, selector: "mat-menu", inputs: ["backdropClass", "aria-label", "aria-labelledby", "aria-describedby", "xPosition", "yPosition", "overlapTrigger", "hasBackdrop", "class", "classList"], outputs: ["closed", "close"], exportAs: ["matMenu"] }, { kind: "component", type: i4$2.MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i4$2.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }, { kind: "directive", type: StopPropagationDirective, selector: "[stop-propagation]" }, { kind: "ngmodule", type: DragDropModule }, { kind: "directive", type: i5.CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: i5.CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "pipe", type: SpaceCasePipe, name: "spaceCase" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
3016
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.0", type: GenColDisplayerComponent, isStandalone: true, selector: "tb-col-displayer", ngImport: i0, template: "@if($columns(); as displayCols){\r\n <span matTooltip=\"Show/hide columns\">\r\n <button mat-icon-button [matMenuTriggerFor]=\"menu\">\r\n <mat-icon color=\"primary\">visibility_off</mat-icon>\r\n </button>\r\n </span>\r\n <mat-menu #menu=\"matMenu\" class=\"my-mat-menu\">\r\n\r\n <button mat-menu-item>\r\n <span matTooltip=\"Close\">\r\n <button class=\"filter-button\" mat-icon-button>\r\n <mat-icon>close</mat-icon>\r\n </button>\r\n </span>\r\n </button>\r\n\r\n <button mat-menu-item stop-propagation>\r\n <span matTooltip=\"Show all columns\">\r\n <button mat-icon-button (click)=\"reset(displayCols)\">\r\n <mat-icon color=\"primary\">done_all</mat-icon>\r\n </button>\r\n </span>\r\n\r\n <span matTooltip=\"Hide all columns\">\r\n <button mat-icon-button (click)=\"unset(displayCols)\">\r\n <mat-icon color=\"primary\">cancel</mat-icon>\r\n </button>\r\n </span>\r\n </button>\r\n\r\n <div cdkDropList (cdkDropListDropped)=\"drop($event)\" stop-propagation [cdkDropListLockAxis]=\"'y'\">\r\n @for (col of displayCols; track col.key) {\r\n <button [class.isHidden]=\"!col.isVisible\" stop-propagation mat-menu-item cdkDrag [cdkDragData]=\"col\">\r\n <div (click)=\"col.isVisible = !col.isVisible; emit(displayCols)\" style=\"display: flex; align-items: center;\">\r\n @if(col.isVisible){\r\n <button mat-icon-button matTooltip=\"Hide Column\" class=\"show-hide\">\r\n <mat-icon color=\"primary\">check_box</mat-icon>\r\n </button>\r\n } @else {\r\n <button mat-icon-button matTooltip=\"Show Column\" class=\"show-hide\">\r\n <mat-icon>indeterminate_check_box</mat-icon>\r\n </button>\r\n }\r\n \r\n <p class=\"label\">\r\n {{col.displayName || (col.key | spaceCase) }}\r\n </p>\r\n\r\n </div>\r\n </button>\r\n }\r\n\r\n </div>\r\n </mat-menu>\r\n}", styles: [".show-hide{margin-right:15px;height:24px;width:24px;padding:4px}.label{color:#6495ed;text-overflow:ellipsis;overflow:hidden;white-space:nowrap;text-align:left;margin:0;font-size:17px;font-weight:700;display:inline-block;width:66%}.row{margin:0;padding:0}.isHidden{background-color:#d3d3d3;color:#a9a9a9;font-weight:700;font-size:17px;white-space:nowrap}.filter-button{margin-top:10px}.cdk-drag-preview{box-sizing:border-box;border-radius:4px;box-shadow:0 5px 5px -3px #0003,0 8px 10px 1px #00000024,0 3px 14px 2px #0000001f}.cdk-drag-placeholder{opacity:0}.cdk-drag-animating{transition:transform .25s cubic-bezier(0,0,.2,1)}.mdc-list-item__primary-text{display:inline-block;width:100%}\n"], dependencies: [{ kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i4$1.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: 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.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: "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: "directive", type: StopPropagationDirective, selector: "[stop-propagation]" }, { kind: "ngmodule", type: DragDropModule }, { kind: "directive", type: i5.CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: i5.CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "pipe", type: SpaceCasePipe, name: "spaceCase" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
2943
3017
  }
2944
3018
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: GenColDisplayerComponent, decorators: [{
2945
3019
  type: Component,
@@ -2981,7 +3055,7 @@ class GenFilterDisplayerComponent {
2981
3055
  this.filterStore.addFilter({ key: metaData.key, fieldType: metaData.fieldType });
2982
3056
  }
2983
3057
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: GenFilterDisplayerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
2984
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.0", type: GenFilterDisplayerComponent, isStandalone: true, selector: "tb-filter-displayer", ngImport: i0, template: "<button stop-propagation class=\"filter-button\" mat-icon-button [matMenuTriggerFor]=\"menu\" [matTooltip]=\"'Add Filter'\">\r\n <mat-icon class=\"filter-icon\" color=\"primary\">filter_list</mat-icon>\r\n</button>\r\n<mat-menu #menu=\"matMenu\">\r\n @for (md of $filterCols(); track md.key) {\r\n <button (click)=\"addFilter(md)\" mat-menu-item>\r\n <span class=\"filter-labels\">{{md.displayName || (md.key | spaceCase)}}</span>\r\n </button>\r\n }\r\n</mat-menu>\r\n", styles: [".filter{margin:15px;display:inline-block}.filter-button{color:#6495ed;font-size:22px;font-weight:700}.cancel-button{margin-right:30px;font-weight:700}.filter-wrapper{margin-top:1em;margin-bottom:1em;float:right}.menu{margin-bottom:10px;width:109.1%}.filter-labels{color:#6495ed;font-size:17px;font-weight:600}.float{position:absolute;width:fit-content;z-index:101;top:10px;right:180px;max-width:90vw}.d-w{display:flex;flex-direction:row;justify-content:flex-end}\n"], dependencies: [{ kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i3$1.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "ngmodule", type: MatMenuModule }, { kind: "component", type: i4$2.MatMenu, selector: "mat-menu", inputs: ["backdropClass", "aria-label", "aria-labelledby", "aria-describedby", "xPosition", "yPosition", "overlapTrigger", "hasBackdrop", "class", "classList"], outputs: ["closed", "close"], exportAs: ["matMenu"] }, { kind: "component", type: i4$2.MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i4$2.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }, { kind: "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: 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 });
3058
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.0", type: GenFilterDisplayerComponent, isStandalone: true, selector: "tb-filter-displayer", ngImport: i0, template: "<button stop-propagation class=\"filter-button\" mat-icon-button [matMenuTriggerFor]=\"menu\" [matTooltip]=\"'Add Filter'\">\r\n <mat-icon class=\"filter-icon\" color=\"primary\">filter_list</mat-icon>\r\n</button>\r\n<mat-menu #menu=\"matMenu\">\r\n @for (md of $filterCols(); track md.key) {\r\n <button (click)=\"addFilter(md)\" mat-menu-item>\r\n <span class=\"filter-labels\">{{md.displayName || (md.key | spaceCase)}}</span>\r\n </button>\r\n }\r\n</mat-menu>\r\n", styles: [".filter{margin:15px;display:inline-block}.filter-button{color:#6495ed;font-size:22px;font-weight:700}.cancel-button{margin-right:30px;font-weight:700}.filter-wrapper{margin-top:1em;margin-bottom:1em;float:right}.menu{margin-bottom:10px;width:109.1%}.filter-labels{color:#6495ed;font-size:17px;font-weight:600}.float{position:absolute;width:fit-content;z-index:101;top:10px;right:180px;max-width:90vw}.d-w{display:flex;flex-direction:row;justify-content:flex-end}\n"], dependencies: [{ 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: "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: 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: 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 });
2985
3059
  }
2986
3060
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: GenFilterDisplayerComponent, decorators: [{
2987
3061
  type: Component,
@@ -3004,7 +3078,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImpor
3004
3078
 
3005
3079
  class FormatFilterTypePipe {
3006
3080
  transform(filterType, value) {
3007
- if (filterType === FilterTypes.IsNull) {
3081
+ if (filterType === FilterType.IsNull) {
3008
3082
  return value ? filterType : 'Is Not Blank';
3009
3083
  }
3010
3084
  return filterType;
@@ -3031,16 +3105,16 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImpor
3031
3105
  args: [{ name: 'formatFilterValue' }]
3032
3106
  }] });
3033
3107
  const transform = (value, meta, filterType) => {
3034
- if (filterType === FilterTypes.IsNull) {
3108
+ if (filterType === FilterType.IsNull) {
3035
3109
  return '';
3036
3110
  }
3037
- if (value && (filterType === FilterTypes.In)) {
3111
+ if (value && (filterType === FilterType.In)) {
3038
3112
  if (meta.fieldType === FieldType.Enum) {
3039
3113
  return value.map((v) => spaceCase(meta.additional.enumMap[v])).join(', ') ?? value;
3040
3114
  }
3041
3115
  return value.join(', ') ?? value;
3042
3116
  }
3043
- if (filterType === FilterTypes.NumberBetween) {
3117
+ if (filterType === FilterType.NumberBetween) {
3044
3118
  return value.Start + ' - ' + value.End;
3045
3119
  }
3046
3120
  if (meta.fieldType === FieldType.Date) {
@@ -3067,7 +3141,7 @@ class FilterChipsComponent {
3067
3141
  }
3068
3142
  $currentFilters = this.filterStore.$currentFilters;
3069
3143
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: FilterChipsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
3070
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.0", type: FilterChipsComponent, isStandalone: true, selector: "lib-filter-list", ngImport: i0, template: "<div class=\"d-w\">\r\n\r\n @if ($currentFilters().length) {\r\n <button class=\"cancel-button\" mat-icon-button (click)=\"clearAll()\" matTooltip=\"Close all Filters Cards\">\r\n <mat-icon class=\"cancel-button\" color=\"primary\">close</mat-icon>\r\n </button>\r\n <div class=\"float\">\r\n @for (filter of $currentFilters(); track filter.key) {\r\n <div class=\"filter\">\r\n <tb-filter [filter]=\"filter\" (close)=\"deleteByIndex($index)\" />\r\n </div>\r\n }\r\n </div>\r\n }\r\n\r\n <mat-chip-set>\r\n @for (filter of $filters(); track filter.key) {\r\n <mat-chip (dblclick)=\"addFilter(filter)\" (removed)=\"tableState.removeFilter(filter.filterId!)\">\r\n {{ (filter.key | keyDisplay)() }} {{filter.filterType | formatFilterType : filter.filterValue}} {{ (filter.filterValue | formatFilterValue: filter.key : filter.filterType)() }}\r\n <mat-icon matChipRemove>cancel</mat-icon>\r\n </mat-chip>\r\n }\r\n @if ($filters().length > 1) {\r\n <mat-chip (removed)=\"tableState.clearFilters()\">\r\n Clear All\r\n <mat-icon matChipRemove>cancel</mat-icon>\r\n </mat-chip>\r\n }\r\n </mat-chip-set>\r\n\r\n</div>\r\n", styles: [".filter{margin:15px;display:inline-block}.filter-button{color:#6495ed;font-size:22px;font-weight:700}.cancel-button{margin-right:30px;font-weight:700}.filter-wrapper{margin-top:1em;margin-bottom:1em;float:right}.menu{margin-bottom:10px;width:109.1%}.filter-labels{color:#6495ed;font-size:17px;font-weight:600}.float{position:absolute;width:fit-content;z-index:101;top:10px;right:180px;max-width:90vw}.d-w{display:flex;flex-direction:row;justify-content:flex-end}\n"], dependencies: [{ kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i3$1.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i4$1.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: FilterComponent, selector: "tb-filter", inputs: ["filter"], outputs: ["close"] }, { kind: "ngmodule", type: MatChipsModule }, { kind: "component", type: i4$3.MatChip, selector: "mat-basic-chip, [mat-basic-chip], mat-chip, [mat-chip]", inputs: ["role", "id", "aria-label", "aria-description", "value", "color", "removable", "highlighted", "disableRipple", "disabled"], outputs: ["removed", "destroyed"], exportAs: ["matChip"] }, { kind: "directive", type: i4$3.MatChipRemove, selector: "[matChipRemove]" }, { kind: "component", type: i4$3.MatChipSet, selector: "mat-chip-set", inputs: ["disabled", "role", "tabIndex"] }, { kind: "pipe", type: KeyDisplayPipe, name: "keyDisplay" }, { kind: "pipe", type: FormatFilterTypePipe, name: "formatFilterType" }, { kind: "pipe", type: FormatFilterValuePipe, name: "formatFilterValue" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
3144
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.0", type: FilterChipsComponent, isStandalone: true, selector: "lib-filter-list", ngImport: i0, template: "<div class=\"d-w\">\r\n\r\n @if ($currentFilters().length) {\r\n <button class=\"cancel-button\" mat-icon-button (click)=\"clearAll()\" matTooltip=\"Close all Filters Cards\">\r\n <mat-icon class=\"cancel-button\" color=\"primary\">close</mat-icon>\r\n </button>\r\n <div class=\"float\">\r\n @for (filter of $currentFilters(); track filter.key) {\r\n <div class=\"filter\">\r\n <tb-filter [filter]=\"filter\" (close)=\"deleteByIndex($index)\" />\r\n </div>\r\n }\r\n </div>\r\n }\r\n\r\n <mat-chip-set>\r\n @for (filter of $filters(); track filter.key) {\r\n <mat-chip (dblclick)=\"addFilter(filter)\" (removed)=\"tableState.removeFilter(filter.filterId!)\">\r\n {{ (filter.key | keyDisplay)() }} {{filter.filterType | formatFilterType : filter.filterValue}} {{ (filter.filterValue | formatFilterValue: filter.key : filter.filterType)() }}\r\n <mat-icon matChipRemove>cancel</mat-icon>\r\n </mat-chip>\r\n }\r\n @if ($filters().length > 1) {\r\n <mat-chip (removed)=\"tableState.clearFilters()\">\r\n Clear All\r\n <mat-icon matChipRemove>cancel</mat-icon>\r\n </mat-chip>\r\n }\r\n </mat-chip-set>\r\n\r\n</div>\r\n", styles: [".filter{margin:15px;display:inline-block}.filter-button{color:#6495ed;font-size:22px;font-weight:700}.cancel-button{margin-right:30px;font-weight:700}.filter-wrapper{margin-top:1em;margin-bottom:1em;float:right}.menu{margin-bottom:10px;width:109.1%}.filter-labels{color:#6495ed;font-size:17px;font-weight:600}.float{position:absolute;width:fit-content;z-index:101;top:10px;right:180px;max-width:90vw}.d-w{display:flex;flex-direction:row;justify-content:flex-end}\n"], dependencies: [{ kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i3$1.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i4$1.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: FilterComponent, selector: "tb-filter", inputs: ["filter"], outputs: ["close"] }, { kind: "ngmodule", type: MatChipsModule }, { kind: "component", type: i4$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: "pipe", type: KeyDisplayPipe, name: "keyDisplay" }, { kind: "pipe", type: FormatFilterTypePipe, name: "formatFilterType" }, { kind: "pipe", type: FormatFilterValuePipe, name: "formatFilterValue" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
3071
3145
  }
3072
3146
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: FilterChipsComponent, decorators: [{
3073
3147
  type: Component,
@@ -3191,7 +3265,7 @@ class RouterLinkColumnComponent {
3191
3265
  >
3192
3266
  {{value()}}
3193
3267
  </a>
3194
- `, isInline: true, dependencies: [{ kind: "ngmodule", type: RouterModule }, { kind: "directive", type: i1$4.RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
3268
+ `, isInline: true, dependencies: [{ kind: "ngmodule", type: RouterModule }, { kind: "directive", type: i1$5.RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
3195
3269
  }
3196
3270
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: RouterLinkColumnComponent, decorators: [{
3197
3271
  type: Component,
@@ -3385,23 +3459,18 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImpor
3385
3459
  args: [{ providedIn: 'root' }]
3386
3460
  }], ctorParameters: () => [] });
3387
3461
 
3388
- class HeaderMenuComponent {
3462
+ class ColumnHeaderMenuComponent {
3389
3463
  tableState = inject(TableStore);
3390
3464
  FieldType = FieldType;
3391
- FilterType = FilterTypes;
3392
- myFilterType;
3465
+ FilterType = FilterType;
3393
3466
  $metaData = input.required({ alias: 'metaData' });
3394
3467
  $trigger = viewChild(MatMenuTrigger);
3395
3468
  hideField(key) {
3396
3469
  this.tableState.hideColumn(key);
3397
3470
  }
3398
- ngOnInit() {
3399
- this.resetFilterType();
3400
- }
3401
- resetFilterType() {
3471
+ $metaFilterType = computed(() => {
3402
3472
  if (this.$metaData().additional?.filterOptions?.filterableValues) {
3403
- this.myFilterType = FilterTypes.In;
3404
- return;
3473
+ return FilterType.In;
3405
3474
  }
3406
3475
  switch (this.$metaData().fieldType) {
3407
3476
  case FieldType.String:
@@ -3409,34 +3478,29 @@ class HeaderMenuComponent {
3409
3478
  case FieldType.PhoneNumber:
3410
3479
  case FieldType.Array:
3411
3480
  case FieldType.Unknown:
3412
- this.myFilterType = FilterTypes.StringContains;
3413
- break;
3481
+ return FilterType.StringContains;
3414
3482
  case FieldType.Currency:
3415
3483
  case FieldType.Number:
3416
- this.myFilterType = FilterTypes.NumberEquals;
3417
- break;
3484
+ return FilterType.NumberEquals;
3418
3485
  case FieldType.Boolean:
3419
- this.myFilterType = FilterTypes.BooleanEquals;
3420
- break;
3486
+ return FilterType.BooleanEquals;
3421
3487
  case FieldType.Date:
3422
3488
  case FieldType.DateTime:
3423
- this.myFilterType = FilterTypes.DateIsOn;
3424
- break;
3489
+ return FilterType.DateIsOn;
3425
3490
  case FieldType.Enum:
3426
- this.myFilterType = FilterTypes.In;
3427
- break;
3491
+ return FilterType.In;
3492
+ default: return FilterType.StringContains;
3428
3493
  }
3429
- }
3494
+ });
3495
+ $currentFilterType = linkedSignal(() => this.$metaFilterType());
3430
3496
  setStringFilterType() {
3431
- this.myFilterType = this.myFilterType === FilterTypes.StringContains ? FilterTypes.StringDoesNotContain : FilterTypes.StringContains;
3497
+ if (this.$currentFilterType() === FilterType.StringContains) {
3498
+ this.$currentFilterType.set(FilterType.StringDoesNotContain);
3499
+ }
3500
+ this.$currentFilterType.set(FilterType.StringContains);
3432
3501
  }
3433
3502
  setFilterType(filterType) {
3434
- if (filterType === this.myFilterType) {
3435
- this.resetFilterType();
3436
- }
3437
- else {
3438
- this.myFilterType = filterType;
3439
- }
3503
+ this.$currentFilterType.set(filterType);
3440
3504
  }
3441
3505
  onEnter(filter) {
3442
3506
  if (filter.filterValue != undefined && filter.filterType) {
@@ -3444,15 +3508,15 @@ class HeaderMenuComponent {
3444
3508
  this.$trigger().closeMenu();
3445
3509
  }
3446
3510
  }
3447
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: HeaderMenuComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
3448
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.0", type: HeaderMenuComponent, isStandalone: true, selector: "tb-header-menu", inputs: { $metaData: { classPropertyName: "$metaData", publicName: "metaData", isSignal: true, isRequired: true, transformFunction: null } }, viewQueries: [{ propertyName: "$trigger", first: true, predicate: MatMenuTrigger, descendants: true, isSignal: true }], ngImport: i0, template: "@let metaData = $metaData();\r\n\r\n<button mat-icon-button class=\"open-menu-icon-button\" disableRipple [matMenuTriggerFor]=\"menu\" [matMenuTriggerRestoreFocus]=\"false\">\r\n <mat-icon class=\"menu-icon\">more_vert</mat-icon>\r\n</button>\r\n<mat-menu #menu=\"matMenu\" >\r\n @if (!(metaData.fieldType === FieldType.NotMapped))\r\n {\r\n <button mat-menu-item (click)=\"tableState.addGroupByKey(metaData.key)\">\r\n <mat-icon color=\"primary\">group</mat-icon>\r\n <span>Group By</span>\r\n </button>\r\n }\r\n <button mat-menu-item (click)=hideField(metaData.key)>\r\n <mat-icon color=\"primary\">visibility_off</mat-icon>\r\n <span>Hide Column</span>\r\n </button>\r\n @if (!(metaData.fieldType === FieldType.NotMapped))\r\n {\r\n <ng-form #myForm=\"ngForm\" (keydown.enter)=\"onEnter(myForm.value)\" class=\"tb-header-filter\">\r\n <input type=\"hidden\" name=\"filterId\" [ngModel]=\"'header-column-' + metaData.key\" />\r\n <input type=\"hidden\" name=\"filterType\" [ngModel]=\"myFilterType\" />\r\n <input type=\"hidden\" name=\"key\" [ngModel]=\"metaData.key\" />\r\n <input type=\"hidden\" name=\"fieldType\" [ngModel]=\"metaData.fieldType\" />\r\n \r\n @if(myFilterType === FilterType.Or || myFilterType === FilterType.In){\r\n <tb-in-list-filter name='filterValue' [key]='metaData.key' [ngModel]=\"undefined\"/>\r\n }\r\n @else if(metaData.fieldType === FieldType.Link || metaData.fieldType === FieldType.String || metaData.fieldType === FieldType.Array || metaData.fieldType === FieldType.Unknown || metaData.fieldType === FieldType.PhoneNumber) {\r\n <mat-form-field stop-propagation class=\"font auto-width\">\r\n <mat-icon matPrefix class=\"search-icon\">search</mat-icon>\r\n <mat-label>{{myFilterType === FilterType.StringDoesNotContain ? 'Does Not Contain...' : 'Contains...'}}</mat-label>\r\n <input matInput name=\"filterValue\" [ngModel]=\"undefined\"/>\r\n <span matSuffix [matTooltip]=\"myFilterType === FilterType.StringDoesNotContain ? 'Contains' : 'Does Not Contain'\">\r\n <button mat-icon-button color=\"primary\" (click)=\"setStringFilterType()\" class=\"header-filter-icon-button\">\r\n <mat-icon [class]=\"{'chosen-icon': myFilterType === FilterType.StringDoesNotContain }\">\r\n block\r\n </mat-icon>\r\n </button>\r\n </span>\r\n </mat-form-field>\r\n }\r\n @else if (metaData.fieldType === FieldType.Number || metaData.fieldType === FieldType.Currency) {\r\n <mat-form-field class=\"auto-width\" stop-propagation>\r\n <mat-label>{{myFilterType === FilterType.NumberEquals ? 'Equals...' : myFilterType === FilterType.NumberLessThan ? 'Less Than...' : 'More Than...'}}</mat-label>\r\n <input matInput type='number' name=\"filterValue\" [ngModel]=\"undefined\" />\r\n <span matPrefix class=\"tb-header-prefix\">\r\n <button mat-icon-button disableRipple class=\"header-filter-icon-button\" (click)=\"setFilterType(FilterType.NumberLessThan)\"\r\n [class]=\"{'chosen-icon': myFilterType === FilterType.NumberLessThan }\">\r\n <mat-icon class=\"suffix-icons\"\r\n >\r\n arrow_back_ios</mat-icon>\r\n </button>\r\n <button mat-icon-button disableRipple class=\"header-filter-icon-button\" (click)=\"setFilterType(FilterType.NumberGreaterThan)\"\r\n [class]=\"{'chosen-icon': myFilterType === FilterType.NumberGreaterThan }\" >\r\n <mat-icon class=\"suffix-icons\">arrow_forward_ios</mat-icon>\r\n </button>\r\n <button mat-icon-button disableRipple class=\"header-filter-icon-button\" (click)=\"setFilterType(FilterType.NumberEquals)\"\r\n [class]=\"{'chosen-icon': myFilterType === FilterType.NumberEquals }\">\r\n <span class=\"suffix-icons\">=</span>\r\n </button>\r\n </span>\r\n </mat-form-field>\r\n }\r\n @else if (metaData.fieldType === FieldType.Boolean) {\r\n <div>\r\n <label>\r\n <mat-icon class=\"search-icon\">filter_list</mat-icon>\r\n </label>\r\n <mat-radio-group stop-propagation #ctrl=\"matRadioGroup\" #boolField='ngModel' class=\"font\" name=\"filterValue\" [ngModel]=\"undefined\" >\r\n <mat-radio-button class=\"filter-radio-button\" (click)=\"boolField.control.setValue(true);\" [value]=\"true\">True</mat-radio-button><br/>\r\n <mat-radio-button class=\"filter-radio-button\" (click)=\"boolField.control.setValue(false)\" [value]=\"false\">False</mat-radio-button><br/>\r\n </mat-radio-group>\r\n </div>\r\n }\r\n @else if (metaData.fieldType === FieldType.Date || metaData.fieldType === FieldType.DateTime) {\r\n <mat-form-field class=\"font auto-width\" stop-propagation >\r\n <span matPrefix class=\"tb-header-prefix\">\r\n <button mat-icon-button disableRipple class=\"header-filter-icon-button\" (click)=\"setFilterType(FilterType.DateOnOrAfter)\"\r\n [class]=\"{'chosen-icon': myFilterType === FilterType.DateOnOrAfter }\">\r\n <mat-icon class=\"suffix-icons underline\">arrow_forward_ios</mat-icon>\r\n </button>\r\n <button mat-icon-button disableRipple class=\"header-filter-icon-button\" (click)=\"setFilterType(FilterType.DateOnOrBefore)\"\r\n [class]=\"{'chosen-icon': myFilterType === FilterType.DateOnOrBefore }\">\r\n <mat-icon class=\"suffix-icons underline\">arrow_back_ios</mat-icon>\r\n </button>\r\n <button mat-icon-button disableRipple class=\"header-filter-icon-button\" (click)=\"setFilterType(FilterType.DateIsOn)\"\r\n [class]=\"{'chosen-icon': myFilterType === FilterType.DateIsOn }\">\r\n <span class=\"suffix-icons underline\"> =</span>\r\n </button>\r\n </span>\r\n <mat-label>{{myFilterType === FilterType.DateIsOn ? 'On...' :\r\n myFilterType === FilterType.DateOnOrBefore ? 'On or Before...' : 'On or After...'}}</mat-label>\r\n <input matInput name=\"filterValue\" [ngModel]=\"undefined\" [matDatepicker]=\"calendar\"\r\n (click)=\"calendar.open()\"/>\r\n <mat-datepicker-toggle class=\"date-toggle header-filter-icon-button\" matSuffix [for]=\"calendar\" preventEnter></mat-datepicker-toggle>\r\n <mat-datepicker #calendar></mat-datepicker>\r\n </mat-form-field>\r\n }\r\n <button mat-button (click)=\"onEnter(myForm.value)\" [disabled]=\"myForm.value.filterValue == undefined\" disableRipple>\r\n Apply\r\n </button>\r\n </ng-form>\r\n }\r\n</mat-menu>\r\n", styles: [":host{--mdc-text-button-container-height: 24px}:host{--mdc-filled-button-container-height: 24px}:host{--mdc-protected-button-container-height: 24px}:host{--mdc-outlined-button-container-height: 24px}:host{--mat-text-button-touch-target-display: none}:host{--mat-filled-button-touch-target-display: none}:host{--mat-protected-button-touch-target-display: none}:host{--mat-outlined-button-touch-target-display: none}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{-webkit-appearance:none;margin:0}.menu-icon{font-size:16px;line-height:16px;vertical-align:top;height:16px;width:16px}.search-icon{margin-right:16px;vertical-align:middle;height:24px;color:#0000008a;font-size:21px;line-height:1.125}.font{font-size:14px}.filter-radio-button:first-of-type{padding-left:0}.filter-radio-button{padding:10px 40px;min-width:110px}.auto-width{width:260px;margin:5px;display:block;height:55px}.open-menu-icon-button{height:28px;width:28px;padding:6px}.header-filter-icon-button{height:18px;width:18px;font-size:18px;padding:0;margin:0 2px}.header-filter-icon-button ::ng-deep *{line-height:initial;font-size:initial;height:18px;width:18px;font-size:18px;bottom:initial}.header-filter-icon-button.chosen-icon,.header-filter-icon-button.chosen-icon ::ng-deep *{height:22px;width:22px;font-size:22px;color:green}mat-icon.mat-icon.suffix-icons.underline{height:20px;text-decoration:underline .1px solid}.chosen-icon mat-icon.mat-icon.suffix-icons.underline{height:24px}::ng-deep .mat-mdc-form-field-icon-prefix:has(.tb-header-prefix),.tb-header-prefix{padding:0;flex-basis:36%}.tb-header-filter ::ng-deep .mat-mdc-form-field-subscript-wrapper{line-height:0}.tb-header-filter ::ng-deep .mat-mdc-form-field-subscript-wrapper:before{height:0}.date-toggle ::ng-deep svg{position:absolute;left:0;top:0}\n"], dependencies: [{ kind: "ngmodule", type: MatMenuModule }, { kind: "component", type: i4$2.MatMenu, selector: "mat-menu", inputs: ["backdropClass", "aria-label", "aria-labelledby", "aria-describedby", "xPosition", "yPosition", "overlapTrigger", "hasBackdrop", "class", "classList"], outputs: ["closed", "close"], exportAs: ["matMenu"] }, { kind: "component", type: i4$2.MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i4$2.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i3$1.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "component", type: i3$1.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i3.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i3.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i3.NgForm, selector: "form:not([ngNoForm]):not([formGroup]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: InListFilterComponent, selector: "tb-in-list-filter , [tb-in-list-filter]", inputs: ["key"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i1$1.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "component", type: i6.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i6.MatLabel, selector: "mat-label" }, { kind: "directive", type: i6.MatPrefix, selector: "[matPrefix], [matIconPrefix], [matTextPrefix]", inputs: ["matTextPrefix"] }, { kind: "directive", type: i6.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i4$1.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "directive", type: StopPropagationDirective, selector: "[stop-propagation]" }, { kind: "ngmodule", type: MatRadioModule }, { kind: "directive", type: i10.MatRadioGroup, selector: "mat-radio-group", inputs: ["color", "name", "labelPosition", "value", "selected", "disabled", "required", "disabledInteractive"], outputs: ["change"], exportAs: ["matRadioGroup"] }, { kind: "component", type: i10.MatRadioButton, selector: "mat-radio-button", inputs: ["id", "name", "aria-label", "aria-labelledby", "aria-describedby", "disableRipple", "tabIndex", "checked", "value", "labelPosition", "disabled", "required", "color", "disabledInteractive"], outputs: ["change"], exportAs: ["matRadioButton"] }, { kind: "ngmodule", type: MatDatepickerModule }, { kind: "component", type: i4.MatDatepicker, selector: "mat-datepicker", exportAs: ["matDatepicker"] }, { kind: "directive", type: i4.MatDatepickerInput, selector: "input[matDatepicker]", inputs: ["matDatepicker", "min", "max", "matDatepickerFilter"], exportAs: ["matDatepickerInput"] }, { kind: "component", type: i4.MatDatepickerToggle, selector: "mat-datepicker-toggle", inputs: ["for", "tabIndex", "aria-label", "disabled", "disableRipple"], exportAs: ["matDatepickerToggle"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
3511
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: ColumnHeaderMenuComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
3512
+ 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 @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</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 });
3449
3513
  }
3450
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: HeaderMenuComponent, decorators: [{
3514
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: ColumnHeaderMenuComponent, decorators: [{
3451
3515
  type: Component,
3452
3516
  args: [{ selector: 'tb-header-menu', changeDetection: ChangeDetectionStrategy.OnPush, imports: [
3453
3517
  MatMenuModule, MatIconModule, MatButtonModule, FormsModule, InListFilterComponent,
3454
3518
  MatInputModule, MatTooltipModule, StopPropagationDirective, MatRadioModule, MatDatepickerModule
3455
- ], template: "@let metaData = $metaData();\r\n\r\n<button mat-icon-button class=\"open-menu-icon-button\" disableRipple [matMenuTriggerFor]=\"menu\" [matMenuTriggerRestoreFocus]=\"false\">\r\n <mat-icon class=\"menu-icon\">more_vert</mat-icon>\r\n</button>\r\n<mat-menu #menu=\"matMenu\" >\r\n @if (!(metaData.fieldType === FieldType.NotMapped))\r\n {\r\n <button mat-menu-item (click)=\"tableState.addGroupByKey(metaData.key)\">\r\n <mat-icon color=\"primary\">group</mat-icon>\r\n <span>Group By</span>\r\n </button>\r\n }\r\n <button mat-menu-item (click)=hideField(metaData.key)>\r\n <mat-icon color=\"primary\">visibility_off</mat-icon>\r\n <span>Hide Column</span>\r\n </button>\r\n @if (!(metaData.fieldType === FieldType.NotMapped))\r\n {\r\n <ng-form #myForm=\"ngForm\" (keydown.enter)=\"onEnter(myForm.value)\" class=\"tb-header-filter\">\r\n <input type=\"hidden\" name=\"filterId\" [ngModel]=\"'header-column-' + metaData.key\" />\r\n <input type=\"hidden\" name=\"filterType\" [ngModel]=\"myFilterType\" />\r\n <input type=\"hidden\" name=\"key\" [ngModel]=\"metaData.key\" />\r\n <input type=\"hidden\" name=\"fieldType\" [ngModel]=\"metaData.fieldType\" />\r\n \r\n @if(myFilterType === FilterType.Or || myFilterType === FilterType.In){\r\n <tb-in-list-filter name='filterValue' [key]='metaData.key' [ngModel]=\"undefined\"/>\r\n }\r\n @else if(metaData.fieldType === FieldType.Link || metaData.fieldType === FieldType.String || metaData.fieldType === FieldType.Array || metaData.fieldType === FieldType.Unknown || metaData.fieldType === FieldType.PhoneNumber) {\r\n <mat-form-field stop-propagation class=\"font auto-width\">\r\n <mat-icon matPrefix class=\"search-icon\">search</mat-icon>\r\n <mat-label>{{myFilterType === FilterType.StringDoesNotContain ? 'Does Not Contain...' : 'Contains...'}}</mat-label>\r\n <input matInput name=\"filterValue\" [ngModel]=\"undefined\"/>\r\n <span matSuffix [matTooltip]=\"myFilterType === FilterType.StringDoesNotContain ? 'Contains' : 'Does Not Contain'\">\r\n <button mat-icon-button color=\"primary\" (click)=\"setStringFilterType()\" class=\"header-filter-icon-button\">\r\n <mat-icon [class]=\"{'chosen-icon': myFilterType === FilterType.StringDoesNotContain }\">\r\n block\r\n </mat-icon>\r\n </button>\r\n </span>\r\n </mat-form-field>\r\n }\r\n @else if (metaData.fieldType === FieldType.Number || metaData.fieldType === FieldType.Currency) {\r\n <mat-form-field class=\"auto-width\" stop-propagation>\r\n <mat-label>{{myFilterType === FilterType.NumberEquals ? 'Equals...' : myFilterType === FilterType.NumberLessThan ? 'Less Than...' : 'More Than...'}}</mat-label>\r\n <input matInput type='number' name=\"filterValue\" [ngModel]=\"undefined\" />\r\n <span matPrefix class=\"tb-header-prefix\">\r\n <button mat-icon-button disableRipple class=\"header-filter-icon-button\" (click)=\"setFilterType(FilterType.NumberLessThan)\"\r\n [class]=\"{'chosen-icon': myFilterType === FilterType.NumberLessThan }\">\r\n <mat-icon class=\"suffix-icons\"\r\n >\r\n arrow_back_ios</mat-icon>\r\n </button>\r\n <button mat-icon-button disableRipple class=\"header-filter-icon-button\" (click)=\"setFilterType(FilterType.NumberGreaterThan)\"\r\n [class]=\"{'chosen-icon': myFilterType === FilterType.NumberGreaterThan }\" >\r\n <mat-icon class=\"suffix-icons\">arrow_forward_ios</mat-icon>\r\n </button>\r\n <button mat-icon-button disableRipple class=\"header-filter-icon-button\" (click)=\"setFilterType(FilterType.NumberEquals)\"\r\n [class]=\"{'chosen-icon': myFilterType === FilterType.NumberEquals }\">\r\n <span class=\"suffix-icons\">=</span>\r\n </button>\r\n </span>\r\n </mat-form-field>\r\n }\r\n @else if (metaData.fieldType === FieldType.Boolean) {\r\n <div>\r\n <label>\r\n <mat-icon class=\"search-icon\">filter_list</mat-icon>\r\n </label>\r\n <mat-radio-group stop-propagation #ctrl=\"matRadioGroup\" #boolField='ngModel' class=\"font\" name=\"filterValue\" [ngModel]=\"undefined\" >\r\n <mat-radio-button class=\"filter-radio-button\" (click)=\"boolField.control.setValue(true);\" [value]=\"true\">True</mat-radio-button><br/>\r\n <mat-radio-button class=\"filter-radio-button\" (click)=\"boolField.control.setValue(false)\" [value]=\"false\">False</mat-radio-button><br/>\r\n </mat-radio-group>\r\n </div>\r\n }\r\n @else if (metaData.fieldType === FieldType.Date || metaData.fieldType === FieldType.DateTime) {\r\n <mat-form-field class=\"font auto-width\" stop-propagation >\r\n <span matPrefix class=\"tb-header-prefix\">\r\n <button mat-icon-button disableRipple class=\"header-filter-icon-button\" (click)=\"setFilterType(FilterType.DateOnOrAfter)\"\r\n [class]=\"{'chosen-icon': myFilterType === FilterType.DateOnOrAfter }\">\r\n <mat-icon class=\"suffix-icons underline\">arrow_forward_ios</mat-icon>\r\n </button>\r\n <button mat-icon-button disableRipple class=\"header-filter-icon-button\" (click)=\"setFilterType(FilterType.DateOnOrBefore)\"\r\n [class]=\"{'chosen-icon': myFilterType === FilterType.DateOnOrBefore }\">\r\n <mat-icon class=\"suffix-icons underline\">arrow_back_ios</mat-icon>\r\n </button>\r\n <button mat-icon-button disableRipple class=\"header-filter-icon-button\" (click)=\"setFilterType(FilterType.DateIsOn)\"\r\n [class]=\"{'chosen-icon': myFilterType === FilterType.DateIsOn }\">\r\n <span class=\"suffix-icons underline\"> =</span>\r\n </button>\r\n </span>\r\n <mat-label>{{myFilterType === FilterType.DateIsOn ? 'On...' :\r\n myFilterType === FilterType.DateOnOrBefore ? 'On or Before...' : 'On or After...'}}</mat-label>\r\n <input matInput name=\"filterValue\" [ngModel]=\"undefined\" [matDatepicker]=\"calendar\"\r\n (click)=\"calendar.open()\"/>\r\n <mat-datepicker-toggle class=\"date-toggle header-filter-icon-button\" matSuffix [for]=\"calendar\" preventEnter></mat-datepicker-toggle>\r\n <mat-datepicker #calendar></mat-datepicker>\r\n </mat-form-field>\r\n }\r\n <button mat-button (click)=\"onEnter(myForm.value)\" [disabled]=\"myForm.value.filterValue == undefined\" disableRipple>\r\n Apply\r\n </button>\r\n </ng-form>\r\n }\r\n</mat-menu>\r\n", styles: [":host{--mdc-text-button-container-height: 24px}:host{--mdc-filled-button-container-height: 24px}:host{--mdc-protected-button-container-height: 24px}:host{--mdc-outlined-button-container-height: 24px}:host{--mat-text-button-touch-target-display: none}:host{--mat-filled-button-touch-target-display: none}:host{--mat-protected-button-touch-target-display: none}:host{--mat-outlined-button-touch-target-display: none}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{-webkit-appearance:none;margin:0}.menu-icon{font-size:16px;line-height:16px;vertical-align:top;height:16px;width:16px}.search-icon{margin-right:16px;vertical-align:middle;height:24px;color:#0000008a;font-size:21px;line-height:1.125}.font{font-size:14px}.filter-radio-button:first-of-type{padding-left:0}.filter-radio-button{padding:10px 40px;min-width:110px}.auto-width{width:260px;margin:5px;display:block;height:55px}.open-menu-icon-button{height:28px;width:28px;padding:6px}.header-filter-icon-button{height:18px;width:18px;font-size:18px;padding:0;margin:0 2px}.header-filter-icon-button ::ng-deep *{line-height:initial;font-size:initial;height:18px;width:18px;font-size:18px;bottom:initial}.header-filter-icon-button.chosen-icon,.header-filter-icon-button.chosen-icon ::ng-deep *{height:22px;width:22px;font-size:22px;color:green}mat-icon.mat-icon.suffix-icons.underline{height:20px;text-decoration:underline .1px solid}.chosen-icon mat-icon.mat-icon.suffix-icons.underline{height:24px}::ng-deep .mat-mdc-form-field-icon-prefix:has(.tb-header-prefix),.tb-header-prefix{padding:0;flex-basis:36%}.tb-header-filter ::ng-deep .mat-mdc-form-field-subscript-wrapper{line-height:0}.tb-header-filter ::ng-deep .mat-mdc-form-field-subscript-wrapper:before{height:0}.date-toggle ::ng-deep svg{position:absolute;left:0;top:0}\n"] }]
3519
+ ], 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 @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</mat-menu>\r\n", styles: [":host{--mdc-text-button-container-height: 24px}:host{--mdc-filled-button-container-height: 24px}:host{--mdc-protected-button-container-height: 24px}:host{--mdc-outlined-button-container-height: 24px}:host{--mat-text-button-touch-target-display: none}:host{--mat-filled-button-touch-target-display: none}:host{--mat-protected-button-touch-target-display: none}:host{--mat-outlined-button-touch-target-display: none}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{-webkit-appearance:none;margin:0}.menu-icon{font-size:16px;line-height:16px;vertical-align:top;height:16px;width:16px}.search-icon{margin-right:16px;vertical-align:middle;height:24px;color:#0000008a;font-size:21px;line-height:1.125}.font{font-size:14px}.filter-radio-button:first-of-type{padding-left:0}.filter-radio-button{padding:10px 40px;min-width:110px}.auto-width{width:260px;margin:5px;display:block;height:55px}.open-menu-icon-button{height:28px;width:28px;padding:6px}.header-filter-icon-button{height:18px;width:18px;font-size:18px;padding:0;margin:0 2px}.header-filter-icon-button ::ng-deep *{line-height:initial;font-size:initial;height:18px;width:18px;font-size:18px;bottom:initial}.header-filter-icon-button.chosen-icon,.header-filter-icon-button.chosen-icon ::ng-deep *{height:22px;width:22px;font-size:22px;color:green}mat-icon.mat-icon.suffix-icons.underline{height:20px;text-decoration:underline .1px solid}.chosen-icon mat-icon.mat-icon.suffix-icons.underline{height:24px}::ng-deep .mat-mdc-form-field-icon-prefix:has(.tb-header-prefix),.tb-header-prefix{padding:0;flex-basis:36%}.tb-header-filter ::ng-deep .mat-mdc-form-field-subscript-wrapper{line-height:0}.tb-header-filter ::ng-deep .mat-mdc-form-field-subscript-wrapper:before{height:0}.date-toggle ::ng-deep svg{position:absolute;left:0;top:0}\n"] }]
3456
3520
  }] });
3457
3521
 
3458
3522
  class ColumnTotalPipe {
@@ -3615,7 +3679,7 @@ class ColumnBuilderComponent {
3615
3679
  return metaData.toolTip(element);
3616
3680
  };
3617
3681
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: ColumnBuilderComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
3618
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.0", type: ColumnBuilderComponent, isStandalone: true, selector: "ng-component", viewQueries: [{ propertyName: "$columnDef", first: true, predicate: MatColumnDef, descendants: true, isSignal: true }, { propertyName: "$bodyTemplate", first: true, predicate: ["body"], descendants: true, isSignal: true }], ngImport: i0, template: "@let metaData = $metaData();\r\n@let customCell = $customCell();\r\n@let styles = $styles()!;\r\n\r\n@if(metaData)\r\n{\r\n <ng-container [matColumnDef]=\"metaData.key\">\r\n\r\n <!-- header -->\r\n <ng-template matHeaderCellDef #myHeader>\r\n <mat-header-cell cdkDrag [style]='styles?.header' resizeColumn [key]=\"metaData.key\" class=\"column-head\"\r\n [class]='metaData.additional?.columnPartClasses?.header'>\r\n <div class=\"header-container\" cdkDragHandle>\r\n @if(!customCell?.columnDef?.headerCell)\r\n {\r\n @if(metaData.fieldType !== FieldType.NotMapped){\r\n <div mat-sort-header [disabled]=\"metaData.noSort\" style=\"width: 100%\">\r\n {{ metaData.displayName ? metaData.displayName : ( metaData.key | spaceCase ) }}\r\n </div>\r\n } @else if(metaData.fieldType === FieldType.NotMapped){\r\n <div style=\"width: 100%\">\r\n {{ metaData.displayName ? metaData.displayName : ( metaData.key | spaceCase ) }}\r\n </div>\r\n }\r\n @if($showFilters()){\r\n <tb-header-menu #menu [metaData]='metaData' />\r\n }\r\n }\r\n @else\r\n {\r\n <ng-container *ngTemplateOutlet=\"customCell!.columnDef!.headerCell.template; context: {metaData: metaData, styles: styles?.header} \">\r\n </ng-container>\r\n }\r\n </div>\r\n </mat-header-cell>\r\n </ng-template>\r\n \r\n <!-- body -->\r\n <ng-container *matCellDef=\"let element;\">\r\n <ng-container *ngTemplateOutlet=\"$outerTemplate()!; context: { metaData: metaData, element: element , styles: styles?.body, $implicit: element }\"/>\r\n </ng-container>\r\n <ng-template #body let-element='element' >\r\n <mat-cell [matTooltip]=\"metaData.toolTip ? (getTooltip | func : element) : ''\" [conditionalClasses]='metaData.classes' [element]='element' [styler]='styles.body' (click)='cellClicked(element, metaData.key)' >\r\n <ng-container *ngTemplateOutlet=\"$innerTemplate()!; context: { value: ($transform()! | func : element), element: element, additional: $additional(), $implicit: element }; Injector: injector\" />\r\n </mat-cell>\r\n </ng-template>\r\n \r\n <!-- footer -->\r\n <ng-template matFooterCellDef>\r\n @if(customCell?.columnDef?.footerCell){\r\n <ng-container\r\n *ngTemplateOutlet=\"customCell!.columnDef!.footerCell.template; context: {metaData: metaData, data: $data, styles : styles.footer }\"/>\r\n } @else {\r\n @let data = $data();\r\n <mat-footer-cell [style]='styles.footer' [class]='metaData.additional?.columnPartClasses?.footer'>\r\n @if(!!data?.length && metaData.additional?.footer){\r\n <span class=\"bold\">\r\n @switch (metaData.fieldType) {\r\n @case (FieldType.Currency) { {{ data | columnTotal: metaData | currency }} }\r\n @case (FieldType.Number) { {{ data | columnTotal: metaData | number }} }\r\n }\r\n </span>\r\n }\r\n \r\n </mat-footer-cell>\r\n }\r\n </ng-template>\r\n </ng-container>\r\n}", styles: [".header-container{display:flex;flex-direction:row;width:100%;align-items:center}.negative-currency{color:red}.column-head{position:relative}.bold,.group-footer{font-weight:900}.cdk-drag-preview{background:#fff;border-radius:4px;box-shadow:0 5px 5px -3px #0003,0 8px 10px 1px #00000024,0 3px 14px 2px #0000001f}.cdk-drag-placeholder{opacity:33%;border-right-width:0px}.cdk-drag-animating{transition:transform .25s cubic-bezier(0,0,.2,1)}.drag-handle{color:#add8e6;cursor:move;margin-right:9px}\n"], dependencies: [{ kind: "ngmodule", type: MatTableModule }, { kind: "directive", type: i1$5.MatHeaderCellDef, selector: "[matHeaderCellDef]" }, { kind: "directive", type: i1$5.MatColumnDef, selector: "[matColumnDef]", inputs: ["matColumnDef"] }, { kind: "directive", type: i1$5.MatCellDef, selector: "[matCellDef]" }, { kind: "directive", type: i1$5.MatFooterCellDef, selector: "[matFooterCellDef]" }, { kind: "directive", type: i1$5.MatHeaderCell, selector: "mat-header-cell, th[mat-header-cell]" }, { kind: "directive", type: i1$5.MatCell, selector: "mat-cell, td[mat-cell]" }, { kind: "directive", type: i1$5.MatFooterCell, selector: "mat-footer-cell, td[mat-footer-cell]" }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: ResizeColumnDirective, selector: "[resizeColumn]", inputs: ["resizeColumn", "key"] }, { kind: "pipe", type: FunctionPipe, name: "func" }, { kind: "directive", type: StylerDirective, selector: "[styler]", inputs: ["element", "styler"] }, { kind: "directive", type: ConditionalClassesDirective, selector: "[conditionalClasses]", inputs: ["element", "conditionalClasses"] }, { kind: "ngmodule", type: DragDropModule }, { kind: "directive", type: i5.CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "directive", type: i5.CdkDragHandle, selector: "[cdkDragHandle]", inputs: ["cdkDragHandleDisabled"] }, { kind: "ngmodule", type: MatSortModule }, { kind: "component", type: i3$2.MatSortHeader, selector: "[mat-sort-header]", inputs: ["mat-sort-header", "arrowPosition", "start", "disabled", "sortActionDescription", "disableClear"], exportAs: ["matSortHeader"] }, { kind: "pipe", type: SpaceCasePipe, name: "spaceCase" }, { kind: "component", type: HeaderMenuComponent, selector: "tb-header-menu", inputs: ["metaData"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i4$1.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "pipe", type: ColumnTotalPipe, name: "columnTotal" }, { kind: "pipe", type: CurrencyPipe, name: "currency" }, { kind: "pipe", type: DecimalPipe, name: "number" }], viewProviders: [
3682
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.0", type: ColumnBuilderComponent, isStandalone: true, selector: "ng-component", viewQueries: [{ propertyName: "$columnDef", first: true, predicate: MatColumnDef, descendants: true, isSignal: true }, { propertyName: "$bodyTemplate", first: true, predicate: ["body"], descendants: true, isSignal: true }], ngImport: i0, template: "@let metaData = $metaData();\r\n@let customCell = $customCell();\r\n@let styles = $styles()!;\r\n\r\n@if(metaData)\r\n{\r\n <ng-container [matColumnDef]=\"metaData.key\">\r\n\r\n <!-- header -->\r\n <ng-template matHeaderCellDef #myHeader>\r\n <mat-header-cell cdkDrag [style]='styles?.header' resizeColumn [key]=\"metaData.key\" class=\"column-head\"\r\n [class]='metaData.additional?.columnPartClasses?.header'>\r\n <div class=\"header-container\" cdkDragHandle>\r\n @if(!customCell?.columnDef?.headerCell)\r\n {\r\n @if(metaData.fieldType !== FieldType.NotMapped){\r\n <div mat-sort-header [disabled]=\"metaData.noSort\" style=\"width: 100%\">\r\n {{ metaData.displayName ? metaData.displayName : ( metaData.key | spaceCase ) }}\r\n </div>\r\n } @else if(metaData.fieldType === FieldType.NotMapped){\r\n <div style=\"width: 100%\">\r\n {{ metaData.displayName ? metaData.displayName : ( metaData.key | spaceCase ) }}\r\n </div>\r\n }\r\n @if($showFilters()){\r\n <tb-header-menu #menu [metaData]='metaData' />\r\n }\r\n }\r\n @else\r\n {\r\n <ng-container *ngTemplateOutlet=\"customCell!.columnDef!.headerCell.template; context: {metaData: metaData, styles: styles?.header} \">\r\n </ng-container>\r\n }\r\n </div>\r\n </mat-header-cell>\r\n </ng-template>\r\n \r\n <!-- body -->\r\n <ng-container *matCellDef=\"let element;\">\r\n <ng-container *ngTemplateOutlet=\"$outerTemplate()!; context: { metaData: metaData, element: element , styles: styles?.body, $implicit: element }\"/>\r\n </ng-container>\r\n <ng-template #body let-element='element' >\r\n <mat-cell [matTooltip]=\"metaData.toolTip ? (getTooltip | func : element) : ''\" [conditionalClasses]='metaData.classes' [element]='element' [styler]='styles.body' (click)='cellClicked(element, metaData.key)' >\r\n <ng-container *ngTemplateOutlet=\"$innerTemplate()!; context: { value: ($transform()! | func : element), element: element, additional: $additional(), $implicit: element }; Injector: injector\" />\r\n </mat-cell>\r\n </ng-template>\r\n \r\n <!-- footer -->\r\n <ng-template matFooterCellDef>\r\n @if(customCell?.columnDef?.footerCell){\r\n <ng-container\r\n *ngTemplateOutlet=\"customCell!.columnDef!.footerCell.template; context: {metaData: metaData, data: $data, styles : styles.footer }\"/>\r\n } @else {\r\n @let data = $data();\r\n <mat-footer-cell [style]='styles.footer' [class]='metaData.additional?.columnPartClasses?.footer'>\r\n @if(!!data?.length && metaData.additional?.footer){\r\n <span class=\"bold\">\r\n @switch (metaData.fieldType) {\r\n @case (FieldType.Currency) { {{ data | columnTotal: metaData | currency }} }\r\n @case (FieldType.Number) { {{ data | columnTotal: metaData | number }} }\r\n }\r\n </span>\r\n }\r\n \r\n </mat-footer-cell>\r\n }\r\n </ng-template>\r\n </ng-container>\r\n}", styles: [".header-container{display:flex;flex-direction:row;width:100%;align-items:center}.negative-currency{color:red}.column-head{position:relative}.bold,.group-footer{font-weight:900}.cdk-drag-preview{background:#fff;border-radius:4px;box-shadow:0 5px 5px -3px #0003,0 8px 10px 1px #00000024,0 3px 14px 2px #0000001f}.cdk-drag-placeholder{opacity:33%;border-right-width:0px}.cdk-drag-animating{transition:transform .25s cubic-bezier(0,0,.2,1)}.drag-handle{color:#add8e6;cursor:move;margin-right:9px}\n"], dependencies: [{ kind: "ngmodule", type: MatTableModule }, { kind: "directive", type: i1$6.MatHeaderCellDef, selector: "[matHeaderCellDef]" }, { kind: "directive", type: i1$6.MatColumnDef, selector: "[matColumnDef]", inputs: ["matColumnDef"] }, { kind: "directive", type: i1$6.MatCellDef, selector: "[matCellDef]" }, { kind: "directive", type: i1$6.MatFooterCellDef, selector: "[matFooterCellDef]" }, { 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: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: ResizeColumnDirective, selector: "[resizeColumn]", inputs: ["resizeColumn", "key"] }, { kind: "pipe", type: FunctionPipe, name: "func" }, { kind: "directive", type: StylerDirective, selector: "[styler]", inputs: ["element", "styler"] }, { kind: "directive", type: ConditionalClassesDirective, selector: "[conditionalClasses]", inputs: ["element", "conditionalClasses"] }, { kind: "ngmodule", type: DragDropModule }, { kind: "directive", type: i5.CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "directive", type: i5.CdkDragHandle, selector: "[cdkDragHandle]", inputs: ["cdkDragHandleDisabled"] }, { kind: "ngmodule", type: MatSortModule }, { kind: "component", type: i3$2.MatSortHeader, selector: "[mat-sort-header]", inputs: ["mat-sort-header", "arrowPosition", "start", "disabled", "sortActionDescription", "disableClear"], exportAs: ["matSortHeader"] }, { kind: "pipe", type: SpaceCasePipe, name: "spaceCase" }, { kind: "component", type: ColumnHeaderMenuComponent, selector: "tb-header-menu", inputs: ["metaData"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i4$1.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "pipe", type: ColumnTotalPipe, name: "columnTotal" }, { kind: "pipe", type: CurrencyPipe, name: "currency" }, { kind: "pipe", type: DecimalPipe, name: "number" }], viewProviders: [
3619
3683
  { provide: CDK_DROP_LIST, useExisting: CdkDropList },
3620
3684
  ], changeDetection: i0.ChangeDetectionStrategy.OnPush });
3621
3685
  }
@@ -3625,7 +3689,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImpor
3625
3689
  { provide: CDK_DROP_LIST, useExisting: CdkDropList },
3626
3690
  ], imports: [
3627
3691
  MatTableModule, NgTemplateOutlet, ResizeColumnDirective, FunctionPipe, StylerDirective,
3628
- ConditionalClassesDirective, DragDropModule, MatSortModule, SpaceCasePipe, HeaderMenuComponent,
3692
+ ConditionalClassesDirective, DragDropModule, MatSortModule, SpaceCasePipe, ColumnHeaderMenuComponent,
3629
3693
  MatTooltipModule, ColumnTotalPipe, CurrencyPipe, DecimalPipe
3630
3694
  ], template: "@let metaData = $metaData();\r\n@let customCell = $customCell();\r\n@let styles = $styles()!;\r\n\r\n@if(metaData)\r\n{\r\n <ng-container [matColumnDef]=\"metaData.key\">\r\n\r\n <!-- header -->\r\n <ng-template matHeaderCellDef #myHeader>\r\n <mat-header-cell cdkDrag [style]='styles?.header' resizeColumn [key]=\"metaData.key\" class=\"column-head\"\r\n [class]='metaData.additional?.columnPartClasses?.header'>\r\n <div class=\"header-container\" cdkDragHandle>\r\n @if(!customCell?.columnDef?.headerCell)\r\n {\r\n @if(metaData.fieldType !== FieldType.NotMapped){\r\n <div mat-sort-header [disabled]=\"metaData.noSort\" style=\"width: 100%\">\r\n {{ metaData.displayName ? metaData.displayName : ( metaData.key | spaceCase ) }}\r\n </div>\r\n } @else if(metaData.fieldType === FieldType.NotMapped){\r\n <div style=\"width: 100%\">\r\n {{ metaData.displayName ? metaData.displayName : ( metaData.key | spaceCase ) }}\r\n </div>\r\n }\r\n @if($showFilters()){\r\n <tb-header-menu #menu [metaData]='metaData' />\r\n }\r\n }\r\n @else\r\n {\r\n <ng-container *ngTemplateOutlet=\"customCell!.columnDef!.headerCell.template; context: {metaData: metaData, styles: styles?.header} \">\r\n </ng-container>\r\n }\r\n </div>\r\n </mat-header-cell>\r\n </ng-template>\r\n \r\n <!-- body -->\r\n <ng-container *matCellDef=\"let element;\">\r\n <ng-container *ngTemplateOutlet=\"$outerTemplate()!; context: { metaData: metaData, element: element , styles: styles?.body, $implicit: element }\"/>\r\n </ng-container>\r\n <ng-template #body let-element='element' >\r\n <mat-cell [matTooltip]=\"metaData.toolTip ? (getTooltip | func : element) : ''\" [conditionalClasses]='metaData.classes' [element]='element' [styler]='styles.body' (click)='cellClicked(element, metaData.key)' >\r\n <ng-container *ngTemplateOutlet=\"$innerTemplate()!; context: { value: ($transform()! | func : element), element: element, additional: $additional(), $implicit: element }; Injector: injector\" />\r\n </mat-cell>\r\n </ng-template>\r\n \r\n <!-- footer -->\r\n <ng-template matFooterCellDef>\r\n @if(customCell?.columnDef?.footerCell){\r\n <ng-container\r\n *ngTemplateOutlet=\"customCell!.columnDef!.footerCell.template; context: {metaData: metaData, data: $data, styles : styles.footer }\"/>\r\n } @else {\r\n @let data = $data();\r\n <mat-footer-cell [style]='styles.footer' [class]='metaData.additional?.columnPartClasses?.footer'>\r\n @if(!!data?.length && metaData.additional?.footer){\r\n <span class=\"bold\">\r\n @switch (metaData.fieldType) {\r\n @case (FieldType.Currency) { {{ data | columnTotal: metaData | currency }} }\r\n @case (FieldType.Number) { {{ data | columnTotal: metaData | number }} }\r\n }\r\n </span>\r\n }\r\n \r\n </mat-footer-cell>\r\n }\r\n </ng-template>\r\n </ng-container>\r\n}", styles: [".header-container{display:flex;flex-direction:row;width:100%;align-items:center}.negative-currency{color:red}.column-head{position:relative}.bold,.group-footer{font-weight:900}.cdk-drag-preview{background:#fff;border-radius:4px;box-shadow:0 5px 5px -3px #0003,0 8px 10px 1px #00000024,0 3px 14px 2px #0000001f}.cdk-drag-placeholder{opacity:33%;border-right-width:0px}.cdk-drag-animating{transition:transform .25s cubic-bezier(0,0,.2,1)}.drag-handle{color:#add8e6;cursor:move;margin-right:9px}\n"] }]
3631
3695
  }] });
@@ -3914,33 +3978,42 @@ class GenericTableComponent {
3914
3978
  return val;
3915
3979
  }
3916
3980
  };
3917
- $rowHeight = this.state.selectSignal(s => {
3918
- if (this.state.$isVirtual() && s.notPersistedTableSettings.virtualSettings?.enforceRowHeight) {
3919
- const height = s.notPersistedTableSettings.virtualSettings.rowHeight;
3920
- return height + 'px';
3981
+ $rowHeight = computed(() => {
3982
+ if (this.state.$userDefinedRowHeight()) {
3983
+ return this.state.$userDefinedRowHeight() + 'px';
3921
3984
  }
3922
- if (typeof s.notPersistedTableSettings.rowHeight === 'number') {
3923
- return s.notPersistedTableSettings.rowHeight + 'px';
3985
+ const notPersistedTableSettings = this.state.$notPersistedTableSettings();
3986
+ if (this.state.$isVirtual() && notPersistedTableSettings.virtualSettings?.enforceRowHeight) {
3987
+ const height = notPersistedTableSettings.virtualSettings.rowHeight;
3988
+ return parseTbSizeToPixels(height) + 'px';
3924
3989
  }
3925
- return s.notPersistedTableSettings.rowHeight;
3990
+ if (notPersistedTableSettings.rowHeight) {
3991
+ return parseTbSizeToPixels(notPersistedTableSettings.rowHeight) + 'px';
3992
+ }
3993
+ return undefined;
3926
3994
  });
3927
- $headerHeight = this.state.selectSignal(s => {
3928
- if (this.state.$isVirtual() && s.notPersistedTableSettings.virtualSettings?.enforceHeaderHeight) {
3929
- const height = s.notPersistedTableSettings.virtualSettings.headerHeight;
3930
- return height + 'px';
3995
+ $headerHeight = computed(() => {
3996
+ if (this.state.$userDefinedHeaderHeight()) {
3997
+ return this.state.$userDefinedHeaderHeight() + 'px';
3931
3998
  }
3932
- if (typeof s.notPersistedTableSettings.headerHeight === 'number') {
3933
- return s.notPersistedTableSettings.headerHeight + 'px';
3999
+ const notPersistedTableSettings = this.state.$notPersistedTableSettings();
4000
+ if (this.state.$isVirtual() && notPersistedTableSettings.virtualSettings?.enforceHeaderHeight) {
4001
+ const height = notPersistedTableSettings.virtualSettings.headerHeight;
4002
+ return parseTbSizeToPixels(height) + 'px';
3934
4003
  }
3935
- return s.notPersistedTableSettings.headerHeight;
4004
+ if (notPersistedTableSettings.headerHeight) {
4005
+ return parseTbSizeToPixels(notPersistedTableSettings.headerHeight) + 'px';
4006
+ }
4007
+ return undefined;
3936
4008
  });
3937
- $groupHeaderHeight = this.state.selectSignal(s => {
3938
- if (s.notPersistedTableSettings.groupHeaderHeight) {
3939
- return s.notPersistedTableSettings.groupHeaderHeight + 'px';
4009
+ $groupHeaderHeight = computed(() => {
4010
+ const groupHeaderHeight = this.state.$notPersistedTableSettings().groupHeaderHeight;
4011
+ if (groupHeaderHeight) {
4012
+ return parseTbSizeToPixels(groupHeaderHeight) + 'px';
3940
4013
  }
3941
4014
  return this.$rowHeight();
3942
4015
  });
3943
- $footerHeight = this.state.selectSignal(s => {
4016
+ $footerHeight = computed(() => {
3944
4017
  const footerStyle = this.$footerRowStyle();
3945
4018
  switch (footerStyle) {
3946
4019
  case 'regular-footer':
@@ -3953,7 +4026,7 @@ class GenericTableComponent {
3953
4026
  });
3954
4027
  $stickyFooter = computed(() => this.state.$props().stickyFooter || this.state.$isVirtual());
3955
4028
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: GenericTableComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
3956
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.0", type: GenericTableComponent, isStandalone: true, selector: "tb-generic-table", inputs: { $displayDataLength: { classPropertyName: "$displayDataLength", publicName: "displayDataLength", isSignal: true, isRequired: true, transformFunction: null }, $data: { classPropertyName: "$data", publicName: "data", isSignal: true, isRequired: true, transformFunction: null }, $rows: { classPropertyName: "$rows", publicName: "rows", isSignal: true, isRequired: false, transformFunction: null }, $columnInfos: { classPropertyName: "$columnInfos", publicName: "columnInfos", isSignal: true, isRequired: true, transformFunction: null }, $dataSource: { classPropertyName: "$dataSource", publicName: "dataSource", isSignal: true, isRequired: true, transformFunction: null }, $trackBy: { classPropertyName: "$trackBy", publicName: "trackBy", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { selection$: "selection" }, viewQueries: [{ propertyName: "$headerRow", first: true, predicate: MatHeaderRowDef, descendants: true, isSignal: true }, { propertyName: "$footerRow", first: true, predicate: MatFooterRowDef, descendants: true, isSignal: true }, { propertyName: "$table", first: true, predicate: MatTable, descendants: true, isSignal: true }, { propertyName: "$dropList", first: true, predicate: CdkDropList, descendants: true, isSignal: true }], ngImport: i0, template: "<mat-table\r\n cdkDropList\r\n cdkDropListLockAxis='x'\r\n cdkDropListOrientation=\"horizontal\"\r\n (cdkDropListDropped)=\"drop($event)\"\r\n class=\"table-drag-list\"\r\n #table\r\n [dataSource]=\"$dataSource()\"\r\n [trackBy]=\"$trackByFunction()\"\r\n [style]=\"$tableWidth()\"\r\n>\r\n\r\n <!-- select column -->\r\n <ng-container matColumnDef=\"select\">\r\n @let selection = $selection();\r\n <mat-header-cell *matHeaderCellDef class=\"select-column\">\r\n <mat-checkbox (change)=\"$event ? masterToggle() : null\"\r\n [checked]=\"!!($masterToggleChecked())\"\r\n [indeterminate]=\"$masterToggleIndeterminate()\">\r\n </mat-checkbox>\r\n </mat-header-cell>\r\n\r\n <mat-cell *matCellDef=\"let row\" class=\"select-column\">\r\n <mat-checkbox\r\n (click)=\"$event.stopPropagation()\"\r\n (change)=\"$event ? selection.toggle(row) : null\"\r\n [checked]=\"selection.isSelected(row)\"/>\r\n </mat-cell>\r\n\r\n <mat-footer-cell *matFooterCellDef class=\"select-column\">\r\n {{ selection.selected.length }}\r\n </mat-footer-cell>\r\n </ng-container>\r\n\r\n\r\n <!-- index column -->\r\n <ng-container matColumnDef=\"index\">\r\n <mat-header-cell *matHeaderCellDef class=\"f-mat-header-cell\" class=\"index-column\">#\r\n </mat-header-cell>\r\n <mat-cell *matCellDef=\"let i = index;\" class=\"index-column\">\r\n {{ 1 + i + $offsetIndex() }}\r\n </mat-cell>\r\n <mat-footer-cell *matFooterCellDef class=\"index-column\"></mat-footer-cell>\r\n </ng-container>\r\n\r\n <!-- Grouping -->\r\n <ng-container matColumnDef=\"groupHeader\">\r\n <mat-cell *matCellDef=\"let row\">\r\n @let expanded = (state.$getIsExpanded | func : row.key : row.groupName );\r\n <div [style.paddingLeft]=\"row.padding + 'px !important'\">\r\n <button mat-icon-button (click)=\"setExpanded(row.key, row.groupName, !expanded());\">\r\n @if (!expanded()) {\r\n <mat-icon>chevron_right</mat-icon>\r\n } @else {\r\n <mat-icon>expand_more</mat-icon>\r\n }\r\n </button>\r\n {{ getTransform | func : row.key : row.groupHeaderDisplay }} ({{ row.length }})\r\n </div>\r\n <div style=\"flex-grow: 1\">\r\n <ng-container *ngTemplateOutlet=\"state.$props().groupHeaderTemplate!; context: { element: row }\"></ng-container>\r\n </div>\r\n </mat-cell>\r\n </ng-container>\r\n\r\n <mat-row [style.height]=\"$rowHeight()\" [style.min-height]=\"$rowHeight()\"\r\n *matRowDef=\"let row; columns: $keys(); let i = index\"/>\r\n <mat-row [style.height]=\"state.$props().groupHeaderHeight ? state.$props().groupHeaderHeight + 'px' : $groupHeaderHeight()\"\r\n [style.min-height]=\"state.$props().groupHeaderHeight ? state.$props().groupHeaderHeight + 'px' : $groupHeaderHeight()\"\r\n *matRowDef=\"let row; columns: ['groupHeader']; when: isGroupHeader\" style=\"background-color: white;\"/>\r\n</mat-table>\r\n\r\n<mat-header-row [style.height]=\"$headerHeight()\" [style.min-height]=\"$headerHeight()\"\r\n *matHeaderRowDef=\"$keys(); sticky: state.$props().isSticky\" [style.top.px]=\"($offset()! * -1)\"/>\r\n<mat-footer-row [style.height]=\"$footerHeight()\" [style.min-height]=\"$footerHeight()\"\r\n *matFooterRowDef=\"$keys(); sticky: $stickyFooter() \"\r\n [style.bottom.px]=\"$stickyFooter() ? ($offset()) : undefined\"/>\r\n", styles: [":host{--mat-paginator-container-size: initial}.select-column{min-width:var(--tb-min-select-column-width, 42px)}.index-column{min-width:var(--tb-min-index-column-width, 42px)}.mat-mdc-row:nth-child(odd){background-color:var(--tb-odd-row-background-color, #cdeefe)}.page-amounts{color:#0000008a;font-family:Roboto,Helvetica Neue,sans-serif;font-size:12px;margin-right:.2rem}:host::ng-deep .table-drag-list.cdk-drop-list-dragging .drag-header:not(.cdk-drag-placeholder){transition:transform .25s cubic-bezier(0,0,.2,1)}:host::ng-deep .mdc-data-table__cell,:host::ng-deep .mdc-data-table__header-cell{padding:var(--tb-cell-padding, 0 0 0 .2rem);line-height:var(--tb-cell-line-height, normal)}::ng-deep .op-date-time-input{line-height:3rem;font-size:.9rem;font-family:Roboto,Helvetica Neue,sans-serif;padding-left:.2rem;width:12rem}\n"], dependencies: [{ kind: "ngmodule", type: MatTableModule }, { kind: "component", type: i1$5.MatTable, selector: "mat-table, table[mat-table]", exportAs: ["matTable"] }, { kind: "directive", type: i1$5.MatHeaderCellDef, selector: "[matHeaderCellDef]" }, { kind: "directive", type: i1$5.MatHeaderRowDef, selector: "[matHeaderRowDef]", inputs: ["matHeaderRowDef", "matHeaderRowDefSticky"] }, { kind: "directive", type: i1$5.MatColumnDef, selector: "[matColumnDef]", inputs: ["matColumnDef"] }, { kind: "directive", type: i1$5.MatCellDef, selector: "[matCellDef]" }, { kind: "directive", type: i1$5.MatRowDef, selector: "[matRowDef]", inputs: ["matRowDefColumns", "matRowDefWhen"] }, { kind: "directive", type: i1$5.MatFooterCellDef, selector: "[matFooterCellDef]" }, { kind: "directive", type: i1$5.MatFooterRowDef, selector: "[matFooterRowDef]", inputs: ["matFooterRowDef", "matFooterRowDefSticky"] }, { kind: "directive", type: i1$5.MatHeaderCell, selector: "mat-header-cell, th[mat-header-cell]" }, { kind: "directive", type: i1$5.MatCell, selector: "mat-cell, td[mat-cell]" }, { kind: "directive", type: i1$5.MatFooterCell, selector: "mat-footer-cell, td[mat-footer-cell]" }, { kind: "component", type: i1$5.MatHeaderRow, selector: "mat-header-row, tr[mat-header-row]", exportAs: ["matHeaderRow"] }, { kind: "component", type: i1$5.MatRow, selector: "mat-row, tr[mat-row]", exportAs: ["matRow"] }, { kind: "component", type: i1$5.MatFooterRow, selector: "mat-footer-row, tr[mat-footer-row]", exportAs: ["matFooterRow"] }, { kind: "ngmodule", type: DragDropModule }, { kind: "directive", type: i5.CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "ngmodule", type: MatCheckboxModule }, { kind: "component", type: i1$2.MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "aria-expanded", "aria-controls", "aria-owns", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "disabledInteractive", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i3$1.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "pipe", type: FunctionPipe, name: "func" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
4029
+ 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 });
3957
4030
  }
3958
4031
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: GenericTableComponent, decorators: [{
3959
4032
  type: Component,
@@ -4241,158 +4314,357 @@ const defaultStorageState = {
4241
4314
  localProfiles: {}
4242
4315
  };
4243
4316
 
4244
- class GroupByListComponent {
4245
- tableStore = inject(TableStore);
4246
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: GroupByListComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
4247
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.0", type: GroupByListComponent, isStandalone: true, selector: "group-by-list", ngImport: i0, template: "<mat-chip-set>\r\n <span class=\"tb-group-label\">Group By:</span>\r\n @for (groupByKey of tableStore.$groupByKeys(); track groupByKey) {\r\n @if($index > 0){\r\n <mat-icon class=\"nested-arrow\">arrow_right</mat-icon>\r\n }\r\n <mat-chip (removed)=\"tableStore.removeGroupByKey(groupByKey)\">\r\n {{groupByKey | spaceCase}}\r\n <mat-icon matChipRemove>cancel</mat-icon>\r\n </mat-chip>\r\n }\r\n</mat-chip-set>\r\n", styles: [".tb-group-label{padding-right:5px}.nested-arrow{margin-right:-8px;margin-left:-8px}\n"], dependencies: [{ kind: "ngmodule", type: MatChipsModule }, { kind: "component", type: i4$3.MatChip, selector: "mat-basic-chip, [mat-basic-chip], mat-chip, [mat-chip]", inputs: ["role", "id", "aria-label", "aria-description", "value", "color", "removable", "highlighted", "disableRipple", "disabled"], outputs: ["removed", "destroyed"], exportAs: ["matChip"] }, { kind: "directive", type: i4$3.MatChipRemove, selector: "[matChipRemove]" }, { kind: "component", type: i4$3.MatChipSet, selector: "mat-chip-set", inputs: ["disabled", "role", "tabIndex"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "pipe", type: SpaceCasePipe, name: "spaceCase" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
4248
- }
4249
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: GroupByListComponent, decorators: [{
4250
- type: Component,
4251
- args: [{ selector: 'group-by-list', changeDetection: ChangeDetectionStrategy.OnPush, imports: [
4252
- MatChipsModule, MatIconModule, SpaceCasePipe
4253
- ], template: "<mat-chip-set>\r\n <span class=\"tb-group-label\">Group By:</span>\r\n @for (groupByKey of tableStore.$groupByKeys(); track groupByKey) {\r\n @if($index > 0){\r\n <mat-icon class=\"nested-arrow\">arrow_right</mat-icon>\r\n }\r\n <mat-chip (removed)=\"tableStore.removeGroupByKey(groupByKey)\">\r\n {{groupByKey | spaceCase}}\r\n <mat-icon matChipRemove>cancel</mat-icon>\r\n </mat-chip>\r\n }\r\n</mat-chip-set>\r\n", styles: [".tb-group-label{padding-right:5px}.nested-arrow{margin-right:-8px;margin-left:-8px}\n"] }]
4254
- }] });
4255
-
4256
- class SortMenuComponentStore extends ComponentStore {
4257
- tableState = inject(TableStore);
4258
- setStoreStateEffect = effect(() => {
4259
- const metaData = this.tableState.$metaData();
4260
- if (!metaData)
4261
- return;
4262
- this.tableState.$selectSorted();
4263
- untracked(() => this.setStateFromTableStore());
4264
- });
4265
- setStateFromTableStore = () => {
4266
- const metaData = this.tableState.$metaData();
4267
- const sorted = [...this.tableState.$selectSorted()].map(s => ({
4268
- ...s,
4269
- displayName: metaData[s.active]?.displayName
4270
- }));
4271
- const notSorted = this.tableState.$metaDataArray()
4272
- .filter(md => md.fieldType !== FieldType.NotMapped && !md.noSort && !sorted.some(s => s.active === md.key))
4273
- .map(meta => ({ active: meta.key, displayName: meta.displayName }));
4274
- this.setState({ sorted, notSorted });
4317
+ //The idea of this is that if filters were only added, and none were removed or changed, then we only need to tag more rows to not be shown. We don't need to remove any 'dont show' tags.
4318
+ // So if filters were only added this method will return the added filters, if filters were removed or changed this method will return undefined.
4319
+ const updateFilterInfoState = (previousState, filterInfos) => {
4320
+ filterInfos = filterNonActiveOrNotReadyFilters(filterInfos);
4321
+ const currentState = {
4322
+ allFilters: filterInfos,
4323
+ onlyAddedFilters: filterInfoOnlyAdded(previousState.allFilters, filterInfos)
4275
4324
  };
4276
- constructor() {
4277
- super({ notSorted: [], sorted: [] });
4278
- }
4279
- setSorted = this.updater((state, sorted) => ({ ...state, sorted }));
4280
- setNotSorted = this.updater((state, notSorted) => ({ ...state, notSorted }));
4281
- $sorted = this.selectSignal(state => state.sorted);
4282
- $notSorted = this.selectSignal(state => state.notSorted);
4283
- setDirection = this.updater((state, sort) => {
4284
- const index = state.sorted.findIndex(s => s.active === sort.active);
4285
- const sorted = [...state.sorted];
4286
- sorted.splice(index, 1, sort);
4287
- return ({ ...state, sorted });
4325
+ return currentState;
4326
+ };
4327
+ const mapFilterInfoStateToPredicateState = (s) => {
4328
+ const mappedAddOnly = s.onlyAddedFilters
4329
+ ?
4330
+ Object.entries(s.onlyAddedFilters).filter(([, v]) => needsFilterCreation(v)).reduce((obj, [key, value]) => {
4331
+ obj[key] = createFilterFunc(value);
4332
+ return obj;
4333
+ }, {})
4334
+ : {};
4335
+ const mappedAll = Object.entries(s.allFilters).filter(([, v]) => needsFilterCreation(v))
4336
+ .filter(([, v]) => !isCustomFilter(v) || !!v.predicate)
4337
+ .map(([key, value]) => {
4338
+ return mappedAddOnly[key] || createFilterFunc(value);
4288
4339
  });
4289
- reset = () => {
4290
- this.setStateFromTableStore();
4340
+ return ({
4341
+ allFilters: mappedAll,
4342
+ onlyAddedFilters: s.onlyAddedFilters ? Object.values(mappedAddOnly) : undefined
4343
+ });
4344
+ };
4345
+ const updateFilterPredicateState = (previousState, filters) => {
4346
+ const currentState = {
4347
+ allFilters: filters,
4348
+ onlyAddedFilters: predicatesOnlyAdded(previousState.allFilters, filters)
4291
4349
  };
4292
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: SortMenuComponentStore, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
4293
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: SortMenuComponentStore });
4350
+ return currentState;
4351
+ };
4352
+ const updateFilterState = (filterInfos, predicates) => {
4353
+ const infos = mapFilterInfoStateToPredicateState(filterInfos.value);
4354
+ const filtersState = {
4355
+ allFilters: [...infos.allFilters, ...predicates.value.allFilters]
4356
+ };
4357
+ if (filterInfos.timestamp > predicates.timestamp && !!filterInfos.value.onlyAddedFilters) {
4358
+ filtersState.onlyAddedFilters = infos.onlyAddedFilters;
4359
+ }
4360
+ else {
4361
+ filtersState.onlyAddedFilters = predicates.value.onlyAddedFilters;
4362
+ }
4363
+ return filtersState;
4364
+ };
4365
+ const filterNonActiveOrNotReadyFilters = (filtersDict) => Object.entries(filtersDict).reduce((obj, [key, value]) => {
4366
+ if (value.active !== false && (!isCustomFilter(value) || !!value.predicate)) {
4367
+ obj[key] = value;
4368
+ }
4369
+ ;
4370
+ return obj;
4371
+ }, {});
4372
+ function filterInfoOnlyAdded(previousFilterInfos, currentFilterInfos) {
4373
+ const previousKeys = Object.keys(previousFilterInfos);
4374
+ const currentKeys = Object.keys(currentFilterInfos);
4375
+ const keysInBoth = intersection(previousKeys, currentKeys);
4376
+ const someRemoved = previousKeys.length > keysInBoth.length;
4377
+ if (someRemoved || !previousKeys.length) {
4378
+ return undefined;
4379
+ }
4380
+ if (filtersInfosUpdated(previousFilterInfos, currentFilterInfos)) {
4381
+ return undefined;
4382
+ }
4383
+ const addedFilters = difference(currentKeys, keysInBoth).reduce((dict, key) => {
4384
+ dict[key] = currentFilterInfos[key];
4385
+ return dict;
4386
+ }, {});
4387
+ return addedFilters;
4294
4388
  }
4295
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: SortMenuComponentStore, decorators: [{
4296
- type: Injectable
4297
- }], ctorParameters: () => [] });
4298
-
4299
- class SortMenuComponent {
4300
- SortDirection = SortDirection;
4301
- tableState = inject(TableStore);
4302
- store = inject(SortMenuComponentStore);
4303
- $sorted = computed(() => [...this.store.$sorted()]);
4304
- $notSorted = computed(() => [...this.store.$notSorted()]);
4305
- $dirty = signal(false);
4306
- reset() {
4307
- this.$dirty.set(false);
4308
- this.store.reset();
4389
+ function predicatesOnlyAdded(previousPredicates, currentPredicates) {
4390
+ if (!previousPredicates.length) {
4391
+ return undefined;
4309
4392
  }
4310
- dropIntoSorted(event) {
4311
- this.$dirty.set(true);
4312
- const sorted = [...event.container.data];
4313
- if (event.previousContainer === event.container) {
4314
- moveItemInArray(sorted, event.previousIndex, event.currentIndex);
4315
- this.store.setSorted(sorted);
4316
- }
4317
- else {
4318
- const notSorted = [...event.previousContainer.data];
4319
- transferArrayItem(notSorted, sorted, event.previousIndex, event.currentIndex);
4320
- sorted[event.currentIndex] = { ...sorted[event.currentIndex], direction: SortDirection.asc };
4321
- this.store.setSorted(sorted);
4322
- this.store.setNotSorted(notSorted);
4323
- }
4393
+ const predicateFiltersRemoved = difference(previousPredicates, currentPredicates).length;
4394
+ if (predicateFiltersRemoved) {
4395
+ return undefined;
4324
4396
  }
4325
- dropIntoNotSorted(event) {
4326
- if (event.previousContainer === event.container) {
4327
- return;
4328
- }
4329
- else {
4330
- this.$dirty.set(true);
4331
- const sorted = [...event.previousContainer.data];
4332
- const notSorted = [...event.container.data];
4333
- transferArrayItem(sorted, notSorted, event.previousIndex, event.currentIndex);
4334
- notSorted[event.currentIndex] = { ...notSorted[event.currentIndex] };
4335
- this.store.setNotSorted(notSorted);
4336
- this.store.setSorted(sorted);
4337
- }
4397
+ return difference(currentPredicates, previousPredicates);
4398
+ }
4399
+ function filtersInfosUpdated(previousFilterInfos, currentFilterInfos) {
4400
+ return !Object.entries(previousFilterInfos).every(([key, val]) => {
4401
+ return currentFilterInfos[key].filterType === val.filterType && currentFilterInfos[key].filterValue === val.filterValue;
4402
+ });
4403
+ }
4404
+ function patchDirectiveFromState(directive, stateFilter) {
4405
+ if (isFilterInfo(stateFilter)) {
4406
+ const filterDirective = directive;
4407
+ filterDirective.setFilterValue(stateFilter.filterValue);
4408
+ filterDirective.update();
4338
4409
  }
4339
- apply = () => {
4340
- this.$dirty.set(false);
4341
- this.tableState.setAllSort(this.store.$sorted());
4342
- };
4343
- setDirection(sort) {
4344
- this.$dirty.set(true);
4345
- this.store.setDirection(sort);
4410
+ if (isCustomFilter(stateFilter)) {
4411
+ directive.active = stateFilter.active ?? false;
4346
4412
  }
4347
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: SortMenuComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
4348
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.0", type: SortMenuComponent, isStandalone: true, selector: "tb-sort-menu", providers: [SortMenuComponentStore], ngImport: i0, template: "@let dirty = $dirty();\r\n@let sorted = $sorted();\r\n@let notSorted = $notSorted();\r\n\r\n<!-- Menu Trigger -->\r\n<span matTooltip=\"Sort\">\r\n <button mat-icon-button [matMenuTriggerFor]=\"menu\">\r\n <mat-icon color=\"primary\">swap_vert</mat-icon>\r\n </button>\r\n</span>\r\n\r\n<!-- Menu -->\r\n<mat-menu #menu=\"matMenu\" class=\"my-mat-menu\" (closed)=\"reset()\">\r\n <div mat-menu-item class=\"menu-button\">\r\n <div class=\"close-button-wrapper\">\r\n <span matTooltip=\"Close\">\r\n <mat-icon>close</mat-icon>\r\n </span>\r\n @if(dirty){\r\n <span matTooltip=\"Undo\" stop-propagation (click)=\"reset()\">\r\n <mat-icon>undo</mat-icon>\r\n </span>\r\n }\r\n \r\n </div>\r\n </div>\r\n\r\n <!-- Apply Button -->\r\n <div class=\"apply-button-wrapper\">\r\n <button mat-button color=\"primary\" (click)=\"apply()\"\r\n stop-propagation [class.apply-border]=\"dirty\"\r\n [disabled]=\"!dirty\">\r\n Apply @if (dirty) { Unsaved Changes }\r\n </button>\r\n </div>\r\n\r\n <!-- Default Sorting Text -->\r\n @if (!sorted.length) {\r\n <div class=\"tip\" >\r\n Sorting List\r\n </div>\r\n }\r\n\r\n <!-- Sorted Menu List -->\r\n <div class=\"list\"\r\n cdkDropList\r\n #sortedGroup=\"cdkDropList\"\r\n [cdkDropListConnectedTo]=\"[notSortedGroup]\"\r\n [cdkDropListData]=\"sorted\"\r\n (cdkDropListDropped)=\"dropIntoSorted($event)\">\r\n\r\n <!-- Menu Item Wrapper -->\r\n @for (sort of sorted; track sort.active) {\r\n <!-- Menu Item Headers -->\r\n @if (sorted.length > 1) {\r\n <span class=\"description sort-header\">{{$index === 0 ? 'First By' : 'Then By'}}</span>\r\n }\r\n\r\n <!-- Menu Item -->\r\n <div mat-menu-item cdkDrag class=\"menu-item\">\r\n <div class=\"sort-item\">\r\n <span class=\"sorted-name\">\r\n {{sort.displayName || (sort.active | spaceCase)}}\r\n <span class=\"direction-text\">{{sort.direction}}</span>\r\n </span>\r\n\r\n <!-- Sort Direction Buttons -->\r\n <div class=\"up-down-buttons-wrapper\">\r\n <button class=\"up-down-button up-button\" stop-propagation\r\n (click)=\"setDirection({active:sort.active,direction:SortDirection.asc,displayName:sort.displayName})\">\r\n <mat-icon [class]=\"sort.direction !== SortDirection.asc ? 'light-arrow' : 'dark-arrow'\" class=\"up-down-icon\">\r\n arrow_upward\r\n </mat-icon>\r\n </button>\r\n\r\n <button class=\"up-down-button\" stop-propagation\r\n (click)=\"setDirection({active:sort.active,direction:SortDirection.desc,displayName:sort.displayName})\">\r\n <mat-icon [class]=\"sort.direction === SortDirection.asc ? 'light-arrow' : 'dark-arrow'\" class=\"up-down-icon\">\r\n arrow_downward\r\n </mat-icon>\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n }\r\n\r\n </div>\r\n\r\n <!-- Default Not Sorted Text -->\r\n @if(!notSorted.length){\r\n <div class=\"tip\" >\r\n Not Sorted List\r\n </div>\r\n }\r\n\r\n <!-- Not Sorted Menu List -->\r\n <div class=\"list\"\r\n cdkDropList\r\n #notSortedGroup=\"cdkDropList\"\r\n [cdkDropListConnectedTo]=\"[sortedGroup]\"\r\n [cdkDropListData]=\"notSorted\"\r\n (cdkDropListDropped)=\"dropIntoNotSorted($event)\">\r\n @for (sort of notSorted; track sort.active) {\r\n <div mat-menu-item class=\"menu-item\" cdkDrag>\r\n <span class=\"not-sorted-name\">{{sort.displayName || (sort.active | spaceCase)}}</span>\r\n </div>\r\n }\r\n </div>\r\n</mat-menu>\r\n", styles: [".cdk-drag-preview{box-sizing:border-box;border-radius:4px;box-shadow:0 5px 5px -3px #0003,0 8px 10px 1px #00000024,0 3px 14px 2px #0000001f}.cdk-drag-placeholder{opacity:0}.cdk-drag-animating{transition:transform .25s cubic-bezier(0,0,.2,1)}.list{padding:5px 2px;border-bottom:solid 1px #ccc;color:#000000de;background:#fff}.light-arrow{color:#93b1ea78}.dark-arrow{color:#224e9c}.up-down-button{background-color:#fff;border-radius:30%;border-color:#0ff;padding:1px 1px 0;border-width:.5px;cursor:pointer;height:27px}.mat-icon.up-down-icon{margin-right:0;font-size:20px;font-weight:lighter}.sort-item{display:flex;align-items:center;justify-content:space-between}.up-down-buttons-wrapper{margin-left:2rem}.up-button{margin-right:.3rem}.mat-mdc-menu-item.menu-item,.mat-mdc-menu-item.menu-button{min-height:initial;padding:0 3px;line-height:25px;height:30px}.mat-mdc-menu-item.menu-item{cursor:move}.sorted-name{color:#224e9c;font-size:17px;font-weight:700}.not-sorted-name{color:#93b1ea;font-size:17px;font-weight:700}.apply-border{border:#224e9c solid .5px}.apply-border:hover{background-color:#faebd7}.apply-button-wrapper{display:grid;justify-content:center}.sort-header{font-size:10px;font-style:italic}.tip{padding:0 3px;color:#d3d3d3}.direction-text{font-size:small;font-weight:400}.close-button-wrapper{display:flex;flex-direction:row-reverse}\n"], dependencies: [{ kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i4$1.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i3$1.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "component", type: i3$1.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatMenuModule }, { kind: "component", type: i4$2.MatMenu, selector: "mat-menu", inputs: ["backdropClass", "aria-label", "aria-labelledby", "aria-describedby", "xPosition", "yPosition", "overlapTrigger", "hasBackdrop", "class", "classList"], outputs: ["closed", "close"], exportAs: ["matMenu"] }, { kind: "component", type: i4$2.MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i4$2.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }, { kind: "directive", type: StopPropagationDirective, selector: "[stop-propagation]" }, { kind: "ngmodule", type: DragDropModule }, { kind: "directive", type: i5.CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: i5.CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "pipe", type: SpaceCasePipe, name: "spaceCase" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
4349
4413
  }
4350
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: SortMenuComponent, decorators: [{
4351
- type: Component,
4352
- args: [{ selector: 'tb-sort-menu', providers: [SortMenuComponentStore], changeDetection: ChangeDetectionStrategy.OnPush, imports: [
4353
- MatTooltipModule, MatButtonModule, MatIconModule, MatMenuModule, StopPropagationDirective, DragDropModule,
4354
- SpaceCasePipe
4355
- ], template: "@let dirty = $dirty();\r\n@let sorted = $sorted();\r\n@let notSorted = $notSorted();\r\n\r\n<!-- Menu Trigger -->\r\n<span matTooltip=\"Sort\">\r\n <button mat-icon-button [matMenuTriggerFor]=\"menu\">\r\n <mat-icon color=\"primary\">swap_vert</mat-icon>\r\n </button>\r\n</span>\r\n\r\n<!-- Menu -->\r\n<mat-menu #menu=\"matMenu\" class=\"my-mat-menu\" (closed)=\"reset()\">\r\n <div mat-menu-item class=\"menu-button\">\r\n <div class=\"close-button-wrapper\">\r\n <span matTooltip=\"Close\">\r\n <mat-icon>close</mat-icon>\r\n </span>\r\n @if(dirty){\r\n <span matTooltip=\"Undo\" stop-propagation (click)=\"reset()\">\r\n <mat-icon>undo</mat-icon>\r\n </span>\r\n }\r\n \r\n </div>\r\n </div>\r\n\r\n <!-- Apply Button -->\r\n <div class=\"apply-button-wrapper\">\r\n <button mat-button color=\"primary\" (click)=\"apply()\"\r\n stop-propagation [class.apply-border]=\"dirty\"\r\n [disabled]=\"!dirty\">\r\n Apply @if (dirty) { Unsaved Changes }\r\n </button>\r\n </div>\r\n\r\n <!-- Default Sorting Text -->\r\n @if (!sorted.length) {\r\n <div class=\"tip\" >\r\n Sorting List\r\n </div>\r\n }\r\n\r\n <!-- Sorted Menu List -->\r\n <div class=\"list\"\r\n cdkDropList\r\n #sortedGroup=\"cdkDropList\"\r\n [cdkDropListConnectedTo]=\"[notSortedGroup]\"\r\n [cdkDropListData]=\"sorted\"\r\n (cdkDropListDropped)=\"dropIntoSorted($event)\">\r\n\r\n <!-- Menu Item Wrapper -->\r\n @for (sort of sorted; track sort.active) {\r\n <!-- Menu Item Headers -->\r\n @if (sorted.length > 1) {\r\n <span class=\"description sort-header\">{{$index === 0 ? 'First By' : 'Then By'}}</span>\r\n }\r\n\r\n <!-- Menu Item -->\r\n <div mat-menu-item cdkDrag class=\"menu-item\">\r\n <div class=\"sort-item\">\r\n <span class=\"sorted-name\">\r\n {{sort.displayName || (sort.active | spaceCase)}}\r\n <span class=\"direction-text\">{{sort.direction}}</span>\r\n </span>\r\n\r\n <!-- Sort Direction Buttons -->\r\n <div class=\"up-down-buttons-wrapper\">\r\n <button class=\"up-down-button up-button\" stop-propagation\r\n (click)=\"setDirection({active:sort.active,direction:SortDirection.asc,displayName:sort.displayName})\">\r\n <mat-icon [class]=\"sort.direction !== SortDirection.asc ? 'light-arrow' : 'dark-arrow'\" class=\"up-down-icon\">\r\n arrow_upward\r\n </mat-icon>\r\n </button>\r\n\r\n <button class=\"up-down-button\" stop-propagation\r\n (click)=\"setDirection({active:sort.active,direction:SortDirection.desc,displayName:sort.displayName})\">\r\n <mat-icon [class]=\"sort.direction === SortDirection.asc ? 'light-arrow' : 'dark-arrow'\" class=\"up-down-icon\">\r\n arrow_downward\r\n </mat-icon>\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n }\r\n\r\n </div>\r\n\r\n <!-- Default Not Sorted Text -->\r\n @if(!notSorted.length){\r\n <div class=\"tip\" >\r\n Not Sorted List\r\n </div>\r\n }\r\n\r\n <!-- Not Sorted Menu List -->\r\n <div class=\"list\"\r\n cdkDropList\r\n #notSortedGroup=\"cdkDropList\"\r\n [cdkDropListConnectedTo]=\"[sortedGroup]\"\r\n [cdkDropListData]=\"notSorted\"\r\n (cdkDropListDropped)=\"dropIntoNotSorted($event)\">\r\n @for (sort of notSorted; track sort.active) {\r\n <div mat-menu-item class=\"menu-item\" cdkDrag>\r\n <span class=\"not-sorted-name\">{{sort.displayName || (sort.active | spaceCase)}}</span>\r\n </div>\r\n }\r\n </div>\r\n</mat-menu>\r\n", styles: [".cdk-drag-preview{box-sizing:border-box;border-radius:4px;box-shadow:0 5px 5px -3px #0003,0 8px 10px 1px #00000024,0 3px 14px 2px #0000001f}.cdk-drag-placeholder{opacity:0}.cdk-drag-animating{transition:transform .25s cubic-bezier(0,0,.2,1)}.list{padding:5px 2px;border-bottom:solid 1px #ccc;color:#000000de;background:#fff}.light-arrow{color:#93b1ea78}.dark-arrow{color:#224e9c}.up-down-button{background-color:#fff;border-radius:30%;border-color:#0ff;padding:1px 1px 0;border-width:.5px;cursor:pointer;height:27px}.mat-icon.up-down-icon{margin-right:0;font-size:20px;font-weight:lighter}.sort-item{display:flex;align-items:center;justify-content:space-between}.up-down-buttons-wrapper{margin-left:2rem}.up-button{margin-right:.3rem}.mat-mdc-menu-item.menu-item,.mat-mdc-menu-item.menu-button{min-height:initial;padding:0 3px;line-height:25px;height:30px}.mat-mdc-menu-item.menu-item{cursor:move}.sorted-name{color:#224e9c;font-size:17px;font-weight:700}.not-sorted-name{color:#93b1ea;font-size:17px;font-weight:700}.apply-border{border:#224e9c solid .5px}.apply-border:hover{background-color:#faebd7}.apply-button-wrapper{display:grid;justify-content:center}.sort-header{font-size:10px;font-style:italic}.tip{padding:0 3px;color:#d3d3d3}.direction-text{font-size:small;font-weight:400}.close-button-wrapper{display:flex;flex-direction:row-reverse}\n"] }]
4356
- }] });
4357
4414
 
4358
- class PaginatorComponent {
4359
- state = inject(TableStore);
4360
- data = inject(DataStore);
4361
- $paginator = viewChild(MatPaginator);
4362
- $dataLength = this.data.selectSignal(d => d.dataLen);
4363
- pageEvent$ = toObservable(this.$paginator).pipe(notNull(), switchMap(p => p.page));
4364
- $pageEvent = toSignal(this.pageEvent$);
4365
- $pageIndexChangeEvent = computed(() => this.$pageEvent()?.pageIndex);
4366
- $pageSizeChangeEvent = computed(() => this.$pageEvent()?.pageSize);
4367
- $currentPageData = computed(() => {
4368
- const pageEvent = this.$pageEvent();
4369
- if (!pageEvent)
4370
- return;
4371
- const paginator = this.$paginator();
4372
- // Reset because initial page event does not have page length
4373
- pageEvent.pageIndex = paginator.pageIndex;
4374
- pageEvent.pageSize = paginator.pageSize;
4375
- pageEvent.length = paginator.length;
4376
- const pageDetails = mapPaginationEventToCurrentPageDetails(pageEvent);
4377
- const dataLength = this.$dataLength();
4378
- return ({ ...pageDetails, total: dataLength });
4379
- });
4380
- onPageIndexEffect = effect(() => {
4381
- const index = this.$pageIndexChangeEvent();
4382
- if (index === undefined)
4383
- return;
4384
- untracked(() => this.state.setCurrentPage(index));
4385
- });
4386
- onPageSizeEffect = effect(() => {
4387
- const size = this.$pageSizeChangeEvent();
4388
- const initialized = this.state.$initializationState() >= InitializationState.Ready;
4389
- if (!size || !initialized)
4390
- return;
4391
- untracked(() => this.state.setUserDefinedPageSize(size));
4392
- });
4393
- onMetaPageSizeEffect = effect(() => {
4394
- const paginator = this.$paginator();
4395
- if (!paginator)
4415
+ function getGroupedData(data, groupByKeys) {
4416
+ return tbGroupBy(data, groupByKeys);
4417
+ }
4418
+ const tbGroupBy = (data, groupByKeys, parentGroupName) => {
4419
+ const currentKey = groupByKeys[0];
4420
+ const res = groupBy(data, currentKey);
4421
+ const remainingGroupByKeys = groupByKeys.slice(1);
4422
+ const finalGroups = !remainingGroupByKeys.length;
4423
+ if (remainingGroupByKeys.length) {
4424
+ Object.keys(res).forEach(key => res[key] = tbGroupBy(res[key], remainingGroupByKeys, key));
4425
+ }
4426
+ return Object.keys(res).map((groupName, i) => {
4427
+ const uniqName = parentGroupName ? `${parentGroupName}-${groupName}` : `${groupName}`;
4428
+ const groupHeaders = res[groupName]?.filter(row => row.isGroupHeader) ?? [];
4429
+ return {
4430
+ isGroupHeader: true,
4431
+ groupHeaderDisplay: groupName,
4432
+ hasTheData: finalGroups,
4433
+ children: finalGroups ? res[groupName] : res[groupName].map(d => { d.padding += 20; return d; }),
4434
+ groupName: `tb_group_${uniqName}`,
4435
+ padding: 1,
4436
+ key: currentKey,
4437
+ length: groupHeaders.reduce((acc, curr) => curr.length + acc, 0) + ((res[groupName] ?? []).length - groupHeaders.length),
4438
+ [initIndexSymbol]: uniqName,
4439
+ };
4440
+ });
4441
+ };
4442
+ function updateGroupByState({ groupedData }, [data, groups, expandedGroups], index) {
4443
+ if (index === 0
4444
+ || dataUpdated(data, groups, expandedGroups)
4445
+ || groupsUpdated(groups, expandedGroups)) {
4446
+ groupedData = groups.value.length ? getGroupedData(data.value, groups.value) : data.value;
4447
+ }
4448
+ const newDisplayData = expandedGroups.value.length === 0
4449
+ ? groupedData
4450
+ : groupedData.map(group => mapGroupHeader(group, expandedGroups.value)).flat();
4451
+ return ({ displayData: newDisplayData, groupedData });
4452
+ }
4453
+ function mapGroupHeader(obj, data) {
4454
+ const showChildren = data.find(a => a.expandedHeaders.includes(obj.groupName));
4455
+ const children = !showChildren ? [] :
4456
+ obj.hasTheData ? obj.children
4457
+ : obj.children.map(a => mapGroupHeader(a, data));
4458
+ return [obj, ...children].flat();
4459
+ }
4460
+ function dataUpdated(data, groups, expandedGroups) {
4461
+ return data.timestamp > groups.timestamp && data.timestamp > expandedGroups.timestamp;
4462
+ }
4463
+ function groupsUpdated(groups, expandedGroups) {
4464
+ return groups.timestamp > expandedGroups.timestamp;
4465
+ }
4466
+ ;
4467
+ const initialGroupByState = { displayData: [], groupedData: [] };
4468
+ const getAllGroupHeaderNames = (data) => {
4469
+ const groups = getGroupHeaders(data, (d) => d.isGroupHeader);
4470
+ return groupBy(groups, 'key');
4471
+ };
4472
+ const getAllGroupHeaderNamesByKeys = (data, keys) => {
4473
+ const groups = getGroupHeaders(data, (d) => d.isGroupHeader && keys.includes(d.key));
4474
+ return groupBy(groups, 'key');
4475
+ };
4476
+ const getGroupHeaders = (data, filterFunc, arr = []) => {
4477
+ const headers = data.filter(filterFunc);
4478
+ arr.push(...headers);
4479
+ headers.forEach(h => { if (!!h.children.length)
4480
+ getGroupHeaders(h.children, filterFunc, arr); });
4481
+ return arr;
4482
+ };
4483
+
4484
+ function sortData(data, sorted) {
4485
+ const ordered = orderBy(data, sorted.map(r => r.active), sorted.map(r => r.direction));
4486
+ return ordered;
4487
+ }
4488
+ function filterData(data, filters, resetAll = false) {
4489
+ for (let index = 0; index < data.length; index++) {
4490
+ const element = data[index];
4491
+ const hide = !filters.every(filter => filter(element));
4492
+ if (hide || resetAll) {
4493
+ element[tbNoShowSymbol] = hide;
4494
+ }
4495
+ }
4496
+ return data;
4497
+ }
4498
+ const tbNoShowSymbol = Symbol('tb_no_show');
4499
+
4500
+ const sortAndFilterData = (data, sortState, filterState) => combineLatest([
4501
+ data.pipe(timestamp()),
4502
+ sortState.pipe(timestamp()),
4503
+ filterState.pipe(timestamp())
4504
+ ]).pipe(scan(({ mappedData: resultData }, [data, sort, f], index) => {
4505
+ if (index === 0 || (data.timestamp > sort.timestamp && data.timestamp > f.timestamp)) {
4506
+ return ({ mappedData: filterData(sortData(data.value, sort.value.sortsToRun), f.value.allFilters) });
4507
+ }
4508
+ if (sort.timestamp > f.timestamp) {
4509
+ return ({ mappedData: sortData(resultData, sort.value.sortsToRun) });
4510
+ }
4511
+ return ({ mappedData: filterData(resultData, f.value.onlyAddedFilters || f.value.allFilters, !f.value.onlyAddedFilters) });
4512
+ }, { mappedData: [] })).pipe(map$1(({ mappedData: resultData }) => resultData.filter(item => !item[tbNoShowSymbol])), defaultShareReplay());
4513
+ const createDataCleaners = (metadatas, mutate = false) => {
4514
+ const transforms = createCleaners(metadatas);
4515
+ return (data) => {
4516
+ if (!mutate) {
4517
+ data = { ...data };
4518
+ }
4519
+ for (const transform of transforms) {
4520
+ transform(data);
4521
+ }
4522
+ return data;
4523
+ };
4524
+ };
4525
+ const createCleaners = (metadatas) => {
4526
+ return metadatas.reduce((transforms, metaData) => {
4527
+ const notNestedKey = metaData.key;
4528
+ switch (metaData.fieldType) {
4529
+ case FieldType.Currency:
4530
+ case FieldType.Number: {
4531
+ const nested = metaData.key.includes('.');
4532
+ if (nested) {
4533
+ transforms.push((t) => {
4534
+ const val = get(t, metaData.key);
4535
+ const num = Number(val);
4536
+ set(t, metaData.key, isNaN(num) || val == null ? null : num);
4537
+ });
4538
+ }
4539
+ else {
4540
+ transforms.push((t) => {
4541
+ const val = t[notNestedKey];
4542
+ const num = Number(val);
4543
+ t[notNestedKey] = (isNaN(num) || val == null ? null : num);
4544
+ });
4545
+ }
4546
+ break;
4547
+ }
4548
+ case FieldType.Date: {
4549
+ const nested = metaData.key.includes('.');
4550
+ if (nested) {
4551
+ transforms.push((t) => {
4552
+ const val = get(t, metaData.key);
4553
+ const date = Date.parse(val);
4554
+ if (isNaN(date)) {
4555
+ set(t, metaData.key, null);
4556
+ return;
4557
+ }
4558
+ const d = new Date(date);
4559
+ d.setHours(0, 0, 0, 0);
4560
+ set(t, metaData.key, d);
4561
+ });
4562
+ }
4563
+ else {
4564
+ transforms.push((t) => {
4565
+ const val = t[notNestedKey];
4566
+ const date = Date.parse(val);
4567
+ if (isNaN(date)) {
4568
+ t[notNestedKey] = null;
4569
+ return;
4570
+ }
4571
+ const d = new Date(date);
4572
+ d.setHours(0, 0, 0, 0);
4573
+ t[notNestedKey] = d;
4574
+ });
4575
+ }
4576
+ break;
4577
+ }
4578
+ case FieldType.DateTime: {
4579
+ const nested = metaData.key.includes('.');
4580
+ if (nested) {
4581
+ transforms.push((t) => {
4582
+ const val = get(t, metaData.key);
4583
+ const dateTime = Date.parse(val);
4584
+ if (isNaN(dateTime)) {
4585
+ set(t, metaData.key, null);
4586
+ return;
4587
+ }
4588
+ const dt = new Date(dateTime);
4589
+ if (metaData.additional?.dateTimeOptions?.includeMilliseconds) {
4590
+ set(t, metaData.key, dt);
4591
+ return;
4592
+ }
4593
+ if (metaData.additional?.dateTimeOptions?.includeSeconds) {
4594
+ dt.setMilliseconds(0);
4595
+ set(t, metaData.key, dt);
4596
+ return;
4597
+ }
4598
+ dt.setSeconds(0, 0);
4599
+ set(t, metaData.key, dt);
4600
+ });
4601
+ }
4602
+ else {
4603
+ transforms.push((t) => {
4604
+ const val = t[notNestedKey];
4605
+ const dateTime = Date.parse(val);
4606
+ if (isNaN(dateTime)) {
4607
+ t[notNestedKey] = null;
4608
+ return;
4609
+ }
4610
+ const dt = new Date(dateTime);
4611
+ if (metaData.additional?.dateTimeOptions?.includeMilliseconds) {
4612
+ t[notNestedKey] = dt;
4613
+ return;
4614
+ }
4615
+ if (metaData.additional?.dateTimeOptions?.includeSeconds) {
4616
+ dt.setMilliseconds(0);
4617
+ t[notNestedKey] = dt;
4618
+ return;
4619
+ }
4620
+ dt.setSeconds(0, 0);
4621
+ t[notNestedKey] = dt;
4622
+ });
4623
+ }
4624
+ }
4625
+ }
4626
+ return transforms;
4627
+ }, []);
4628
+ };
4629
+
4630
+ class PaginatorComponent {
4631
+ state = inject(TableStore);
4632
+ data = inject(DataStore);
4633
+ $paginator = viewChild(MatPaginator);
4634
+ $dataLength = this.data.selectSignal(d => d.dataLen);
4635
+ pageEvent$ = toObservable(this.$paginator).pipe(notNull(), switchMap(p => p.page));
4636
+ $pageEvent = toSignal(this.pageEvent$);
4637
+ $pageIndexChangeEvent = computed(() => this.$pageEvent()?.pageIndex);
4638
+ $pageSizeChangeEvent = computed(() => this.$pageEvent()?.pageSize);
4639
+ $currentPageData = computed(() => {
4640
+ const pageEvent = this.$pageEvent();
4641
+ if (!pageEvent)
4642
+ return;
4643
+ const paginator = this.$paginator();
4644
+ // Reset because initial page event does not have page length
4645
+ pageEvent.pageIndex = paginator.pageIndex;
4646
+ pageEvent.pageSize = paginator.pageSize;
4647
+ pageEvent.length = paginator.length;
4648
+ const pageDetails = mapPaginationEventToCurrentPageDetails(pageEvent);
4649
+ const dataLength = this.$dataLength();
4650
+ return ({ ...pageDetails, total: dataLength });
4651
+ });
4652
+ onPageIndexEffect = effect(() => {
4653
+ const index = this.$pageIndexChangeEvent();
4654
+ if (index === undefined)
4655
+ return;
4656
+ untracked(() => this.state.setCurrentPage(index));
4657
+ });
4658
+ onPageSizeEffect = effect(() => {
4659
+ const size = this.$pageSizeChangeEvent();
4660
+ const initialized = this.state.$initializationState() >= InitializationState.Ready;
4661
+ if (!size || !initialized)
4662
+ return;
4663
+ untracked(() => this.state.setUserDefinedPageSize(size));
4664
+ });
4665
+ onMetaPageSizeEffect = effect(() => {
4666
+ const paginator = this.$paginator();
4667
+ if (!paginator)
4396
4668
  return;
4397
4669
  const metaPageSize = this.state.$pageSize();
4398
4670
  untracked(() => paginator._changePageSize(metaPageSize));
@@ -4425,7 +4697,7 @@ class PaginatorComponent {
4425
4697
  </mat-paginator>
4426
4698
  @if ($showAllOption()) {<button mat-button (click)="showAll()"><span [style.text-decoration]="$showAll() ? 'line-through' : ''" >All</span></button>}
4427
4699
  </div>
4428
- `, isInline: true, styles: [":host{--mat-paginator-container-size: initial}.select-column{min-width:var(--tb-min-select-column-width, 42px)}.index-column{min-width:var(--tb-min-index-column-width, 42px)}.mat-mdc-row:nth-child(odd){background-color:var(--tb-odd-row-background-color, #cdeefe)}.page-amounts{color:#0000008a;font-family:Roboto,Helvetica Neue,sans-serif;font-size:12px;margin-right:.2rem}:host::ng-deep .table-drag-list.cdk-drop-list-dragging .drag-header:not(.cdk-drag-placeholder){transition:transform .25s cubic-bezier(0,0,.2,1)}:host::ng-deep .mdc-data-table__cell,:host::ng-deep .mdc-data-table__header-cell{padding:var(--tb-cell-padding, 0 0 0 .2rem);line-height:var(--tb-cell-line-height, normal)}::ng-deep .op-date-time-input{line-height:3rem;font-size:.9rem;font-family:Roboto,Helvetica Neue,sans-serif;padding-left:.2rem;width:12rem}\n", ".collapse-icon{font-size:16px;height:16px;color:#3f51b5;align-self:flex-start}.collapse-icon:hover{cursor:pointer}.hide{display:none}.paginator-row{display:flex;align-items:center}\n"], dependencies: [{ kind: "ngmodule", type: MatPaginatorModule }, { kind: "component", type: i1$6.MatPaginator, selector: "mat-paginator", inputs: ["color", "pageIndex", "length", "pageSize", "pageSizeOptions", "hidePageSize", "showFirstLastButtons", "selectConfig", "disabled"], outputs: ["page"], exportAs: ["matPaginator"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i3$1.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
4700
+ `, isInline: true, styles: [":host{--mat-paginator-container-size: initial}.select-column{min-width:var(--tb-min-select-column-width, 42px)}.index-column{min-width:var(--tb-min-index-column-width, 42px)}.mat-mdc-row:nth-child(odd){background-color:var(--tb-odd-row-background-color, #cdeefe)}.page-amounts{color:#0000008a;font-family:Roboto,Helvetica Neue,sans-serif;font-size:12px;margin-right:.2rem}:host::ng-deep .table-drag-list.cdk-drop-list-dragging .drag-header:not(.cdk-drag-placeholder){transition:transform .25s cubic-bezier(0,0,.2,1)}:host::ng-deep .mdc-data-table__cell,:host::ng-deep .mdc-data-table__header-cell{padding:var(--tb-cell-padding, 0 0 0 .2rem);line-height:var(--tb-cell-line-height, normal)}::ng-deep .op-date-time-input{line-height:3rem;font-size:.9rem;font-family:Roboto,Helvetica Neue,sans-serif;padding-left:.2rem;width:12rem}\n", ".collapse-icon{font-size:16px;height:16px;color:#3f51b5;align-self:flex-start}.collapse-icon:hover{cursor:pointer}.hide{display:none}.paginator-row{display:flex;align-items:center}\n"], dependencies: [{ kind: "ngmodule", type: MatPaginatorModule }, { kind: "component", type: i1$7.MatPaginator, selector: "mat-paginator", inputs: ["color", "pageIndex", "length", "pageSize", "pageSizeOptions", "hidePageSize", "showFirstLastButtons", "selectConfig", "disabled"], outputs: ["page"], exportAs: ["matPaginator"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i3$1.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
4429
4701
  }
4430
4702
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: PaginatorComponent, decorators: [{
4431
4703
  type: Component,
@@ -4449,689 +4721,601 @@ const mapPaginationEventToCurrentPageDetails = (pageData) => ({
4449
4721
  total: pageData.length
4450
4722
  });
4451
4723
 
4452
- class TableVirtualScrollStrategy {
4453
- itemHeight;
4454
- headerHeight;
4455
- scrolledIndexChange;
4456
- dataLength = 0;
4457
- indexChange = new Subject();
4458
- viewport;
4459
- constructor(itemHeight, headerHeight) {
4460
- this.itemHeight = itemHeight;
4461
- this.headerHeight = headerHeight;
4462
- this.scrolledIndexChange = this.indexChange.pipe(distinctUntilChanged());
4724
+ class TableBuilderDataSource extends MatTableDataSource {
4725
+ subscription;
4726
+ #$dataSrc = signal([]);
4727
+ $dataSize = signal({ start: 0, end: 0 }, {
4728
+ equal: (a, b) => a.start === b.start && a.end === b.end
4729
+ });
4730
+ _ = effect(() => {
4731
+ const data = this.#$dataSrc();
4732
+ const dataSize = this.$dataSize();
4733
+ untracked(() => this.data = data.slice(dataSize.start, dataSize.end));
4734
+ });
4735
+ setData(data) {
4736
+ this.#$dataSrc.set(data);
4463
4737
  }
4464
- attach(viewport) {
4465
- this.viewport = viewport;
4466
- this.onDataLengthChanged();
4738
+ constructor(state, data) {
4739
+ super([]);
4740
+ const $currentPage = state.$currentPage;
4741
+ const $pageSize = state.$pageSize;
4742
+ const $virtualEnds = data.selectSignal(d => d.virtualEnds);
4743
+ const $dataLength = computed(() => this.#$dataSrc().length);
4744
+ const $dataSize = computed(() => {
4745
+ const viewType = state.$viewType();
4746
+ const dataLength = $dataLength();
4747
+ const currentPage = $currentPage();
4748
+ const pageSize = $pageSize();
4749
+ const virtualEnds = $virtualEnds();
4750
+ const previousPageRecords = currentPage * pageSize;
4751
+ if (viewType === 'virtual paginator') {
4752
+ return ({ start: virtualEnds.start + previousPageRecords, end: Math.min(virtualEnds.end, pageSize) + previousPageRecords });
4753
+ }
4754
+ if (viewType === 'paginator') {
4755
+ return ({ start: previousPageRecords, end: previousPageRecords + pageSize });
4756
+ }
4757
+ if (viewType === 'all') {
4758
+ return ({ start: 0, end: dataLength });
4759
+ }
4760
+ return ({ start: virtualEnds.start, end: virtualEnds.end });
4761
+ });
4762
+ this.$dataSize = $dataSize;
4467
4763
  }
4468
- contentScrolled$ = new Subject();
4469
- sub = subscriber(this.contentScrolled$.pipe(observeOn(animationFrameScheduler)), () => {
4470
- this.updateContent();
4471
- });
4472
- onContentScrolled() {
4473
- this.contentScrolled$.next();
4764
+ connect() {
4765
+ return super.connect();
4474
4766
  }
4475
- onDataLengthChanged() {
4476
- if (this.viewport) {
4477
- this.viewport.setTotalContentSize(this.dataLength * this.itemHeight);
4478
- this.updateContent();
4767
+ disconnect() {
4768
+ if (this.subscription) {
4769
+ this.subscription.unsubscribe();
4770
+ this.subscription = undefined;
4479
4771
  }
4772
+ super.disconnect();
4480
4773
  }
4481
- setDataLength(length) {
4482
- this.dataLength = length;
4483
- this.onDataLengthChanged();
4774
+ }
4775
+
4776
+ function mergeCustomCellMetaData(metaData1, metaData2) {
4777
+ if (!metaData2) {
4778
+ metaData1.noExport = true;
4779
+ return metaData1;
4484
4780
  }
4485
- detach() { }
4486
- onContentRendered() { }
4487
- onRenderedOffsetChanged() {
4781
+ if (!metaData1.displayName)
4782
+ metaData1.displayName = metaData2.displayName;
4783
+ if (!metaData1.preSort)
4784
+ metaData1.preSort = metaData2.preSort;
4785
+ if (!metaData1.order)
4786
+ metaData1.order = metaData2.order;
4787
+ if (!metaData1.width)
4788
+ metaData1.width = metaData2.width;
4789
+ if (metaData2.fieldType)
4790
+ metaData1.fieldType = metaData2.fieldType;
4791
+ metaData1.noExport = metaData2.noExport;
4792
+ return ({ ...metaData2, ...metaData1 });
4793
+ }
4794
+
4795
+ class GroupByListComponent {
4796
+ tableStore = inject(TableStore);
4797
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: GroupByListComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
4798
+ 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 });
4799
+ }
4800
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: GroupByListComponent, decorators: [{
4801
+ type: Component,
4802
+ args: [{ selector: 'group-by-list', changeDetection: ChangeDetectionStrategy.OnPush, imports: [
4803
+ MatChipsModule, MatIconModule, SpaceCasePipe
4804
+ ], 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"] }]
4805
+ }] });
4806
+
4807
+ class ProfilesMenuComponent {
4808
+ stateService = inject(TableBuilderStateStore);
4809
+ tableStore = inject(TableStore);
4810
+ $tableId = input.required({ alias: 'tableId' });
4811
+ $isMatMenuChild = input(false, { alias: 'isMatMenuChild' });
4812
+ trigger = viewChild('trigger');
4813
+ menu = viewChild.required(MatMenu);
4814
+ allProfilesPanelOpened = signal(false);
4815
+ newProfilePanelOpened = signal(false);
4816
+ $currentProfile = computed(() => this.stateService.$selectLocalProfileCurrentKey(this.$tableId())());
4817
+ $defaultProfile = computed(() => this.stateService.$selectLocalProfileDefaultKey(this.$tableId())());
4818
+ $keys = computed(() => this.stateService.$selectLocalProfileKeys(this.$tableId())());
4819
+ saveState(key) {
4820
+ const tableState = this.tableStore.$savableState();
4821
+ this.stateService.saveTableSettingsToLocalAndStorage(this.$tableId(), key, tableState);
4488
4822
  }
4489
- scrollToIndex(index, behavior) {
4823
+ addState(key, asDefault) {
4824
+ const tableState = this.tableStore.$savableState();
4825
+ this.stateService.addNewStateToLocalAndStorage(this.$tableId(), key, tableState, asDefault);
4490
4826
  }
4491
- updateContent() {
4492
- if (!this.viewport) {
4493
- return;
4494
- }
4495
- const amountOfRows = Math.ceil((this.viewport.getViewportSize() - this.headerHeight) / this.itemHeight);
4496
- const offset = this.viewport.measureScrollOffset();
4497
- const buffer = 35;
4498
- const skip = Math.round(offset / this.itemHeight);
4499
- // always start at an even index so we don't change the color patterns for odd and even rows.
4500
- const index = skip % 2 === 0 ? skip : skip - 1;
4501
- const start = Math.max(0, index - buffer);
4502
- const end = Math.min(this.dataLength, index + amountOfRows + buffer);
4503
- this.viewport.setRenderedContentOffset(this.itemHeight * start);
4504
- this.viewport.setRenderedRange({ start, end });
4505
- this.indexChange.next(index);
4827
+ setDefault(key) {
4828
+ this.stateService.setDefaultInLocalAndStorage(this.$tableId(), key);
4829
+ }
4830
+ unsetDefault() {
4831
+ this.stateService.unsetDefaultFromLocalAndStorage(this.$tableId());
4506
4832
  }
4833
+ defaultName = 'My Profile';
4834
+ position$ = new Subject();
4835
+ setPosition = (e) => {
4836
+ const rect = e.getBoundingClientRect();
4837
+ if (rect.top === 0)
4838
+ return;
4839
+ const a = {
4840
+ right: `${(window.innerWidth - rect.right)}px`,
4841
+ top: `${rect.top}px`,
4842
+ };
4843
+ return a;
4844
+ };
4845
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: ProfilesMenuComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
4846
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.0", type: ProfilesMenuComponent, isStandalone: true, selector: "tb-profiles-menu", inputs: { $tableId: { classPropertyName: "$tableId", publicName: "tableId", isSignal: true, isRequired: true, transformFunction: null }, $isMatMenuChild: { classPropertyName: "$isMatMenuChild", publicName: "isMatMenuChild", isSignal: true, isRequired: false, transformFunction: null } }, viewQueries: [{ propertyName: "trigger", first: true, predicate: ["trigger"], descendants: true, isSignal: true }, { propertyName: "menu", first: true, predicate: MatMenu, descendants: true, isSignal: true }], ngImport: i0, template: "@if(!$isMatMenuChild())\r\n{\r\n <button mat-icon-button [matMenuTriggerFor]=\"menu\" #trigger=\"matMenuTrigger\" [matTooltip]=\"'Profiles'\">\r\n <mat-icon color=\"primary\">people</mat-icon>\r\n </button>\r\n}\r\n<mat-menu #menu=\"matMenu\" (closed)=\"addedKey.value = null; allProfilesPanelOpened.set(false); newProfilePanelOpened.set(false)\">\r\n @if(!!$currentProfile())\r\n {\r\n <div mat-menu-item [matTooltip]=\"'Save Profile'\" mat-stroked-button (click)=\"saveState($currentProfile()!)\">\r\n <mat-icon color=\"primary\">save</mat-icon>\r\n <span>{{$currentProfile()}}</span>\r\n </div>\r\n }\r\n @else\r\n {\r\n <div class=\"profile-line\">\r\n <button class=\"first-in-line first-button\" mat-stroked-button (click)=\"addState(defaultName, m.checked);\">\r\n <mat-icon class=\"save-for-default-icon button-save-icon\" color=\"primary\">save</mat-icon>\r\n <span>Save as <span class=\"current-name\">{{defaultName}}</span> </span>\r\n </button>\r\n <button [matTooltip]=\"'Toggle Profile Being Created As Default'\" stop-propagation mat-icon-button (click)=\"m.toggle()\" >\r\n <mat-icon style=\"color: green;\">{{m.checked ? 'star' : 'star_border'}}</mat-icon>\r\n </button>\r\n <mat-checkbox class=\"display-none\" [checked]=\"true\" #m />\r\n </div>\r\n }\r\n @if (allProfilesPanelOpened()) {<hr class=\"divider\"/>}\r\n <div [class]=\"{ hide: !$keys().length, 'all-profile-row': true }\" mat-menu-item stop-propagation (click)=\"allProfilesPanelOpened.set(!allProfilesPanelOpened())\">\r\n <div class=\"all-profiles\">\r\n <span>All Profiles</span>\r\n <span [class]=\"(allProfilesPanelOpened() ? 'all-profile-arrow-close' : 'all-profile-arrow-open') + ' all-profile-arrow'\" class=\"arrow\"></span>\r\n </div>\r\n </div>\r\n <div [class]=\"{ hide: !allProfilesPanelOpened(), panel: true }\">\r\n @for (key of $keys() ; track key) {\r\n <div class=\"profile-line\" [class]=\"key === $currentProfile() ? 'current-in-list' : 'not-current-in-list'\">\r\n <button [matTooltip]=\"'Select Profile'\" class=\"menu-item first-in-line\" mat-stroked-button (click)='stateService.setLocalCurrentState({ tableId: $tableId(), currentStateKey: key})'>\r\n <span>{{key}}</span>\r\n </button>\r\n @if(key !== $defaultProfile())\r\n {\r\n <button [matTooltip]=\"'Toggle Profile Being Default'\" stop-propagation mat-icon-button (click)=\"setDefault(key)\">\r\n <mat-icon style=\"color: green;\">star_border</mat-icon>\r\n </button>\r\n }\r\n @else\r\n {\r\n <button [matTooltip]=\"'Toggle Profile Being Default'\" stop-propagation mat-icon-button (click)=\"unsetDefault()\">\r\n <mat-icon style=\"color: green;\">star</mat-icon>\r\n </button>\r\n }\r\n <button [matTooltip]=\"'Delete Profile'\" class=\"last-in-line\" stop-propagation mat-icon-button (click)='stateService.deleteProfileFromLocalAndStorage($tableId(), key)'>\r\n <mat-icon color='warn'>delete_forever</mat-icon>\r\n </button>\r\n </div>\r\n }\r\n <hr class=\"divider\"/>\r\n </div>\r\n <div class=\"add-new-profile-row\" mat-menu-item stop-propagation (click)=\"newProfilePanelOpened.set(!newProfilePanelOpened()); addedKey.focus()\">Add New Profile</div>\r\n <div [class]=\"{ hide: !newProfilePanelOpened(), panel: true }\" >\r\n <div class=\"profile-line\" stop-propagation>\r\n <div class=\"new-name-input\">\r\n <i class=\"input-hint\">Enter New Name</i>\r\n <input matInput #addedKey=\"matInput\" [name]=\"'key'\" />\r\n </div>\r\n <button [matTooltip]=\"'Toggle Profile Being Created As Default'\" stop-propagation mat-icon-button (click)=\"m2.toggle()\" >\r\n <mat-icon style=\"color: green;\">{{m2.checked ? 'star' : 'star_border'}}</mat-icon>\r\n </button>\r\n <mat-checkbox class=\"display-none\" [ngModel]=\"!$defaultProfile()\" #m2 />\r\n </div>\r\n <button class=\"add-button\" color=\"primary\" [matTooltip]=\"'Create New Profile'\" mat-raised-button (click)=\"addState(addedKey.value, m2.checked); addedKey.value = null\" [disabled]=\"!addedKey.value\">\r\n Add\r\n </button>\r\n </div>\r\n</mat-menu>\r\n", styles: [":host ::ng-deep .mat-expansion-panel-header{padding:0}.current-name{color:#00f}.menu-item{display:inline-flex;width:initial;flex-grow:1}.profile-line{display:flex;justify-content:space-between;align-items:center}.first-in-line{--f-b: 2rem;margin-left:var(--mat-menu-item-with-icon-leading-spacing)}.first-in-line.first-button{height:var(--f-b);margin:.2rem}.first-in-line .button-save-icon{height:var(--f-b);width:var(--f-b);font-size:var(--f-b)}.main-save-button{height:4rem;width:4rem;padding:.5rem}.main-save-button mat-icon{height:3rem;width:3rem;font-size:3rem}.save-for-default-icon{margin:0}.display-none{display:none}.last-in-line{padding-right:var(--mat-menu-item-with-icon-trailing-spacing)}.default-cursor{cursor:default}.as-def{padding-left:var(--mat-menu-item-with-icon-leading-spacing)}.divider{margin:.2px 0}.add-key{max-width:8.5rem;margin-left:2px}.add-key ::ng-deep .mdc-text-field{padding:0}.panel{transition:height .1s}.hide{height:0;min-height:0;overflow:hidden}.open-panel-button{width:100%;height:2.5rem}.current-in-list{border-left:3px solid blue;background-color:#0000ff0d}.not-current-in-list{border-left:3px solid rgba(255,255,255,0)}.add-new-profile-row,.all-profile-row{border-top:rgba(128,128,128,.25) solid 1px}.all-profiles{display:flex;justify-content:space-between}.all-profiles:has(.all-profile-arrow-close){align-items:center}.all-profile-arrow{display:inline-block;height:.7rem;width:.7rem;border-color:#000;transform:rotate(-45deg)}.all-profile-arrow-open{border-left:solid 2px;border-bottom:solid 2px}.all-profile-arrow-close{border-right:solid 2px;border-top:solid 2px}.new-name-input{margin-left:3px;display:flex;flex-direction:column}.new-name-input .input-hint{font-size:smaller;font-weight:200;color:gray}.add-button{height:20px;line-height:20px;margin:3px 0 0 3px}\n"], dependencies: [{ kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "ngmodule", type: MatMenuModule }, { kind: "component", type: 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: "component", type: MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "directive", type: MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "component", type: MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "aria-expanded", "aria-controls", "aria-owns", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "disabledInteractive", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { kind: "directive", type: StopPropagationDirective, selector: "[stop-propagation]" }, { kind: "ngmodule", type: MatInputModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }] });
4507
4847
  }
4848
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: ProfilesMenuComponent, decorators: [{
4849
+ type: Component,
4850
+ args: [{ selector: 'tb-profiles-menu', imports: [MatIcon, MatTooltip, MatIconButton, MatMenuModule, MatButton, MatInput,
4851
+ MatCheckbox, StopPropagationDirective, MatInputModule, FormsModule
4852
+ ], template: "@if(!$isMatMenuChild())\r\n{\r\n <button mat-icon-button [matMenuTriggerFor]=\"menu\" #trigger=\"matMenuTrigger\" [matTooltip]=\"'Profiles'\">\r\n <mat-icon color=\"primary\">people</mat-icon>\r\n </button>\r\n}\r\n<mat-menu #menu=\"matMenu\" (closed)=\"addedKey.value = null; allProfilesPanelOpened.set(false); newProfilePanelOpened.set(false)\">\r\n @if(!!$currentProfile())\r\n {\r\n <div mat-menu-item [matTooltip]=\"'Save Profile'\" mat-stroked-button (click)=\"saveState($currentProfile()!)\">\r\n <mat-icon color=\"primary\">save</mat-icon>\r\n <span>{{$currentProfile()}}</span>\r\n </div>\r\n }\r\n @else\r\n {\r\n <div class=\"profile-line\">\r\n <button class=\"first-in-line first-button\" mat-stroked-button (click)=\"addState(defaultName, m.checked);\">\r\n <mat-icon class=\"save-for-default-icon button-save-icon\" color=\"primary\">save</mat-icon>\r\n <span>Save as <span class=\"current-name\">{{defaultName}}</span> </span>\r\n </button>\r\n <button [matTooltip]=\"'Toggle Profile Being Created As Default'\" stop-propagation mat-icon-button (click)=\"m.toggle()\" >\r\n <mat-icon style=\"color: green;\">{{m.checked ? 'star' : 'star_border'}}</mat-icon>\r\n </button>\r\n <mat-checkbox class=\"display-none\" [checked]=\"true\" #m />\r\n </div>\r\n }\r\n @if (allProfilesPanelOpened()) {<hr class=\"divider\"/>}\r\n <div [class]=\"{ hide: !$keys().length, 'all-profile-row': true }\" mat-menu-item stop-propagation (click)=\"allProfilesPanelOpened.set(!allProfilesPanelOpened())\">\r\n <div class=\"all-profiles\">\r\n <span>All Profiles</span>\r\n <span [class]=\"(allProfilesPanelOpened() ? 'all-profile-arrow-close' : 'all-profile-arrow-open') + ' all-profile-arrow'\" class=\"arrow\"></span>\r\n </div>\r\n </div>\r\n <div [class]=\"{ hide: !allProfilesPanelOpened(), panel: true }\">\r\n @for (key of $keys() ; track key) {\r\n <div class=\"profile-line\" [class]=\"key === $currentProfile() ? 'current-in-list' : 'not-current-in-list'\">\r\n <button [matTooltip]=\"'Select Profile'\" class=\"menu-item first-in-line\" mat-stroked-button (click)='stateService.setLocalCurrentState({ tableId: $tableId(), currentStateKey: key})'>\r\n <span>{{key}}</span>\r\n </button>\r\n @if(key !== $defaultProfile())\r\n {\r\n <button [matTooltip]=\"'Toggle Profile Being Default'\" stop-propagation mat-icon-button (click)=\"setDefault(key)\">\r\n <mat-icon style=\"color: green;\">star_border</mat-icon>\r\n </button>\r\n }\r\n @else\r\n {\r\n <button [matTooltip]=\"'Toggle Profile Being Default'\" stop-propagation mat-icon-button (click)=\"unsetDefault()\">\r\n <mat-icon style=\"color: green;\">star</mat-icon>\r\n </button>\r\n }\r\n <button [matTooltip]=\"'Delete Profile'\" class=\"last-in-line\" stop-propagation mat-icon-button (click)='stateService.deleteProfileFromLocalAndStorage($tableId(), key)'>\r\n <mat-icon color='warn'>delete_forever</mat-icon>\r\n </button>\r\n </div>\r\n }\r\n <hr class=\"divider\"/>\r\n </div>\r\n <div class=\"add-new-profile-row\" mat-menu-item stop-propagation (click)=\"newProfilePanelOpened.set(!newProfilePanelOpened()); addedKey.focus()\">Add New Profile</div>\r\n <div [class]=\"{ hide: !newProfilePanelOpened(), panel: true }\" >\r\n <div class=\"profile-line\" stop-propagation>\r\n <div class=\"new-name-input\">\r\n <i class=\"input-hint\">Enter New Name</i>\r\n <input matInput #addedKey=\"matInput\" [name]=\"'key'\" />\r\n </div>\r\n <button [matTooltip]=\"'Toggle Profile Being Created As Default'\" stop-propagation mat-icon-button (click)=\"m2.toggle()\" >\r\n <mat-icon style=\"color: green;\">{{m2.checked ? 'star' : 'star_border'}}</mat-icon>\r\n </button>\r\n <mat-checkbox class=\"display-none\" [ngModel]=\"!$defaultProfile()\" #m2 />\r\n </div>\r\n <button class=\"add-button\" color=\"primary\" [matTooltip]=\"'Create New Profile'\" mat-raised-button (click)=\"addState(addedKey.value, m2.checked); addedKey.value = null\" [disabled]=\"!addedKey.value\">\r\n Add\r\n </button>\r\n </div>\r\n</mat-menu>\r\n", styles: [":host ::ng-deep .mat-expansion-panel-header{padding:0}.current-name{color:#00f}.menu-item{display:inline-flex;width:initial;flex-grow:1}.profile-line{display:flex;justify-content:space-between;align-items:center}.first-in-line{--f-b: 2rem;margin-left:var(--mat-menu-item-with-icon-leading-spacing)}.first-in-line.first-button{height:var(--f-b);margin:.2rem}.first-in-line .button-save-icon{height:var(--f-b);width:var(--f-b);font-size:var(--f-b)}.main-save-button{height:4rem;width:4rem;padding:.5rem}.main-save-button mat-icon{height:3rem;width:3rem;font-size:3rem}.save-for-default-icon{margin:0}.display-none{display:none}.last-in-line{padding-right:var(--mat-menu-item-with-icon-trailing-spacing)}.default-cursor{cursor:default}.as-def{padding-left:var(--mat-menu-item-with-icon-leading-spacing)}.divider{margin:.2px 0}.add-key{max-width:8.5rem;margin-left:2px}.add-key ::ng-deep .mdc-text-field{padding:0}.panel{transition:height .1s}.hide{height:0;min-height:0;overflow:hidden}.open-panel-button{width:100%;height:2.5rem}.current-in-list{border-left:3px solid blue;background-color:#0000ff0d}.not-current-in-list{border-left:3px solid rgba(255,255,255,0)}.add-new-profile-row,.all-profile-row{border-top:rgba(128,128,128,.25) solid 1px}.all-profiles{display:flex;justify-content:space-between}.all-profiles:has(.all-profile-arrow-close){align-items:center}.all-profile-arrow{display:inline-block;height:.7rem;width:.7rem;border-color:#000;transform:rotate(-45deg)}.all-profile-arrow-open{border-left:solid 2px;border-bottom:solid 2px}.all-profile-arrow-close{border-right:solid 2px;border-top:solid 2px}.new-name-input{margin-left:3px;display:flex;flex-direction:column}.new-name-input .input-hint{font-size:smaller;font-weight:200;color:gray}.add-button{height:20px;line-height:20px;margin:3px 0 0 3px}\n"] }]
4853
+ }] });
4508
4854
 
4509
- class VirtualScrollContainer {
4510
- state = inject(TableStore);
4511
- dataStore = inject(DataStore);
4512
- viewport = viewChild(CdkVirtualScrollViewport);
4513
- genericTable = contentChild(GenericTableComponent);
4514
- tableContainer = inject(TableContainerComponent);
4515
- defaultOptions = new VirtualScrollOptions();
4516
- scrollStrategy = new TableVirtualScrollStrategy(this.computedRowHeight(), this.computedHeaderHeight());
4517
- $usePaginator = this.state.selectSignal(s => s.notPersistedTableSettings.usePaginator);
4518
- $pageSize = this.state.$pageSize;
4519
- $currentPage = this.state.$currentPage;
4520
- $showAll = this.state.$showAll;
4521
- $stateDataLength = this.dataStore.selectSignal(s => s.dataLen);
4522
- viewPort$ = toObservable(this.viewport).pipe(notNull());
4523
- $scrolledIndexChange = toSignal(this.viewPort$.pipe(switchMap$1(v => v.scrolledIndexChange)));
4524
- $renderedRange = toSignal(this.viewPort$.pipe(switchMap$1(v => v.renderedRangeStream)));
4525
- $virtualScrollOptions = computed(() => this.state.$tableSettings().virtualSettings);
4526
- $dataLength = computed(() => {
4527
- const paginated = this.$usePaginator() && !this.$showAll();
4528
- const pageSize = this.$pageSize();
4529
- const pageNumber = this.$currentPage();
4530
- const dataLen = this.$stateDataLength();
4531
- if (paginated)
4532
- return Math.min(dataLen - (pageNumber * pageSize), pageSize);
4533
- return dataLen;
4855
+ class SortMenuComponentStore extends ComponentStore {
4856
+ tableState = inject(TableStore);
4857
+ setStoreStateEffect = effect(() => {
4858
+ const metaData = this.tableState.$metaData();
4859
+ if (!metaData)
4860
+ return;
4861
+ this.tableState.$selectSorted();
4862
+ untracked(() => this.setStateFromTableStore());
4534
4863
  });
4864
+ setStateFromTableStore = () => {
4865
+ const metaData = this.tableState.$metaData();
4866
+ const sorted = [...this.tableState.$selectSorted()].map(s => ({
4867
+ ...s,
4868
+ displayName: metaData[s.active]?.displayName
4869
+ }));
4870
+ const notSorted = this.tableState.$metaDataArray()
4871
+ .filter(md => md.fieldType !== FieldType.NotMapped && !md.noSort && !sorted.some(s => s.active === md.key))
4872
+ .map(meta => ({ active: meta.key, displayName: meta.displayName }));
4873
+ this.setState({ sorted, notSorted });
4874
+ };
4535
4875
  constructor() {
4536
- addEventListener('resize', this.resizeHandler);
4876
+ super({ notSorted: [], sorted: [] });
4537
4877
  }
4538
- setViewportEffect = effect(() => {
4539
- const viewport = this.viewport();
4540
- untracked(() => {
4541
- if (!!viewport) {
4542
- this.setSize(this.viewport().elementRef);
4543
- }
4544
- ;
4545
- });
4878
+ setSorted = this.updater((state, sorted) => ({ ...state, sorted }));
4879
+ setNotSorted = this.updater((state, notSorted) => ({ ...state, notSorted }));
4880
+ $sorted = this.selectSignal(state => state.sorted);
4881
+ $notSorted = this.selectSignal(state => state.notSorted);
4882
+ setDirection = this.updater((state, sort) => {
4883
+ const index = state.sorted.findIndex(s => s.active === sort.active);
4884
+ const sorted = [...state.sorted];
4885
+ sorted.splice(index, 1, sort);
4886
+ return ({ ...state, sorted });
4546
4887
  });
4547
- subscriber = subscriber();
4548
- onRenderedRangeEffect = effect(() => {
4549
- const renderedRange = this.$renderedRange();
4550
- if (!renderedRange)
4551
- return;
4552
- untracked(() => {
4553
- this.dataStore.patchState({
4554
- virtualEnds: {
4555
- start: renderedRange.start,
4556
- end: renderedRange.end + 25,
4557
- }
4558
- });
4559
- this.setSize(this.viewport().elementRef);
4560
- });
4561
- });
4562
- onDataLengthEffect = effect(() => {
4563
- const dataLength = this.$dataLength();
4564
- untracked(() => {
4565
- this.scrollStrategy.setDataLength(dataLength);
4566
- });
4567
- });
4568
- onOffsetEffect = effect(() => {
4569
- const offset = this.$offset();
4570
- untracked(() => {
4571
- this.dataStore.patchState({ virtualScrollOffset: offset });
4572
- });
4573
- });
4574
- $offset = computed(() => {
4575
- const viewport = this.viewport();
4576
- const scrolledIndexChange = this.$scrolledIndexChange();
4577
- if (!scrolledIndexChange || !viewport)
4578
- return 0;
4579
- return viewport.getOffsetToRenderedContentStart() ?? 0;
4580
- });
4581
- ngOnDestroy() {
4582
- removeEventListener('resize', this.resizeHandler);
4583
- }
4584
- setSize(el) {
4585
- const virtualScrollOptions = this.$virtualScrollOptions();
4586
- if (virtualScrollOptions.dynamicHeight) {
4587
- this.calcDynamic(el);
4888
+ reset = () => {
4889
+ this.setStateFromTableStore();
4890
+ };
4891
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: SortMenuComponentStore, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
4892
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: SortMenuComponentStore });
4893
+ }
4894
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: SortMenuComponentStore, decorators: [{
4895
+ type: Injectable
4896
+ }], ctorParameters: () => [] });
4897
+
4898
+ class SortMenuComponent {
4899
+ SortDirection = SortDirection;
4900
+ tableState = inject(TableStore);
4901
+ store = inject(SortMenuComponentStore);
4902
+ $sorted = computed(() => [...this.store.$sorted()]);
4903
+ $notSorted = computed(() => [...this.store.$notSorted()]);
4904
+ $dirty = signal(false);
4905
+ reset() {
4906
+ this.$dirty.set(false);
4907
+ this.store.reset();
4908
+ }
4909
+ dropIntoSorted(event) {
4910
+ this.$dirty.set(true);
4911
+ const sorted = [...event.container.data];
4912
+ if (event.previousContainer === event.container) {
4913
+ moveItemInArray(sorted, event.previousIndex, event.currentIndex);
4914
+ this.store.setSorted(sorted);
4915
+ }
4916
+ else {
4917
+ const notSorted = [...event.previousContainer.data];
4918
+ transferArrayItem(notSorted, sorted, event.previousIndex, event.currentIndex);
4919
+ sorted[event.currentIndex] = { ...sorted[event.currentIndex], direction: SortDirection.asc };
4920
+ this.store.setSorted(sorted);
4921
+ this.store.setNotSorted(notSorted);
4922
+ }
4923
+ }
4924
+ dropIntoNotSorted(event) {
4925
+ if (event.previousContainer === event.container) {
4588
4926
  return;
4589
4927
  }
4590
- const rowHeight = this.computedRowHeight();
4591
- let amountOfVisibleItems = virtualScrollOptions?.amountOfVisibleItems || this.defaultOptions.amountOfVisibleItems;
4592
- amountOfVisibleItems = Math.min(amountOfVisibleItems, this.$dataLength());
4593
- let height = (rowHeight * amountOfVisibleItems);
4594
- const footerHeight = this.computedFooterHeight();
4595
- const headerHeight = this.computedHeaderHeight();
4596
- height += (footerHeight + headerHeight);
4597
- if (virtualScrollOptions?.maxViewPortHeight && virtualScrollOptions.maxViewPortHeight < height)
4598
- height = virtualScrollOptions.maxViewPortHeight;
4599
- this.setHeight(height, el);
4600
- }
4601
- calcDynamic$ = new Subject();
4602
- $calcDynamic = toSignal(this.calcDynamic$.pipe(debounceTime(300)));
4603
- #onCalcDynamicEffect = effect(() => {
4604
- const el = this.$calcDynamic();
4605
- if (!el)
4606
- return;
4607
- this.calcDynamic(el);
4608
- });
4609
- calcDynamic(el) {
4610
- const virtualScrollOptions = this.$virtualScrollOptions();
4611
- const t = this.tableContainer.elementRef.nativeElement.querySelector(`#${TableContainerComponent.headerId}`);
4612
- const rect = t?.getBoundingClientRect();
4613
- const viewportHeight = window.innerHeight;
4614
- const distanceFromBottom = viewportHeight - rect.bottom;
4615
- const rowHeight = this.computedRowHeight();
4616
- const footerHeight = this.computedFooterHeight();
4617
- const headerHeight = this.computedHeaderHeight();
4618
- let tableSize = distanceFromBottom;
4619
- if (virtualScrollOptions?.maxViewPortHeight && virtualScrollOptions.maxViewPortHeight < tableSize) {
4620
- tableSize = virtualScrollOptions.maxViewPortHeight;
4928
+ else {
4929
+ this.$dirty.set(true);
4930
+ const sorted = [...event.previousContainer.data];
4931
+ const notSorted = [...event.container.data];
4932
+ transferArrayItem(sorted, notSorted, event.previousIndex, event.currentIndex);
4933
+ notSorted[event.currentIndex] = { ...notSorted[event.currentIndex] };
4934
+ this.store.setNotSorted(notSorted);
4935
+ this.store.setSorted(sorted);
4621
4936
  }
4622
- const available = (distanceFromBottom - footerHeight) - headerHeight;
4623
- const amountOfRowsThatWillFit = Math.floor(available / rowHeight);
4624
- const minAmountOfRows = virtualScrollOptions?.amountOfVisibleItems || this.defaultOptions.amountOfVisibleItems;
4625
- const amountOfVisibleItems = Math.min(Math.max(amountOfRowsThatWillFit, minAmountOfRows), this.$dataLength());
4626
- let height = (rowHeight * amountOfVisibleItems);
4627
- height += (footerHeight + headerHeight) - 10;
4628
- this.setHeight(height, el);
4629
- }
4630
- setHeight(height, el) {
4631
- const vsViewport = el.nativeElement;
4632
- vsViewport.setAttribute('style', `height: ${height}px !important;`);
4633
- this.viewport()?.checkViewportSize();
4634
- const virtualScrollOffset = this.viewport()?.getOffsetToRenderedContentStart() ?? 0;
4635
- this.dataStore.patchState({ virtualScrollOffset });
4636
4937
  }
4637
- resizeHandler = () => {
4638
- if (this.viewport() && this.$virtualScrollOptions().dynamicHeight) {
4639
- this.setSize(this.viewport().elementRef);
4640
- }
4938
+ apply = () => {
4939
+ this.$dirty.set(false);
4940
+ this.tableState.setAllSort(this.store.$sorted());
4641
4941
  };
4642
- computedRowHeight() {
4643
- const virtualScrollOptions = this.state.$tableSettings().virtualSettings;
4644
- const rowHeight = virtualScrollOptions?.rowHeight || (typeof this.state.$tableSettings().rowHeight === 'number' && this.state.$tableSettings().rowHeight) || this.defaultOptions.rowHeight;
4645
- return rowHeight;
4646
- }
4647
- computedHeaderHeight() {
4648
- if (this.state.$tableSettings().hideHeader)
4649
- return 0;
4650
- const virtualScrollOptions = this.state.$tableSettings().virtualSettings;
4651
- const headerHeight = virtualScrollOptions?.headerHeight || (typeof this.state.$tableSettings().headerHeight === 'number' && this.state.$tableSettings().headerHeight) || this.defaultOptions.headerHeight;
4652
- return headerHeight;
4653
- }
4654
- computedFooterHeight() {
4655
- return parseFloat(this.genericTable()?.$footerHeight()?.replace('px', '') || '0');
4942
+ setDirection(sort) {
4943
+ this.$dirty.set(true);
4944
+ this.store.setDirection(sort);
4656
4945
  }
4657
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: VirtualScrollContainer, deps: [], target: i0.ɵɵFactoryTarget.Component });
4658
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "19.0.0", type: VirtualScrollContainer, isStandalone: true, selector: "tb-virtual-scroll-container", queries: [{ propertyName: "genericTable", first: true, predicate: GenericTableComponent, descendants: true, isSignal: true }], viewQueries: [{ propertyName: "viewport", first: true, predicate: CdkVirtualScrollViewport, descendants: true, isSignal: true }], ngImport: i0, template: `
4659
- <cdk-virtual-scroll-viewport>
4660
- <ng-content/>
4661
- </cdk-virtual-scroll-viewport>
4662
- `, isInline: true, dependencies: [{ kind: "ngmodule", type: ScrollingModule }, { kind: "component", type: i1$7.CdkVirtualScrollViewport, selector: "cdk-virtual-scroll-viewport", inputs: ["orientation", "appendOnly"], outputs: ["scrolledIndexChange"] }], viewProviders: [
4663
- {
4664
- provide: VIRTUAL_SCROLL_STRATEGY,
4665
- useFactory: (c) => c.scrollStrategy,
4666
- deps: [forwardRef(() => VirtualScrollContainer)],
4667
- },
4668
- ], changeDetection: i0.ChangeDetectionStrategy.OnPush });
4946
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: SortMenuComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
4947
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.0", type: SortMenuComponent, isStandalone: true, selector: "tb-sort-menu", providers: [SortMenuComponentStore], ngImport: i0, template: "@let dirty = $dirty();\r\n@let sorted = $sorted();\r\n@let notSorted = $notSorted();\r\n\r\n<!-- Menu Trigger -->\r\n<span matTooltip=\"Sort\">\r\n <button mat-icon-button [matMenuTriggerFor]=\"menu\">\r\n <mat-icon color=\"primary\">swap_vert</mat-icon>\r\n </button>\r\n</span>\r\n\r\n<!-- Menu -->\r\n<mat-menu #menu=\"matMenu\" class=\"my-mat-menu\" (closed)=\"reset()\">\r\n <div mat-menu-item class=\"menu-button\">\r\n <div class=\"close-button-wrapper\">\r\n <span matTooltip=\"Close\">\r\n <mat-icon>close</mat-icon>\r\n </span>\r\n @if(dirty){\r\n <span matTooltip=\"Undo\" stop-propagation (click)=\"reset()\">\r\n <mat-icon>undo</mat-icon>\r\n </span>\r\n }\r\n \r\n </div>\r\n </div>\r\n\r\n <!-- Apply Button -->\r\n <div class=\"apply-button-wrapper\">\r\n <button mat-button color=\"primary\" (click)=\"apply()\"\r\n stop-propagation [class.apply-border]=\"dirty\"\r\n [disabled]=\"!dirty\">\r\n Apply @if (dirty) { Unsaved Changes }\r\n </button>\r\n </div>\r\n\r\n <!-- Default Sorting Text -->\r\n @if (!sorted.length) {\r\n <div class=\"tip\" >\r\n Sorting List\r\n </div>\r\n }\r\n\r\n <!-- Sorted Menu List -->\r\n <div class=\"list\"\r\n cdkDropList\r\n #sortedGroup=\"cdkDropList\"\r\n [cdkDropListConnectedTo]=\"[notSortedGroup]\"\r\n [cdkDropListData]=\"sorted\"\r\n (cdkDropListDropped)=\"dropIntoSorted($event)\">\r\n\r\n <!-- Menu Item Wrapper -->\r\n @for (sort of sorted; track sort.active) {\r\n <!-- Menu Item Headers -->\r\n @if (sorted.length > 1) {\r\n <span class=\"description sort-header\">{{$index === 0 ? 'First By' : 'Then By'}}</span>\r\n }\r\n\r\n <!-- Menu Item -->\r\n <div mat-menu-item cdkDrag class=\"menu-item\">\r\n <div class=\"sort-item\">\r\n <span class=\"sorted-name\">\r\n {{sort.displayName || (sort.active | spaceCase)}}\r\n <span class=\"direction-text\">{{sort.direction}}</span>\r\n </span>\r\n\r\n <!-- Sort Direction Buttons -->\r\n <div class=\"up-down-buttons-wrapper\">\r\n <button class=\"up-down-button up-button\" stop-propagation\r\n (click)=\"setDirection({active:sort.active,direction:SortDirection.asc,displayName:sort.displayName})\">\r\n <mat-icon [class]=\"sort.direction !== SortDirection.asc ? 'light-arrow' : 'dark-arrow'\" class=\"up-down-icon\">\r\n arrow_upward\r\n </mat-icon>\r\n </button>\r\n\r\n <button class=\"up-down-button\" stop-propagation\r\n (click)=\"setDirection({active:sort.active,direction:SortDirection.desc,displayName:sort.displayName})\">\r\n <mat-icon [class]=\"sort.direction === SortDirection.asc ? 'light-arrow' : 'dark-arrow'\" class=\"up-down-icon\">\r\n arrow_downward\r\n </mat-icon>\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n }\r\n\r\n </div>\r\n\r\n <!-- Default Not Sorted Text -->\r\n @if(!notSorted.length){\r\n <div class=\"tip\" >\r\n Not Sorted List\r\n </div>\r\n }\r\n\r\n <!-- Not Sorted Menu List -->\r\n <div class=\"list\"\r\n cdkDropList\r\n #notSortedGroup=\"cdkDropList\"\r\n [cdkDropListConnectedTo]=\"[sortedGroup]\"\r\n [cdkDropListData]=\"notSorted\"\r\n (cdkDropListDropped)=\"dropIntoNotSorted($event)\">\r\n @for (sort of notSorted; track sort.active) {\r\n <div mat-menu-item class=\"menu-item\" cdkDrag>\r\n <span class=\"not-sorted-name\">{{sort.displayName || (sort.active | spaceCase)}}</span>\r\n </div>\r\n }\r\n </div>\r\n</mat-menu>\r\n", styles: [".cdk-drag-preview{box-sizing:border-box;border-radius:4px;box-shadow:0 5px 5px -3px #0003,0 8px 10px 1px #00000024,0 3px 14px 2px #0000001f}.cdk-drag-placeholder{opacity:0}.cdk-drag-animating{transition:transform .25s cubic-bezier(0,0,.2,1)}.list{padding:5px 2px;border-bottom:solid 1px #ccc;color:#000000de;background:#fff}.light-arrow{color:#93b1ea78}.dark-arrow{color:#224e9c}.up-down-button{background-color:#fff;border-radius:30%;border-color:#0ff;padding:1px 1px 0;border-width:.5px;cursor:pointer;height:27px}.mat-icon.up-down-icon{margin-right:0;font-size:20px;font-weight:lighter}.sort-item{display:flex;align-items:center;justify-content:space-between}.up-down-buttons-wrapper{margin-left:2rem}.up-button{margin-right:.3rem}.mat-mdc-menu-item.menu-item,.mat-mdc-menu-item.menu-button{min-height:initial;padding:0 3px;line-height:25px;height:30px}.mat-mdc-menu-item.menu-item{cursor:move}.sorted-name{color:#224e9c;font-size:17px;font-weight:700}.not-sorted-name{color:#93b1ea;font-size:17px;font-weight:700}.apply-border{border:#224e9c solid .5px}.apply-border:hover{background-color:#faebd7}.apply-button-wrapper{display:grid;justify-content:center}.sort-header{font-size:10px;font-style:italic}.tip{padding:0 3px;color:#d3d3d3}.direction-text{font-size:small;font-weight:400}.close-button-wrapper{display:flex;flex-direction:row-reverse}\n"], dependencies: [{ kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i4$1.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i3$1.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "component", type: i3$1.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatMenuModule }, { kind: "component", type: 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: "directive", type: StopPropagationDirective, selector: "[stop-propagation]" }, { kind: "ngmodule", type: DragDropModule }, { kind: "directive", type: i5.CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: i5.CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "pipe", type: SpaceCasePipe, name: "spaceCase" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
4669
4948
  }
4670
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: VirtualScrollContainer, decorators: [{
4949
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: SortMenuComponent, decorators: [{
4671
4950
  type: Component,
4672
- args: [{
4673
- selector: 'tb-virtual-scroll-container',
4674
- template: `
4675
- <cdk-virtual-scroll-viewport>
4676
- <ng-content/>
4677
- </cdk-virtual-scroll-viewport>
4678
- `,
4679
- changeDetection: ChangeDetectionStrategy.OnPush,
4680
- imports: [ScrollingModule],
4681
- viewProviders: [
4682
- {
4683
- provide: VIRTUAL_SCROLL_STRATEGY,
4684
- useFactory: (c) => c.scrollStrategy,
4685
- deps: [forwardRef(() => VirtualScrollContainer)],
4686
- },
4687
- ],
4688
- }]
4689
- }], ctorParameters: () => [] });
4951
+ args: [{ selector: 'tb-sort-menu', providers: [SortMenuComponentStore], changeDetection: ChangeDetectionStrategy.OnPush, imports: [
4952
+ MatTooltipModule, MatButtonModule, MatIconModule, MatMenuModule, StopPropagationDirective, DragDropModule,
4953
+ SpaceCasePipe
4954
+ ], template: "@let dirty = $dirty();\r\n@let sorted = $sorted();\r\n@let notSorted = $notSorted();\r\n\r\n<!-- Menu Trigger -->\r\n<span matTooltip=\"Sort\">\r\n <button mat-icon-button [matMenuTriggerFor]=\"menu\">\r\n <mat-icon color=\"primary\">swap_vert</mat-icon>\r\n </button>\r\n</span>\r\n\r\n<!-- Menu -->\r\n<mat-menu #menu=\"matMenu\" class=\"my-mat-menu\" (closed)=\"reset()\">\r\n <div mat-menu-item class=\"menu-button\">\r\n <div class=\"close-button-wrapper\">\r\n <span matTooltip=\"Close\">\r\n <mat-icon>close</mat-icon>\r\n </span>\r\n @if(dirty){\r\n <span matTooltip=\"Undo\" stop-propagation (click)=\"reset()\">\r\n <mat-icon>undo</mat-icon>\r\n </span>\r\n }\r\n \r\n </div>\r\n </div>\r\n\r\n <!-- Apply Button -->\r\n <div class=\"apply-button-wrapper\">\r\n <button mat-button color=\"primary\" (click)=\"apply()\"\r\n stop-propagation [class.apply-border]=\"dirty\"\r\n [disabled]=\"!dirty\">\r\n Apply @if (dirty) { Unsaved Changes }\r\n </button>\r\n </div>\r\n\r\n <!-- Default Sorting Text -->\r\n @if (!sorted.length) {\r\n <div class=\"tip\" >\r\n Sorting List\r\n </div>\r\n }\r\n\r\n <!-- Sorted Menu List -->\r\n <div class=\"list\"\r\n cdkDropList\r\n #sortedGroup=\"cdkDropList\"\r\n [cdkDropListConnectedTo]=\"[notSortedGroup]\"\r\n [cdkDropListData]=\"sorted\"\r\n (cdkDropListDropped)=\"dropIntoSorted($event)\">\r\n\r\n <!-- Menu Item Wrapper -->\r\n @for (sort of sorted; track sort.active) {\r\n <!-- Menu Item Headers -->\r\n @if (sorted.length > 1) {\r\n <span class=\"description sort-header\">{{$index === 0 ? 'First By' : 'Then By'}}</span>\r\n }\r\n\r\n <!-- Menu Item -->\r\n <div mat-menu-item cdkDrag class=\"menu-item\">\r\n <div class=\"sort-item\">\r\n <span class=\"sorted-name\">\r\n {{sort.displayName || (sort.active | spaceCase)}}\r\n <span class=\"direction-text\">{{sort.direction}}</span>\r\n </span>\r\n\r\n <!-- Sort Direction Buttons -->\r\n <div class=\"up-down-buttons-wrapper\">\r\n <button class=\"up-down-button up-button\" stop-propagation\r\n (click)=\"setDirection({active:sort.active,direction:SortDirection.asc,displayName:sort.displayName})\">\r\n <mat-icon [class]=\"sort.direction !== SortDirection.asc ? 'light-arrow' : 'dark-arrow'\" class=\"up-down-icon\">\r\n arrow_upward\r\n </mat-icon>\r\n </button>\r\n\r\n <button class=\"up-down-button\" stop-propagation\r\n (click)=\"setDirection({active:sort.active,direction:SortDirection.desc,displayName:sort.displayName})\">\r\n <mat-icon [class]=\"sort.direction === SortDirection.asc ? 'light-arrow' : 'dark-arrow'\" class=\"up-down-icon\">\r\n arrow_downward\r\n </mat-icon>\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n }\r\n\r\n </div>\r\n\r\n <!-- Default Not Sorted Text -->\r\n @if(!notSorted.length){\r\n <div class=\"tip\" >\r\n Not Sorted List\r\n </div>\r\n }\r\n\r\n <!-- Not Sorted Menu List -->\r\n <div class=\"list\"\r\n cdkDropList\r\n #notSortedGroup=\"cdkDropList\"\r\n [cdkDropListConnectedTo]=\"[sortedGroup]\"\r\n [cdkDropListData]=\"notSorted\"\r\n (cdkDropListDropped)=\"dropIntoNotSorted($event)\">\r\n @for (sort of notSorted; track sort.active) {\r\n <div mat-menu-item class=\"menu-item\" cdkDrag>\r\n <span class=\"not-sorted-name\">{{sort.displayName || (sort.active | spaceCase)}}</span>\r\n </div>\r\n }\r\n </div>\r\n</mat-menu>\r\n", styles: [".cdk-drag-preview{box-sizing:border-box;border-radius:4px;box-shadow:0 5px 5px -3px #0003,0 8px 10px 1px #00000024,0 3px 14px 2px #0000001f}.cdk-drag-placeholder{opacity:0}.cdk-drag-animating{transition:transform .25s cubic-bezier(0,0,.2,1)}.list{padding:5px 2px;border-bottom:solid 1px #ccc;color:#000000de;background:#fff}.light-arrow{color:#93b1ea78}.dark-arrow{color:#224e9c}.up-down-button{background-color:#fff;border-radius:30%;border-color:#0ff;padding:1px 1px 0;border-width:.5px;cursor:pointer;height:27px}.mat-icon.up-down-icon{margin-right:0;font-size:20px;font-weight:lighter}.sort-item{display:flex;align-items:center;justify-content:space-between}.up-down-buttons-wrapper{margin-left:2rem}.up-button{margin-right:.3rem}.mat-mdc-menu-item.menu-item,.mat-mdc-menu-item.menu-button{min-height:initial;padding:0 3px;line-height:25px;height:30px}.mat-mdc-menu-item.menu-item{cursor:move}.sorted-name{color:#224e9c;font-size:17px;font-weight:700}.not-sorted-name{color:#93b1ea;font-size:17px;font-weight:700}.apply-border{border:#224e9c solid .5px}.apply-border:hover{background-color:#faebd7}.apply-button-wrapper{display:grid;justify-content:center}.sort-header{font-size:10px;font-style:italic}.tip{padding:0 3px;color:#d3d3d3}.direction-text{font-size:small;font-weight:400}.close-button-wrapper{display:flex;flex-direction:row-reverse}\n"] }]
4955
+ }] });
4690
4956
 
4691
- class ProfilesMenuComponent {
4692
- stateService = inject(TableBuilderStateStore);
4693
- tableStore = inject(TableStore);
4694
- $tableId = input.required();
4695
- onSaveState = output();
4696
- trigger = viewChild('trigger');
4697
- allProfilesPanelOpened = signal(false);
4698
- newProfilePanelOpened = signal(false);
4699
- $currentProfile = computed(() => this.stateService.$selectLocalProfileCurrentKey(this.$tableId())());
4700
- $defaultProfile = computed(() => this.stateService.$selectLocalProfileDefaultKey(this.$tableId())());
4701
- $keys = computed(() => this.stateService.$selectLocalProfileKeys(this.$tableId())());
4702
- saveState(key) {
4703
- const tableState = this.tableStore.$savableState();
4704
- this.onSaveState.emit(null);
4705
- this.stateService.saveTableSettingsToLocalAndStorage(this.$tableId(), key, tableState);
4706
- }
4707
- addState(key, asDefault) {
4708
- const tableState = this.tableStore.$savableState();
4709
- this.stateService.addNewStateToLocalAndStorage(this.$tableId(), key, tableState, asDefault);
4710
- }
4711
- setDefault(key) {
4712
- this.stateService.setDefaultInLocalAndStorage(this.$tableId(), key);
4957
+ class ResetMenuComponent {
4958
+ menu = viewChild.required(MatMenu);
4959
+ tableContainer = inject(TableContainerComponent);
4960
+ state = this.tableContainer.state;
4961
+ onStateReset$ = output({ alias: 'onStateReset' });
4962
+ resetState() {
4963
+ this.tableContainer.$customFilterDirectives().forEach(cf => cf.reset());
4964
+ this.tableContainer.$filterDirectives().forEach(cf => cf.reset());
4965
+ this.state.resetState();
4966
+ this.onStateReset$.emit(null);
4713
4967
  }
4714
- unsetDefault() {
4715
- this.stateService.unsetDefaultFromLocalAndStorage(this.$tableId());
4968
+ $filtersSet = computed(() => {
4969
+ return Object.values(this.state.$filters())
4970
+ .filter(f => (isCustomFilter(f) && f.active) || f.filterValue != undefined)
4971
+ .length;
4972
+ });
4973
+ $sortSet = computed(() => {
4974
+ const sorts = this.state.$selectSorted();
4975
+ if (!sorts.length)
4976
+ return false;
4977
+ const preSorts = this.state.$preSort();
4978
+ if (!preSorts.length)
4979
+ return true;
4980
+ return !sortsAreSame(preSorts, sorts);
4981
+ });
4982
+ $groupBySet = computed(() => this.state.$groupByKeys().length);
4983
+ $hiddenSet = computed(() => this.state.$hiddenKeys().length);
4984
+ $orderSet = computed(() => Object.keys(this.state.$userDefinedOrder()).length);
4985
+ $widthsSet = computed(() => Object.keys(this.state.$getUserDefinedWidths()).length);
4986
+ $rowHeightSet = this.state.$userDefinedRowHeight;
4987
+ headerHeightSet = this.state.$userDefinedHeaderHeight;
4988
+ pageSizeSet = this.state.selectSignal(s => s.userDefined.pageSize);
4989
+ showAllSet = this.state.selectSignal(s => s.userDefined.showAll);
4990
+ $set = computed(() => {
4991
+ const arr = [];
4992
+ if (this.$filtersSet()) {
4993
+ arr.push('Filters');
4994
+ }
4995
+ if (this.$sortSet()) {
4996
+ arr.push('Sorting');
4997
+ }
4998
+ if (this.$groupBySet()) {
4999
+ arr.push('Group By');
5000
+ }
5001
+ if (this.$hiddenSet()) {
5002
+ arr.push('Hidden Columns');
5003
+ }
5004
+ if (this.$orderSet()) {
5005
+ arr.push('Column Order');
5006
+ }
5007
+ if (this.$widthsSet()) {
5008
+ arr.push('Column Widths');
5009
+ }
5010
+ if (this.$rowHeightSet()) {
5011
+ arr.push('Row Height');
5012
+ }
5013
+ if (this.headerHeightSet()) {
5014
+ arr.push('Header Height');
5015
+ }
5016
+ if (this.pageSizeSet()) {
5017
+ arr.push('Page Size');
5018
+ }
5019
+ if (this.showAllSet()) {
5020
+ arr.push('Show All');
5021
+ }
5022
+ return arr;
5023
+ });
5024
+ resetable = resetable;
5025
+ reset(s) {
5026
+ this.state.resetPart(s);
4716
5027
  }
4717
- defaultName = 'My Profile';
4718
- position$ = new Subject();
4719
- setPosition = (e) => {
4720
- const rect = e.getBoundingClientRect();
4721
- if (rect.top === 0)
4722
- return;
4723
- const a = {
4724
- right: `${(window.innerWidth - rect.right)}px`,
4725
- top: `${rect.top}px`,
4726
- };
4727
- return a;
4728
- };
4729
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: ProfilesMenuComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
4730
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.0", type: ProfilesMenuComponent, isStandalone: true, selector: "tb-profiles-menu", inputs: { $tableId: { classPropertyName: "$tableId", publicName: "$tableId", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { onSaveState: "onSaveState" }, viewQueries: [{ propertyName: "trigger", first: true, predicate: ["trigger"], descendants: true, isSignal: true }], ngImport: i0, template: "<button mat-icon-button [matMenuTriggerFor]=\"menu\" #trigger=\"matMenuTrigger\" [matTooltip]=\"'Profiles'\">\r\n <mat-icon color=\"primary\">people</mat-icon>\r\n</button>\r\n<mat-menu #menu=\"matMenu\" (closed)=\"addedKey.value = null; allProfilesPanelOpened.set(false); newProfilePanelOpened.set(false)\">\r\n @if(!!$currentProfile())\r\n {\r\n <div mat-menu-item [matTooltip]=\"'Save Profile'\" mat-stroked-button (click)=\"saveState($currentProfile()!)\">\r\n <mat-icon color=\"primary\">save</mat-icon>\r\n <span>{{$currentProfile()}}</span>\r\n </div>\r\n }\r\n @else\r\n {\r\n <div class=\"profile-line\">\r\n <button class=\"first-in-line first-button\" mat-stroked-button (click)=\"addState(defaultName, m.checked);\">\r\n <mat-icon class=\"save-for-default-icon button-save-icon\" color=\"primary\">save</mat-icon>\r\n <span>Save as <span class=\"current-name\">{{defaultName}}</span> </span>\r\n </button>\r\n <button [matTooltip]=\"'Toggle Profile Being Created As Default'\" stop-propagation mat-icon-button (click)=\"m.toggle()\" >\r\n <mat-icon style=\"color: green;\">{{m.checked ? 'star' : 'star_border'}}</mat-icon>\r\n </button>\r\n <mat-checkbox class=\"display-none\" [checked]=\"true\" #m />\r\n </div>\r\n }\r\n @if (allProfilesPanelOpened()) {<hr class=\"divider\"/>}\r\n <div [class]=\"{ hide: !$keys().length, 'all-profile-row': true }\" mat-menu-item stop-propagation (click)=\"allProfilesPanelOpened.set(!allProfilesPanelOpened())\">\r\n <div class=\"all-profiles\">\r\n <span>All Profiles</span>\r\n <span [class]=\"(allProfilesPanelOpened() ? 'all-profile-arrow-close' : 'all-profile-arrow-open') + ' all-profile-arrow'\" class=\"arrow\"></span>\r\n </div>\r\n </div>\r\n <div [class]=\"{ hide: !allProfilesPanelOpened(), panel: true }\">\r\n @for (key of $keys() ; track key) {\r\n <div class=\"profile-line\" [class]=\"key === $currentProfile() ? 'current-in-list' : 'not-current-in-list'\">\r\n <button [matTooltip]=\"'Select Profile'\" class=\"menu-item first-in-line\" mat-stroked-button (click)='stateService.setLocalCurrentState({ tableId: $tableId(), currentStateKey: key})'>\r\n <span>{{key}}</span>\r\n </button>\r\n @if(key !== $defaultProfile())\r\n {\r\n <button [matTooltip]=\"'Toggle Profile Being Default'\" stop-propagation mat-icon-button (click)=\"setDefault(key)\">\r\n <mat-icon style=\"color: green;\">star_border</mat-icon>\r\n </button>\r\n }\r\n @else\r\n {\r\n <button [matTooltip]=\"'Toggle Profile Being Default'\" stop-propagation mat-icon-button (click)=\"unsetDefault()\">\r\n <mat-icon style=\"color: green;\">star</mat-icon>\r\n </button>\r\n }\r\n <button [matTooltip]=\"'Delete Profile'\" class=\"last-in-line\" stop-propagation mat-icon-button (click)='stateService.deleteProfileFromLocalAndStorage($tableId(), key)'>\r\n <mat-icon color='warn'>delete_forever</mat-icon>\r\n </button>\r\n </div>\r\n }\r\n <hr class=\"divider\"/>\r\n </div>\r\n <div class=\"add-new-profile-row\" mat-menu-item stop-propagation (click)=\"newProfilePanelOpened.set(!newProfilePanelOpened()); addedKey.focus()\">Add New Profile</div>\r\n <div [class]=\"{ hide: !newProfilePanelOpened(), panel: true }\" >\r\n <div class=\"profile-line\" stop-propagation>\r\n <div class=\"new-name-input\">\r\n <i class=\"input-hint\">Enter New Name</i>\r\n <input matInput #addedKey=\"matInput\" [name]=\"'key'\" />\r\n </div>\r\n <button [matTooltip]=\"'Toggle Profile Being Created As Default'\" stop-propagation mat-icon-button (click)=\"m2.toggle()\" >\r\n <mat-icon style=\"color: green;\">{{m2.checked ? 'star' : 'star_border'}}</mat-icon>\r\n </button>\r\n <mat-checkbox class=\"display-none\" [ngModel]=\"!$defaultProfile()\" #m2 />\r\n </div>\r\n <button class=\"add-button\" color=\"primary\" [matTooltip]=\"'Create New Profile'\" mat-raised-button (click)=\"addState(addedKey.value, m2.checked); addedKey.value = null\" [disabled]=\"!addedKey.value\">\r\n Add\r\n </button>\r\n </div>\r\n</mat-menu>\r\n", styles: [":host ::ng-deep .mat-expansion-panel-header{padding:0}.current-name{color:#00f}.menu-item{display:inline-flex;width:initial;flex-grow:1}.profile-line{display:flex;justify-content:space-between;align-items:center}.first-in-line{--f-b: 2rem;margin-left:var(--mat-menu-item-with-icon-leading-spacing)}.first-in-line.first-button{height:var(--f-b);margin:.2rem}.first-in-line .button-save-icon{height:var(--f-b);width:var(--f-b);font-size:var(--f-b)}.main-save-button{height:4rem;width:4rem;padding:.5rem}.main-save-button mat-icon{height:3rem;width:3rem;font-size:3rem}.save-for-default-icon{margin:0}.display-none{display:none}.last-in-line{padding-right:var(--mat-menu-item-with-icon-trailing-spacing)}.default-cursor{cursor:default}.as-def{padding-left:var(--mat-menu-item-with-icon-leading-spacing)}.divider{margin:.2px 0}.add-key{max-width:8.5rem;margin-left:2px}.add-key ::ng-deep .mdc-text-field{padding:0}.panel{transition:height .1s}.hide{height:0;min-height:0;overflow:hidden}.open-panel-button{width:100%;height:2.5rem}.current-in-list{border-left:3px solid blue;background-color:#0000ff0d}.not-current-in-list{border-left:3px solid rgba(255,255,255,0)}.add-new-profile-row,.all-profile-row{border-top:rgba(128,128,128,.25) solid 1px}.all-profiles{display:flex;justify-content:space-between}.all-profiles:has(.all-profile-arrow-close){align-items:center}.all-profile-arrow{display:inline-block;height:.7rem;width:.7rem;border-color:#000;transform:rotate(-45deg)}.all-profile-arrow-open{border-left:solid 2px;border-bottom:solid 2px}.all-profile-arrow-close{border-right:solid 2px;border-top:solid 2px}.new-name-input{margin-left:3px;display:flex;flex-direction:column}.new-name-input .input-hint{font-size:smaller;font-weight:200;color:gray}.add-button{height:20px;line-height:20px;margin:3px 0 0 3px}\n"], dependencies: [{ kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "ngmodule", type: MatMenuModule }, { kind: "component", type: i4$2.MatMenu, selector: "mat-menu", inputs: ["backdropClass", "aria-label", "aria-labelledby", "aria-describedby", "xPosition", "yPosition", "overlapTrigger", "hasBackdrop", "class", "classList"], outputs: ["closed", "close"], exportAs: ["matMenu"] }, { kind: "component", type: i4$2.MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i4$2.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }, { kind: "component", type: MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "directive", type: MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "component", type: MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "aria-expanded", "aria-controls", "aria-owns", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "disabledInteractive", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { kind: "directive", type: StopPropagationDirective, selector: "[stop-propagation]" }, { kind: "ngmodule", type: MatInputModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }] });
5028
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: ResetMenuComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
5029
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.0", type: ResetMenuComponent, isStandalone: true, selector: "lib-reset-menu", outputs: { onStateReset$: "onStateReset" }, viewQueries: [{ propertyName: "menu", first: true, predicate: MatMenu, descendants: true, isSignal: true }], ngImport: i0, template: "<mat-menu #menu2=\"matMenu\">\r\n @if($set().length > 1)\r\n {\r\n <button mat-menu-item (click)=\"state.resetState()\">All</button>\r\n }\r\n @for (item of $set(); track $index)\r\n {\r\n <button mat-menu-item (click)=\"state.resetPart(item)\">Reset {{item}}</button>\r\n }\r\n</mat-menu>", styles: [":host{display:contents}\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: "ngmodule", type: MatButtonModule }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
4731
5030
  }
4732
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: ProfilesMenuComponent, decorators: [{
5031
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: ResetMenuComponent, decorators: [{
4733
5032
  type: Component,
4734
- args: [{ selector: 'tb-profiles-menu', imports: [MatIcon, MatTooltip, MatIconButton, MatMenuModule, MatButton, MatInput,
4735
- MatCheckbox, StopPropagationDirective, MatInputModule, FormsModule
4736
- ], template: "<button mat-icon-button [matMenuTriggerFor]=\"menu\" #trigger=\"matMenuTrigger\" [matTooltip]=\"'Profiles'\">\r\n <mat-icon color=\"primary\">people</mat-icon>\r\n</button>\r\n<mat-menu #menu=\"matMenu\" (closed)=\"addedKey.value = null; allProfilesPanelOpened.set(false); newProfilePanelOpened.set(false)\">\r\n @if(!!$currentProfile())\r\n {\r\n <div mat-menu-item [matTooltip]=\"'Save Profile'\" mat-stroked-button (click)=\"saveState($currentProfile()!)\">\r\n <mat-icon color=\"primary\">save</mat-icon>\r\n <span>{{$currentProfile()}}</span>\r\n </div>\r\n }\r\n @else\r\n {\r\n <div class=\"profile-line\">\r\n <button class=\"first-in-line first-button\" mat-stroked-button (click)=\"addState(defaultName, m.checked);\">\r\n <mat-icon class=\"save-for-default-icon button-save-icon\" color=\"primary\">save</mat-icon>\r\n <span>Save as <span class=\"current-name\">{{defaultName}}</span> </span>\r\n </button>\r\n <button [matTooltip]=\"'Toggle Profile Being Created As Default'\" stop-propagation mat-icon-button (click)=\"m.toggle()\" >\r\n <mat-icon style=\"color: green;\">{{m.checked ? 'star' : 'star_border'}}</mat-icon>\r\n </button>\r\n <mat-checkbox class=\"display-none\" [checked]=\"true\" #m />\r\n </div>\r\n }\r\n @if (allProfilesPanelOpened()) {<hr class=\"divider\"/>}\r\n <div [class]=\"{ hide: !$keys().length, 'all-profile-row': true }\" mat-menu-item stop-propagation (click)=\"allProfilesPanelOpened.set(!allProfilesPanelOpened())\">\r\n <div class=\"all-profiles\">\r\n <span>All Profiles</span>\r\n <span [class]=\"(allProfilesPanelOpened() ? 'all-profile-arrow-close' : 'all-profile-arrow-open') + ' all-profile-arrow'\" class=\"arrow\"></span>\r\n </div>\r\n </div>\r\n <div [class]=\"{ hide: !allProfilesPanelOpened(), panel: true }\">\r\n @for (key of $keys() ; track key) {\r\n <div class=\"profile-line\" [class]=\"key === $currentProfile() ? 'current-in-list' : 'not-current-in-list'\">\r\n <button [matTooltip]=\"'Select Profile'\" class=\"menu-item first-in-line\" mat-stroked-button (click)='stateService.setLocalCurrentState({ tableId: $tableId(), currentStateKey: key})'>\r\n <span>{{key}}</span>\r\n </button>\r\n @if(key !== $defaultProfile())\r\n {\r\n <button [matTooltip]=\"'Toggle Profile Being Default'\" stop-propagation mat-icon-button (click)=\"setDefault(key)\">\r\n <mat-icon style=\"color: green;\">star_border</mat-icon>\r\n </button>\r\n }\r\n @else\r\n {\r\n <button [matTooltip]=\"'Toggle Profile Being Default'\" stop-propagation mat-icon-button (click)=\"unsetDefault()\">\r\n <mat-icon style=\"color: green;\">star</mat-icon>\r\n </button>\r\n }\r\n <button [matTooltip]=\"'Delete Profile'\" class=\"last-in-line\" stop-propagation mat-icon-button (click)='stateService.deleteProfileFromLocalAndStorage($tableId(), key)'>\r\n <mat-icon color='warn'>delete_forever</mat-icon>\r\n </button>\r\n </div>\r\n }\r\n <hr class=\"divider\"/>\r\n </div>\r\n <div class=\"add-new-profile-row\" mat-menu-item stop-propagation (click)=\"newProfilePanelOpened.set(!newProfilePanelOpened()); addedKey.focus()\">Add New Profile</div>\r\n <div [class]=\"{ hide: !newProfilePanelOpened(), panel: true }\" >\r\n <div class=\"profile-line\" stop-propagation>\r\n <div class=\"new-name-input\">\r\n <i class=\"input-hint\">Enter New Name</i>\r\n <input matInput #addedKey=\"matInput\" [name]=\"'key'\" />\r\n </div>\r\n <button [matTooltip]=\"'Toggle Profile Being Created As Default'\" stop-propagation mat-icon-button (click)=\"m2.toggle()\" >\r\n <mat-icon style=\"color: green;\">{{m2.checked ? 'star' : 'star_border'}}</mat-icon>\r\n </button>\r\n <mat-checkbox class=\"display-none\" [ngModel]=\"!$defaultProfile()\" #m2 />\r\n </div>\r\n <button class=\"add-button\" color=\"primary\" [matTooltip]=\"'Create New Profile'\" mat-raised-button (click)=\"addState(addedKey.value, m2.checked); addedKey.value = null\" [disabled]=\"!addedKey.value\">\r\n Add\r\n </button>\r\n </div>\r\n</mat-menu>\r\n", styles: [":host ::ng-deep .mat-expansion-panel-header{padding:0}.current-name{color:#00f}.menu-item{display:inline-flex;width:initial;flex-grow:1}.profile-line{display:flex;justify-content:space-between;align-items:center}.first-in-line{--f-b: 2rem;margin-left:var(--mat-menu-item-with-icon-leading-spacing)}.first-in-line.first-button{height:var(--f-b);margin:.2rem}.first-in-line .button-save-icon{height:var(--f-b);width:var(--f-b);font-size:var(--f-b)}.main-save-button{height:4rem;width:4rem;padding:.5rem}.main-save-button mat-icon{height:3rem;width:3rem;font-size:3rem}.save-for-default-icon{margin:0}.display-none{display:none}.last-in-line{padding-right:var(--mat-menu-item-with-icon-trailing-spacing)}.default-cursor{cursor:default}.as-def{padding-left:var(--mat-menu-item-with-icon-leading-spacing)}.divider{margin:.2px 0}.add-key{max-width:8.5rem;margin-left:2px}.add-key ::ng-deep .mdc-text-field{padding:0}.panel{transition:height .1s}.hide{height:0;min-height:0;overflow:hidden}.open-panel-button{width:100%;height:2.5rem}.current-in-list{border-left:3px solid blue;background-color:#0000ff0d}.not-current-in-list{border-left:3px solid rgba(255,255,255,0)}.add-new-profile-row,.all-profile-row{border-top:rgba(128,128,128,.25) solid 1px}.all-profiles{display:flex;justify-content:space-between}.all-profiles:has(.all-profile-arrow-close){align-items:center}.all-profile-arrow{display:inline-block;height:.7rem;width:.7rem;border-color:#000;transform:rotate(-45deg)}.all-profile-arrow-open{border-left:solid 2px;border-bottom:solid 2px}.all-profile-arrow-close{border-right:solid 2px;border-top:solid 2px}.new-name-input{margin-left:3px;display:flex;flex-direction:column}.new-name-input .input-hint{font-size:smaller;font-weight:200;color:gray}.add-button{height:20px;line-height:20px;margin:3px 0 0 3px}\n"] }]
5033
+ args: [{ selector: 'lib-reset-menu', imports: [MatMenuModule, MatButtonModule], changeDetection: ChangeDetectionStrategy.OnPush, template: "<mat-menu #menu2=\"matMenu\">\r\n @if($set().length > 1)\r\n {\r\n <button mat-menu-item (click)=\"state.resetState()\">All</button>\r\n }\r\n @for (item of $set(); track $index)\r\n {\r\n <button mat-menu-item (click)=\"state.resetPart(item)\">Reset {{item}}</button>\r\n }\r\n</mat-menu>", styles: [":host{display:contents}\n"] }]
4737
5034
  }] });
4738
5035
 
4739
- const containerImports = [
4740
- NgTemplateOutlet,
4741
- PaginatorComponent,
4742
- MultiSortDirective, GroupByListComponent, FilterChipsComponent, GenFilterDisplayerComponent, GenColDisplayerComponent,
4743
- SortMenuComponent, GenericTableComponent, StopPropagationDirective, ProfilesMenuComponent,
4744
- MatButtonModule, MatMenuModule, MatIconModule, MatTooltipModule, VirtualScrollContainer
4745
- ];
5036
+ class TableHeaderMenuComponent {
5037
+ menu = viewChild.required(MatMenu);
5038
+ exportToCsvService = inject(ExportToCsvService);
5039
+ tableContainer = inject(TableContainerComponent);
5040
+ state = this.tableContainer.state;
5041
+ $rowHeightNum = computed(() => +(this.tableContainer.$genericTable()?.$rowHeight()?.replace('px', '') || 0));
5042
+ $headerHeightNum = computed(() => +(this.tableContainer.$genericTable()?.$headerHeight()?.replace('px', '') || 0));
5043
+ exportToCsv() {
5044
+ this.exportToCsvService.exportToCsv(this.tableContainer.$data());
5045
+ }
5046
+ updateHeight(v, element) {
5047
+ if (+element.value < 10)
5048
+ element.value = '10';
5049
+ if (+element.value > 100)
5050
+ element.value = '100';
5051
+ if (v === 'row')
5052
+ this.state.setUserDefinedRowHeight(+element.value);
5053
+ if (v === 'header')
5054
+ this.state.setUserDefinedHeaderHeight(+element.value);
5055
+ }
5056
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: TableHeaderMenuComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
5057
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.0", type: TableHeaderMenuComponent, isStandalone: true, selector: "lib-table-header-menu", viewQueries: [{ propertyName: "menu", first: true, predicate: MatMenu, descendants: true, isSignal: true }], ngImport: i0, template: "<mat-menu #mainMenu='matMenu' [xPosition]=\"'before'\">\r\n <span [matTooltip]=\"!r.$set().length ? 'Nothing To Reset' : ''\">\r\n <button mat-menu-item [matMenuTriggerFor]=\"r.menu()\" #d=\"matMenuItem\" [disabled]=\"!r.$set().length\">\r\n <mat-icon color=\"primary\">autorenew</mat-icon>\r\n <span>Reset</span>\r\n </button>\r\n </span>\r\n @if (!tableContainer.state.$tableSettings().hideExport) {\r\n <button mat-menu-item (click)=\"exportToCsv()\">\r\n <mat-icon color=\"primary\">file_download</mat-icon>\r\n <span>Export Table</span>\r\n </button>\r\n }\r\n @if (tableContainer.$tableId(); as tableId) {\r\n <button stop-propagation mat-menu-item [matMenuTriggerFor]=\"pm.menu()\">\r\n <mat-icon color=\"primary\">people</mat-icon>\r\n <span>Profiles</span>\r\n </button>\r\n <tb-profiles-menu class=\"profiles-menu\" #pm [tableId]=\"tableId\" [isMatMenuChild]=\"true\" />\r\n }\r\n\r\n\r\n <div mat-menu-item>\r\n <div class=\"height-input-wrapper\">\r\n <span>Row Height</span>\r\n <input #i class=\"input\" stop-propagation type=\"number\" [value]=\"$rowHeightNum()\" (change)=\"updateHeight('row', i)\" [min]=\"10\" [max]=\"100\" />\r\n </div>\r\n </div>\r\n @if(!state.$tableSettings().hideHeader)\r\n {\r\n <div mat-menu-item>\r\n <div class=\"height-input-wrapper\">\r\n <span>Header Height</span>\r\n <input #i2 class=\"input\" stop-propagation type=\"number\" [value]=\"$headerHeightNum()\" (change)=\"updateHeight('header', i2)\" [min]=\"10\" [max]=\"100\"/>\r\n </div>\r\n </div>\r\n }\r\n</mat-menu>\r\n<lib-reset-menu #r/>\r\n\r\n", styles: [".input{appearance:none;border:none;outline:none;background:none;box-shadow:none;margin:0;font:inherit;color:inherit;border:1px solid black;border-radius:4px;width:50px;padding:0 0 0 4px}.height-input-wrapper{display:flex;gap:4px}\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: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: ProfilesMenuComponent, selector: "tb-profiles-menu", inputs: ["tableId", "isMatMenuChild"] }, { kind: "component", type: ResetMenuComponent, selector: "lib-reset-menu", outputs: ["onStateReset"] }, { kind: "directive", type: MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "directive", type: StopPropagationDirective, selector: "[stop-propagation]" }] });
5058
+ }
5059
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: TableHeaderMenuComponent, decorators: [{
5060
+ type: Component,
5061
+ args: [{ selector: 'lib-table-header-menu', imports: [MatMenuModule, MatIcon, ProfilesMenuComponent, ResetMenuComponent, MatTooltip, StopPropagationDirective], template: "<mat-menu #mainMenu='matMenu' [xPosition]=\"'before'\">\r\n <span [matTooltip]=\"!r.$set().length ? 'Nothing To Reset' : ''\">\r\n <button mat-menu-item [matMenuTriggerFor]=\"r.menu()\" #d=\"matMenuItem\" [disabled]=\"!r.$set().length\">\r\n <mat-icon color=\"primary\">autorenew</mat-icon>\r\n <span>Reset</span>\r\n </button>\r\n </span>\r\n @if (!tableContainer.state.$tableSettings().hideExport) {\r\n <button mat-menu-item (click)=\"exportToCsv()\">\r\n <mat-icon color=\"primary\">file_download</mat-icon>\r\n <span>Export Table</span>\r\n </button>\r\n }\r\n @if (tableContainer.$tableId(); as tableId) {\r\n <button stop-propagation mat-menu-item [matMenuTriggerFor]=\"pm.menu()\">\r\n <mat-icon color=\"primary\">people</mat-icon>\r\n <span>Profiles</span>\r\n </button>\r\n <tb-profiles-menu class=\"profiles-menu\" #pm [tableId]=\"tableId\" [isMatMenuChild]=\"true\" />\r\n }\r\n\r\n\r\n <div mat-menu-item>\r\n <div class=\"height-input-wrapper\">\r\n <span>Row Height</span>\r\n <input #i class=\"input\" stop-propagation type=\"number\" [value]=\"$rowHeightNum()\" (change)=\"updateHeight('row', i)\" [min]=\"10\" [max]=\"100\" />\r\n </div>\r\n </div>\r\n @if(!state.$tableSettings().hideHeader)\r\n {\r\n <div mat-menu-item>\r\n <div class=\"height-input-wrapper\">\r\n <span>Header Height</span>\r\n <input #i2 class=\"input\" stop-propagation type=\"number\" [value]=\"$headerHeightNum()\" (change)=\"updateHeight('header', i2)\" [min]=\"10\" [max]=\"100\"/>\r\n </div>\r\n </div>\r\n }\r\n</mat-menu>\r\n<lib-reset-menu #r/>\r\n\r\n", styles: [".input{appearance:none;border:none;outline:none;background:none;box-shadow:none;margin:0;font:inherit;color:inherit;border:1px solid black;border-radius:4px;width:50px;padding:0 0 0 4px}.height-input-wrapper{display:flex;gap:4px}\n"] }]
5062
+ }] });
4746
5063
 
4747
- //The idea of this is that if filters were only added, and none were removed or changed, then we only need to tag more rows to not be shown. We don't need to remove any 'dont show' tags.
4748
- // So if filters were only added this method will return the added filters, if filters were removed or changed this method will return undefined.
4749
- const updateFilterInfoState = (previousState, filterInfos) => {
4750
- filterInfos = filterNonActiveOrNotReadyFilters(filterInfos);
4751
- const currentState = {
4752
- allFilters: filterInfos,
4753
- onlyAddedFilters: filterInfoOnlyAdded(previousState.allFilters, filterInfos)
4754
- };
4755
- return currentState;
4756
- };
4757
- const mapFilterInfoStateToPredicateState = (s) => {
4758
- const mappedAddOnly = s.onlyAddedFilters
4759
- ?
4760
- Object.entries(s.onlyAddedFilters).filter(([, v]) => needsFilterCreation(v)).reduce((obj, [key, value]) => {
4761
- obj[key] = createFilterFunc(value);
4762
- return obj;
4763
- }, {})
4764
- : {};
4765
- const mappedAll = Object.entries(s.allFilters).filter(([, v]) => needsFilterCreation(v))
4766
- .filter(([, v]) => !isCustomFilter(v) || !!v.predicate)
4767
- .map(([key, value]) => {
4768
- return mappedAddOnly[key] || createFilterFunc(value);
4769
- });
4770
- return ({
4771
- allFilters: mappedAll,
4772
- onlyAddedFilters: s.onlyAddedFilters ? Object.values(mappedAddOnly) : undefined
4773
- });
4774
- };
4775
- const updateFilterPredicateState = (previousState, filters) => {
4776
- const currentState = {
4777
- allFilters: filters,
4778
- onlyAddedFilters: predicatesOnlyAdded(previousState.allFilters, filters)
4779
- };
4780
- return currentState;
4781
- };
4782
- const updateFilterState = (filterInfos, predicates) => {
4783
- const infos = mapFilterInfoStateToPredicateState(filterInfos.value);
4784
- const filtersState = {
4785
- allFilters: [...infos.allFilters, ...predicates.value.allFilters]
4786
- };
4787
- if (filterInfos.timestamp > predicates.timestamp && !!filterInfos.value.onlyAddedFilters) {
4788
- filtersState.onlyAddedFilters = infos.onlyAddedFilters;
4789
- }
4790
- else {
4791
- filtersState.onlyAddedFilters = predicates.value.onlyAddedFilters;
5064
+ class TableVirtualScrollStrategy {
5065
+ scrollContainer;
5066
+ scrolledIndexChange;
5067
+ dataLength = 0;
5068
+ indexChange = new Subject();
5069
+ viewport;
5070
+ $rowHeight;
5071
+ $headerHeight;
5072
+ constructor(scrollContainer) {
5073
+ this.scrollContainer = scrollContainer;
5074
+ this.scrolledIndexChange = this.indexChange.pipe(distinctUntilChanged());
5075
+ this.$rowHeight = scrollContainer.computedRowHeight;
5076
+ const a = scrollContainer.computedRowHeight;
5077
+ this.$headerHeight = scrollContainer.computedHeaderHeight;
4792
5078
  }
4793
- return filtersState;
4794
- };
4795
- const filterNonActiveOrNotReadyFilters = (filtersDict) => Object.entries(filtersDict).reduce((obj, [key, value]) => {
4796
- if (value.active !== false && (!isCustomFilter(value) || !!value.predicate)) {
4797
- obj[key] = value;
5079
+ attach(viewport) {
5080
+ this.viewport = viewport;
5081
+ this.onDataLengthChanged();
4798
5082
  }
4799
- ;
4800
- return obj;
4801
- }, {});
4802
- function filterInfoOnlyAdded(previousFilterInfos, currentFilterInfos) {
4803
- const previousKeys = Object.keys(previousFilterInfos);
4804
- const currentKeys = Object.keys(currentFilterInfos);
4805
- const keysInBoth = intersection(previousKeys, currentKeys);
4806
- const someRemoved = previousKeys.length > keysInBoth.length;
4807
- if (someRemoved || !previousKeys.length) {
4808
- return undefined;
4809
- }
4810
- if (filtersInfosUpdated(previousFilterInfos, currentFilterInfos)) {
4811
- return undefined;
4812
- }
4813
- const addedFilters = difference(currentKeys, keysInBoth).reduce((dict, key) => {
4814
- dict[key] = currentFilterInfos[key];
4815
- return dict;
4816
- }, {});
4817
- return addedFilters;
4818
- }
4819
- function predicatesOnlyAdded(previousPredicates, currentPredicates) {
4820
- if (!previousPredicates.length) {
4821
- return undefined;
4822
- }
4823
- const predicateFiltersRemoved = difference(previousPredicates, currentPredicates).length;
4824
- if (predicateFiltersRemoved) {
4825
- return undefined;
4826
- }
4827
- return difference(currentPredicates, previousPredicates);
4828
- }
4829
- function filtersInfosUpdated(previousFilterInfos, currentFilterInfos) {
4830
- return !Object.entries(previousFilterInfos).every(([key, val]) => {
4831
- return currentFilterInfos[key].filterType === val.filterType && currentFilterInfos[key].filterValue === val.filterValue;
4832
- });
4833
- }
4834
- function patchDirectiveFromState(directive, stateFilter) {
4835
- if (isFilterInfo(stateFilter)) {
4836
- const filterDirective = directive;
4837
- filterDirective.setFilterValue(stateFilter.filterValue);
4838
- filterDirective.update();
4839
- }
4840
- if (isCustomFilter(stateFilter)) {
4841
- directive.active = stateFilter.active ?? false;
4842
- }
4843
- }
4844
-
4845
- function getGroupedData(data, groupByKeys) {
4846
- return tbGroupBy(data, groupByKeys);
4847
- }
4848
- const tbGroupBy = (data, groupByKeys, parentGroupName) => {
4849
- const currentKey = groupByKeys[0];
4850
- const res = groupBy(data, currentKey);
4851
- const remainingGroupByKeys = groupByKeys.slice(1);
4852
- const finalGroups = !remainingGroupByKeys.length;
4853
- if (remainingGroupByKeys.length) {
4854
- Object.keys(res).forEach(key => res[key] = tbGroupBy(res[key], remainingGroupByKeys, key));
4855
- }
4856
- return Object.keys(res).map((groupName, i) => {
4857
- const uniqName = parentGroupName ? `${parentGroupName}-${groupName}` : `${groupName}`;
4858
- const groupHeaders = res[groupName]?.filter(row => row.isGroupHeader) ?? [];
4859
- return {
4860
- isGroupHeader: true,
4861
- groupHeaderDisplay: groupName,
4862
- hasTheData: finalGroups,
4863
- children: finalGroups ? res[groupName] : res[groupName].map(d => { d.padding += 20; return d; }),
4864
- groupName: `tb_group_${uniqName}`,
4865
- padding: 1,
4866
- key: currentKey,
4867
- length: groupHeaders.reduce((acc, curr) => curr.length + acc, 0) + ((res[groupName] ?? []).length - groupHeaders.length),
4868
- [initIndexSymbol]: uniqName,
4869
- };
5083
+ contentScrolled$ = new Subject();
5084
+ sub = subscriber(this.contentScrolled$.pipe(observeOn(animationFrameScheduler)), () => {
5085
+ this.updateContent();
4870
5086
  });
4871
- };
4872
- function updateGroupByState({ groupedData }, [data, groups, expandedGroups], index) {
4873
- if (index === 0
4874
- || dataUpdated(data, groups, expandedGroups)
4875
- || groupsUpdated(groups, expandedGroups)) {
4876
- groupedData = groups.value.length ? getGroupedData(data.value, groups.value) : data.value;
4877
- }
4878
- const newDisplayData = expandedGroups.value.length === 0
4879
- ? groupedData
4880
- : groupedData.map(group => mapGroupHeader(group, expandedGroups.value)).flat();
4881
- return ({ displayData: newDisplayData, groupedData });
4882
- }
4883
- function mapGroupHeader(obj, data) {
4884
- const showChildren = data.find(a => a.expandedHeaders.includes(obj.groupName));
4885
- const children = !showChildren ? [] :
4886
- obj.hasTheData ? obj.children
4887
- : obj.children.map(a => mapGroupHeader(a, data));
4888
- return [obj, ...children].flat();
4889
- }
4890
- function dataUpdated(data, groups, expandedGroups) {
4891
- return data.timestamp > groups.timestamp && data.timestamp > expandedGroups.timestamp;
4892
- }
4893
- function groupsUpdated(groups, expandedGroups) {
4894
- return groups.timestamp > expandedGroups.timestamp;
4895
- }
4896
- ;
4897
- const initialGroupByState = { displayData: [], groupedData: [] };
4898
- const getAllGroupHeaderNames = (data) => {
4899
- const groups = getGroupHeaders(data, (d) => d.isGroupHeader);
4900
- return groupBy(groups, 'key');
4901
- };
4902
- const getAllGroupHeaderNamesByKeys = (data, keys) => {
4903
- const groups = getGroupHeaders(data, (d) => d.isGroupHeader && keys.includes(d.key));
4904
- return groupBy(groups, 'key');
4905
- };
4906
- const getGroupHeaders = (data, filterFunc, arr = []) => {
4907
- const headers = data.filter(filterFunc);
4908
- arr.push(...headers);
4909
- headers.forEach(h => { if (!!h.children.length)
4910
- getGroupHeaders(h.children, filterFunc, arr); });
4911
- return arr;
4912
- };
4913
-
4914
- function sortData(data, sorted) {
4915
- const ordered = orderBy(data, sorted.map(r => r.active), sorted.map(r => r.direction));
4916
- return ordered;
4917
- }
4918
- function filterData(data, filters, resetAll = false) {
4919
- for (let index = 0; index < data.length; index++) {
4920
- const element = data[index];
4921
- const hide = !filters.every(filter => filter(element));
4922
- if (hide || resetAll) {
4923
- element[tbNoShowSymbol] = hide;
4924
- }
4925
- }
4926
- return data;
4927
- }
4928
- const tbNoShowSymbol = Symbol('tb_no_show');
4929
-
4930
- const sortAndFilterData = (data, sortState, filterState) => combineLatest([
4931
- data.pipe(timestamp()),
4932
- sortState.pipe(timestamp()),
4933
- filterState.pipe(timestamp())
4934
- ]).pipe(scan(({ mappedData: resultData }, [data, sort, f], index) => {
4935
- if (index === 0 || (data.timestamp > sort.timestamp && data.timestamp > f.timestamp)) {
4936
- return ({ mappedData: filterData(sortData(data.value, sort.value.sortsToRun), f.value.allFilters) });
4937
- }
4938
- if (sort.timestamp > f.timestamp) {
4939
- return ({ mappedData: sortData(resultData, sort.value.sortsToRun) });
5087
+ onContentScrolled() {
5088
+ this.contentScrolled$.next();
4940
5089
  }
4941
- return ({ mappedData: filterData(resultData, f.value.onlyAddedFilters || f.value.allFilters, !f.value.onlyAddedFilters) });
4942
- }, { mappedData: [] })).pipe(map$1(({ mappedData: resultData }) => resultData.filter(item => !item[tbNoShowSymbol])), defaultShareReplay());
4943
- const createDataCleaners = (metadatas, mutate = false) => {
4944
- const transforms = createCleaners(metadatas);
4945
- return (data) => {
4946
- if (!mutate) {
4947
- data = { ...data };
4948
- }
4949
- for (const transform of transforms) {
4950
- transform(data);
5090
+ onDataLengthChanged() {
5091
+ if (this.viewport && this.$rowHeight) {
5092
+ this.viewport.setTotalContentSize(this.dataLength * this.$rowHeight());
5093
+ this.updateContent();
4951
5094
  }
4952
- return data;
4953
- };
4954
- };
4955
- const createCleaners = (metadatas) => {
4956
- return metadatas.reduce((transforms, metaData) => {
4957
- const notNestedKey = metaData.key;
4958
- switch (metaData.fieldType) {
4959
- case FieldType.Currency:
4960
- case FieldType.Number: {
4961
- const nested = metaData.key.includes('.');
4962
- if (nested) {
4963
- transforms.push((t) => {
4964
- const val = get(t, metaData.key);
4965
- const num = Number(val);
4966
- set(t, metaData.key, isNaN(num) || val == null ? null : num);
4967
- });
4968
- }
4969
- else {
4970
- transforms.push((t) => {
4971
- const val = t[notNestedKey];
4972
- const num = Number(val);
4973
- t[notNestedKey] = (isNaN(num) || val == null ? null : num);
4974
- });
4975
- }
4976
- break;
4977
- }
4978
- case FieldType.Date: {
4979
- const nested = metaData.key.includes('.');
4980
- if (nested) {
4981
- transforms.push((t) => {
4982
- const val = get(t, metaData.key);
4983
- const date = Date.parse(val);
4984
- if (isNaN(date)) {
4985
- set(t, metaData.key, null);
4986
- return;
4987
- }
4988
- const d = new Date(date);
4989
- d.setHours(0, 0, 0, 0);
4990
- set(t, metaData.key, d);
4991
- });
4992
- }
4993
- else {
4994
- transforms.push((t) => {
4995
- const val = t[notNestedKey];
4996
- const date = Date.parse(val);
4997
- if (isNaN(date)) {
4998
- t[notNestedKey] = null;
4999
- return;
5000
- }
5001
- const d = new Date(date);
5002
- d.setHours(0, 0, 0, 0);
5003
- t[notNestedKey] = d;
5004
- });
5005
- }
5006
- break;
5007
- }
5008
- case FieldType.DateTime: {
5009
- const nested = metaData.key.includes('.');
5010
- if (nested) {
5011
- transforms.push((t) => {
5012
- const val = get(t, metaData.key);
5013
- const dateTime = Date.parse(val);
5014
- if (isNaN(dateTime)) {
5015
- set(t, metaData.key, null);
5016
- return;
5017
- }
5018
- const dt = new Date(dateTime);
5019
- if (metaData.additional?.dateTimeOptions?.includeMilliseconds) {
5020
- set(t, metaData.key, dt);
5021
- return;
5022
- }
5023
- if (metaData.additional?.dateTimeOptions?.includeSeconds) {
5024
- dt.setMilliseconds(0);
5025
- set(t, metaData.key, dt);
5026
- return;
5027
- }
5028
- dt.setSeconds(0, 0);
5029
- set(t, metaData.key, dt);
5030
- });
5031
- }
5032
- else {
5033
- transforms.push((t) => {
5034
- const val = t[notNestedKey];
5035
- const dateTime = Date.parse(val);
5036
- if (isNaN(dateTime)) {
5037
- t[notNestedKey] = null;
5038
- return;
5039
- }
5040
- const dt = new Date(dateTime);
5041
- if (metaData.additional?.dateTimeOptions?.includeMilliseconds) {
5042
- t[notNestedKey] = dt;
5043
- return;
5044
- }
5045
- if (metaData.additional?.dateTimeOptions?.includeSeconds) {
5046
- dt.setMilliseconds(0);
5047
- t[notNestedKey] = dt;
5048
- return;
5049
- }
5050
- dt.setSeconds(0, 0);
5051
- t[notNestedKey] = dt;
5052
- });
5053
- }
5054
- }
5095
+ }
5096
+ setDataLength(length) {
5097
+ this.dataLength = length;
5098
+ this.onDataLengthChanged();
5099
+ }
5100
+ detach() { }
5101
+ onContentRendered() { }
5102
+ onRenderedOffsetChanged() {
5103
+ }
5104
+ scrollToIndex(index, behavior) {
5105
+ }
5106
+ #onHeaderChange = effect(() => {
5107
+ this.$headerHeight && this.$headerHeight();
5108
+ this.updateContent();
5109
+ });
5110
+ #onRowChange = effect(() => {
5111
+ this.$rowHeight && this.$rowHeight();
5112
+ this.updateContent();
5113
+ });
5114
+ updateContent() {
5115
+ if (!this.viewport || !this.$rowHeight) {
5116
+ return;
5055
5117
  }
5056
- return transforms;
5057
- }, []);
5058
- };
5118
+ const amountOfRows = Math.ceil((this.viewport.getViewportSize() - this.$headerHeight()) / this.$rowHeight());
5119
+ const offset = this.viewport.measureScrollOffset();
5120
+ const buffer = 35;
5121
+ const skip = Math.round(offset / this.$rowHeight());
5122
+ // always start at an even index so we don't change the color patterns for odd and even rows.
5123
+ const index = skip % 2 === 0 ? skip : skip - 1;
5124
+ const start = Math.max(0, index - buffer);
5125
+ const end = Math.min(this.dataLength, index + amountOfRows + buffer);
5126
+ this.viewport.setRenderedContentOffset(this.$rowHeight() * start);
5127
+ this.viewport.setRenderedRange({ start, end });
5128
+ this.indexChange.next(index);
5129
+ }
5130
+ }
5059
5131
 
5060
- class TableBuilderDataSource extends MatTableDataSource {
5061
- subscription;
5062
- #$dataSrc = signal([]);
5063
- $dataSize = signal({ start: 0, end: 0 }, {
5064
- equal: (a, b) => a.start === b.start && a.end === b.end
5065
- });
5066
- _ = effect(() => {
5067
- const data = this.#$dataSrc();
5068
- const dataSize = this.$dataSize();
5069
- untracked(() => this.data = data.slice(dataSize.start, dataSize.end));
5132
+ class VirtualScrollContainer {
5133
+ state = inject(TableStore);
5134
+ dataStore = inject(DataStore);
5135
+ viewport = viewChild(CdkVirtualScrollViewport);
5136
+ genericTable = contentChild(GenericTableComponent);
5137
+ tableContainer = inject(TableContainerComponent);
5138
+ defaultOptions = new VirtualScrollOptions();
5139
+ $usePaginator = this.state.selectSignal(s => s.notPersistedTableSettings.usePaginator);
5140
+ $pageSize = this.state.$pageSize;
5141
+ $currentPage = this.state.$currentPage;
5142
+ $showAll = this.state.$showAll;
5143
+ $stateDataLength = this.dataStore.selectSignal(s => s.dataLen);
5144
+ viewPort$ = toObservable(this.viewport).pipe(notNull());
5145
+ $scrolledIndexChange = toSignal(this.viewPort$.pipe(switchMap$1(v => v.scrolledIndexChange)));
5146
+ $renderedRange = toSignal(this.viewPort$.pipe(switchMap$1(v => v.renderedRangeStream)));
5147
+ $virtualScrollOptions = computed(() => this.state.$tableSettings().virtualSettings);
5148
+ $dataLength = computed(() => {
5149
+ const paginated = this.$usePaginator() && !this.$showAll();
5150
+ const pageSize = this.$pageSize();
5151
+ const pageNumber = this.$currentPage();
5152
+ const dataLen = this.$stateDataLength();
5153
+ if (paginated)
5154
+ return Math.min(dataLen - (pageNumber * pageSize), pageSize);
5155
+ return dataLen;
5070
5156
  });
5071
- setData(data) {
5072
- this.#$dataSrc.set(data);
5157
+ constructor() {
5158
+ addEventListener('resize', this.resizeHandler);
5073
5159
  }
5074
- constructor(state, data) {
5075
- super([]);
5076
- const $currentPage = state.$currentPage;
5077
- const $pageSize = state.$pageSize;
5078
- const $virtualEnds = data.selectSignal(d => d.virtualEnds);
5079
- const $dataLength = computed(() => this.#$dataSrc().length);
5080
- const $dataSize = computed(() => {
5081
- const viewType = state.$viewType();
5082
- const dataLength = $dataLength();
5083
- const currentPage = $currentPage();
5084
- const pageSize = $pageSize();
5085
- const virtualEnds = $virtualEnds();
5086
- const previousPageRecords = currentPage * pageSize;
5087
- if (viewType === 'virtual paginator') {
5088
- return ({ start: virtualEnds.start + previousPageRecords, end: Math.min(virtualEnds.end, pageSize) + previousPageRecords });
5089
- }
5090
- if (viewType === 'paginator') {
5091
- return ({ start: previousPageRecords, end: previousPageRecords + pageSize });
5092
- }
5093
- if (viewType === 'all') {
5094
- return ({ start: 0, end: dataLength });
5160
+ setViewportEffect = effect(() => {
5161
+ const viewport = this.viewport();
5162
+ untracked(() => {
5163
+ if (!!viewport) {
5164
+ this.setSize(this.viewport().elementRef);
5095
5165
  }
5096
- return ({ start: virtualEnds.start, end: virtualEnds.end });
5166
+ ;
5097
5167
  });
5098
- this.$dataSize = $dataSize;
5168
+ });
5169
+ subscriber = subscriber();
5170
+ onRenderedRangeEffect = effect(() => {
5171
+ const renderedRange = this.$renderedRange();
5172
+ if (!renderedRange)
5173
+ return;
5174
+ untracked(() => {
5175
+ this.dataStore.patchState({
5176
+ virtualEnds: {
5177
+ start: renderedRange.start,
5178
+ end: renderedRange.end + 25,
5179
+ }
5180
+ });
5181
+ this.setSize(this.viewport().elementRef);
5182
+ });
5183
+ });
5184
+ onDataLengthEffect = effect(() => {
5185
+ const dataLength = this.$dataLength();
5186
+ untracked(() => {
5187
+ this.scrollStrategy.setDataLength(dataLength);
5188
+ });
5189
+ });
5190
+ onOffsetEffect = effect(() => {
5191
+ const offset = this.$offset();
5192
+ untracked(() => {
5193
+ this.dataStore.patchState({ virtualScrollOffset: offset });
5194
+ });
5195
+ });
5196
+ $offset = computed(() => {
5197
+ const viewport = this.viewport();
5198
+ const scrolledIndexChange = this.$scrolledIndexChange();
5199
+ if (!scrolledIndexChange || !viewport)
5200
+ return 0;
5201
+ return viewport.getOffsetToRenderedContentStart() ?? 0;
5202
+ });
5203
+ ngOnDestroy() {
5204
+ removeEventListener('resize', this.resizeHandler);
5099
5205
  }
5100
- connect() {
5101
- return super.connect();
5206
+ setSize(el) {
5207
+ const virtualScrollOptions = this.$virtualScrollOptions();
5208
+ if (virtualScrollOptions.dynamicHeight) {
5209
+ this.calcDynamic(el);
5210
+ return;
5211
+ }
5212
+ const rowHeight = this.computedRowHeight();
5213
+ let amountOfVisibleItems = virtualScrollOptions?.amountOfVisibleItems || this.defaultOptions.amountOfVisibleItems;
5214
+ amountOfVisibleItems = Math.min(amountOfVisibleItems, this.$dataLength());
5215
+ let height = (rowHeight * amountOfVisibleItems);
5216
+ const footerHeight = this.computedFooterHeight();
5217
+ const headerHeight = this.computedHeaderHeight();
5218
+ height += (footerHeight + headerHeight);
5219
+ const maxViewPortHeightPx = parseTbSizeToPixels(virtualScrollOptions.maxViewPortHeight) || 0;
5220
+ if (virtualScrollOptions?.maxViewPortHeight && maxViewPortHeightPx)
5221
+ height = maxViewPortHeightPx;
5222
+ this.setHeight(height, el);
5102
5223
  }
5103
- disconnect() {
5104
- if (this.subscription) {
5105
- this.subscription.unsubscribe();
5106
- this.subscription = undefined;
5224
+ calcDynamic$ = new Subject();
5225
+ $calcDynamic = toSignal(this.calcDynamic$.pipe(debounceTime(300)));
5226
+ #onCalcDynamicEffect = effect(() => {
5227
+ const el = this.$calcDynamic();
5228
+ if (!el)
5229
+ return;
5230
+ this.calcDynamic(el);
5231
+ });
5232
+ calcDynamic(el) {
5233
+ const virtualScrollOptions = this.$virtualScrollOptions();
5234
+ const t = this.tableContainer.elementRef.nativeElement.querySelector(`#${TableContainerComponent.headerId}`);
5235
+ const rect = t?.getBoundingClientRect();
5236
+ const viewportHeight = window.innerHeight;
5237
+ const distanceFromBottom = viewportHeight - rect.bottom;
5238
+ const rowHeight = this.computedRowHeight();
5239
+ const footerHeight = this.computedFooterHeight();
5240
+ const headerHeight = this.computedHeaderHeight();
5241
+ const maxViewPortHeightPx = parseTbSizeToPixels(virtualScrollOptions.maxViewPortHeight) || 0;
5242
+ let tableSize = distanceFromBottom;
5243
+ if (virtualScrollOptions?.maxViewPortHeight && maxViewPortHeightPx < tableSize) {
5244
+ tableSize = maxViewPortHeightPx;
5107
5245
  }
5108
- super.disconnect();
5246
+ const available = (distanceFromBottom - footerHeight) - headerHeight;
5247
+ const amountOfRowsThatWillFit = Math.floor(available / rowHeight);
5248
+ const minAmountOfRows = virtualScrollOptions?.amountOfVisibleItems || this.defaultOptions.amountOfVisibleItems;
5249
+ const amountOfVisibleItems = Math.min(Math.max(amountOfRowsThatWillFit, minAmountOfRows), this.$dataLength());
5250
+ let height = (rowHeight * amountOfVisibleItems);
5251
+ height += (footerHeight + headerHeight) - 10;
5252
+ this.setHeight(height, el);
5109
5253
  }
5110
- }
5111
-
5112
- function mergeCustomCellMetaData(metaData1, metaData2) {
5113
- if (!metaData2) {
5114
- metaData1.noExport = true;
5115
- return metaData1;
5254
+ setHeight(height, el) {
5255
+ const vsViewport = el.nativeElement;
5256
+ vsViewport.setAttribute('style', `height: ${height}px !important;`);
5257
+ this.viewport()?.checkViewportSize();
5258
+ const virtualScrollOffset = this.viewport()?.getOffsetToRenderedContentStart() ?? 0;
5259
+ this.dataStore.patchState({ virtualScrollOffset });
5116
5260
  }
5117
- if (!metaData1.displayName)
5118
- metaData1.displayName = metaData2.displayName;
5119
- if (!metaData1.preSort)
5120
- metaData1.preSort = metaData2.preSort;
5121
- if (!metaData1.order)
5122
- metaData1.order = metaData2.order;
5123
- if (!metaData1.width)
5124
- metaData1.width = metaData2.width;
5125
- if (metaData2.fieldType)
5126
- metaData1.fieldType = metaData2.fieldType;
5127
- metaData1.noExport = metaData2.noExport;
5128
- return ({ ...metaData2, ...metaData1 });
5261
+ resizeHandler = () => {
5262
+ if (this.viewport() && this.$virtualScrollOptions().dynamicHeight) {
5263
+ this.setSize(this.viewport().elementRef);
5264
+ }
5265
+ };
5266
+ computedRowHeight = computed(() => {
5267
+ const virtualScrollOptions = this.state.$tableSettings().virtualSettings;
5268
+ const rowHeight = this.state.$userDefinedRowHeight() || virtualScrollOptions?.rowHeight || this.state.$tableSettings().rowHeight || this.defaultOptions.rowHeight;
5269
+ return parseTbSizeToPixels(rowHeight) || 0;
5270
+ });
5271
+ computedHeaderHeight = computed(() => {
5272
+ if (this.state.$tableSettings().hideHeader)
5273
+ return 0;
5274
+ const virtualScrollOptions = this.state.$tableSettings().virtualSettings;
5275
+ const headerHeight = this.state.$userDefinedHeaderHeight() || virtualScrollOptions?.headerHeight || this.state.$tableSettings().headerHeight || this.defaultOptions.headerHeight;
5276
+ return parseTbSizeToPixels(headerHeight) || 0;
5277
+ });
5278
+ computedFooterHeight() {
5279
+ return parseFloat(this.genericTable()?.$footerHeight()?.replace('px', '') || '0');
5280
+ }
5281
+ scrollStrategy = new TableVirtualScrollStrategy(this);
5282
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: VirtualScrollContainer, deps: [], target: i0.ɵɵFactoryTarget.Component });
5283
+ 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: `
5284
+ <cdk-virtual-scroll-viewport>
5285
+ <ng-content/>
5286
+ </cdk-virtual-scroll-viewport>
5287
+ `, isInline: true, dependencies: [{ kind: "ngmodule", type: ScrollingModule }, { kind: "component", type: i1$8.CdkVirtualScrollViewport, selector: "cdk-virtual-scroll-viewport", inputs: ["orientation", "appendOnly"], outputs: ["scrolledIndexChange"] }], viewProviders: [
5288
+ {
5289
+ provide: VIRTUAL_SCROLL_STRATEGY,
5290
+ useFactory: (c) => c.scrollStrategy,
5291
+ deps: [forwardRef(() => VirtualScrollContainer)],
5292
+ },
5293
+ ], changeDetection: i0.ChangeDetectionStrategy.OnPush });
5129
5294
  }
5295
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: VirtualScrollContainer, decorators: [{
5296
+ type: Component,
5297
+ args: [{
5298
+ selector: 'tb-virtual-scroll-container',
5299
+ template: `
5300
+ <cdk-virtual-scroll-viewport>
5301
+ <ng-content/>
5302
+ </cdk-virtual-scroll-viewport>
5303
+ `,
5304
+ changeDetection: ChangeDetectionStrategy.OnPush,
5305
+ imports: [ScrollingModule],
5306
+ viewProviders: [
5307
+ {
5308
+ provide: VIRTUAL_SCROLL_STRATEGY,
5309
+ useFactory: (c) => c.scrollStrategy,
5310
+ deps: [forwardRef(() => VirtualScrollContainer)],
5311
+ },
5312
+ ],
5313
+ }]
5314
+ }], ctorParameters: () => [] });
5130
5315
 
5131
5316
  class TableContainerComponent {
5132
5317
  state = inject(TableStore);
5133
5318
  dataStore = inject(DataStore);
5134
- exportToCsvService = inject((ExportToCsvService));
5135
5319
  wrapper = inject(TableWrapperDirective, { optional: true });
5136
5320
  stateService = inject(TableBuilderStateStore);
5137
5321
  injector = inject(Injector);
@@ -5144,6 +5328,11 @@ class TableContainerComponent {
5144
5328
  _$customRows = contentChildren((MatRowDef));
5145
5329
  $customRows = computed(() => [...this._$customRows()]);
5146
5330
  $customCells = contentChildren(CustomCellDirective);
5331
+ $menu = viewChild.required(MatMenu);
5332
+ menuInjector = Injector.create({
5333
+ providers: [{ provide: MatMenu, useFactory: () => this.$menu() }],
5334
+ parent: this.injector
5335
+ });
5147
5336
  $tableBuilder = input.required({ alias: 'tableBuilder' });
5148
5337
  $tableId = input(undefined, { alias: 'tableId' });
5149
5338
  $trackBy = input(undefined, { alias: 'trackBy' });
@@ -5198,15 +5387,6 @@ class TableContainerComponent {
5198
5387
  $collapsedFooter = this.state.$footerCollapsed;
5199
5388
  $collapsedHeader = this.state.$headerCollapsed;
5200
5389
  $displayDataLength = computed(() => this.$displayData().length);
5201
- resetState() {
5202
- this.$customFilterDirectives().forEach(cf => cf.reset());
5203
- this.$filterDirectives().forEach(cf => cf.reset());
5204
- this.state.resetState();
5205
- this.onStateReset$.emit(null);
5206
- }
5207
- exportToCsv() {
5208
- this.exportToCsvService.exportToCsv(this.$data());
5209
- }
5210
5390
  #initializeTableSettingsFromTableBuilderAndPersistedStateEffect = effect(() => {
5211
5391
  const metaLoaded = this.$isInitializationState(InitializationState.MetaDataLoaded)();
5212
5392
  if (!metaLoaded)
@@ -5343,11 +5523,15 @@ class TableContainerComponent {
5343
5523
  static headerId = 'tb-header-wrapper';
5344
5524
  headerId = TableContainerComponent.headerId;
5345
5525
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: TableContainerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
5346
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.0", type: TableContainerComponent, isStandalone: true, selector: "tb-table-container", inputs: { $tableBuilder: { classPropertyName: "$tableBuilder", publicName: "tableBuilder", isSignal: true, isRequired: true, transformFunction: null }, $tableId: { classPropertyName: "$tableId", publicName: "tableId", isSignal: true, isRequired: false, transformFunction: null }, $trackBy: { classPropertyName: "$trackBy", publicName: "trackBy", isSignal: true, isRequired: false, transformFunction: null }, $inputFilters: { classPropertyName: "$inputFilters", publicName: "inputFilters", isSignal: true, isRequired: false, transformFunction: null }, $indexColumn: { classPropertyName: "$indexColumn", publicName: "indexColumn", isSignal: true, isRequired: false, transformFunction: null }, $selectionColumn: { classPropertyName: "$selectionColumn", publicName: "selectionColumn", isSignal: true, isRequired: false, transformFunction: null }, $isSticky: { classPropertyName: "$isSticky", publicName: "isSticky", isSignal: true, isRequired: false, transformFunction: null }, $stickyFooter: { classPropertyName: "$stickyFooter", publicName: "stickyFooter", isSignal: true, isRequired: false, transformFunction: null }, $groupHeaderTemplate: { classPropertyName: "$groupHeaderTemplate", publicName: "groupHeaderTemplate", isSignal: true, isRequired: false, transformFunction: null }, $groupHeaderHeight: { classPropertyName: "$groupHeaderHeight", publicName: "groupHeaderHeight", isSignal: true, isRequired: false, transformFunction: null }, $pageSize: { classPropertyName: "$pageSize", publicName: "pageSize", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { $inputFilters: "inputFiltersChange", selection$: "selection", onStateReset$: "onStateReset", onSaveState$: "onSaveState", state$: "state", data$: "data" }, providers: [TableStore, ExportToCsvService, WrapperFilterStore, DataStore], queries: [{ propertyName: "$filterDirectives", predicate: TableFilterDirective, descendants: true, isSignal: true }, { propertyName: "$customFilterDirectives", predicate: TableCustomFilterDirective, descendants: true, isSignal: true }, { propertyName: "_$customRows", predicate: (MatRowDef), isSignal: true }, { propertyName: "$customCells", predicate: CustomCellDirective, isSignal: true }], viewQueries: [{ propertyName: "$paginatorComponent", first: true, predicate: PaginatorComponent, descendants: true, isSignal: true }, { propertyName: "$genericTable", first: true, predicate: GenericTableComponent, descendants: true, isSignal: true }], ngImport: i0, template: "@let tableId = $tableId();\r\n@let tableSettings = state.$tableSettings();\r\n\r\n<ng-content select=\"[before]\" />\r\n<ng-container multiSort>\r\n <div class=\"tb-header-wrapper\" [id]=\"headerId\">\r\n <div class=\"title\">\r\n @if ((!$collapsedHeader()) || tableSettings.showTitleWhenHeaderCollapsed) {\r\n <ng-content select=\".tb-header-title\"/>\r\n }\r\n @if(state.$groupByKeys().length){\r\n <group-by-list />\r\n }\r\n </div>\r\n <div class=\"flx-row-end\">\r\n <lib-filter-list />\r\n @if (!tableSettings.hideHeader) {\r\n @if (!$collapsedHeader()) {\r\n <ng-container *ngTemplateOutlet=\"headerMenu\"/>\r\n <button mat-icon-button color='primary' [matMenuTriggerFor]=\"mainMenu\">\r\n <mat-icon>more_vert</mat-icon>\r\n </button>\r\n <mat-menu #mainMenu='matMenu'>\r\n <ng-container *ngTemplateOutlet=\"headerMenuExtra\"/>\r\n </mat-menu>\r\n }\r\n @else {\r\n <mat-icon color=\"primary\" [matMenuTriggerFor]=\"mainMenu\" class=\"flat-menu-button pointer\">more_horiz</mat-icon>\r\n <mat-menu #mainMenu='matMenu'>\r\n <div class=\"flex-column\">\r\n <ng-container *ngTemplateOutlet=\"headerMenu\"/>\r\n </div>\r\n <ng-container *ngTemplateOutlet=\"headerMenuExtra\"/>\r\n </mat-menu>\r\n }\r\n <mat-icon [matTooltip]=\"$collapsedHeader() ? 'expand' : 'collapse'\" class=\"collapse-icon header\"\r\n (click)=\"state.toggleCollapseHeader()\">\r\n {{$collapsedHeader() ? 'expand_less' : 'expand_more'}}\r\n </mat-icon>\r\n }\r\n\r\n </div>\r\n </div>\r\n\r\n @if($useVirtual())\r\n {\r\n <tb-virtual-scroll-container class=\"scrollable\">\r\n <tb-generic-table [rows]=\"$customRows()\" [data]=\"$data()!\" [displayDataLength]=\"$displayDataLength()\"\r\n (selection)='selection$.emit($event)' [columnInfos]='$myColumns()' [trackBy]=\"$trackBy()\" [dataSource]=\"dataSource\" />\r\n </tb-virtual-scroll-container>\r\n }\r\n @else\r\n {\r\n <tb-generic-table [rows]=\"$customRows()\" [data]=\"$data()!\" [displayDataLength]=\"$displayDataLength()\"\r\n (selection)='selection$.emit($event)' [columnInfos]='$myColumns()' [trackBy]=\"$trackBy()\" [dataSource]=\"dataSource\" />\r\n }\r\n @if(tableSettings.usePaginator)\r\n {\r\n <div class=\"paginator\">\r\n <tb-paginator #tbPaginator />\r\n\r\n <mat-icon [matTooltip]=\"$collapsedFooter() ? 'expand' : 'collapse'\" class=\"collapse-icon footer\"\r\n (click)=\"state.toggleCollapseFooter()\">\r\n {{$collapsedFooter() ? 'expand_more' : 'expand_less'}}\r\n </mat-icon>\r\n </div>\r\n }\r\n\r\n <ng-template #headerMenu>\r\n @if (!tableSettings.hideFilter) {<tb-filter-displayer/>}\r\n @if (!tableSettings.hideColumnSettings) {<tb-col-displayer/>}\r\n @if (!tableSettings.hideSort) {<tb-sort-menu/>}\r\n @if (!!tableId) {<tb-profiles-menu [$tableId]=\"tableId\" (onSaveState)=\"onSaveState$.emit($event)\"/>}\r\n </ng-template>\r\n\r\n <ng-template #headerMenuExtra>\r\n <button mat-menu-item (click)=\"resetState()\">\r\n <mat-icon color=\"primary\">autorenew</mat-icon>\r\n <span>Reset table</span>\r\n </button>\r\n @if (!tableSettings.hideExport) {\r\n <button mat-menu-item (click)=\"exportToCsv()\">\r\n <mat-icon color=\"primary\">file_download</mat-icon>\r\n <span>Export Table</span>\r\n </button>\r\n }\r\n @if (tableId) {\r\n <button stop-propagation mat-menu-item (click)=\"pm.trigger()?.toggleMenu()\">\r\n <mat-icon color=\"primary\">people</mat-icon>\r\n <span>Profiles</span>\r\n </button>\r\n <tb-profiles-menu class=\"profiles-menu\" #pm [$tableId]=\"tableId\" (onSaveState)=\"onSaveState$.emit($event)\"/>\r\n }\r\n </ng-template>\r\n</ng-container>\r\n", styles: [".tb-header-wrapper{display:flex;flex-direction:row;justify-content:space-between;width:100%}.flx-row-end{display:flex;flex-direction:row;justify-content:flex-end;align-items:center}.flat-menu{line-height:initial;height:initial}.pointer{cursor:pointer}.add-key{width:90%}.paginator{display:flex;flex-direction:row;justify-content:flex-end;align-items:center;background-color:#fff;bottom:0;position:sticky;border-top:.5px solid rgba(0,0,0,.12)}.profiles-menu{visibility:hidden;width:0px;height:0px;display:block;overflow:hidden;position:absolute;top:50px}\n", ".collapse-icon{font-size:16px;height:16px;color:#3f51b5;align-self:flex-start}.collapse-icon:hover{cursor:pointer}.hide{display:none}.paginator-row{display:flex;align-items:center}\n"], dependencies: [{ kind: "directive", type: i1$8.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: PaginatorComponent, selector: "tb-paginator" }, { kind: "directive", type: MultiSortDirective, selector: "[multiSort]", inputs: ["matSortDisabled"], exportAs: ["multiSort"] }, { kind: "component", type: GroupByListComponent, selector: "group-by-list" }, { kind: "component", type: FilterChipsComponent, selector: "lib-filter-list" }, { kind: "component", type: GenFilterDisplayerComponent, selector: "tb-filter-displayer" }, { kind: "component", type: GenColDisplayerComponent, selector: "tb-col-displayer" }, { kind: "component", type: SortMenuComponent, selector: "tb-sort-menu" }, { kind: "component", type: GenericTableComponent, selector: "tb-generic-table", inputs: ["displayDataLength", "data", "rows", "columnInfos", "dataSource", "trackBy"], outputs: ["selection"] }, { kind: "directive", type: StopPropagationDirective, selector: "[stop-propagation]" }, { kind: "component", type: ProfilesMenuComponent, selector: "tb-profiles-menu", inputs: ["$tableId"], outputs: ["onSaveState"] }, { kind: "ngmodule", type: i3$1.MatButtonModule }, { kind: "component", type: i3$1.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "ngmodule", type: i4$2.MatMenuModule }, { kind: "component", type: i4$2.MatMenu, selector: "mat-menu", inputs: ["backdropClass", "aria-label", "aria-labelledby", "aria-describedby", "xPosition", "yPosition", "overlapTrigger", "hasBackdrop", "class", "classList"], outputs: ["closed", "close"], exportAs: ["matMenu"] }, { kind: "component", type: i4$2.MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i4$2.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }, { kind: "ngmodule", type: i2.MatIconModule }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: i4$1.MatTooltipModule }, { kind: "directive", type: i4$1.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: VirtualScrollContainer, selector: "tb-virtual-scroll-container" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
5526
+ 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 });
5347
5527
  }
5348
5528
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: TableContainerComponent, decorators: [{
5349
5529
  type: Component,
5350
- args: [{ selector: 'tb-table-container', changeDetection: ChangeDetectionStrategy.OnPush, providers: [TableStore, ExportToCsvService, WrapperFilterStore, DataStore], imports: containerImports, template: "@let tableId = $tableId();\r\n@let tableSettings = state.$tableSettings();\r\n\r\n<ng-content select=\"[before]\" />\r\n<ng-container multiSort>\r\n <div class=\"tb-header-wrapper\" [id]=\"headerId\">\r\n <div class=\"title\">\r\n @if ((!$collapsedHeader()) || tableSettings.showTitleWhenHeaderCollapsed) {\r\n <ng-content select=\".tb-header-title\"/>\r\n }\r\n @if(state.$groupByKeys().length){\r\n <group-by-list />\r\n }\r\n </div>\r\n <div class=\"flx-row-end\">\r\n <lib-filter-list />\r\n @if (!tableSettings.hideHeader) {\r\n @if (!$collapsedHeader()) {\r\n <ng-container *ngTemplateOutlet=\"headerMenu\"/>\r\n <button mat-icon-button color='primary' [matMenuTriggerFor]=\"mainMenu\">\r\n <mat-icon>more_vert</mat-icon>\r\n </button>\r\n <mat-menu #mainMenu='matMenu'>\r\n <ng-container *ngTemplateOutlet=\"headerMenuExtra\"/>\r\n </mat-menu>\r\n }\r\n @else {\r\n <mat-icon color=\"primary\" [matMenuTriggerFor]=\"mainMenu\" class=\"flat-menu-button pointer\">more_horiz</mat-icon>\r\n <mat-menu #mainMenu='matMenu'>\r\n <div class=\"flex-column\">\r\n <ng-container *ngTemplateOutlet=\"headerMenu\"/>\r\n </div>\r\n <ng-container *ngTemplateOutlet=\"headerMenuExtra\"/>\r\n </mat-menu>\r\n }\r\n <mat-icon [matTooltip]=\"$collapsedHeader() ? 'expand' : 'collapse'\" class=\"collapse-icon header\"\r\n (click)=\"state.toggleCollapseHeader()\">\r\n {{$collapsedHeader() ? 'expand_less' : 'expand_more'}}\r\n </mat-icon>\r\n }\r\n\r\n </div>\r\n </div>\r\n\r\n @if($useVirtual())\r\n {\r\n <tb-virtual-scroll-container class=\"scrollable\">\r\n <tb-generic-table [rows]=\"$customRows()\" [data]=\"$data()!\" [displayDataLength]=\"$displayDataLength()\"\r\n (selection)='selection$.emit($event)' [columnInfos]='$myColumns()' [trackBy]=\"$trackBy()\" [dataSource]=\"dataSource\" />\r\n </tb-virtual-scroll-container>\r\n }\r\n @else\r\n {\r\n <tb-generic-table [rows]=\"$customRows()\" [data]=\"$data()!\" [displayDataLength]=\"$displayDataLength()\"\r\n (selection)='selection$.emit($event)' [columnInfos]='$myColumns()' [trackBy]=\"$trackBy()\" [dataSource]=\"dataSource\" />\r\n }\r\n @if(tableSettings.usePaginator)\r\n {\r\n <div class=\"paginator\">\r\n <tb-paginator #tbPaginator />\r\n\r\n <mat-icon [matTooltip]=\"$collapsedFooter() ? 'expand' : 'collapse'\" class=\"collapse-icon footer\"\r\n (click)=\"state.toggleCollapseFooter()\">\r\n {{$collapsedFooter() ? 'expand_more' : 'expand_less'}}\r\n </mat-icon>\r\n </div>\r\n }\r\n\r\n <ng-template #headerMenu>\r\n @if (!tableSettings.hideFilter) {<tb-filter-displayer/>}\r\n @if (!tableSettings.hideColumnSettings) {<tb-col-displayer/>}\r\n @if (!tableSettings.hideSort) {<tb-sort-menu/>}\r\n @if (!!tableId) {<tb-profiles-menu [$tableId]=\"tableId\" (onSaveState)=\"onSaveState$.emit($event)\"/>}\r\n </ng-template>\r\n\r\n <ng-template #headerMenuExtra>\r\n <button mat-menu-item (click)=\"resetState()\">\r\n <mat-icon color=\"primary\">autorenew</mat-icon>\r\n <span>Reset table</span>\r\n </button>\r\n @if (!tableSettings.hideExport) {\r\n <button mat-menu-item (click)=\"exportToCsv()\">\r\n <mat-icon color=\"primary\">file_download</mat-icon>\r\n <span>Export Table</span>\r\n </button>\r\n }\r\n @if (tableId) {\r\n <button stop-propagation mat-menu-item (click)=\"pm.trigger()?.toggleMenu()\">\r\n <mat-icon color=\"primary\">people</mat-icon>\r\n <span>Profiles</span>\r\n </button>\r\n <tb-profiles-menu class=\"profiles-menu\" #pm [$tableId]=\"tableId\" (onSaveState)=\"onSaveState$.emit($event)\"/>\r\n }\r\n </ng-template>\r\n</ng-container>\r\n", styles: [".tb-header-wrapper{display:flex;flex-direction:row;justify-content:space-between;width:100%}.flx-row-end{display:flex;flex-direction:row;justify-content:flex-end;align-items:center}.flat-menu{line-height:initial;height:initial}.pointer{cursor:pointer}.add-key{width:90%}.paginator{display:flex;flex-direction:row;justify-content:flex-end;align-items:center;background-color:#fff;bottom:0;position:sticky;border-top:.5px solid rgba(0,0,0,.12)}.profiles-menu{visibility:hidden;width:0px;height:0px;display:block;overflow:hidden;position:absolute;top:50px}\n", ".collapse-icon{font-size:16px;height:16px;color:#3f51b5;align-self:flex-start}.collapse-icon:hover{cursor:pointer}.hide{display:none}.paginator-row{display:flex;align-items:center}\n"] }]
5530
+ args: [{ selector: 'tb-table-container', changeDetection: ChangeDetectionStrategy.OnPush, providers: [TableStore, ExportToCsvService, WrapperFilterStore, DataStore], imports: [NgTemplateOutlet,
5531
+ PaginatorComponent,
5532
+ MultiSortDirective, GroupByListComponent, FilterChipsComponent, GenFilterDisplayerComponent, GenColDisplayerComponent,
5533
+ SortMenuComponent, GenericTableComponent, StopPropagationDirective, ProfilesMenuComponent, TableHeaderMenuComponent,
5534
+ 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"] }]
5351
5535
  }] });
5352
5536
 
5353
5537
  class TableBuilderModule {
@@ -5760,5 +5944,5 @@ const setUpStoreFactory = () => {
5760
5944
  * Generated bundle index. Do not edit.
5761
5945
  */
5762
5946
 
5763
- export { ActionStateSpinnerComponent, ActionStateUiModule, ActionStatus, AppStatusState, ArrayStyle, AutoFocusDirective, CancellationToken, ClickEmitterDirective, ClickSubjectDirective, ConditionalClassesDirective, CreateTableBuilder, CustomCellDirective, DateFilterComponent, DefaultVirtualScrollOptions, DialogDirective, DialogService, DialogWrapper, FieldType, FilterChipsComponent, FilterComponent, FilterTypes, FunctionPipe, GenColDisplayerComponent, GenFilterDisplayerComponent, GeneralTableSettings, GenericTableComponent, GroupByListComponent, HttpErrorStateDirective, HttpInProgressStateDirective, HttpNotStartedStateDirective, HttpRequestModule, HttpRequestStateDirective, HttpRequestStateFactory, HttpRequestStateStore, HttpRequestStatus, HttpRequestStrategy, HttpSuccessStateDirective, MatButtonToggleFilterDirective, MatCheckboxTbFilterDirective, MatOptionTbFilterDirective, MatRadioButtonTbFilterDirective, MatSlideToggleGroupDirective, MatSlideToggleTbFilterDirective, MatTableObservableDataSource, MultiSortDirective, NgrxExtModule, NotPersistedTableSettings, PaginatorComponent, PaginatorOptions, PersistedTableSettings, PhoneNumberPipe, PreventEnterDirective, ResizeColumnDirective, SortDirection, SpaceCasePipe, StopPropagationDirective, StylerDirective, Subjectifier, Subscriber, TableBuilder, TableBuilderConfigToken, TableBuilderModule, TableColumnHeaderSettings, TableContainerComponent, TableCustomFilterDirective, TableCustomFilterDirectiveBase, TableFilterDirective, TableFilterStringContainsDirective, TableSettings, TableWrapperDirective, TableWrapperFooterSettings, TableWrapperHeaderSettings, Target, TbSelectedFilterDirective, TrimWhitespaceDirective, UtilitiesModule, VirtualScrollOptions, actionStatusReducer, chainRequest, clearActionableSelectorRequestCache, combineArrays, createActionResultSelector, createActionSelector, createActionableResultSelector, createActionableSelector, createFailure, createRequestor, createSuccess, defaultFilter, defaultShareReplay, delayOn, filterArray, getRequestorBody, getRequestorStatus, getStatusState, httpRequest, httpRequestor, inProgress, initialState, isErrorState, isSuccessOrErrorState, isSuccessState, mapArray, mapError, metaDataArrToDict, notNull, notStarted, onWait, onceWhen, previousAndCurrent, provideActionableSelector, provideTableBuilder, selectAll, selectEntities, selectEntity, selectIds, selectTotal, serverStatusTypes, setUpStoreFactory, skipOneWhen, sortsAreSame, spaceCase, startWithIfEmpty, statusAdapter, statusIsSuccessOrInProgress, subscriber, switchOff, tapError, tapSuccess, wrapInArr };
5947
+ 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, skipOneWhen, sortsAreSame, spaceCase, startWithIfEmpty, statusAdapter, statusIsSuccessOrInProgress, subscriber, switchOff, tapError, tapSuccess, wrapInArr };
5764
5948
  //# sourceMappingURL=one-paragon-angular-utilities.mjs.map