@one-paragon/angular-utilities 2.3.11 → 2.3.13

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,5 +1,5 @@
1
1
  import * as i0 from '@angular/core';
2
- import { Input, Directive, inject, Injector, TemplateRef, ViewContainerRef, NgModule, assertInInjectionContext, DestroyRef, signal, computed, isSignal, effect, untracked, InjectionToken, Injectable, runInInjectionContext, input, Renderer2, ElementRef, booleanAttribute, Pipe, makeEnvironmentProviders, ChangeDetectionStrategy, Component, HostListener, EventEmitter, Output, ContentChildren, ChangeDetectorRef, output, viewChild, EnvironmentInjector, createComponent, linkedSignal, contentChild, forwardRef, contentChildren, provideAppInitializer } from '@angular/core';
2
+ import { Input, Directive, inject, Injector, TemplateRef, ViewContainerRef, NgModule, assertInInjectionContext, DestroyRef, signal, computed, isSignal, effect, untracked, InjectionToken, Injectable, runInInjectionContext, input, Renderer2, ElementRef, booleanAttribute, Pipe, makeEnvironmentProviders, HostListener, ChangeDetectionStrategy, Component, EventEmitter, Output, ContentChildren, ChangeDetectorRef, output, viewChild, EnvironmentInjector, createComponent, linkedSignal, contentChild, forwardRef, contentChildren, provideAppInitializer } from '@angular/core';
3
3
  import { shareReplay, map, switchAll, filter, tap, catchError, startWith, switchMap, mergeMap, concatMap as concatMap$1, takeUntil, distinctUntilChanged, debounceTime } from 'rxjs/operators';
4
4
  import * as i1 from 'rxjs';
5
5
  import { isObservable, Subject, of, ReplaySubject, filter as filter$1, first, map as map$1, Observable, combineLatest, Subscription, startWith as startWith$1, pairwise, pipe, concatMap, merge, delay, fromEvent, takeUntil as takeUntil$1, tap as tap$1, switchMap as switchMap$1, scan, timestamp } from 'rxjs';
@@ -18,7 +18,8 @@ import { MatCheckbox, MatCheckboxModule } from '@angular/material/checkbox';
18
18
  import * as i2 from '@angular/forms';
19
19
  import { NgControl, NgForm, ControlContainer, FormsModule, NG_VALUE_ACCESSOR } from '@angular/forms';
20
20
  import { MatOption } from '@angular/material/core';
21
- import { DatePipe, CurrencyPipe, NgTemplateOutlet, formatDate, formatCurrency, DecimalPipe, formatNumber, CommonModule, AsyncPipe } from '@angular/common';
21
+ import { DatePipe, CurrencyPipe, formatDate, formatCurrency, NgTemplateOutlet, DecimalPipe, formatNumber, CommonModule, AsyncPipe } from '@angular/common';
22
+ import { MatDialog, MAT_DIALOG_DEFAULT_OPTIONS } from '@angular/material/dialog';
22
23
  import { ComponentStore } from '@ngrx/component-store';
23
24
  import * as i5 from '@angular/cdk/drag-drop';
24
25
  import { moveItemInArray, DragDropModule, CdkDropList, CDK_DROP_LIST, transferArrayItem } from '@angular/cdk/drag-drop';
@@ -28,7 +29,6 @@ import * as i3 from '@angular/material/datepicker';
28
29
  import { MatDatepickerModule } from '@angular/material/datepicker';
29
30
  import * as i1$3 from '@angular/material/card';
30
31
  import { MatCardModule } from '@angular/material/card';
31
- import { MatDialog, MAT_DIALOG_DEFAULT_OPTIONS } from '@angular/material/dialog';
32
32
  import * as i3$1 from '@angular/material/button';
33
33
  import { MatButtonModule, MatIconButton, MatButton } from '@angular/material/button';
34
34
  import * as i4 from '@angular/material/tooltip';
@@ -857,6 +857,7 @@ class TableWrapperHeaderSettings {
857
857
  this.hideSort = false;
858
858
  this.collapse = false;
859
859
  this.showTitleWhenCollapsed = true;
860
+ this.title = undefined;
860
861
  this.headerHeight = undefined;
861
862
  }
862
863
  }
@@ -918,6 +919,7 @@ class NotPersistedTableSettings {
918
919
  this.hideColumnSettings = false;
919
920
  this.hideSort = false;
920
921
  this.showTitleWhenHeaderCollapsed = true;
922
+ this.title = undefined;
921
923
  this.hideHeader = false;
922
924
  this.hideColumnHeaderFilters = false;
923
925
  this.hideColumnHeader = false;
@@ -938,6 +940,7 @@ class NotPersistedTableSettings {
938
940
  newNpts.hideFilter = tableSettings.headerSettings?.hideFilter ?? newNpts.hideFilter;
939
941
  newNpts.hideSort = tableSettings.headerSettings?.hideSort ?? newNpts.hideSort;
940
942
  newNpts.showTitleWhenHeaderCollapsed = tableSettings.headerSettings?.showTitleWhenCollapsed ?? newNpts.showTitleWhenHeaderCollapsed;
943
+ newNpts.title = tableSettings.headerSettings?.title ?? newNpts.title;
941
944
  newNpts.hideHeader = tableSettings.headerSettings?.hideHeader ?? newNpts.hideHeader;
942
945
  newNpts.hideColumnHeaderFilters = tableSettings.columnHeaderSettings?.noFilters ?? newNpts.hideColumnHeaderFilters;
943
946
  newNpts.hideColumnHeader = tableSettings.columnHeaderSettings?.noHeader ?? newNpts.hideColumnHeader;
@@ -1709,1366 +1712,1536 @@ function provideTableBuilder(config) {
1709
1712
  ]);
1710
1713
  }
1711
1714
 
1712
- const isNull = (filterInfo) => {
1713
- const func = filterInfo.filterValue ?
1714
- (val) => val == null || val === ''
1715
- :
1716
- (val) => val != null && val !== '';
1717
- return func;
1718
- };
1719
-
1720
- const stringEqualFunc = (filterInfo) => {
1721
- const equalsVal = prepareForStringCompare(filterInfo.filterValue);
1722
- return ((val) => prepareForStringCompare(val) === equalsVal);
1723
- };
1724
- const stringContainsFunc = (filterInfo) => {
1725
- const containsVal = prepareForStringCompare(filterInfo.filterValue);
1726
- return ((val) => prepareForStringCompare(val).includes(containsVal));
1727
- };
1728
- const stringDoesNotContainFunc = (filterInfo) => {
1729
- const doesNotContainVal = prepareForStringCompare(filterInfo.filterValue);
1730
- return ((val) => !prepareForStringCompare(val)?.includes(doesNotContainVal));
1731
- };
1732
- const stringStartsWithFunc = (filterInfo) => {
1733
- const startsWith = prepareForStringCompare(filterInfo.filterValue);
1734
- return ((val) => prepareForStringCompare(val).startsWith(startsWith));
1735
- };
1736
- const stringEndsWithFunc = (filterInfo) => {
1737
- const startsWith = prepareForStringCompare(filterInfo.filterValue);
1738
- return ((val) => prepareForStringCompare(val).endsWith(startsWith));
1739
- };
1740
- const multipleStringValuesEqualsFunc = (filterInfo) => {
1741
- const filterVals = filterInfo.filterValue.map((v) => prepareForStringCompare(v));
1742
- return ((val) => {
1743
- const v = prepareForStringCompare(val);
1744
- return filterVals.some((s) => v === s);
1745
- });
1746
- };
1747
- const StringFilterFuncs = {
1748
- [FilterType.StringEquals]: stringEqualFunc,
1749
- [FilterType.StringContains]: stringContainsFunc,
1750
- [FilterType.StringDoesNotContain]: stringDoesNotContainFunc,
1751
- [FilterType.StringStartWith]: stringStartsWithFunc,
1752
- [FilterType.StringEndsWith]: stringEndsWithFunc,
1753
- [FilterType.IsNull]: isNull,
1754
- [FilterType.In]: multipleStringValuesEqualsFunc,
1755
- };
1756
- const EnumFilterFuncs = {
1757
- [FilterType.IsNull]: isNull,
1758
- [FilterType.In]: multipleStringValuesEqualsFunc,
1759
- };
1760
- const prepareForStringCompare = (val) => (val?.toString().trim().toLowerCase());
1761
-
1762
- const numberEqalsFunc = (filterInfo) => (val) => {
1763
- return val === filterInfo.filterValue;
1764
- };
1765
- const numberNotEqualFunc = (filterInfo) => (val) => {
1766
- return val !== filterInfo.filterValue;
1767
- };
1768
- const numberGreaterThanFunc = (filterInfo) => (val) => {
1769
- return val > filterInfo.filterValue;
1770
- };
1771
- const numberLessThanFunc = (filterInfo) => (val) => {
1772
- return val < filterInfo.filterValue;
1773
- };
1774
- const numberBetweenFunc = (filterInfo) => {
1775
- const startVal = Number(filterInfo.filterValue.Start);
1776
- const endVal = Number(filterInfo.filterValue.End);
1777
- return ((val) => (val > startVal) && (val < endVal));
1778
- };
1779
- const multipleNumberValuesEqualsFunc = (filterInfo) => {
1780
- return ((val) => filterInfo.filterValue.some((value) => val === value));
1781
- };
1782
- const NumberFilterFuncs = {
1783
- [FilterType.NumberEquals]: numberEqalsFunc,
1784
- [FilterType.NumberNotEqual]: numberNotEqualFunc,
1785
- [FilterType.NumberGreaterThan]: numberGreaterThanFunc,
1786
- [FilterType.NumberLessThan]: numberLessThanFunc,
1787
- [FilterType.NumberBetween]: numberBetweenFunc,
1788
- [FilterType.IsNull]: isNull,
1789
- [FilterType.In]: multipleNumberValuesEqualsFunc,
1790
- };
1791
-
1792
- const dateIsOnFunc = (filterInfo) => {
1793
- const isOnVal = new Date(filterInfo.filterValue).getTime();
1794
- const clean = filterInfo.fieldType === FieldType.Date ? (a, b) => b : cleanDateTime;
1795
- return ((val) => clean(filterInfo, val).getTime() === isOnVal);
1796
- };
1797
- const dateIsNotOnFunc = (filterInfo) => {
1798
- const isNotOnVal = new Date(filterInfo.filterValue).getTime();
1799
- const clean = filterInfo.fieldType === FieldType.Date ? (a, b) => b : cleanDateTime;
1800
- return ((val) => clean(filterInfo, val).getTime() !== isNotOnVal);
1801
- };
1802
- const dateIsOnOrAfterFunc = (filterInfo) => {
1803
- const afterVal = new Date(filterInfo.filterValue).getTime();
1804
- const clean = filterInfo.fieldType === FieldType.Date ? (a, b) => b : cleanDateTime;
1805
- return ((val) => clean(filterInfo, val).getTime() >= afterVal);
1806
- };
1807
- const dateIsOnOrBeforeFunc = (filterInfo) => {
1808
- const beforeVal = new Date(filterInfo.filterValue).getTime();
1809
- const clean = filterInfo.fieldType === FieldType.Date ? (a, b) => b : cleanDateTime;
1810
- return ((val) => clean(filterInfo, val).getTime() <= beforeVal);
1811
- };
1812
- const dateIsInFunc = (filterInfo) => {
1813
- const filterVals = filterInfo.filterValue.map(v => new Date(v).getTime());
1814
- const clean = filterInfo.fieldType === FieldType.Date ? (a, b) => b : cleanDateTime;
1815
- return ((val) => {
1816
- const d = clean(filterInfo, val).getTime();
1817
- return filterVals.some((f) => f === d);
1818
- });
1819
- };
1820
- const dateBetweenFunc = (filterInfo) => {
1821
- const startVal = new Date(filterInfo.filterValue.Start);
1822
- const endVal = new Date(filterInfo.filterValue.End);
1823
- const clean = filterInfo.fieldType === FieldType.Date ? (a, b) => b : cleanDateTime;
1824
- return ((val) => {
1825
- const cleanedVal = clean(filterInfo, val);
1826
- return cleanedVal >= startVal && cleanedVal <= endVal;
1827
- });
1828
- };
1829
- const cleanDateTime = (filterInfo, val) => {
1830
- if (!!DateFilterFuncs[filterInfo.filterType]) {
1831
- const d = new Date(val);
1832
- d.setHours(0, 0, 0, 0);
1833
- return d;
1715
+ class PreventEnterDirective {
1716
+ onKeyDown() {
1717
+ return false;
1834
1718
  }
1835
- return val;
1836
- };
1837
- const DateFilterFuncs = {
1838
- [FilterType.DateIsOn]: dateIsOnFunc,
1839
- [FilterType.DateIsNotOn]: dateIsNotOnFunc,
1840
- [FilterType.DateOnOrAfter]: dateIsOnOrAfterFunc,
1841
- [FilterType.DateOnOrBefore]: dateIsOnOrBeforeFunc,
1842
- [FilterType.DateBetween]: dateBetweenFunc,
1843
- [FilterType.In]: dateIsInFunc,
1844
- [FilterType.IsNull]: isNull,
1845
- };
1846
- const DateTimeFilterFuncs = {
1847
- ...DateFilterFuncs,
1848
- [FilterType.DateTimeIsAt]: dateIsOnFunc,
1849
- [FilterType.DateTimeIsNotAt]: dateIsNotOnFunc,
1850
- [FilterType.DateTimeAtOrAfter]: dateIsOnOrAfterFunc,
1851
- [FilterType.DateTimeAtOrBefore]: dateIsOnOrBeforeFunc,
1852
- [FilterType.DateTimeBetween]: dateBetweenFunc,
1853
- [FilterType.In]: dateIsInFunc,
1854
- [FilterType.IsNull]: isNull,
1855
- };
1856
-
1857
- const booleanEqualsFunc = (filterInfo) => (val) => {
1858
- return filterInfo.filterValue === val;
1859
- };
1860
- const BooleanFilterFuncs = {
1861
- [FilterType.BooleanEquals]: booleanEqualsFunc,
1862
- [FilterType.IsNull]: isNull,
1863
- };
1864
-
1865
- function sortData(data, sorted) {
1866
- return data.sort(compareT(sorted));
1719
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.3", ngImport: i0, type: PreventEnterDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
1720
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.0.3", type: PreventEnterDirective, isStandalone: true, selector: "preventEnter", host: { listeners: { "keydown.enter": "onKeyDown($event)" } }, ngImport: i0 }); }
1867
1721
  }
1868
- function filterData(data, filters, resetAll = false) {
1869
- if (filters.length === 0) {
1870
- if (resetAll) {
1871
- for (let index = 0; index < data.length; index++) {
1872
- const element = data[index];
1873
- element[tbNoShowSymbol] = false;
1874
- }
1875
- }
1876
- return data;
1722
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.3", ngImport: i0, type: PreventEnterDirective, decorators: [{
1723
+ type: Directive,
1724
+ args: [{
1725
+ selector: 'preventEnter',
1726
+ }]
1727
+ }], propDecorators: { onKeyDown: [{
1728
+ type: HostListener,
1729
+ args: ['keydown.enter', ['$event']]
1730
+ }] } });
1731
+
1732
+ class StopPropagationDirective {
1733
+ onClick(event) {
1734
+ event.stopPropagation();
1877
1735
  }
1878
- for (let index = 0; index < data.length; index++) {
1879
- const element = data[index];
1880
- const hide = !filters.every(filter => filter(element));
1881
- if (hide || resetAll) {
1882
- element[tbNoShowSymbol] = hide;
1883
- }
1736
+ onMousedown(event) {
1737
+ event.stopPropagation();
1884
1738
  }
1885
- return data;
1739
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.3", ngImport: i0, type: StopPropagationDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
1740
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.0.3", type: StopPropagationDirective, isStandalone: true, selector: "[stop-propagation]", host: { listeners: { "click": "onClick($event)", "mousedown": "onMousedown($event)" } }, ngImport: i0 }); }
1886
1741
  }
1887
- const tbNoShowSymbol = Symbol('tb_no_show');
1888
- function compareT(criteria) {
1889
- const transforms = criteria.reduce((acc, c) => {
1890
- acc[c.active] = {
1891
- transform: c.sortBy ? c.sortBy : getFactory(c.active), nulls: c.nulls === 'first' ? -1 : 1
1892
- };
1893
- return acc;
1894
- }, {});
1895
- return function (a, b) {
1896
- for (let index = 0; index < criteria.length; index++) {
1897
- const c = criteria[index];
1898
- const d = transforms[c.active];
1899
- const nullValue = d.nulls;
1900
- if (a == null) {
1901
- if (b == null)
1902
- return 0;
1903
- return nullValue;
1904
- }
1905
- if (b == null)
1906
- return -nullValue;
1907
- const transform = d.transform;
1908
- const aVal = transform(a);
1909
- const bVal = transform(b);
1910
- if (aVal == null) {
1911
- if (bVal == null)
1912
- return 0;
1913
- return nullValue;
1914
- }
1915
- if (bVal == null)
1916
- return -nullValue;
1917
- if (aVal < bVal)
1918
- return c.direction === 'asc' ? -1 : 1;
1919
- if (aVal > bVal)
1920
- return c.direction === 'asc' ? 1 : -1;
1742
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.3", ngImport: i0, type: StopPropagationDirective, decorators: [{
1743
+ type: Directive,
1744
+ args: [{
1745
+ selector: "[stop-propagation]",
1746
+ }]
1747
+ }], propDecorators: { onClick: [{
1748
+ type: HostListener,
1749
+ args: ["click", ["$event"]]
1750
+ }], onMousedown: [{
1751
+ type: HostListener,
1752
+ args: ["mousedown", ["$event"]]
1753
+ }] } });
1754
+
1755
+ class AutoFocusDirective {
1756
+ constructor() {
1757
+ this.elementRef = inject(ElementRef);
1758
+ this.autoFocus = true;
1759
+ }
1760
+ ngAfterViewInit() {
1761
+ if (this.autoFocus) {
1762
+ setTimeout(() => {
1763
+ this.elementRef.nativeElement.focus();
1764
+ });
1921
1765
  }
1922
- return 0;
1923
- };
1924
- }
1925
- function getFactory(b) {
1926
- if (typeof b !== 'string')
1927
- return (a) => a[b];
1928
- if (!b.includes('.'))
1929
- return (a) => {
1930
- if (!a)
1931
- return a;
1932
- return a[b];
1933
- };
1934
- const arr = b.split('.');
1935
- return (a) => {
1936
- let val = a;
1937
- if (!a)
1938
- return a;
1939
- for (let index = 0; index < arr.length; index++) {
1940
- val = val[arr[index]];
1941
- if (val == undefined)
1942
- return undefined;
1943
- if (typeof val !== 'object' && index + 1 < arr.length)
1944
- return undefined;
1945
- }
1946
- return val;
1947
- };
1766
+ }
1767
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.3", ngImport: i0, type: AutoFocusDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
1768
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.0.3", type: AutoFocusDirective, isStandalone: true, selector: "[autoFocus]", inputs: { autoFocus: "autoFocus" }, ngImport: i0 }); }
1948
1769
  }
1770
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.3", ngImport: i0, type: AutoFocusDirective, decorators: [{
1771
+ type: Directive,
1772
+ args: [{
1773
+ selector: '[autoFocus]',
1774
+ }]
1775
+ }], propDecorators: { autoFocus: [{
1776
+ type: Input
1777
+ }] } });
1949
1778
 
1950
- const filterFactoryMap = {
1951
- [FilterType.And]: (filter) => {
1952
- const filters = createFilterFuncs(filter.filterValue);
1953
- return (obj) => filters.every(f => f(obj));
1954
- },
1955
- [FilterType.In]: (filter) => {
1956
- const filters = createFilterFuncs(filter.filterValue);
1957
- return (obj) => filters.some(f => f(obj));
1958
- },
1959
- };
1960
- const filterTypeFuncMap = {
1961
- [FieldType.Array]: StringFilterFuncs,
1962
- [FieldType.Boolean]: BooleanFilterFuncs,
1963
- [FieldType.Currency]: NumberFilterFuncs,
1964
- [FieldType.Date]: DateFilterFuncs,
1965
- [FieldType.DateTime]: DateTimeFilterFuncs,
1966
- [FieldType.Enum]: EnumFilterFuncs,
1967
- [FieldType.Link]: StringFilterFuncs,
1968
- [FieldType.Number]: NumberFilterFuncs,
1969
- [FieldType.PhoneNumber]: StringFilterFuncs,
1970
- [FieldType.String]: StringFilterFuncs,
1971
- [FieldType.Unknown]: StringFilterFuncs,
1972
- };
1973
- const filterTypeMap = Object.entries(filterTypeFuncMap).reduce((acc, [key, value]) => ({ ...acc, [key]: Object.keys(value) }), {});
1974
- function isCustomFilter(filter) {
1975
- return filter && filter.filterType === FilterType.Custom;
1976
- }
1977
- function isFilterInfo(filter) {
1978
- return filter && typeof filter.key === 'string' && filter.filterType !== FilterType.Custom;
1979
- }
1980
- const defaultPredicate = () => true;
1981
- function createFilterFuncs(filters) {
1982
- return filters.filter(needsFilterCreation).map(createFilterFunc);
1983
- }
1984
- function needsFilterCreation(filter) {
1985
- if (isCustomFilter(filter)) {
1986
- return filter.active !== false;
1987
- }
1988
- return filter.filterValue != undefined && filter.active !== false;
1989
- }
1990
- function createFilterFunc(filter) {
1991
- if (isCustomFilter(filter)) {
1992
- return filter.active ? filter.predicate : defaultPredicate;
1993
- }
1994
- if (filter.filterValue == undefined) {
1995
- return defaultPredicate;
1779
+ class ClickSubjectDirective extends Subject {
1780
+ constructor() {
1781
+ super();
1996
1782
  }
1997
- const func = filterTypeFuncMap[filter.fieldType][filter.filterType](filter);
1998
- if (!func) {
1999
- if (filterFactoryMap[filter.filterType]) {
2000
- return filterFactoryMap[filter.filterType](filter);
2001
- }
1783
+ set clickSubject(val) {
1784
+ this._val = val;
2002
1785
  }
2003
- const cannotBeTrueForNull = !FalseyValueCanBeIncludedFilterTypes.includes(filter.filterType);
2004
- const getter = filter.filterBy || getFactory(filter.key);
2005
- return (rowObj) => {
2006
- const value = getter(rowObj);
2007
- return ((value == undefined) && cannotBeTrueForNull)
2008
- ? false
2009
- : func(value);
2010
- };
1786
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.3", ngImport: i0, type: ClickSubjectDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
1787
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.0.3", type: ClickSubjectDirective, isStandalone: true, selector: "[clickSubject]", inputs: { clickSubject: "clickSubject" }, host: { listeners: { "click": "next(this._val)" } }, exportAs: ["clickSubject"], usesInheritance: true, ngImport: i0 }); }
2011
1788
  }
2012
- const FalseyValueCanBeIncludedFilterTypes = [
2013
- FilterType.IsNull,
2014
- FilterType.NumberNotEqual,
2015
- FilterType.DateIsNotOn,
2016
- FilterType.StringDoesNotContain,
2017
- ];
1789
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.3", ngImport: i0, type: ClickSubjectDirective, decorators: [{
1790
+ type: Directive,
1791
+ args: [{
1792
+ selector: '[clickSubject]',
1793
+ exportAs: 'clickSubject',
1794
+ host: {
1795
+ '(click)': 'next(this._val)'
1796
+ },
1797
+ }]
1798
+ }], ctorParameters: () => [], propDecorators: { clickSubject: [{
1799
+ type: Input,
1800
+ args: ['clickSubject']
1801
+ }] } });
2018
1802
 
2019
- const replaceInArrayWithClone = (arr, findMeth, actionOnClone = ((t) => { })) => {
2020
- const index = arr.findIndex(findMeth);
2021
- const clonedArray = [...arr];
2022
- const t = clonedArray[index];
2023
- clonedArray[index] =
2024
- t != null && typeof t === 'object' ?
2025
- Array.isArray(t) ?
2026
- [...t]
2027
- : { ...t }
2028
- : t;
2029
- actionOnClone(clonedArray[index]);
2030
- return clonedArray;
2031
- };
1803
+ class ClickEmitterDirective extends Subject {
1804
+ constructor() {
1805
+ super();
1806
+ }
1807
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.3", ngImport: i0, type: ClickEmitterDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
1808
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.0.3", type: ClickEmitterDirective, isStandalone: true, selector: "[clickEmitter]", host: { listeners: { "click": "next(true)" } }, exportAs: ["clickEmitter"], usesInheritance: true, ngImport: i0 }); }
1809
+ }
1810
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.3", ngImport: i0, type: ClickEmitterDirective, decorators: [{
1811
+ type: Directive,
1812
+ args: [{
1813
+ selector: '[clickEmitter]',
1814
+ exportAs: 'clickEmitter',
1815
+ host: {
1816
+ '(click)': 'next(true)'
1817
+ },
1818
+ }]
1819
+ }], ctorParameters: () => [] });
2032
1820
 
2033
- const orderedStateVisibleMetaData = (state) => {
2034
- const ordered = orderStateMetaData(state);
2035
- const orderedVisible = ordered
2036
- .filter(metaData => !state.hiddenKeys.includes(metaData.key) && state.metaData[metaData.key].fieldType !== FieldType.Hidden);
2037
- return orderedVisible;
2038
- };
2039
- const orderedCodeVisibleMetaData = (state) => orderStateMetaData(state).filter(md => md.fieldType !== FieldType.Hidden);
2040
- const orderStateMetaData = (state) => {
2041
- return orderMetaData(state.metaData, state.userDefined.order);
2042
- };
2043
- const orderMetaData = (metaData, userDefined) => {
2044
- const userOrderArr = Object.entries(userDefined);
2045
- return userOrderArr.length ?
2046
- Object.values(metaData).sort((a, b) => {
2047
- const orderA = userDefined[a.key];
2048
- const orderB = userDefined[b.key];
2049
- return order(orderA, orderB);
2050
- })
2051
- :
2052
- Object.values(metaData).sort((a, b) => {
2053
- const orderA = a.order;
2054
- const orderB = b.order;
2055
- return order(orderA, orderB);
2056
- });
2057
- };
2058
- function order(orderA, orderB) {
2059
- if (orderA == null && orderB == null) {
2060
- return 0;
1821
+ class DialogService {
1822
+ constructor() {
1823
+ this.allOpenOpDialogs = [];
2061
1824
  }
2062
- if (orderA == null) {
2063
- return 1;
1825
+ addDialogRef(ref) {
1826
+ this.allOpenOpDialogs.push(ref);
2064
1827
  }
2065
- if (orderB == null) {
2066
- return -1;
1828
+ removeDialogRef(ref) {
1829
+ this.allOpenOpDialogs = this.allOpenOpDialogs.filter(rf => ref.id !== rf.id);
2067
1830
  }
2068
- return orderA - orderB;
2069
- }
2070
- function cleanPersistedState(state, pState) {
2071
- const metas = Object.values(state.metaData);
2072
- const filters = Object.values(pState.filters).filter(fltr => isCustomFilter(fltr) || metas.some(m => m.key === fltr.key)).reduce((obj, filter) => {
2073
- obj[filter.filterId] = pState.filters[filter.filterId];
2074
- return obj;
2075
- }, {});
2076
- const sorted = pState.sorted.filter(s => metas.some(m => m.key === s.active));
2077
- return ({ ...pState, filters, sorted });
2078
- }
2079
- const mapSaveableState = (s) => {
2080
- const savableState = { ...s };
2081
- keysToDelete.forEach(key => delete savableState[key]);
2082
- return savableState;
2083
- };
2084
- const createPreSort = (metaDatas) => {
2085
- return Object.values(metaDatas).filter((metaData) => !!metaData.preSort)
2086
- .sort(({ preSort: ps1 }, { preSort: ps2 }) => (ps1.precedence || Number.MAX_VALUE) - (ps2.precedence || Number.MAX_VALUE))
2087
- .map(({ key, preSort: { direction } }) => ({ active: key, direction }));
2088
- };
2089
- const mergeMeta = (orig, merge) => {
2090
- return {
2091
- key: orig.key,
2092
- displayName: merge.displayName ?? orig.displayName,
2093
- fieldType: merge.fieldType || orig.fieldType,
2094
- additional: { ...orig.additional, ...merge.additional },
2095
- order: merge.order ?? orig.order,
2096
- preSort: merge.preSort ?? orig.preSort,
2097
- width: merge.width ?? orig.width,
2098
- noExport: merge.noExport || orig.noExport,
2099
- noFilter: merge.noFilter || orig.noFilter,
2100
- customCell: merge.customCell ?? orig.customCell,
2101
- transform: merge.transform ?? orig.transform,
2102
- map: merge.map ?? orig.map,
2103
- click: merge.click ?? orig.click,
2104
- classes: merge.classes ?? orig.classes,
2105
- noSort: merge.noSort ?? orig.noSort,
2106
- template: merge.template ?? orig.template,
2107
- toolTip: merge.toolTip ?? orig.toolTip,
2108
- useIcon: merge.useIcon ?? orig.useIcon,
2109
- filterLogic: merge.filterLogic ?? orig.filterLogic,
2110
- sortLogic: merge.sortLogic ?? orig.sortLogic,
2111
- groupByLogic: merge.groupByLogic ?? orig.groupByLogic,
2112
- };
2113
- };
2114
- const initializeOrder = (state, mds) => {
2115
- const viewableMetaDataArr = Object.values(mds).filter(a => a.fieldType !== FieldType.Hidden);
2116
- let userDefinedOrder = state.userDefined.order;
2117
- if (viewableMetaDataArr.some(meta => userDefinedOrder[meta.key] == null)) {
2118
- return {};
1831
+ closeAllOpDialogs() {
1832
+ this.allOpenOpDialogs.forEach(ref => ref.close());
2119
1833
  }
2120
- return userDefinedOrder;
2121
- };
1834
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.3", ngImport: i0, type: DialogService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
1835
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.0.3", ngImport: i0, type: DialogService, providedIn: 'root' }); }
1836
+ }
1837
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.3", ngImport: i0, type: DialogService, decorators: [{
1838
+ type: Injectable,
1839
+ args: [{ providedIn: 'root' }]
1840
+ }] });
2122
1841
 
2123
- class TableStore extends ComponentStore {
1842
+ class DialogWrapper {
2124
1843
  constructor() {
2125
- const config = inject(TableBuilderConfigToken);
2126
- const settingsFromConfig = {
2127
- persistedTableSettings: new PersistedTableSettings().merge(config.defaultTableSettings),
2128
- notPersistedTableSettings: new NotPersistedTableSettings().merge(config.defaultTableSettings),
1844
+ this.vcr = inject(ViewContainerRef);
1845
+ this.viewEmbedded = false;
1846
+ this.viewContext = {
1847
+ close: () => { },
2129
1848
  };
2130
- if (config.defaultTableSettings?.pageSize) {
2131
- settingsFromConfig.notPersistedTableSettings.paginatorSettings.pageSize = config.defaultTableSettings?.pageSize;
1849
+ }
1850
+ set template(tmpl) {
1851
+ if (this.viewEmbedded) {
1852
+ this.vcr.clear();
2132
1853
  }
2133
- const pageSize = settingsFromConfig.notPersistedTableSettings.paginatorSettings.pageSize || defaultTableState.pageSize;
2134
- const showAll = settingsFromConfig.notPersistedTableSettings.paginatorSettings.defaultAll || defaultTableState.showAll;
2135
- super({ ...defaultTableState, ...settingsFromConfig, pageSize, showAll });
2136
- this.$initializationState = this.selectSignal(state => state.initializationState);
2137
- this.$savableState = computed(() => {
2138
- const state = this.state();
2139
- return mapSaveableState(state);
2140
- });
2141
- this.$userDefinedOrder = this.selectSignal(state => state.userDefined.order);
2142
- this.metaData$ = this.select(state => state.metaData);
2143
- this.$metaData = this.selectSignal(state => state.metaData);
2144
- this.$metaDataArray = this.selectSignal(this.$metaData, this.$userDefinedOrder, orderMetaData);
2145
- this.$orderedCodeVisibleMetaDatas = this.selectSignal(this.$metaDataArray, (mds) => mds.filter(m => m.fieldType !== FieldType.Hidden), { equal: (a, b) => b.length === a.length && b.every((s, i) => a[i].key === s.key) });
2146
- this.$getMetaData = (key) => computed(() => {
2147
- const metaData = this.state().metaData[key];
2148
- if (!metaData)
2149
- console.warn(`Meta data with key ${key} not found`);
2150
- return metaData;
2151
- });
2152
- this.$hiddenKeys = this.selectSignal(state => state.hiddenKeys);
2153
- this.$orderedVisibleColumns = this.selectSignal(this.$orderedCodeVisibleMetaDatas, this.$hiddenKeys, (cs, hiddenKeys) => cs.filter(m => !hiddenKeys.includes(m.key)).map(m => m.key));
2154
- this.$getUserDefinedWidths = this.selectSignal(state => state.userDefined.widths);
2155
- this.$tableSettingsMinWidth = this.selectSignal(state => parseTbSizeToPixels(state.notPersistedTableSettings.minColumnWidth));
2156
- this.$getUserDefinedWidth = (key) => this.selectSignal(this.$getUserDefinedWidths, widths => widths[key]);
2157
- this.$filters = this.selectSignal(state => state.filters);
2158
- this.filters$ = this.select(state => state.filters);
2159
- this.$getFilter = (filterId) => {
2160
- return this.selectSignal(this.$filters, filters => filters[filterId]);
1854
+ this.viewEmbedded = true;
1855
+ this.vcr.createEmbeddedView(tmpl, this.viewContext);
1856
+ }
1857
+ set close(closeMethod) {
1858
+ this.viewContext.close = closeMethod;
1859
+ }
1860
+ set data(value) {
1861
+ this.viewContext.$implicit = value;
1862
+ this.viewContext.opDialog = value;
1863
+ }
1864
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.3", ngImport: i0, type: DialogWrapper, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1865
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.0.3", type: DialogWrapper, isStandalone: true, selector: "dialog-wrapper", ngImport: i0, template: ``, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1866
+ }
1867
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.3", ngImport: i0, type: DialogWrapper, decorators: [{
1868
+ type: Component,
1869
+ args: [{
1870
+ selector: 'dialog-wrapper',
1871
+ template: ``,
1872
+ changeDetection: ChangeDetectionStrategy.OnPush,
1873
+ }]
1874
+ }] });
1875
+ const defaultDialogConfig = {
1876
+ maxHeight: '95vh',
1877
+ };
1878
+ class DialogDirective {
1879
+ constructor() {
1880
+ this.templateRef = inject(TemplateRef);
1881
+ this.dialog = inject(MatDialog);
1882
+ this.dialogConfig = inject(MAT_DIALOG_DEFAULT_OPTIONS, { optional: true }) || {};
1883
+ this.service = inject(DialogService);
1884
+ this.opDialogClosed = new EventEmitter();
1885
+ this._dialogConfig = { ...this.dialogConfig, ...defaultDialogConfig };
1886
+ this.opDialogAddDialogClass = true;
1887
+ this.injector = inject(Injector);
1888
+ this.subscriber = subscriber(this.injector);
1889
+ this._data = new Subject();
1890
+ this.setDataAndState = (data) => {
1891
+ if (data) {
1892
+ this.opDialogConfig.data = data;
1893
+ this.setDialogState(true);
1894
+ }
1895
+ else {
1896
+ this.setDialogState(false);
1897
+ }
2161
1898
  };
2162
- this.$preSort = computed(() => createPreSort(this.$metaData()));
2163
- this._$selectSorted = this.selectSignal(state => state.sorted, {
2164
- equal: sortsAreSame
2165
- });
2166
- this.$selectSorted = computed(() => {
2167
- const metaDict = this.$metaData();
2168
- return this._$selectSorted().map(s => {
2169
- const meta = metaDict[s.active];
2170
- const sortLogic = meta.sortLogic;
2171
- const sortBy = sortLogic?.sortBy === 'use map' ? meta.map : sortLogic?.sortBy;
2172
- return ({ ...s, ...sortLogic, sortBy });
2173
- });
2174
- });
2175
- this.selectSorted$ = this.select(state => state.sorted).pipe(distinctUntilChanged(sortsAreSame));
2176
- this.$getSorts = this.selectSignal(() => this.$initializationState() !== InitializationState.Ready ? [] : this.$selectSorted());
2177
- this.sort$ = toObservable(this.$getSorts);
2178
- this.$getUserDefinedTableWidth = this.selectSignal(state => state.userDefined.table.width);
2179
- this.getUserDefinedTableWidth$ = this.select(state => state.userDefined.table.width);
2180
- this.$userDefinedRowHeight = this.selectSignal(state => (state.userDefined.rowHeight));
2181
- this.$userDefinedHeaderHeight = this.selectSignal(state => (state.userDefined.headerHeight));
2182
- this.$userDefinedPageSize = this.selectSignal(state => (state.userDefined.pageSize));
2183
- this.$footerCollapsed = this.selectSignal(state => state.persistedTableSettings.collapseFooter);
2184
- this.$headerCollapsed = this.selectSignal(state => state.persistedTableSettings.collapseHeader);
2185
- this.$groupBy = this.selectSignal(state => state.groupBy);
2186
- this.$groupByKeys = this.selectSignal(this.$groupBy, this.$metaDataArray, (gb, mds) => gb.map(gbk => gbk.key).filter(bg => mds.some(md => md.key === bg)), {
2187
- equal: (prev, curr) => prev.length === curr.length && curr.every((k, i) => prev[i] === k)
1899
+ }
1900
+ set opDialogConfig(config) {
1901
+ this._dialogConfig = { ...this.dialogConfig, ...defaultDialogConfig, ...config };
1902
+ }
1903
+ get opDialogConfig() {
1904
+ return this._dialogConfig;
1905
+ }
1906
+ set setControl(i) {
1907
+ let o;
1908
+ if (isSignal(i)) {
1909
+ o = toObservable(i, { injector: this.injector });
1910
+ }
1911
+ else {
1912
+ o = i;
1913
+ }
1914
+ untracked(() => {
1915
+ this.subscriber.on(o, this.setDataAndState);
2188
1916
  });
2189
- this.groupByKeys$ = this.select(state => state.groupBy.map(gbk => gbk.key))
2190
- .pipe(distinctUntilChanged((prev, curr) => prev.length === curr.length && curr.every((k, i) => prev[i] === k)));
2191
- this.expandedGroups$ = this.select(state => state.groupBy).pipe(distinctUntilChanged((a, b) => {
2192
- const aa = a.flatMap(g => g.expandedHeaders);
2193
- const bb = b.flatMap(g => g.expandedHeaders);
2194
- return aa.length === bb.length && aa.every((k) => bb.includes(k));
2195
- }));
2196
- this.$expandGroups = this.selectSignal(state => state.groupBy, { equal: (a, b) => {
2197
- const aa = a.flatMap(g => g.expandedHeaders);
2198
- const bb = b.flatMap(g => g.expandedHeaders);
2199
- return aa.length === bb.length && aa.every((k) => bb.includes(k));
2200
- } });
2201
- this.$getIsExpanded = (columnKey, groupUniqueName) => {
2202
- return this.selectSignal(state => !!state.groupBy.filter(g => g.key === columnKey && g.expandedHeaders.includes(groupUniqueName)).length);
2203
- };
2204
- this.$currentPage = this.selectSignal(state => state.currentPage);
2205
- this.$pageSize = this.selectSignal(s => s.userDefined?.pageSize || s.pageSize);
2206
- this.$showAll = this.selectSignal(s => s.userDefined?.showAll ?? s.showAll);
2207
- this.$tableSettings = this.selectSignal(state => {
2208
- const ts = { ...state.persistedTableSettings, ...state.notPersistedTableSettings };
2209
- return ts;
1917
+ }
1918
+ close() {
1919
+ this.dialogRef?.close();
1920
+ }
1921
+ initDialog() {
1922
+ if (this.nativeElement) {
1923
+ const rect = this.nativeElement.getBoundingClientRect();
1924
+ const position = { left: `${rect.left}px`, top: `${rect.bottom - 50}px` };
1925
+ this.opDialogConfig = { ...this.opDialogConfig, position };
1926
+ }
1927
+ if (this.opDialogAddDialogClass) {
1928
+ this.opDialogConfig.panelClass = [...(Array.isArray(this.opDialogConfig.panelClass) ? this.opDialogConfig.panelClass : this.opDialogConfig.panelClass ? [this.opDialogConfig.panelClass] : []), 'opDialog'];
1929
+ }
1930
+ this.dialogRef = this.dialog.open(DialogWrapper, this.opDialogConfig);
1931
+ this.componentWrapper = this.dialogRef.componentInstance;
1932
+ this.componentWrapper.close = () => this.dialogRef?.close();
1933
+ this.componentWrapper.data = this.opDialogConfig.data;
1934
+ this.componentWrapper.template = this.templateRef;
1935
+ if (!this.opDialogConfig.disableClose) {
1936
+ this.service.addDialogRef(this.dialogRef);
1937
+ }
1938
+ const sub = this.dialogRef.afterClosed().subscribe(() => {
1939
+ this.opDialogClosed.emit(true);
1940
+ this.service.removeDialogRef(this.dialogRef);
1941
+ this.dialogRef = undefined;
1942
+ sub.unsubscribe();
2210
1943
  });
2211
- this.$notPersistedTableSettings = this.selectSignal(state => state.notPersistedTableSettings);
2212
- this.tableSettings$ = toObservable(this.$tableSettings);
2213
- this.$props = this.selectSignal(s => s.props);
2214
- this.$getLinkInfo = (md) => this.selectSignal(state => state.linkMaps[md.key]);
2215
- this.$isVirtual = this.selectSignal(state => state.notPersistedTableSettings.useVirtualScroll
2216
- || state.showAll
2217
- || state.userDefined?.showAll);
2218
- this.$viewType = this.selectSignal(state => {
2219
- const usePaginator = state.notPersistedTableSettings.usePaginator;
2220
- const showAll = state.showAll || state.userDefined?.showAll;
2221
- const useVirtualScroll = state.notPersistedTableSettings.useVirtualScroll;
2222
- if (showAll || (useVirtualScroll && !usePaginator)) {
2223
- return 'virtual all';
2224
- }
2225
- else if (useVirtualScroll && usePaginator) {
2226
- return 'virtual paginator';
2227
- }
2228
- else if (usePaginator) {
2229
- return 'paginator';
1944
+ }
1945
+ setDialogState(open) {
1946
+ if (open) {
1947
+ if (!this.dialogRef) {
1948
+ this.initDialog();
2230
1949
  }
2231
1950
  else {
2232
- return 'all';
1951
+ this.componentWrapper.data = this.opDialogConfig.data;
2233
1952
  }
1953
+ }
1954
+ else if (!open && this.dialogRef) {
1955
+ this.dialogRef.close();
1956
+ }
1957
+ }
1958
+ static ngTemplateContextGuard(dir, ctx) {
1959
+ return true;
1960
+ }
1961
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.3", ngImport: i0, type: DialogDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
1962
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.0.3", type: DialogDirective, isStandalone: true, selector: "[opDialog]", inputs: { opDialogAddDialogClass: "opDialogAddDialogClass", opDialogConfig: "opDialogConfig", setControl: ["opDialog", "setControl"], nativeElement: ["opDialogOrigin", "nativeElement"] }, outputs: { opDialogClosed: "opDialogClosed" }, ngImport: i0 }); }
1963
+ }
1964
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.3", ngImport: i0, type: DialogDirective, decorators: [{
1965
+ type: Directive,
1966
+ args: [{ selector: '[opDialog]', }]
1967
+ }], propDecorators: { opDialogClosed: [{
1968
+ type: Output
1969
+ }], opDialogAddDialogClass: [{
1970
+ type: Input
1971
+ }], opDialogConfig: [{
1972
+ type: Input
1973
+ }], setControl: [{
1974
+ type: Input,
1975
+ args: ['opDialog']
1976
+ }], nativeElement: [{
1977
+ type: Input,
1978
+ args: ['opDialogOrigin']
1979
+ }] } });
1980
+
1981
+ class StylerDirective {
1982
+ constructor() {
1983
+ this.el = inject(ElementRef);
1984
+ this.renderer = inject(Renderer2);
1985
+ this.$stylesApplied = signal({});
1986
+ this.$element = input.required({ alias: 'element' });
1987
+ this.$styler = input.required({ alias: 'styler' });
1988
+ this.#stylerEffect = effect(() => {
1989
+ const styles = this.$styler();
1990
+ untracked(() => {
1991
+ const element = this.$element();
1992
+ const toApply = Object.entries(styles ?? {}).reduce((acc, [key, val]) => {
1993
+ if (!val)
1994
+ return acc;
1995
+ if (typeof (val) === 'string') {
1996
+ acc[key] = val;
1997
+ this.el.nativeElement.style[key] = val;
1998
+ }
1999
+ else if (!val?.condition || val?.condition === true || val?.condition(element)) {
2000
+ const value = typeof (val.value) === 'string' ? val.value : val?.value(element);
2001
+ acc[key] = value;
2002
+ this.el.nativeElement.style[key] = value;
2003
+ }
2004
+ return acc;
2005
+ }, {});
2006
+ Object.keys(this.$stylesApplied()).filter(key => !Object.keys(toApply).includes(key)).forEach(key => {
2007
+ this.renderer.removeStyle(this.el.nativeElement, key);
2008
+ });
2009
+ this.$stylesApplied.set(toApply);
2010
+ });
2234
2011
  });
2235
- this.resetState = this.updater((state) => {
2236
- const sorted = this.$preSort();
2237
- return ({ ...state, hiddenKeys: [], sorted, filters: {}, groupBy: [], userDefined: { widths: {}, order: {}, table: {} } });
2238
- });
2239
- this.resetPart = this.updater((state, part) => {
2240
- const newState = { ...state };
2241
- switch (part) {
2242
- case 'Sorting':
2243
- newState.sorted = this.$preSort();
2244
- return newState;
2245
- case 'Filters':
2246
- newState.filters = {};
2247
- return newState;
2248
- case 'Group By':
2249
- newState.groupBy = [];
2250
- return newState;
2251
- case 'Hidden Columns':
2252
- newState.hiddenKeys = [];
2253
- return newState;
2254
- case 'Column Widths':
2255
- newState.userDefined.widths = {};
2256
- newState.userDefined.table = {};
2257
- return newState;
2258
- case 'Column Order':
2259
- newState.userDefined.order = {};
2260
- return newState;
2261
- case 'Page Size':
2262
- delete newState.userDefined.pageSize;
2263
- return newState;
2264
- case 'Show All':
2265
- delete newState.userDefined.showAll;
2266
- return newState;
2267
- case 'Row Height':
2268
- delete newState.userDefined.rowHeight;
2269
- return newState;
2270
- case 'Header Height':
2271
- delete newState.userDefined.headerHeight;
2272
- return newState;
2012
+ }
2013
+ #stylerEffect;
2014
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.3", ngImport: i0, type: StylerDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
2015
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "20.0.3", type: StylerDirective, isStandalone: true, selector: "[styler]", inputs: { $element: { classPropertyName: "$element", publicName: "element", isSignal: true, isRequired: true, transformFunction: null }, $styler: { classPropertyName: "$styler", publicName: "styler", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0 }); }
2016
+ }
2017
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.3", ngImport: i0, type: StylerDirective, decorators: [{
2018
+ type: Directive,
2019
+ args: [{ selector: '[styler]' }]
2020
+ }] });
2021
+
2022
+ class MatSlideToggleGroupDirective {
2023
+ constructor() {
2024
+ this.allowMultiple = false;
2025
+ this._ready = new ReplaySubject(1);
2026
+ }
2027
+ set toggles(val) {
2028
+ this._toggles = val;
2029
+ this._ready.next(true);
2030
+ }
2031
+ get valueEmitter() {
2032
+ return this._ready.pipe(switchMap$1(_ => this.getObs()));
2033
+ }
2034
+ getInitValue() {
2035
+ const startValue = this._toggles.reduce((prev, cur) => {
2036
+ if (!cur.name) {
2037
+ throw new Error('toggle must have the name attribute set');
2273
2038
  }
2274
- });
2275
- this.updateStateFromPersistedState = this.updater((state, persistedState) => {
2276
- const incomingTableState = cleanPersistedState(state, persistedState);
2277
- const newState = this.updateStateFunc(state, incomingTableState);
2278
- newState.initializationState = state.initializationState <= InitializationState.MetaDataLoaded ? InitializationState.TableSettingsLoaded : state.initializationState;
2279
- return newState;
2280
- });
2281
- this.updateStateFunc = (state, incomingTableState) => {
2282
- const metaData = state.metaData;
2283
- const sorted = incomingTableState.sorted?.length ? incomingTableState.sorted
2284
- : state.initializationState <= InitializationState.Created ? createPreSort(metaData) : state.sorted;
2285
- return { ...state, ...incomingTableState, metaData, sorted };
2286
- };
2287
- this.setTableSettings = this.updater((state, settings) => {
2288
- const s = {
2289
- ...state,
2290
- persistedTableSettings: state.persistedTableSettings.merge(settings),
2291
- notPersistedTableSettings: state.notPersistedTableSettings.merge(settings),
2292
- initializationState: InitializationState.TableSettingsLoaded
2293
- };
2294
- s.pageSize = settings.tableSettings?.paginatorSettings?.pageSize ?? s.pageSize;
2295
- s.showAll = settings.tableSettings?.paginatorSettings?.defaultAll ?? s.showAll;
2296
- return s;
2297
- });
2298
- this.setMetaData = this.updater((state, md) => {
2299
- const metaData = md
2300
- .reduce((prev, curr) => {
2301
- if (prev[curr.key]) {
2302
- prev[curr.key] = mergeMeta(prev[curr.key], curr);
2303
- }
2304
- else {
2305
- prev[curr.key] = curr;
2039
+ prev[cur.name] = cur.checked;
2040
+ return prev;
2041
+ }, {});
2042
+ return startValue;
2043
+ }
2044
+ getObs() {
2045
+ var toggleChanges = merge(...this._toggles.map(toggle => toggle.change));
2046
+ const startValue = this.getInitValue();
2047
+ return toggleChanges.pipe(scan((prev, cur) => {
2048
+ const toggleName = cur.source.name;
2049
+ const newVal = { ...prev, [toggleName]: cur.checked };
2050
+ if (cur.checked && !this.allowMultiple) {
2051
+ Object.keys(prev)
2052
+ .filter(key => key !== toggleName && prev[key])
2053
+ .forEach(key => {
2054
+ newVal[key] = false;
2055
+ this._toggles.find(toggle => toggle.name === key).toggle();
2056
+ });
2057
+ }
2058
+ return newVal;
2059
+ }, startValue), startWith$1(startValue));
2060
+ }
2061
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.3", ngImport: i0, type: MatSlideToggleGroupDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
2062
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.0.3", type: MatSlideToggleGroupDirective, isStandalone: true, selector: "[opMatSlideToggleGroup]", inputs: { allowMultiple: "allowMultiple" }, outputs: { valueEmitter: "valueEmitter" }, queries: [{ propertyName: "toggles", predicate: MatSlideToggle }], ngImport: i0 }); }
2063
+ }
2064
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.3", ngImport: i0, type: MatSlideToggleGroupDirective, decorators: [{
2065
+ type: Directive,
2066
+ args: [{ selector: '[opMatSlideToggleGroup]',
2067
+ }]
2068
+ }], propDecorators: { allowMultiple: [{
2069
+ type: Input
2070
+ }], toggles: [{
2071
+ type: ContentChildren,
2072
+ args: [MatSlideToggle]
2073
+ }], valueEmitter: [{
2074
+ type: Output
2075
+ }] } });
2076
+
2077
+ class TrimWhitespaceDirective {
2078
+ constructor() {
2079
+ this.elem = inject(ElementRef);
2080
+ }
2081
+ onBlur() {
2082
+ const inputString = this.elem.nativeElement.value;
2083
+ if (inputString) {
2084
+ const newValue = inputString.trim().replace(/\t/g, '');
2085
+ if (inputString !== newValue) {
2086
+ this.elem.nativeElement.value = newValue;
2087
+ this.elem.nativeElement.dispatchEvent(new Event('input', { bubbles: true }));
2088
+ }
2089
+ }
2090
+ }
2091
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.3", ngImport: i0, type: TrimWhitespaceDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
2092
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.0.3", type: TrimWhitespaceDirective, isStandalone: true, selector: "input[trimWhitespace]", host: { listeners: { "blur": "onBlur()" } }, ngImport: i0 }); }
2093
+ }
2094
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.3", ngImport: i0, type: TrimWhitespaceDirective, decorators: [{
2095
+ type: Directive,
2096
+ args: [{
2097
+ selector: 'input[trimWhitespace]',
2098
+ }]
2099
+ }], propDecorators: { onBlur: [{
2100
+ type: HostListener,
2101
+ args: ['blur']
2102
+ }] } });
2103
+
2104
+ class FunctionPipe {
2105
+ transform(func, ...args) {
2106
+ if (typeof func === 'string') {
2107
+ const [instance, ...tail] = args;
2108
+ const method = instance[func].bind(instance);
2109
+ return method(...tail);
2110
+ }
2111
+ return func(...args);
2112
+ }
2113
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.3", ngImport: i0, type: FunctionPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); }
2114
+ static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "20.0.3", ngImport: i0, type: FunctionPipe, isStandalone: true, name: "func" }); }
2115
+ }
2116
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.3", ngImport: i0, type: FunctionPipe, decorators: [{
2117
+ type: Pipe,
2118
+ args: [{
2119
+ name: 'func',
2120
+ }]
2121
+ }] });
2122
+
2123
+ class ConditionalClassesDirective {
2124
+ constructor() {
2125
+ this.el = inject(ElementRef);
2126
+ this.renderer = inject(Renderer2);
2127
+ this.$element = input.required({ alias: 'element' });
2128
+ this.$classes = input(undefined, { alias: 'conditionalClasses' });
2129
+ this.classesApplied = [];
2130
+ this.#onClasses = effect(() => {
2131
+ const classes = this.$classes();
2132
+ untracked(() => {
2133
+ const element = this.$element();
2134
+ let toApply = [];
2135
+ if (classes) {
2136
+ toApply = Object.keys(classes)
2137
+ .filter(key => (classes[key] === true) || classes[key](element));
2306
2138
  }
2307
- return prev;
2308
- }, {});
2309
- const sortedInitialized = state.sorted.length > 0;
2310
- const sorted = sortedInitialized ? state.sorted : createPreSort(metaData);
2311
- const order = initializeOrder(state, metaData);
2312
- const initializationState = state.initializationState == InitializationState.Created ? InitializationState.MetaDataLoaded : state.initializationState;
2313
- return { ...state, initializationState, metaData, sorted, userDefined: { ...state.userDefined, order: order } };
2314
- });
2315
- this.showColumn = this.updater((state, key) => ({
2316
- ...state,
2317
- hiddenKeys: state.hiddenKeys.filter(k => k !== key),
2318
- }));
2319
- this.hideColumn = this.updater((state, key) => ({
2320
- ...state,
2321
- hiddenKeys: [...state.hiddenKeys.filter(k => k !== key), key],
2322
- }));
2323
- this.setHiddenColumns = this.updater((state, displayCols) => {
2324
- return ({ ...state, hiddenKeys: displayCols.filter(d => !d.visible).map(d => d.key) });
2325
- });
2326
- this.setUserDefinedWidth = this.updater((state, colWidths) => {
2327
- const userDefinedWidths = { ...state.userDefined.widths };
2328
- colWidths.forEach(cw => {
2329
- userDefinedWidths[cw.key] = cw.widthInPixel;
2139
+ var classesNotYetApplied = toApply.filter(c => !this.classesApplied.includes(c));
2140
+ var classesToRemove = this.classesApplied.filter(c => !toApply.includes(c));
2141
+ classesToRemove.forEach(c => this.renderer.removeClass(this.el.nativeElement, c));
2142
+ classesNotYetApplied.forEach(c => this.renderer.addClass(this.el.nativeElement, c));
2143
+ this.classesApplied = toApply;
2330
2144
  });
2331
- return { ...state, userDefined: { ...state.userDefined, widths: userDefinedWidths } };
2332
- });
2333
- this.setUserDefinedOrder = this.updater((state, moved) => {
2334
- const { newOrder, oldOrder } = moved;
2335
- const mdsArr = orderedStateVisibleMetaData(state);
2336
- moveItemInArray(mdsArr, oldOrder, newOrder);
2337
- const userDefinedOrder = mdsArr.reduce((aggregate, current, index) => {
2338
- aggregate[current.key] = index;
2339
- return aggregate;
2340
- }, {});
2341
- return ({ ...state, userDefined: { ...state.userDefined, order: userDefinedOrder } });
2342
- });
2343
- this.setUserDefinedRowHeight = this.updater((state, rowHeight) => {
2344
- return ({ ...state, userDefined: { ...state.userDefined, rowHeight } });
2345
- });
2346
- this.setUserDefinedHeaderHeight = this.updater((state, headerHeight) => {
2347
- return ({ ...state, userDefined: { ...state.userDefined, headerHeight } });
2348
- });
2349
- this.addFilter = this.updater((state, filter) => {
2350
- return this.addFiltersToState(state, [filter]);
2351
- });
2352
- this.addFilters = this.updater((state, filters) => {
2353
- return this.addFiltersToState(state, filters);
2354
- });
2355
- this.removeFilter = this.updater((state, filterId) => {
2356
- const filtersCopy = { ...state.filters };
2357
- delete filtersCopy[filterId];
2358
- return ({ ...state, filters: filtersCopy });
2359
- });
2360
- this.removeFilters = this.updater((state, filterIds) => {
2361
- const filtersCopy = { ...state.filters };
2362
- filterIds.forEach(id => { delete filtersCopy[id]; });
2363
- return ({ ...state, filters: filtersCopy });
2364
2145
  });
2365
- this.clearFilters = this.updater((state) => ({ ...state, filters: {} }));
2366
- this.addFiltersToState = (state, filters) => {
2367
- var customFilters = filters.filter(isCustomFilter);
2368
- var filterInfos = filters.filter(isFilterInfo);
2369
- const filtersObj = filterInfos
2370
- .filter(fltr => Object.keys(state.metaData).some(key => key === fltr.key) || console.warn(`Meta data with key ${fltr.key} not found`))
2371
- .reduce((filtersObj, filter) => {
2372
- if (!filter.filterId) {
2373
- filter.filterId = crypto.randomUUID();
2374
- }
2375
- filtersObj[filter.filterId] = filter;
2376
- return filtersObj;
2377
- }, {});
2378
- customFilters.forEach(fltr => {
2379
- if (!fltr.filterId) {
2380
- fltr.filterId = crypto.randomUUID();
2381
- }
2382
- filtersObj[fltr.filterId] = fltr;
2383
- });
2384
- return {
2385
- ...state,
2386
- filters: { ...state.filters, ...filtersObj }
2387
- };
2146
+ }
2147
+ #onClasses;
2148
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.3", ngImport: i0, type: ConditionalClassesDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
2149
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "20.0.3", type: ConditionalClassesDirective, isStandalone: true, selector: "[conditionalClasses]", inputs: { $element: { classPropertyName: "$element", publicName: "element", isSignal: true, isRequired: true, transformFunction: null }, $classes: { classPropertyName: "$classes", publicName: "conditionalClasses", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0 }); }
2150
+ }
2151
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.3", ngImport: i0, type: ConditionalClassesDirective, decorators: [{
2152
+ type: Directive,
2153
+ args: [{
2154
+ selector: '[conditionalClasses]',
2155
+ }]
2156
+ }] });
2157
+
2158
+ class UtilitiesModule {
2159
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.3", ngImport: i0, type: UtilitiesModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
2160
+ static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.0.3", ngImport: i0, type: UtilitiesModule, imports: [SpaceCasePipe,
2161
+ PhoneNumberPipe,
2162
+ FunctionPipe,
2163
+ StopPropagationDirective,
2164
+ StylerDirective,
2165
+ PreventEnterDirective,
2166
+ AutoFocusDirective,
2167
+ TrimWhitespaceDirective,
2168
+ ClickSubjectDirective,
2169
+ ClickEmitterDirective,
2170
+ DialogDirective,
2171
+ MatSlideToggleGroupDirective,
2172
+ ConditionalClassesDirective], exports: [StopPropagationDirective,
2173
+ PreventEnterDirective,
2174
+ SpaceCasePipe,
2175
+ PhoneNumberPipe,
2176
+ FunctionPipe,
2177
+ TrimWhitespaceDirective,
2178
+ StylerDirective,
2179
+ AutoFocusDirective,
2180
+ ClickSubjectDirective,
2181
+ ClickEmitterDirective,
2182
+ DialogDirective,
2183
+ MatSlideToggleGroupDirective,
2184
+ ConditionalClassesDirective] }); }
2185
+ static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.0.3", ngImport: i0, type: UtilitiesModule, providers: [
2186
+ DialogService
2187
+ ] }); }
2188
+ }
2189
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.3", ngImport: i0, type: UtilitiesModule, decorators: [{
2190
+ type: NgModule,
2191
+ args: [{
2192
+ exports: [
2193
+ StopPropagationDirective,
2194
+ PreventEnterDirective,
2195
+ SpaceCasePipe,
2196
+ PhoneNumberPipe,
2197
+ FunctionPipe,
2198
+ TrimWhitespaceDirective,
2199
+ StylerDirective,
2200
+ AutoFocusDirective,
2201
+ ClickSubjectDirective,
2202
+ ClickEmitterDirective,
2203
+ DialogDirective,
2204
+ MatSlideToggleGroupDirective,
2205
+ ConditionalClassesDirective,
2206
+ ],
2207
+ imports: [
2208
+ SpaceCasePipe,
2209
+ PhoneNumberPipe,
2210
+ FunctionPipe,
2211
+ StopPropagationDirective,
2212
+ StylerDirective,
2213
+ PreventEnterDirective,
2214
+ AutoFocusDirective,
2215
+ TrimWhitespaceDirective,
2216
+ ClickSubjectDirective,
2217
+ ClickEmitterDirective,
2218
+ DialogDirective,
2219
+ MatSlideToggleGroupDirective,
2220
+ ConditionalClassesDirective,
2221
+ ],
2222
+ providers: [
2223
+ DialogService
2224
+ ]
2225
+ }]
2226
+ }] });
2227
+
2228
+ function sortData(data, sorted) {
2229
+ return data.sort(compareT(sorted));
2230
+ }
2231
+ function filterData(data, filters, resetAll = false) {
2232
+ if (filters.length === 0) {
2233
+ if (resetAll) {
2234
+ for (let index = 0; index < data.length; index++) {
2235
+ const element = data[index];
2236
+ element[tbNoShowSymbol] = false;
2237
+ }
2238
+ }
2239
+ return data;
2240
+ }
2241
+ for (let index = 0; index < data.length; index++) {
2242
+ const element = data[index];
2243
+ const hide = !filters.every(filter => filter(element));
2244
+ if (hide || resetAll) {
2245
+ element[tbNoShowSymbol] = hide;
2246
+ }
2247
+ }
2248
+ return data;
2249
+ }
2250
+ const tbNoShowSymbol = Symbol('tb_no_show');
2251
+ function compareT(criteria) {
2252
+ const transforms = criteria.reduce((acc, c) => {
2253
+ acc[c.active] = {
2254
+ transform: c.sortBy ? c.sortBy : getFactory(c.active), nulls: c.nulls === 'first' ? -1 : 1
2388
2255
  };
2389
- this.setSort = this.updater((state, { key, direction }) => {
2390
- const sortArray = state.sorted.filter(s => s.active !== key);
2391
- if (direction) {
2392
- sortArray.unshift({ active: key, direction });
2256
+ return acc;
2257
+ }, {});
2258
+ return function (a, b) {
2259
+ for (let index = 0; index < criteria.length; index++) {
2260
+ const c = criteria[index];
2261
+ const d = transforms[c.active];
2262
+ const nullValue = d.nulls;
2263
+ if (a == null) {
2264
+ if (b == null)
2265
+ return 0;
2266
+ return nullValue;
2393
2267
  }
2394
- return {
2395
- ...state,
2396
- sorted: sortArray,
2397
- };
2398
- });
2399
- this.setAllSort = this.updater((state, sortArray) => {
2400
- return {
2401
- ...state,
2402
- sorted: sortArray,
2403
- };
2404
- });
2405
- this.setCurrentPage = this.updater((state, currentPage) => ({ ...state, currentPage }));
2406
- this.setPageSize = this.updater((state, pageSize) => ({ ...state, pageSize }));
2407
- this.setUserDefinedPageSize = this.updater((state, pageSize) => ({ ...state, userDefined: { ...state.userDefined, pageSize } }));
2408
- this.setUserDefinedShowAll = this.updater((state, showAll) => ({ ...state, showAll, userDefined: { ...state.userDefined, showAll } }));
2409
- this.setProps = this.updater((state, props) => {
2410
- return ({ ...state, props });
2411
- });
2412
- this.setTableWidth = this.updater((state, widthInPixels) => ({ ...state, userDefined: { ...state.userDefined, table: { width: widthInPixels } } }));
2413
- this.setInitializationState = this.updater((state, initializationState) => {
2414
- return { ...state, initializationState };
2415
- });
2416
- this.toggleCollapseHeader = this.updater((state) => {
2417
- const tableSettings = { ...state.persistedTableSettings };
2418
- tableSettings.collapseHeader = !tableSettings.collapseHeader;
2419
- return ({ ...state, persistedTableSettings: new PersistedTableSettings(tableSettings) });
2420
- });
2421
- this.toggleCollapseFooter = this.updater((state, options) => {
2422
- const tableSettings = { ...state.persistedTableSettings };
2423
- tableSettings.collapseFooter = options?.collapseFooter ?? !tableSettings.collapseFooter;
2424
- return ({ ...state, persistedTableSettings: new PersistedTableSettings(tableSettings) });
2425
- });
2426
- this.addGroupByKey = this.updater((state, metaDataKey) => ({
2427
- ...state,
2428
- groupBy: [...state.groupBy, { key: metaDataKey, expandedHeaders: [] }]
2429
- }));
2430
- this.removeGroupByKey = this.updater((state, groupByKey) => ({
2431
- ...state,
2432
- groupBy: state.groupBy.filter(key => groupByKey !== key.key)
2433
- }));
2434
- this.updateExpandedGroups = this.updater((state, data) => {
2435
- const gbk = replaceInArrayWithClone(state.groupBy, k => k.key === data.key, gk => {
2436
- gk.expandedHeaders = data.isExpanded ? [...gk.expandedHeaders, data.groupUniqueName] : gk.expandedHeaders.filter(g => g !== data.groupUniqueName);
2437
- });
2438
- return ({
2439
- ...state,
2440
- groupBy: gbk
2441
- });
2442
- });
2443
- this.expandAllOfGroup = this.updater((state, data) => {
2444
- const newGroupedData = state.groupBy.map(gb => ({
2445
- key: gb.key,
2446
- expandedHeaders: data.groupHeadersByKey[gb.key]?.map(g => g.uniqueName) ?? gb.expandedHeaders
2447
- }));
2448
- return ({ ...state, groupBy: newGroupedData });
2449
- });
2450
- this.collapseAll = this.updater((state) => ({
2451
- ...state,
2452
- groupBy: state.groupBy.map(gb => ({ key: gb.key, expandedHeaders: [] }))
2453
- }));
2454
- this.collapseAllOfKey = this.updater((state, data) => ({
2455
- ...state,
2456
- groupBy: state.groupBy.map(gb => ({
2457
- key: gb.key,
2458
- expandedHeaders: data.keys.includes(gb.key) ? [] : gb.expandedHeaders
2459
- }))
2460
- }));
2461
- this.setLinkMaps = this.updater((state, maps) => {
2462
- return ({ ...state, linkMaps: maps });
2463
- });
2464
- this.updateRowProps = this.updater((state, updates) => {
2465
- const notPersistedTableSettings = merge$1(new NotPersistedTableSettings(), (state.notPersistedTableSettings));
2466
- if (updates.rowClasses)
2467
- notPersistedTableSettings.rowClasses = updates.rowClasses;
2468
- if (updates.rowClick)
2469
- notPersistedTableSettings.rowClick = updates.rowClick;
2470
- if (updates.rowStyles)
2471
- notPersistedTableSettings.rowStyles = updates.rowStyles;
2472
- return ({ ...state, notPersistedTableSettings });
2473
- });
2474
- this.on = (srcObservable, func) => {
2475
- this.effect(() => srcObservable.pipe(tap(func)));
2476
- return this;
2268
+ if (b == null)
2269
+ return -nullValue;
2270
+ const transform = d.transform;
2271
+ const aVal = transform(a);
2272
+ const bVal = transform(b);
2273
+ if (aVal == null) {
2274
+ if (bVal == null)
2275
+ return 0;
2276
+ return nullValue;
2277
+ }
2278
+ if (bVal == null)
2279
+ return -nullValue;
2280
+ if (aVal < bVal)
2281
+ return c.direction === 'asc' ? -1 : 1;
2282
+ if (aVal > bVal)
2283
+ return c.direction === 'asc' ? 1 : -1;
2284
+ }
2285
+ return 0;
2286
+ };
2287
+ }
2288
+ function getFactory(b) {
2289
+ if (typeof b !== 'string')
2290
+ return (a) => a[b];
2291
+ if (!b.includes('.'))
2292
+ return (a) => {
2293
+ if (!a)
2294
+ return a;
2295
+ return a[b];
2477
2296
  };
2478
- }
2479
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.3", ngImport: i0, type: TableStore, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
2480
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.0.3", ngImport: i0, type: TableStore }); }
2297
+ const arr = b.split('.');
2298
+ return (a) => {
2299
+ let val = a;
2300
+ if (!a)
2301
+ return a;
2302
+ for (let index = 0; index < arr.length; index++) {
2303
+ val = val[arr[index]];
2304
+ if (val == undefined)
2305
+ return undefined;
2306
+ if (typeof val !== 'object' && index + 1 < arr.length)
2307
+ return undefined;
2308
+ }
2309
+ return val;
2310
+ };
2481
2311
  }
2482
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.3", ngImport: i0, type: TableStore, decorators: [{
2483
- type: Injectable
2484
- }], ctorParameters: () => [] });
2485
- const resetable = [
2486
- 'Sorting',
2487
- 'Filters',
2488
- 'Group By',
2489
- 'Hidden Columns',
2490
- 'Column Widths',
2491
- 'Column Order',
2492
- 'Row Height',
2493
- 'Header Height',
2494
- 'Page Size',
2495
- 'Show All',
2496
- ];
2497
2312
 
2498
- class MultiSortDirective extends MatSort {
2499
- constructor() {
2500
- super();
2501
- this.state = inject(TableStore);
2502
- this.state.setSort(this.sortChange.pipe(distinctUntilChanged((f, s) => f.active === s.active && f.direction === s.direction), map(sc => ({ key: sc.active, direction: sc.direction }))));
2503
- this.state.on(this.state.sort$, (rules) => {
2504
- const topRule = { active: rules[0]?.active || '', direction: rules[0]?.direction || '' };
2505
- const topActiveChanged = topRule.active !== this.active || '';
2506
- const topDirectionChanged = topRule.direction !== this.direction || '';
2507
- if (topActiveChanged || topDirectionChanged) {
2508
- this.active = topRule.active;
2509
- this.direction = topRule.direction;
2510
- this.sortChange.emit(topRule);
2313
+ function isPipe(o) {
2314
+ return typeof (o.transform) === 'function';
2315
+ }
2316
+ function createTransformer(metaData, config, noIcons = false, forItem = false) {
2317
+ const defaultFunc = getFactory(metaData.key);
2318
+ if (metaData.map && !forItem) {
2319
+ return (value) => {
2320
+ return metaData.map(value);
2321
+ };
2322
+ }
2323
+ if (metaData.mapItem) {
2324
+ return (value) => {
2325
+ return metaData.mapItem(defaultFunc(value));
2326
+ };
2327
+ }
2328
+ if (metaData.transform) {
2329
+ if (isPipe(metaData.transform)) {
2330
+ return (value) => metaData.transform.transform(defaultFunc(value));
2331
+ }
2332
+ return metaData.fieldType === FieldType.Expression ? metaData.transform : (value) => metaData.transform(defaultFunc(value), value);
2333
+ }
2334
+ if (config.transformers && config.transformers[metaData.fieldType]) {
2335
+ var transformer = config.transformers[metaData.fieldType];
2336
+ return (value) => transformer(defaultFunc(value));
2337
+ }
2338
+ const defaultDateFormat = config.dateFormats?.dateFormat ?? 'shortDate';
2339
+ const defaultDateTimeFormat = config.dateFormats?.dateTimeFormat ?? 'short';
2340
+ switch (metaData.fieldType) {
2341
+ case FieldType.Date:
2342
+ const dateFormat = metaData.additional?.dateFormat ?? defaultDateFormat;
2343
+ return (value) => dateFormatter(defaultFunc(value), dateFormat);
2344
+ case FieldType.DateTime:
2345
+ const dateTimeFormat = metaData.additional?.dateTimeOptions?.format ?? defaultDateTimeFormat;
2346
+ return (value) => dateFormatter(defaultFunc(value), dateTimeFormat);
2347
+ case FieldType.Currency:
2348
+ return (value) => currencyFormatter(defaultFunc(value));
2349
+ case FieldType.PhoneNumber:
2350
+ return (value) => phoneFormatter(defaultFunc(value));
2351
+ case FieldType.Enum:
2352
+ return (value) => spaceCase(metaData.additional?.enumMap[defaultFunc(value)]);
2353
+ case FieldType.Boolean:
2354
+ if (noIcons) {
2355
+ return defaultFunc;
2511
2356
  }
2512
- });
2357
+ let forTrue = 'check';
2358
+ let forFalse = '';
2359
+ if (metaData.additional?.boolean?.forTrue) {
2360
+ forTrue = metaData?.additional.boolean.forTrue.icon;
2361
+ }
2362
+ if (metaData.additional?.boolean?.showForFalse === true) {
2363
+ forFalse = 'clear';
2364
+ }
2365
+ else if (metaData.additional?.boolean?.showForFalse?.icon) {
2366
+ forFalse = metaData.additional?.boolean?.showForFalse?.icon;
2367
+ }
2368
+ return (value) => defaultFunc(value) ? forTrue : forFalse;
2513
2369
  }
2514
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.3", ngImport: i0, type: MultiSortDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
2515
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.0.3", type: MultiSortDirective, isStandalone: true, selector: "[multiSort]", inputs: { disabled: ["matSortDisabled", "disabled"] }, providers: [
2516
- { provide: MatSort, useExisting: MultiSortDirective }
2517
- ], exportAs: ["multiSort"], usesInheritance: true, ngImport: i0 }); }
2370
+ return defaultFunc;
2518
2371
  }
2519
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.3", ngImport: i0, type: MultiSortDirective, decorators: [{
2520
- type: Directive,
2521
- args: [{
2522
- selector: '[multiSort]',
2523
- exportAs: 'multiSort',
2524
- inputs: ['disabled: matSortDisabled'],
2525
- providers: [
2526
- { provide: MatSort, useExisting: MultiSortDirective }
2527
- ],
2528
- }]
2529
- }], ctorParameters: () => [] });
2530
- function sortsAreSame(a, b) {
2531
- if (a.length !== b.length) {
2532
- return false;
2372
+ function createItemTransformer(metaData, config, noIcons = false, mutate = false) {
2373
+ const transform = createTransformer(metaData, config, noIcons);
2374
+ return (t) => {
2375
+ if (!mutate) {
2376
+ t = { ...t };
2377
+ }
2378
+ t[metaData.key] = transform(t);
2379
+ };
2380
+ }
2381
+ function createItemTransformers(metaDatas, config, noIcons = false, mutate = false) {
2382
+ const transformers = metaDatas.map(meta => createItemTransformer(meta, config, noIcons, true));
2383
+ return (t) => {
2384
+ if (!t)
2385
+ return t;
2386
+ if (!mutate) {
2387
+ t = { ...t };
2388
+ }
2389
+ transformers.forEach(m => m(t));
2390
+ return t;
2391
+ };
2392
+ }
2393
+ function dateFormatter(date, format) {
2394
+ if (!date)
2395
+ return;
2396
+ return formatDate(date, format, 'en-US');
2397
+ }
2398
+ function currencyFormatter(amt) {
2399
+ return formatCurrency(amt, 'en-US', '$');
2400
+ }
2401
+
2402
+ function buildInAllValuesFilter(config, previousMeta, currentMeta, data, metaTimestamp, dataTimestamp, currentAllFilters) {
2403
+ const currentAll = currentMeta.filter(m => {
2404
+ const filterable = m.additional?.filterOptions?.filterableValues;
2405
+ return filterable === 'all values' || filterable?.allValues === true;
2406
+ });
2407
+ if (dataTimestamp > metaTimestamp) {
2408
+ return currentAll.reduce((dict, md) => {
2409
+ dict[md.key] = buildFilter(data, md, config);
2410
+ return dict;
2411
+ }, {});
2533
2412
  }
2534
- for (let i = 0; i < a.length; i++) {
2535
- if (a[i].active !== b[i].active || a[i].direction !== b[i].direction) {
2536
- return false;
2413
+ const previousAll = previousMeta.filter(m => {
2414
+ const filterable = m.additional?.filterOptions?.filterableValues;
2415
+ return filterable === 'all values' || filterable?.allValues === true;
2416
+ });
2417
+ const newCurrent = currentAll.filter(c => previousAll.every(p => c.key !== p.key));
2418
+ if (newCurrent.length) {
2419
+ const c = { ...currentAllFilters };
2420
+ newCurrent.forEach(md => c[md.key] = buildFilter(data, md, config));
2421
+ return c;
2422
+ }
2423
+ return currentAllFilters;
2424
+ }
2425
+ const blankValueFilter = '__tb_sp_blank';
2426
+ const blankValueAndEmptyStringFilter = '__tb_sp_BLANK';
2427
+ function buildFilter(data, metaData, config) {
2428
+ const map = createTransformer(metaData, config, true, true);
2429
+ const mapped = data.map(v => {
2430
+ const mappedV = map(v);
2431
+ return [mappedV?.toString(), mappedV];
2432
+ });
2433
+ const blankAsOption = metaData?.additional?.filterOptions?.filterableValues?.doNotIncludeBlanks !== true;
2434
+ const stringsAsBlanks = metaData?.additional?.filterOptions?.filterableValues?.doNotTreatEmptyStringsAsBlanks !== true;
2435
+ const blankAsOptionAndHasBlanks = blankAsOption && mapped.some(([, v]) => v == undefined || (stringsAsBlanks && v === ''));
2436
+ if (blankAsOptionAndHasBlanks) {
2437
+ if (stringsAsBlanks) {
2438
+ mapped.push(['BLANK', blankValueAndEmptyStringFilter]);
2439
+ }
2440
+ else {
2441
+ mapped.push(['BLANK', blankValueFilter]);
2537
2442
  }
2538
2443
  }
2539
- return true;
2444
+ return [...new Map(mapped).values()].filter(v => v != undefined && (!blankAsOption || !stringsAsBlanks || v !== '')).sort((a, b) => {
2445
+ const isSymbolA = typeof a === 'symbol';
2446
+ const isSymbolB = typeof b === 'symbol';
2447
+ if (isSymbolA || isSymbolB)
2448
+ return 0; // keep symbols in place
2449
+ return String(a).localeCompare(String(b)); // normal string sort
2450
+ });
2451
+ }
2452
+ const splitOutBlankFilter = (arr) => {
2453
+ const result = Object.groupBy(arr, v => isBlankValueFilter(v) ? 'blank' : 'values');
2454
+ const blank = result.blank?.at(0);
2455
+ const blankFilter = blank === blankValueFilter ?
2456
+ (val) => val == undefined
2457
+ : blank === blankValueAndEmptyStringFilter ? (val) => {
2458
+ return (val === '' || val == null);
2459
+ }
2460
+ : undefined;
2461
+ return ({
2462
+ blankFilter,
2463
+ values: result.values || [],
2464
+ });
2465
+ };
2466
+ function isBlankValueFilter(val) {
2467
+ return val === blankValueFilter || val === blankValueAndEmptyStringFilter;
2468
+ }
2469
+ function isNotBlankValueFilter(val) {
2470
+ return !isBlankValueFilter(val);
2540
2471
  }
2541
2472
 
2542
- class DateFilterComponent {
2543
- constructor() {
2544
- this.FilterType = FilterType;
2473
+ const isNull = (filterInfo) => {
2474
+ const func = filterInfo.filterValue ?
2475
+ (val) => val == null || val === ''
2476
+ :
2477
+ (val) => val != null && val !== '';
2478
+ return func;
2479
+ };
2480
+
2481
+ const stringEqualFunc = (filterInfo) => {
2482
+ const equalsVal = prepareForStringCompare(filterInfo.filterValue);
2483
+ return ((val) => prepareForStringCompare(val) === equalsVal);
2484
+ };
2485
+ const stringContainsFunc = (filterInfo) => {
2486
+ const containsVal = prepareForStringCompare(filterInfo.filterValue);
2487
+ return ((val) => prepareForStringCompare(val).includes(containsVal));
2488
+ };
2489
+ const stringDoesNotContainFunc = (filterInfo) => {
2490
+ const doesNotContainVal = prepareForStringCompare(filterInfo.filterValue);
2491
+ return ((val) => !prepareForStringCompare(val)?.includes(doesNotContainVal));
2492
+ };
2493
+ const stringStartsWithFunc = (filterInfo) => {
2494
+ const startsWith = prepareForStringCompare(filterInfo.filterValue);
2495
+ return ((val) => prepareForStringCompare(val).startsWith(startsWith));
2496
+ };
2497
+ const stringEndsWithFunc = (filterInfo) => {
2498
+ const startsWith = prepareForStringCompare(filterInfo.filterValue);
2499
+ return ((val) => prepareForStringCompare(val).endsWith(startsWith));
2500
+ };
2501
+ const multipleStringValuesEqualsFunc = (filterInfo) => {
2502
+ const { blankFilter, values } = splitOutBlankFilter(filterInfo.filterValue);
2503
+ const filterVals = values.map((v) => prepareForStringCompare(v));
2504
+ const basicFunc = (val) => filterVals.some((s) => val === s);
2505
+ const func = blankFilter ? ((val) => blankFilter(val) || basicFunc(val)) : basicFunc;
2506
+ return ((val) => {
2507
+ const v = prepareForStringCompare(val);
2508
+ return func(v);
2509
+ });
2510
+ };
2511
+ const StringFilterFuncs = {
2512
+ [FilterType.StringEquals]: stringEqualFunc,
2513
+ [FilterType.StringContains]: stringContainsFunc,
2514
+ [FilterType.StringDoesNotContain]: stringDoesNotContainFunc,
2515
+ [FilterType.StringStartWith]: stringStartsWithFunc,
2516
+ [FilterType.StringEndsWith]: stringEndsWithFunc,
2517
+ [FilterType.IsNull]: isNull,
2518
+ [FilterType.In]: multipleStringValuesEqualsFunc,
2519
+ };
2520
+ const EnumFilterFuncs = {
2521
+ [FilterType.IsNull]: isNull,
2522
+ [FilterType.In]: multipleStringValuesEqualsFunc,
2523
+ };
2524
+ const prepareForStringCompare = (val) => (val?.toString().trim().toLowerCase());
2525
+
2526
+ const numberEqalsFunc = (filterInfo) => (val) => {
2527
+ return val === filterInfo.filterValue;
2528
+ };
2529
+ const numberNotEqualFunc = (filterInfo) => (val) => {
2530
+ return val !== filterInfo.filterValue;
2531
+ };
2532
+ const numberGreaterThanFunc = (filterInfo) => (val) => {
2533
+ return val > filterInfo.filterValue;
2534
+ };
2535
+ const numberLessThanFunc = (filterInfo) => (val) => {
2536
+ return val < filterInfo.filterValue;
2537
+ };
2538
+ const numberBetweenFunc = (filterInfo) => {
2539
+ const startVal = Number(filterInfo.filterValue.Start);
2540
+ const endVal = Number(filterInfo.filterValue.End);
2541
+ return ((val) => (val > startVal) && (val < endVal));
2542
+ };
2543
+ const multipleNumberValuesEqualsFunc = (filterInfo) => {
2544
+ const { blankFilter, values } = splitOutBlankFilter(filterInfo.filterValue);
2545
+ const basicFunc = (val) => values.some((s) => val === s);
2546
+ const func = blankFilter ? ((val) => blankFilter(val) || basicFunc(val)) : basicFunc;
2547
+ return func;
2548
+ };
2549
+ const NumberFilterFuncs = {
2550
+ [FilterType.NumberEquals]: numberEqalsFunc,
2551
+ [FilterType.NumberNotEqual]: numberNotEqualFunc,
2552
+ [FilterType.NumberGreaterThan]: numberGreaterThanFunc,
2553
+ [FilterType.NumberLessThan]: numberLessThanFunc,
2554
+ [FilterType.NumberBetween]: numberBetweenFunc,
2555
+ [FilterType.IsNull]: isNull,
2556
+ [FilterType.In]: multipleNumberValuesEqualsFunc,
2557
+ };
2558
+
2559
+ const dateIsOnFunc = (filterInfo) => {
2560
+ const isOnVal = new Date(filterInfo.filterValue).getTime();
2561
+ const clean = filterInfo.fieldType === FieldType.Date ? (a, b) => b : cleanDateTime;
2562
+ return ((val) => clean(filterInfo, val).getTime() === isOnVal);
2563
+ };
2564
+ const dateIsNotOnFunc = (filterInfo) => {
2565
+ const isNotOnVal = new Date(filterInfo.filterValue).getTime();
2566
+ const clean = filterInfo.fieldType === FieldType.Date ? (a, b) => b : cleanDateTime;
2567
+ return ((val) => clean(filterInfo, val).getTime() !== isNotOnVal);
2568
+ };
2569
+ const dateIsOnOrAfterFunc = (filterInfo) => {
2570
+ const afterVal = new Date(filterInfo.filterValue).getTime();
2571
+ const clean = filterInfo.fieldType === FieldType.Date ? (a, b) => b : cleanDateTime;
2572
+ return ((val) => clean(filterInfo, val).getTime() >= afterVal);
2573
+ };
2574
+ const dateIsOnOrBeforeFunc = (filterInfo) => {
2575
+ const beforeVal = new Date(filterInfo.filterValue).getTime();
2576
+ const clean = filterInfo.fieldType === FieldType.Date ? (a, b) => b : cleanDateTime;
2577
+ return ((val) => clean(filterInfo, val).getTime() <= beforeVal);
2578
+ };
2579
+ const dateIsInFunc = (filterInfo) => {
2580
+ const { blankFilter, values } = splitOutBlankFilter(filterInfo.filterValue);
2581
+ const filterVals = values.map(v => new Date(v).getTime());
2582
+ const clean = filterInfo.fieldType === FieldType.Date ? (a, b) => b : cleanDateTime;
2583
+ const basicFunc = (val) => filterVals.some((f) => f === val);
2584
+ const func = blankFilter ? ((val) => blankFilter(val) || basicFunc(val)) : basicFunc;
2585
+ return ((val) => {
2586
+ const d = clean(filterInfo, val)?.getTime();
2587
+ return func(d);
2588
+ });
2589
+ };
2590
+ const dateBetweenFunc = (filterInfo) => {
2591
+ const startVal = new Date(filterInfo.filterValue.Start);
2592
+ const endVal = new Date(filterInfo.filterValue.End);
2593
+ const clean = filterInfo.fieldType === FieldType.Date ? (a, b) => b : cleanDateTime;
2594
+ return ((val) => {
2595
+ const cleanedVal = clean(filterInfo, val);
2596
+ return cleanedVal >= startVal && cleanedVal <= endVal;
2597
+ });
2598
+ };
2599
+ const cleanDateTime = (filterInfo, val) => {
2600
+ if (!!DateFilterFuncs[filterInfo.filterType]) {
2601
+ const d = new Date(val);
2602
+ d.setHours(0, 0, 0, 0);
2603
+ return d;
2545
2604
  }
2546
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.3", ngImport: i0, type: DateFilterComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
2547
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.0.3", type: DateFilterComponent, isStandalone: true, selector: "tb-date-filter", inputs: { info: "info", CurrentFilterType: "CurrentFilterType" }, ngImport: i0, template: "@if (CurrentFilterType !== FilterType.DateBetween && CurrentFilterType !== FilterType.IsNull)\r\n{\r\n <mat-form-field>\r\n <input matInput name=\"filterValue\" [ngModel]=\"info.filterValue\" [matDatepicker]=\"cal\"/>\r\n <mat-datepicker-toggle class=\"small-button date-toggle\" matSuffix preventEnter [for]=\"cal\" />\r\n <mat-datepicker #cal />\r\n </mat-form-field>\r\n}\r\n@if(CurrentFilterType === FilterType.DateBetween)\r\n{\r\n <ng-container ngModelGroup=\"filterValue\">\r\n <mat-form-field class=\"my-filter\" >\r\n <input matInput name=\"Start\" placeholder=\"From\" [ngModel]=\"info.filterValue?.Start\" [matDatepicker]=\"fromVal\"\r\n (click)=\"fromVal.open()\"/>\r\n <mat-datepicker-toggle matSuffix class=\"small-button date-toggle\" preventEnter [for]=\"fromVal\" />\r\n <mat-datepicker #fromVal />\r\n </mat-form-field>\r\n <mat-form-field>\r\n <input matInput name=\"End\" placeholder=\"To\" [ngModel]=\"info.filterValue?.End\" [matDatepicker]=\"toVal\" (click)=\"toVal.open()\"/>\r\n <mat-datepicker-toggle matSuffix class=\"small-button date-toggle\" preventEnter [for]=\"toVal\" />\r\n <mat-datepicker #toVal />\r\n </mat-form-field>\r\n </ng-container>\r\n}\r\n\r\n", styles: [".filter-name{color:var(tb-filter-name);margin:10px 0;font-weight:600;display:inline-block}.switch{display:inline-block}.head-row{display:flex;width:100%;align-items:center;justify-content:space-between}.filter-row{display:flex;align-items:center;gap:1rem}mat-card.filter-card::ng-deep mat-form-field{width:150px}mat-card.filter-card::ng-deep .mat-mdc-form-field-subscript-wrapper{line-height:0}mat-card.filter-card::ng-deep .mat-mdc-form-field-subscript-wrapper:before{height:0}.inline{display:inline-block}.small-button{height:18px;width:18px;font-size:18px;padding:0;margin:0}.small-button ::ng-deep *{line-height:initial;font-size:initial;height:18px;width:18px;font-size:18px;bottom:initial}.cancel-button{font-weight:700}.date-toggle ::ng-deep svg{position:absolute;left:0;top:0}\n"], dependencies: [{ kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i1$1.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "component", type: i1$1.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i1$1.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.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: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i2.NgModelGroup, selector: "[ngModelGroup]", inputs: ["ngModelGroup"], exportAs: ["ngModelGroup"] }, { kind: "ngmodule", type: MatDatepickerModule }, { kind: "component", type: i3.MatDatepicker, selector: "mat-datepicker", exportAs: ["matDatepicker"] }, { kind: "directive", type: i3.MatDatepickerInput, selector: "input[matDatepicker]", inputs: ["matDatepicker", "min", "max", "matDatepickerFilter"], exportAs: ["matDatepickerInput"] }, { kind: "component", type: i3.MatDatepickerToggle, selector: "mat-datepicker-toggle", inputs: ["for", "tabIndex", "aria-label", "disabled", "disableRipple"], exportAs: ["matDatepickerToggle"] }], viewProviders: [{ provide: ControlContainer, useExisting: NgForm }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
2548
- }
2549
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.3", ngImport: i0, type: DateFilterComponent, decorators: [{
2550
- type: Component,
2551
- args: [{ selector: 'tb-date-filter', changeDetection: ChangeDetectionStrategy.OnPush, viewProviders: [{ provide: ControlContainer, useExisting: NgForm }], imports: [
2552
- MatInputModule, FormsModule, MatDatepickerModule
2553
- ], template: "@if (CurrentFilterType !== FilterType.DateBetween && CurrentFilterType !== FilterType.IsNull)\r\n{\r\n <mat-form-field>\r\n <input matInput name=\"filterValue\" [ngModel]=\"info.filterValue\" [matDatepicker]=\"cal\"/>\r\n <mat-datepicker-toggle class=\"small-button date-toggle\" matSuffix preventEnter [for]=\"cal\" />\r\n <mat-datepicker #cal />\r\n </mat-form-field>\r\n}\r\n@if(CurrentFilterType === FilterType.DateBetween)\r\n{\r\n <ng-container ngModelGroup=\"filterValue\">\r\n <mat-form-field class=\"my-filter\" >\r\n <input matInput name=\"Start\" placeholder=\"From\" [ngModel]=\"info.filterValue?.Start\" [matDatepicker]=\"fromVal\"\r\n (click)=\"fromVal.open()\"/>\r\n <mat-datepicker-toggle matSuffix class=\"small-button date-toggle\" preventEnter [for]=\"fromVal\" />\r\n <mat-datepicker #fromVal />\r\n </mat-form-field>\r\n <mat-form-field>\r\n <input matInput name=\"End\" placeholder=\"To\" [ngModel]=\"info.filterValue?.End\" [matDatepicker]=\"toVal\" (click)=\"toVal.open()\"/>\r\n <mat-datepicker-toggle matSuffix class=\"small-button date-toggle\" preventEnter [for]=\"toVal\" />\r\n <mat-datepicker #toVal />\r\n </mat-form-field>\r\n </ng-container>\r\n}\r\n\r\n", styles: [".filter-name{color:var(tb-filter-name);margin:10px 0;font-weight:600;display:inline-block}.switch{display:inline-block}.head-row{display:flex;width:100%;align-items:center;justify-content:space-between}.filter-row{display:flex;align-items:center;gap:1rem}mat-card.filter-card::ng-deep mat-form-field{width:150px}mat-card.filter-card::ng-deep .mat-mdc-form-field-subscript-wrapper{line-height:0}mat-card.filter-card::ng-deep .mat-mdc-form-field-subscript-wrapper:before{height:0}.inline{display:inline-block}.small-button{height:18px;width:18px;font-size:18px;padding:0;margin:0}.small-button ::ng-deep *{line-height:initial;font-size:initial;height:18px;width:18px;font-size:18px;bottom:initial}.cancel-button{font-weight:700}.date-toggle ::ng-deep svg{position:absolute;left:0;top:0}\n"] }]
2554
- }], propDecorators: { info: [{
2555
- type: Input
2556
- }], CurrentFilterType: [{
2557
- type: Input
2558
- }] } });
2605
+ return val;
2606
+ };
2607
+ const DateFilterFuncs = {
2608
+ [FilterType.DateIsOn]: dateIsOnFunc,
2609
+ [FilterType.DateIsNotOn]: dateIsNotOnFunc,
2610
+ [FilterType.DateOnOrAfter]: dateIsOnOrAfterFunc,
2611
+ [FilterType.DateOnOrBefore]: dateIsOnOrBeforeFunc,
2612
+ [FilterType.DateBetween]: dateBetweenFunc,
2613
+ [FilterType.In]: dateIsInFunc,
2614
+ [FilterType.IsNull]: isNull,
2615
+ };
2616
+ const DateTimeFilterFuncs = {
2617
+ ...DateFilterFuncs,
2618
+ [FilterType.DateTimeIsAt]: dateIsOnFunc,
2619
+ [FilterType.DateTimeIsNotAt]: dateIsNotOnFunc,
2620
+ [FilterType.DateTimeAtOrAfter]: dateIsOnOrAfterFunc,
2621
+ [FilterType.DateTimeAtOrBefore]: dateIsOnOrBeforeFunc,
2622
+ [FilterType.DateTimeBetween]: dateBetweenFunc,
2623
+ [FilterType.In]: dateIsInFunc,
2624
+ [FilterType.IsNull]: isNull,
2625
+ };
2559
2626
 
2560
- class PreventEnterDirective {
2561
- onKeyDown() {
2562
- return false;
2563
- }
2564
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.3", ngImport: i0, type: PreventEnterDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
2565
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.0.3", type: PreventEnterDirective, isStandalone: true, selector: "preventEnter", host: { listeners: { "keydown.enter": "onKeyDown($event)" } }, ngImport: i0 }); }
2566
- }
2567
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.3", ngImport: i0, type: PreventEnterDirective, decorators: [{
2568
- type: Directive,
2569
- args: [{
2570
- selector: 'preventEnter',
2571
- }]
2572
- }], propDecorators: { onKeyDown: [{
2573
- type: HostListener,
2574
- args: ['keydown.enter', ['$event']]
2575
- }] } });
2627
+ const booleanEqualsFunc = (filterInfo) => (val) => {
2628
+ return filterInfo.filterValue === val;
2629
+ };
2630
+ const BooleanFilterFuncs = {
2631
+ [FilterType.BooleanEquals]: booleanEqualsFunc,
2632
+ [FilterType.IsNull]: isNull,
2633
+ };
2576
2634
 
2577
- class StopPropagationDirective {
2578
- onClick(event) {
2579
- event.stopPropagation();
2580
- }
2581
- onMousedown(event) {
2582
- event.stopPropagation();
2583
- }
2584
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.3", ngImport: i0, type: StopPropagationDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
2585
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.0.3", type: StopPropagationDirective, isStandalone: true, selector: "[stop-propagation]", host: { listeners: { "click": "onClick($event)", "mousedown": "onMousedown($event)" } }, ngImport: i0 }); }
2635
+ const filterFactoryMap = {
2636
+ [FilterType.And]: (filter) => {
2637
+ const filters = createFilterFuncs(filter.filterValue);
2638
+ return (obj) => filters.every(f => f(obj));
2639
+ },
2640
+ [FilterType.In]: (filter) => {
2641
+ const filters = createFilterFuncs(filter.filterValue);
2642
+ return (obj) => filters.some(f => f(obj));
2643
+ },
2644
+ };
2645
+ const filterTypeFuncMap = {
2646
+ [FieldType.Array]: StringFilterFuncs,
2647
+ [FieldType.Boolean]: BooleanFilterFuncs,
2648
+ [FieldType.Currency]: NumberFilterFuncs,
2649
+ [FieldType.Date]: DateFilterFuncs,
2650
+ [FieldType.DateTime]: DateTimeFilterFuncs,
2651
+ [FieldType.Enum]: EnumFilterFuncs,
2652
+ [FieldType.Link]: StringFilterFuncs,
2653
+ [FieldType.Number]: NumberFilterFuncs,
2654
+ [FieldType.PhoneNumber]: StringFilterFuncs,
2655
+ [FieldType.String]: StringFilterFuncs,
2656
+ [FieldType.Unknown]: StringFilterFuncs,
2657
+ };
2658
+ const filterTypeMap = Object.entries(filterTypeFuncMap).reduce((acc, [key, value]) => ({ ...acc, [key]: Object.keys(value) }), {});
2659
+ function isCustomFilter(filter) {
2660
+ return filter && filter.filterType === FilterType.Custom;
2586
2661
  }
2587
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.3", ngImport: i0, type: StopPropagationDirective, decorators: [{
2588
- type: Directive,
2589
- args: [{
2590
- selector: "[stop-propagation]",
2591
- }]
2592
- }], propDecorators: { onClick: [{
2593
- type: HostListener,
2594
- args: ["click", ["$event"]]
2595
- }], onMousedown: [{
2596
- type: HostListener,
2597
- args: ["mousedown", ["$event"]]
2598
- }] } });
2599
-
2600
- class AutoFocusDirective {
2601
- constructor() {
2602
- this.elementRef = inject(ElementRef);
2603
- this.autoFocus = true;
2604
- }
2605
- ngAfterViewInit() {
2606
- if (this.autoFocus) {
2607
- setTimeout(() => {
2608
- this.elementRef.nativeElement.focus();
2609
- });
2610
- }
2611
- }
2612
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.3", ngImport: i0, type: AutoFocusDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
2613
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.0.3", type: AutoFocusDirective, isStandalone: true, selector: "[autoFocus]", inputs: { autoFocus: "autoFocus" }, ngImport: i0 }); }
2662
+ function isFilterInfo(filter) {
2663
+ return filter && typeof filter.key === 'string' && filter.filterType !== FilterType.Custom;
2614
2664
  }
2615
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.3", ngImport: i0, type: AutoFocusDirective, decorators: [{
2616
- type: Directive,
2617
- args: [{
2618
- selector: '[autoFocus]',
2619
- }]
2620
- }], propDecorators: { autoFocus: [{
2621
- type: Input
2622
- }] } });
2623
-
2624
- class ClickSubjectDirective extends Subject {
2625
- constructor() {
2626
- super();
2627
- }
2628
- set clickSubject(val) {
2629
- this._val = val;
2630
- }
2631
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.3", ngImport: i0, type: ClickSubjectDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
2632
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.0.3", type: ClickSubjectDirective, isStandalone: true, selector: "[clickSubject]", inputs: { clickSubject: "clickSubject" }, host: { listeners: { "click": "next(this._val)" } }, exportAs: ["clickSubject"], usesInheritance: true, ngImport: i0 }); }
2665
+ const defaultPredicate = () => true;
2666
+ function createFilterFuncs(filters) {
2667
+ return filters.filter(needsFilterCreation).map(createFilterFunc);
2633
2668
  }
2634
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.3", ngImport: i0, type: ClickSubjectDirective, decorators: [{
2635
- type: Directive,
2636
- args: [{
2637
- selector: '[clickSubject]',
2638
- exportAs: 'clickSubject',
2639
- host: {
2640
- '(click)': 'next(this._val)'
2641
- },
2642
- }]
2643
- }], ctorParameters: () => [], propDecorators: { clickSubject: [{
2644
- type: Input,
2645
- args: ['clickSubject']
2646
- }] } });
2647
-
2648
- class ClickEmitterDirective extends Subject {
2649
- constructor() {
2650
- super();
2669
+ function needsFilterCreation(filter) {
2670
+ if (isCustomFilter(filter)) {
2671
+ return filter.active !== false;
2651
2672
  }
2652
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.3", ngImport: i0, type: ClickEmitterDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
2653
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.0.3", type: ClickEmitterDirective, isStandalone: true, selector: "[clickEmitter]", host: { listeners: { "click": "next(true)" } }, exportAs: ["clickEmitter"], usesInheritance: true, ngImport: i0 }); }
2673
+ return filter.filterValue != undefined && filter.active !== false;
2654
2674
  }
2655
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.3", ngImport: i0, type: ClickEmitterDirective, decorators: [{
2656
- type: Directive,
2657
- args: [{
2658
- selector: '[clickEmitter]',
2659
- exportAs: 'clickEmitter',
2660
- host: {
2661
- '(click)': 'next(true)'
2662
- },
2663
- }]
2664
- }], ctorParameters: () => [] });
2665
-
2666
- class DialogService {
2667
- constructor() {
2668
- this.allOpenOpDialogs = [];
2669
- }
2670
- addDialogRef(ref) {
2671
- this.allOpenOpDialogs.push(ref);
2672
- }
2673
- removeDialogRef(ref) {
2674
- this.allOpenOpDialogs = this.allOpenOpDialogs.filter(rf => ref.id !== rf.id);
2675
+ function createFilterFunc(filter) {
2676
+ if (isCustomFilter(filter)) {
2677
+ return filter.active ? filter.predicate : defaultPredicate;
2675
2678
  }
2676
- closeAllOpDialogs() {
2677
- this.allOpenOpDialogs.forEach(ref => ref.close());
2679
+ if (filter.filterValue == undefined) {
2680
+ return defaultPredicate;
2678
2681
  }
2679
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.3", ngImport: i0, type: DialogService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
2680
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.0.3", ngImport: i0, type: DialogService, providedIn: 'root' }); }
2682
+ const func = filterTypeFuncMap[filter.fieldType][filter.filterType](filter);
2683
+ if (!func) {
2684
+ if (filterFactoryMap[filter.filterType]) {
2685
+ return filterFactoryMap[filter.filterType](filter);
2686
+ }
2687
+ }
2688
+ const canBeTrueForNull = FalseyValueCanBeIncludedFilterTypes.includes(filter.filterType)
2689
+ || (filter.filterType === FilterType.In && filter.filterValue?.some(isBlankValueFilter));
2690
+ const getter = filter.filterBy || getFactory(filter.key);
2691
+ return (rowObj) => {
2692
+ const value = getter(rowObj);
2693
+ return ((value == undefined) && !canBeTrueForNull)
2694
+ ? false
2695
+ : func(value);
2696
+ };
2681
2697
  }
2682
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.3", ngImport: i0, type: DialogService, decorators: [{
2683
- type: Injectable,
2684
- args: [{ providedIn: 'root' }]
2685
- }] });
2698
+ const FalseyValueCanBeIncludedFilterTypes = [
2699
+ FilterType.IsNull,
2700
+ FilterType.NumberNotEqual,
2701
+ FilterType.DateIsNotOn,
2702
+ FilterType.StringDoesNotContain,
2703
+ ];
2686
2704
 
2687
- class DialogWrapper {
2688
- constructor() {
2689
- this.vcr = inject(ViewContainerRef);
2690
- this.viewEmbedded = false;
2691
- this.viewContext = {
2692
- close: () => { },
2693
- };
2694
- }
2695
- set template(tmpl) {
2696
- if (this.viewEmbedded) {
2697
- this.vcr.clear();
2698
- }
2699
- this.viewEmbedded = true;
2700
- this.vcr.createEmbeddedView(tmpl, this.viewContext);
2705
+ const replaceInArrayWithClone = (arr, findMeth, actionOnClone = ((t) => { })) => {
2706
+ const index = arr.findIndex(findMeth);
2707
+ const clonedArray = [...arr];
2708
+ const t = clonedArray[index];
2709
+ clonedArray[index] =
2710
+ t != null && typeof t === 'object' ?
2711
+ Array.isArray(t) ?
2712
+ [...t]
2713
+ : { ...t }
2714
+ : t;
2715
+ actionOnClone(clonedArray[index]);
2716
+ return clonedArray;
2717
+ };
2718
+
2719
+ const orderedStateVisibleMetaData = (state) => {
2720
+ const ordered = orderStateMetaData(state);
2721
+ const orderedVisible = ordered
2722
+ .filter(metaData => !state.hiddenKeys.includes(metaData.key) && state.metaData[metaData.key].fieldType !== FieldType.Hidden);
2723
+ return orderedVisible;
2724
+ };
2725
+ const orderedCodeVisibleMetaData = (state) => orderStateMetaData(state).filter(md => md.fieldType !== FieldType.Hidden);
2726
+ const orderStateMetaData = (state) => {
2727
+ return orderMetaData(state.metaData, state.userDefined.order);
2728
+ };
2729
+ const orderMetaData = (metaData, userDefined) => {
2730
+ const userOrderArr = Object.entries(userDefined);
2731
+ return userOrderArr.length ?
2732
+ Object.values(metaData).sort((a, b) => {
2733
+ const orderA = userDefined[a.key];
2734
+ const orderB = userDefined[b.key];
2735
+ return order(orderA, orderB);
2736
+ })
2737
+ :
2738
+ Object.values(metaData).sort((a, b) => {
2739
+ const orderA = a.order;
2740
+ const orderB = b.order;
2741
+ return order(orderA, orderB);
2742
+ });
2743
+ };
2744
+ function order(orderA, orderB) {
2745
+ if (orderA == null && orderB == null) {
2746
+ return 0;
2701
2747
  }
2702
- set close(closeMethod) {
2703
- this.viewContext.close = closeMethod;
2748
+ if (orderA == null) {
2749
+ return 1;
2704
2750
  }
2705
- set data(value) {
2706
- this.viewContext.$implicit = value;
2707
- this.viewContext.opDialog = value;
2751
+ if (orderB == null) {
2752
+ return -1;
2708
2753
  }
2709
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.3", ngImport: i0, type: DialogWrapper, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
2710
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.0.3", type: DialogWrapper, isStandalone: true, selector: "dialog-wrapper", ngImport: i0, template: ``, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
2754
+ return orderA - orderB;
2711
2755
  }
2712
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.3", ngImport: i0, type: DialogWrapper, decorators: [{
2713
- type: Component,
2714
- args: [{
2715
- selector: 'dialog-wrapper',
2716
- template: ``,
2717
- changeDetection: ChangeDetectionStrategy.OnPush,
2718
- }]
2719
- }] });
2720
- const defaultDialogConfig = {
2721
- maxHeight: '95vh',
2756
+ function cleanPersistedState(state, pState) {
2757
+ const metas = Object.values(state.metaData);
2758
+ const filters = Object.values(pState.filters).filter(fltr => isCustomFilter(fltr) || metas.some(m => m.key === fltr.key)).reduce((obj, filter) => {
2759
+ obj[filter.filterId] = pState.filters[filter.filterId];
2760
+ return obj;
2761
+ }, {});
2762
+ const sorted = pState.sorted.filter(s => metas.some(m => m.key === s.active));
2763
+ return ({ ...pState, filters, sorted });
2764
+ }
2765
+ const mapSaveableState = (s) => {
2766
+ const savableState = { ...s };
2767
+ keysToDelete.forEach(key => delete savableState[key]);
2768
+ return savableState;
2722
2769
  };
2723
- class DialogDirective {
2770
+ const createPreSort = (metaDatas) => {
2771
+ return Object.values(metaDatas).filter((metaData) => !!metaData.preSort)
2772
+ .sort(({ preSort: ps1 }, { preSort: ps2 }) => (ps1.precedence || Number.MAX_VALUE) - (ps2.precedence || Number.MAX_VALUE))
2773
+ .map(({ key, preSort: { direction } }) => ({ active: key, direction }));
2774
+ };
2775
+ const mergeMeta = (orig, merge) => {
2776
+ return {
2777
+ key: orig.key,
2778
+ displayName: merge.displayName ?? orig.displayName,
2779
+ fieldType: merge.fieldType || orig.fieldType,
2780
+ additional: { ...orig.additional, ...merge.additional },
2781
+ order: merge.order ?? orig.order,
2782
+ preSort: merge.preSort ?? orig.preSort,
2783
+ width: merge.width ?? orig.width,
2784
+ noExport: merge.noExport || orig.noExport,
2785
+ noFilter: merge.noFilter || orig.noFilter,
2786
+ customCell: merge.customCell ?? orig.customCell,
2787
+ transform: merge.transform ?? orig.transform,
2788
+ map: merge.map ?? orig.map,
2789
+ click: merge.click ?? orig.click,
2790
+ classes: merge.classes ?? orig.classes,
2791
+ noSort: merge.noSort ?? orig.noSort,
2792
+ template: merge.template ?? orig.template,
2793
+ toolTip: merge.toolTip ?? orig.toolTip,
2794
+ useIcon: merge.useIcon ?? orig.useIcon,
2795
+ filterLogic: merge.filterLogic ?? orig.filterLogic,
2796
+ sortLogic: merge.sortLogic ?? orig.sortLogic,
2797
+ groupByLogic: merge.groupByLogic ?? orig.groupByLogic,
2798
+ };
2799
+ };
2800
+ const initializeOrder = (state, mds) => {
2801
+ const viewableMetaDataArr = Object.values(mds).filter(a => a.fieldType !== FieldType.Hidden);
2802
+ let userDefinedOrder = state.userDefined.order;
2803
+ if (viewableMetaDataArr.some(meta => userDefinedOrder[meta.key] == null)) {
2804
+ return {};
2805
+ }
2806
+ return userDefinedOrder;
2807
+ };
2808
+
2809
+ class TableStore extends ComponentStore {
2724
2810
  constructor() {
2725
- this.templateRef = inject(TemplateRef);
2726
- this.dialog = inject(MatDialog);
2727
- this.dialogConfig = inject(MAT_DIALOG_DEFAULT_OPTIONS, { optional: true }) || {};
2728
- this.service = inject(DialogService);
2729
- this.opDialogClosed = new EventEmitter();
2730
- this._dialogConfig = { ...this.dialogConfig, ...defaultDialogConfig };
2731
- this.opDialogAddDialogClass = true;
2732
- this.injector = inject(Injector);
2733
- this.subscriber = subscriber(this.injector);
2734
- this._data = new Subject();
2735
- this.setDataAndState = (data) => {
2736
- if (data) {
2737
- this.opDialogConfig.data = data;
2738
- this.setDialogState(true);
2811
+ const config = inject(TableBuilderConfigToken);
2812
+ const settingsFromConfig = {
2813
+ persistedTableSettings: new PersistedTableSettings().merge(config.defaultTableSettings),
2814
+ notPersistedTableSettings: new NotPersistedTableSettings().merge(config.defaultTableSettings),
2815
+ };
2816
+ if (config.defaultTableSettings?.pageSize) {
2817
+ settingsFromConfig.notPersistedTableSettings.paginatorSettings.pageSize = config.defaultTableSettings?.pageSize;
2818
+ }
2819
+ const pageSize = settingsFromConfig.notPersistedTableSettings.paginatorSettings.pageSize || defaultTableState.pageSize;
2820
+ const showAll = settingsFromConfig.notPersistedTableSettings.paginatorSettings.defaultAll || defaultTableState.showAll;
2821
+ super({ ...defaultTableState, ...settingsFromConfig, pageSize, showAll });
2822
+ this.$initializationState = this.selectSignal(state => state.initializationState);
2823
+ this.$savableState = computed(() => {
2824
+ const state = this.state();
2825
+ return mapSaveableState(state);
2826
+ });
2827
+ this.$userDefinedOrder = this.selectSignal(state => state.userDefined.order);
2828
+ this.metaData$ = this.select(state => state.metaData);
2829
+ this.$metaData = this.selectSignal(state => state.metaData);
2830
+ this.$metaDataArray = this.selectSignal(this.$metaData, this.$userDefinedOrder, orderMetaData);
2831
+ this.$orderedCodeVisibleMetaDatas = this.selectSignal(this.$metaDataArray, (mds) => mds.filter(m => m.fieldType !== FieldType.Hidden), { equal: (a, b) => b.length === a.length && b.every((s, i) => a[i].key === s.key) });
2832
+ this.$getMetaData = (key) => computed(() => {
2833
+ const metaData = this.state().metaData[key];
2834
+ if (!metaData)
2835
+ console.warn(`Meta data with key ${key} not found`);
2836
+ return metaData;
2837
+ });
2838
+ this.$hiddenKeys = this.selectSignal(state => state.hiddenKeys);
2839
+ this.$orderedVisibleColumns = this.selectSignal(this.$orderedCodeVisibleMetaDatas, this.$hiddenKeys, (cs, hiddenKeys) => cs.filter(m => !hiddenKeys.includes(m.key)).map(m => m.key));
2840
+ this.$getUserDefinedWidths = this.selectSignal(state => state.userDefined.widths);
2841
+ this.$tableSettingsMinWidth = this.selectSignal(state => parseTbSizeToPixels(state.notPersistedTableSettings.minColumnWidth));
2842
+ this.$getUserDefinedWidth = (key) => this.selectSignal(this.$getUserDefinedWidths, widths => widths[key]);
2843
+ this.$filters = this.selectSignal(state => state.filters);
2844
+ this.filters$ = this.select(state => state.filters);
2845
+ this.$getFilter = (filterId) => {
2846
+ return this.selectSignal(this.$filters, filters => filters[filterId]);
2847
+ };
2848
+ this.$preSort = computed(() => createPreSort(this.$metaData()));
2849
+ this._$selectSorted = this.selectSignal(state => state.sorted, {
2850
+ equal: sortsAreSame
2851
+ });
2852
+ this.$selectSorted = computed(() => {
2853
+ const metaDict = this.$metaData();
2854
+ return this._$selectSorted().map(s => {
2855
+ const meta = metaDict[s.active];
2856
+ const sortLogic = meta.sortLogic;
2857
+ const sortBy = sortLogic?.sortBy === 'use map' ? meta.map : sortLogic?.sortBy;
2858
+ return ({ ...s, ...sortLogic, sortBy });
2859
+ });
2860
+ });
2861
+ this.selectSorted$ = this.select(state => state.sorted).pipe(distinctUntilChanged(sortsAreSame));
2862
+ this.$getSorts = this.selectSignal(() => this.$initializationState() !== InitializationState.Ready ? [] : this.$selectSorted());
2863
+ this.sort$ = toObservable(this.$getSorts);
2864
+ this.$getUserDefinedTableWidth = this.selectSignal(state => state.userDefined.table.width);
2865
+ this.getUserDefinedTableWidth$ = this.select(state => state.userDefined.table.width);
2866
+ this.$userDefinedRowHeight = this.selectSignal(state => (state.userDefined.rowHeight));
2867
+ this.$userDefinedHeaderHeight = this.selectSignal(state => (state.userDefined.headerHeight));
2868
+ this.$userDefinedPageSize = this.selectSignal(state => (state.userDefined.pageSize));
2869
+ this.$footerCollapsed = this.selectSignal(state => state.persistedTableSettings.collapseFooter);
2870
+ this.$headerCollapsed = this.selectSignal(state => state.persistedTableSettings.collapseHeader);
2871
+ this.$groupBy = this.selectSignal(state => state.groupBy);
2872
+ this.$groupByKeys = this.selectSignal(this.$groupBy, this.$metaDataArray, (gb, mds) => gb.map(gbk => gbk.key).filter(bg => mds.some(md => md.key === bg)), {
2873
+ equal: (prev, curr) => prev.length === curr.length && curr.every((k, i) => prev[i] === k)
2874
+ });
2875
+ this.groupByKeys$ = this.select(state => state.groupBy.map(gbk => gbk.key))
2876
+ .pipe(distinctUntilChanged((prev, curr) => prev.length === curr.length && curr.every((k, i) => prev[i] === k)));
2877
+ this.expandedGroups$ = this.select(state => state.groupBy).pipe(distinctUntilChanged((a, b) => {
2878
+ const aa = a.flatMap(g => g.expandedHeaders);
2879
+ const bb = b.flatMap(g => g.expandedHeaders);
2880
+ return aa.length === bb.length && aa.every((k) => bb.includes(k));
2881
+ }));
2882
+ this.$expandGroups = this.selectSignal(state => state.groupBy, { equal: (a, b) => {
2883
+ const aa = a.flatMap(g => g.expandedHeaders);
2884
+ const bb = b.flatMap(g => g.expandedHeaders);
2885
+ return aa.length === bb.length && aa.every((k) => bb.includes(k));
2886
+ } });
2887
+ this.$getIsExpanded = (columnKey, groupUniqueName) => {
2888
+ return this.selectSignal(state => !!state.groupBy.filter(g => g.key === columnKey && g.expandedHeaders.includes(groupUniqueName)).length);
2889
+ };
2890
+ this.$currentPage = this.selectSignal(state => state.currentPage);
2891
+ this.$pageSize = this.selectSignal(s => s.userDefined?.pageSize || s.pageSize);
2892
+ this.$showAll = this.selectSignal(s => s.userDefined?.showAll ?? s.showAll);
2893
+ this.$tableSettings = this.selectSignal(state => {
2894
+ const ts = { ...state.persistedTableSettings, ...state.notPersistedTableSettings };
2895
+ return ts;
2896
+ });
2897
+ this.$notPersistedTableSettings = this.selectSignal(state => state.notPersistedTableSettings);
2898
+ this.tableSettings$ = toObservable(this.$tableSettings);
2899
+ this.$props = this.selectSignal(s => s.props);
2900
+ this.$getLinkInfo = (md) => this.selectSignal(state => state.linkMaps[md.key]);
2901
+ this.$isVirtual = this.selectSignal(state => state.notPersistedTableSettings.useVirtualScroll
2902
+ || state.showAll
2903
+ || state.userDefined?.showAll);
2904
+ this.$viewType = this.selectSignal(state => {
2905
+ const usePaginator = state.notPersistedTableSettings.usePaginator;
2906
+ const showAll = state.showAll || state.userDefined?.showAll;
2907
+ const useVirtualScroll = state.notPersistedTableSettings.useVirtualScroll;
2908
+ if (showAll || (useVirtualScroll && !usePaginator)) {
2909
+ return 'virtual all';
2910
+ }
2911
+ else if (useVirtualScroll && usePaginator) {
2912
+ return 'virtual paginator';
2913
+ }
2914
+ else if (usePaginator) {
2915
+ return 'paginator';
2739
2916
  }
2740
2917
  else {
2741
- this.setDialogState(false);
2918
+ return 'all';
2742
2919
  }
2743
- };
2744
- }
2745
- set opDialogConfig(config) {
2746
- this._dialogConfig = { ...this.dialogConfig, ...defaultDialogConfig, ...config };
2747
- }
2748
- get opDialogConfig() {
2749
- return this._dialogConfig;
2750
- }
2751
- set setControl(i) {
2752
- let o;
2753
- if (isSignal(i)) {
2754
- o = toObservable(i, { injector: this.injector });
2755
- }
2756
- else {
2757
- o = i;
2758
- }
2759
- untracked(() => {
2760
- this.subscriber.on(o, this.setDataAndState);
2761
2920
  });
2762
- }
2763
- close() {
2764
- this.dialogRef?.close();
2765
- }
2766
- initDialog() {
2767
- if (this.nativeElement) {
2768
- const rect = this.nativeElement.getBoundingClientRect();
2769
- const position = { left: `${rect.left}px`, top: `${rect.bottom - 50}px` };
2770
- this.opDialogConfig = { ...this.opDialogConfig, position };
2771
- }
2772
- if (this.opDialogAddDialogClass) {
2773
- this.opDialogConfig.panelClass = [...(Array.isArray(this.opDialogConfig.panelClass) ? this.opDialogConfig.panelClass : this.opDialogConfig.panelClass ? [this.opDialogConfig.panelClass] : []), 'opDialog'];
2774
- }
2775
- this.dialogRef = this.dialog.open(DialogWrapper, this.opDialogConfig);
2776
- this.componentWrapper = this.dialogRef.componentInstance;
2777
- this.componentWrapper.close = () => this.dialogRef?.close();
2778
- this.componentWrapper.data = this.opDialogConfig.data;
2779
- this.componentWrapper.template = this.templateRef;
2780
- if (!this.opDialogConfig.disableClose) {
2781
- this.service.addDialogRef(this.dialogRef);
2782
- }
2783
- const sub = this.dialogRef.afterClosed().subscribe(() => {
2784
- this.opDialogClosed.emit(true);
2785
- this.service.removeDialogRef(this.dialogRef);
2786
- this.dialogRef = undefined;
2787
- sub.unsubscribe();
2921
+ this.resetState = this.updater((state) => {
2922
+ const sorted = this.$preSort();
2923
+ return ({ ...state, hiddenKeys: [], sorted, filters: {}, groupBy: [], userDefined: { widths: {}, order: {}, table: {} } });
2788
2924
  });
2789
- }
2790
- setDialogState(open) {
2791
- if (open) {
2792
- if (!this.dialogRef) {
2793
- this.initDialog();
2794
- }
2795
- else {
2796
- this.componentWrapper.data = this.opDialogConfig.data;
2925
+ this.resetPart = this.updater((state, part) => {
2926
+ const newState = { ...state };
2927
+ switch (part) {
2928
+ case 'Sorting':
2929
+ newState.sorted = this.$preSort();
2930
+ return newState;
2931
+ case 'Filters':
2932
+ newState.filters = {};
2933
+ return newState;
2934
+ case 'Group By':
2935
+ newState.groupBy = [];
2936
+ return newState;
2937
+ case 'Hidden Columns':
2938
+ newState.hiddenKeys = [];
2939
+ return newState;
2940
+ case 'Column Widths':
2941
+ newState.userDefined.widths = {};
2942
+ newState.userDefined.table = {};
2943
+ return newState;
2944
+ case 'Column Order':
2945
+ newState.userDefined.order = {};
2946
+ return newState;
2947
+ case 'Page Size':
2948
+ delete newState.userDefined.pageSize;
2949
+ return newState;
2950
+ case 'Show All':
2951
+ delete newState.userDefined.showAll;
2952
+ return newState;
2953
+ case 'Row Height':
2954
+ delete newState.userDefined.rowHeight;
2955
+ return newState;
2956
+ case 'Header Height':
2957
+ delete newState.userDefined.headerHeight;
2958
+ return newState;
2797
2959
  }
2798
- }
2799
- else if (!open && this.dialogRef) {
2800
- this.dialogRef.close();
2801
- }
2802
- }
2803
- static ngTemplateContextGuard(dir, ctx) {
2804
- return true;
2805
- }
2806
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.3", ngImport: i0, type: DialogDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
2807
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.0.3", type: DialogDirective, isStandalone: true, selector: "[opDialog]", inputs: { opDialogAddDialogClass: "opDialogAddDialogClass", opDialogConfig: "opDialogConfig", setControl: ["opDialog", "setControl"], nativeElement: ["opDialogOrigin", "nativeElement"] }, outputs: { opDialogClosed: "opDialogClosed" }, ngImport: i0 }); }
2808
- }
2809
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.3", ngImport: i0, type: DialogDirective, decorators: [{
2810
- type: Directive,
2811
- args: [{ selector: '[opDialog]', }]
2812
- }], propDecorators: { opDialogClosed: [{
2813
- type: Output
2814
- }], opDialogAddDialogClass: [{
2815
- type: Input
2816
- }], opDialogConfig: [{
2817
- type: Input
2818
- }], setControl: [{
2819
- type: Input,
2820
- args: ['opDialog']
2821
- }], nativeElement: [{
2822
- type: Input,
2823
- args: ['opDialogOrigin']
2824
- }] } });
2825
-
2826
- class StylerDirective {
2827
- constructor() {
2828
- this.el = inject(ElementRef);
2829
- this.renderer = inject(Renderer2);
2830
- this.$stylesApplied = signal({});
2831
- this.$element = input.required({ alias: 'element' });
2832
- this.$styler = input.required({ alias: 'styler' });
2833
- this.#stylerEffect = effect(() => {
2834
- const styles = this.$styler();
2835
- untracked(() => {
2836
- const element = this.$element();
2837
- const toApply = Object.entries(styles ?? {}).reduce((acc, [key, val]) => {
2838
- if (!val)
2839
- return acc;
2840
- if (typeof (val) === 'string') {
2841
- acc[key] = val;
2842
- this.el.nativeElement.style[key] = val;
2843
- }
2844
- else if (!val?.condition || val?.condition === true || val?.condition(element)) {
2845
- const value = typeof (val.value) === 'string' ? val.value : val?.value(element);
2846
- acc[key] = value;
2847
- this.el.nativeElement.style[key] = value;
2848
- }
2849
- return acc;
2850
- }, {});
2851
- Object.keys(this.$stylesApplied()).filter(key => !Object.keys(toApply).includes(key)).forEach(key => {
2852
- this.renderer.removeStyle(this.el.nativeElement, key);
2853
- });
2854
- this.$stylesApplied.set(toApply);
2960
+ });
2961
+ this.updateStateFromPersistedState = this.updater((state, persistedState) => {
2962
+ const incomingTableState = cleanPersistedState(state, persistedState);
2963
+ const newState = this.updateStateFunc(state, incomingTableState);
2964
+ newState.initializationState = state.initializationState <= InitializationState.MetaDataLoaded ? InitializationState.TableSettingsLoaded : state.initializationState;
2965
+ return newState;
2966
+ });
2967
+ this.updateStateFunc = (state, incomingTableState) => {
2968
+ const metaData = state.metaData;
2969
+ const sorted = incomingTableState.sorted?.length ? incomingTableState.sorted
2970
+ : state.initializationState <= InitializationState.Created ? createPreSort(metaData) : state.sorted;
2971
+ return { ...state, ...incomingTableState, metaData, sorted };
2972
+ };
2973
+ this.setTableSettings = this.updater((state, settings) => {
2974
+ const s = {
2975
+ ...state,
2976
+ persistedTableSettings: state.persistedTableSettings.merge(settings),
2977
+ notPersistedTableSettings: state.notPersistedTableSettings.merge(settings),
2978
+ initializationState: InitializationState.TableSettingsLoaded
2979
+ };
2980
+ s.pageSize = settings.tableSettings?.paginatorSettings?.pageSize ?? s.pageSize;
2981
+ s.showAll = settings.tableSettings?.paginatorSettings?.defaultAll ?? s.showAll;
2982
+ return s;
2983
+ });
2984
+ this.setMetaData = this.updater((state, md) => {
2985
+ const metaData = md
2986
+ .reduce((prev, curr) => {
2987
+ if (prev[curr.key]) {
2988
+ prev[curr.key] = mergeMeta(prev[curr.key], curr);
2989
+ }
2990
+ else {
2991
+ prev[curr.key] = curr;
2992
+ }
2993
+ return prev;
2994
+ }, {});
2995
+ const sortedInitialized = state.sorted.length > 0;
2996
+ const sorted = sortedInitialized ? state.sorted : createPreSort(metaData);
2997
+ const order = initializeOrder(state, metaData);
2998
+ const initializationState = state.initializationState == InitializationState.Created ? InitializationState.MetaDataLoaded : state.initializationState;
2999
+ return { ...state, initializationState, metaData, sorted, userDefined: { ...state.userDefined, order: order } };
3000
+ });
3001
+ this.showColumn = this.updater((state, key) => ({
3002
+ ...state,
3003
+ hiddenKeys: state.hiddenKeys.filter(k => k !== key),
3004
+ }));
3005
+ this.hideColumn = this.updater((state, key) => ({
3006
+ ...state,
3007
+ hiddenKeys: [...state.hiddenKeys.filter(k => k !== key), key],
3008
+ }));
3009
+ this.setHiddenColumns = this.updater((state, displayCols) => {
3010
+ return ({ ...state, hiddenKeys: displayCols.filter(d => !d.visible).map(d => d.key) });
3011
+ });
3012
+ this.setUserDefinedWidth = this.updater((state, colWidths) => {
3013
+ const userDefinedWidths = { ...state.userDefined.widths };
3014
+ colWidths.forEach(cw => {
3015
+ userDefinedWidths[cw.key] = cw.widthInPixel;
2855
3016
  });
3017
+ return { ...state, userDefined: { ...state.userDefined, widths: userDefinedWidths } };
3018
+ });
3019
+ this.setUserDefinedOrder = this.updater((state, moved) => {
3020
+ const { newOrder, oldOrder } = moved;
3021
+ const mdsArr = orderedStateVisibleMetaData(state);
3022
+ moveItemInArray(mdsArr, oldOrder, newOrder);
3023
+ const userDefinedOrder = mdsArr.reduce((aggregate, current, index) => {
3024
+ aggregate[current.key] = index;
3025
+ return aggregate;
3026
+ }, {});
3027
+ return ({ ...state, userDefined: { ...state.userDefined, order: userDefinedOrder } });
3028
+ });
3029
+ this.setUserDefinedRowHeight = this.updater((state, rowHeight) => {
3030
+ return ({ ...state, userDefined: { ...state.userDefined, rowHeight } });
3031
+ });
3032
+ this.setUserDefinedHeaderHeight = this.updater((state, headerHeight) => {
3033
+ return ({ ...state, userDefined: { ...state.userDefined, headerHeight } });
3034
+ });
3035
+ this.addFilter = this.updater((state, filter) => {
3036
+ return this.addFiltersToState(state, [filter]);
3037
+ });
3038
+ this.addFilters = this.updater((state, filters) => {
3039
+ return this.addFiltersToState(state, filters);
3040
+ });
3041
+ this.removeFilter = this.updater((state, filterId) => {
3042
+ const filtersCopy = { ...state.filters };
3043
+ delete filtersCopy[filterId];
3044
+ return ({ ...state, filters: filtersCopy });
3045
+ });
3046
+ this.removeFilters = this.updater((state, filterIds) => {
3047
+ const filtersCopy = { ...state.filters };
3048
+ filterIds.forEach(id => { delete filtersCopy[id]; });
3049
+ return ({ ...state, filters: filtersCopy });
2856
3050
  });
2857
- }
2858
- #stylerEffect;
2859
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.3", ngImport: i0, type: StylerDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
2860
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "20.0.3", type: StylerDirective, isStandalone: true, selector: "[styler]", inputs: { $element: { classPropertyName: "$element", publicName: "element", isSignal: true, isRequired: true, transformFunction: null }, $styler: { classPropertyName: "$styler", publicName: "styler", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0 }); }
2861
- }
2862
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.3", ngImport: i0, type: StylerDirective, decorators: [{
2863
- type: Directive,
2864
- args: [{ selector: '[styler]' }]
2865
- }] });
2866
-
2867
- class MatSlideToggleGroupDirective {
2868
- constructor() {
2869
- this.allowMultiple = false;
2870
- this._ready = new ReplaySubject(1);
2871
- }
2872
- set toggles(val) {
2873
- this._toggles = val;
2874
- this._ready.next(true);
2875
- }
2876
- get valueEmitter() {
2877
- return this._ready.pipe(switchMap$1(_ => this.getObs()));
2878
- }
2879
- getInitValue() {
2880
- const startValue = this._toggles.reduce((prev, cur) => {
2881
- if (!cur.name) {
2882
- throw new Error('toggle must have the name attribute set');
2883
- }
2884
- prev[cur.name] = cur.checked;
2885
- return prev;
2886
- }, {});
2887
- return startValue;
2888
- }
2889
- getObs() {
2890
- var toggleChanges = merge(...this._toggles.map(toggle => toggle.change));
2891
- const startValue = this.getInitValue();
2892
- return toggleChanges.pipe(scan((prev, cur) => {
2893
- const toggleName = cur.source.name;
2894
- const newVal = { ...prev, [toggleName]: cur.checked };
2895
- if (cur.checked && !this.allowMultiple) {
2896
- Object.keys(prev)
2897
- .filter(key => key !== toggleName && prev[key])
2898
- .forEach(key => {
2899
- newVal[key] = false;
2900
- this._toggles.find(toggle => toggle.name === key).toggle();
2901
- });
2902
- }
2903
- return newVal;
2904
- }, startValue), startWith$1(startValue));
2905
- }
2906
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.3", ngImport: i0, type: MatSlideToggleGroupDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
2907
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.0.3", type: MatSlideToggleGroupDirective, isStandalone: true, selector: "[opMatSlideToggleGroup]", inputs: { allowMultiple: "allowMultiple" }, outputs: { valueEmitter: "valueEmitter" }, queries: [{ propertyName: "toggles", predicate: MatSlideToggle }], ngImport: i0 }); }
2908
- }
2909
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.3", ngImport: i0, type: MatSlideToggleGroupDirective, decorators: [{
2910
- type: Directive,
2911
- args: [{ selector: '[opMatSlideToggleGroup]',
2912
- }]
2913
- }], propDecorators: { allowMultiple: [{
2914
- type: Input
2915
- }], toggles: [{
2916
- type: ContentChildren,
2917
- args: [MatSlideToggle]
2918
- }], valueEmitter: [{
2919
- type: Output
2920
- }] } });
2921
-
2922
- class TrimWhitespaceDirective {
2923
- constructor() {
2924
- this.elem = inject(ElementRef);
2925
- }
2926
- onBlur() {
2927
- const inputString = this.elem.nativeElement.value;
2928
- if (inputString) {
2929
- const newValue = inputString.trim().replace(/\t/g, '');
2930
- if (inputString !== newValue) {
2931
- this.elem.nativeElement.value = newValue;
2932
- this.elem.nativeElement.dispatchEvent(new Event('input', { bubbles: true }));
3051
+ this.clearFilters = this.updater((state) => ({ ...state, filters: {} }));
3052
+ this.addFiltersToState = (state, filters) => {
3053
+ var customFilters = filters.filter(isCustomFilter);
3054
+ var filterInfos = filters.filter(isFilterInfo);
3055
+ const filtersObj = filterInfos
3056
+ .filter(fltr => Object.keys(state.metaData).some(key => key === fltr.key) || console.warn(`Meta data with key ${fltr.key} not found`))
3057
+ .reduce((filtersObj, filter) => {
3058
+ if (!filter.filterId) {
3059
+ filter.filterId = crypto.randomUUID();
3060
+ }
3061
+ filtersObj[filter.filterId] = filter;
3062
+ return filtersObj;
3063
+ }, {});
3064
+ customFilters.forEach(fltr => {
3065
+ if (!fltr.filterId) {
3066
+ fltr.filterId = crypto.randomUUID();
3067
+ }
3068
+ filtersObj[fltr.filterId] = fltr;
3069
+ });
3070
+ return {
3071
+ ...state,
3072
+ filters: { ...state.filters, ...filtersObj }
3073
+ };
3074
+ };
3075
+ this.setSort = this.updater((state, { key, direction }) => {
3076
+ const sortArray = state.sorted.filter(s => s.active !== key);
3077
+ if (direction) {
3078
+ sortArray.unshift({ active: key, direction });
2933
3079
  }
2934
- }
2935
- }
2936
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.3", ngImport: i0, type: TrimWhitespaceDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
2937
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.0.3", type: TrimWhitespaceDirective, isStandalone: true, selector: "input[trimWhitespace]", host: { listeners: { "blur": "onBlur()" } }, ngImport: i0 }); }
2938
- }
2939
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.3", ngImport: i0, type: TrimWhitespaceDirective, decorators: [{
2940
- type: Directive,
2941
- args: [{
2942
- selector: 'input[trimWhitespace]',
2943
- }]
2944
- }], propDecorators: { onBlur: [{
2945
- type: HostListener,
2946
- args: ['blur']
2947
- }] } });
2948
-
2949
- class FunctionPipe {
2950
- transform(func, ...args) {
2951
- if (typeof func === 'string') {
2952
- const [instance, ...tail] = args;
2953
- const method = instance[func].bind(instance);
2954
- return method(...tail);
2955
- }
2956
- return func(...args);
3080
+ return {
3081
+ ...state,
3082
+ sorted: sortArray,
3083
+ };
3084
+ });
3085
+ this.setAllSort = this.updater((state, sortArray) => {
3086
+ return {
3087
+ ...state,
3088
+ sorted: sortArray,
3089
+ };
3090
+ });
3091
+ this.setCurrentPage = this.updater((state, currentPage) => ({ ...state, currentPage }));
3092
+ this.setPageSize = this.updater((state, pageSize) => ({ ...state, pageSize }));
3093
+ this.setUserDefinedPageSize = this.updater((state, pageSize) => ({ ...state, userDefined: { ...state.userDefined, pageSize } }));
3094
+ this.setUserDefinedShowAll = this.updater((state, showAll) => ({ ...state, showAll, userDefined: { ...state.userDefined, showAll } }));
3095
+ this.setProps = this.updater((state, props) => {
3096
+ return ({ ...state, props });
3097
+ });
3098
+ this.setTableWidth = this.updater((state, widthInPixels) => ({ ...state, userDefined: { ...state.userDefined, table: { width: widthInPixels } } }));
3099
+ this.setInitializationState = this.updater((state, initializationState) => {
3100
+ return { ...state, initializationState };
3101
+ });
3102
+ this.toggleCollapseHeader = this.updater((state) => {
3103
+ const tableSettings = { ...state.persistedTableSettings };
3104
+ tableSettings.collapseHeader = !tableSettings.collapseHeader;
3105
+ return ({ ...state, persistedTableSettings: new PersistedTableSettings(tableSettings) });
3106
+ });
3107
+ this.toggleCollapseFooter = this.updater((state, options) => {
3108
+ const tableSettings = { ...state.persistedTableSettings };
3109
+ tableSettings.collapseFooter = options?.collapseFooter ?? !tableSettings.collapseFooter;
3110
+ return ({ ...state, persistedTableSettings: new PersistedTableSettings(tableSettings) });
3111
+ });
3112
+ this.addGroupByKey = this.updater((state, metaDataKey) => ({
3113
+ ...state,
3114
+ groupBy: [...state.groupBy, { key: metaDataKey, expandedHeaders: [] }]
3115
+ }));
3116
+ this.removeGroupByKey = this.updater((state, groupByKey) => ({
3117
+ ...state,
3118
+ groupBy: state.groupBy.filter(key => groupByKey !== key.key)
3119
+ }));
3120
+ this.updateExpandedGroups = this.updater((state, data) => {
3121
+ const gbk = replaceInArrayWithClone(state.groupBy, k => k.key === data.key, gk => {
3122
+ gk.expandedHeaders = data.isExpanded ? [...gk.expandedHeaders, data.groupUniqueName] : gk.expandedHeaders.filter(g => g !== data.groupUniqueName);
3123
+ });
3124
+ return ({
3125
+ ...state,
3126
+ groupBy: gbk
3127
+ });
3128
+ });
3129
+ this.expandAllOfGroup = this.updater((state, data) => {
3130
+ const newGroupedData = state.groupBy.map(gb => ({
3131
+ key: gb.key,
3132
+ expandedHeaders: data.groupHeadersByKey[gb.key]?.map(g => g.uniqueName) ?? gb.expandedHeaders
3133
+ }));
3134
+ return ({ ...state, groupBy: newGroupedData });
3135
+ });
3136
+ this.collapseAll = this.updater((state) => ({
3137
+ ...state,
3138
+ groupBy: state.groupBy.map(gb => ({ key: gb.key, expandedHeaders: [] }))
3139
+ }));
3140
+ this.collapseAllOfKey = this.updater((state, data) => ({
3141
+ ...state,
3142
+ groupBy: state.groupBy.map(gb => ({
3143
+ key: gb.key,
3144
+ expandedHeaders: data.keys.includes(gb.key) ? [] : gb.expandedHeaders
3145
+ }))
3146
+ }));
3147
+ this.setLinkMaps = this.updater((state, maps) => {
3148
+ return ({ ...state, linkMaps: maps });
3149
+ });
3150
+ this.updateRowProps = this.updater((state, updates) => {
3151
+ const notPersistedTableSettings = merge$1(new NotPersistedTableSettings(), (state.notPersistedTableSettings));
3152
+ if (updates.rowClasses)
3153
+ notPersistedTableSettings.rowClasses = updates.rowClasses;
3154
+ if (updates.rowClick)
3155
+ notPersistedTableSettings.rowClick = updates.rowClick;
3156
+ if (updates.rowStyles)
3157
+ notPersistedTableSettings.rowStyles = updates.rowStyles;
3158
+ return ({ ...state, notPersistedTableSettings });
3159
+ });
3160
+ this.on = (srcObservable, func) => {
3161
+ this.effect(() => srcObservable.pipe(tap(func)));
3162
+ return this;
3163
+ };
2957
3164
  }
2958
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.3", ngImport: i0, type: FunctionPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); }
2959
- static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "20.0.3", ngImport: i0, type: FunctionPipe, isStandalone: true, name: "func" }); }
3165
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.3", ngImport: i0, type: TableStore, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
3166
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.0.3", ngImport: i0, type: TableStore }); }
2960
3167
  }
2961
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.3", ngImport: i0, type: FunctionPipe, decorators: [{
2962
- type: Pipe,
2963
- args: [{
2964
- name: 'func',
2965
- }]
2966
- }] });
2967
-
2968
- class ConditionalClassesDirective {
2969
- constructor() {
2970
- this.el = inject(ElementRef);
2971
- this.renderer = inject(Renderer2);
2972
- this.$element = input.required({ alias: 'element' });
2973
- this.$classes = input(undefined, { alias: 'conditionalClasses' });
2974
- this.classesApplied = [];
2975
- this.#onClasses = effect(() => {
2976
- const classes = this.$classes();
2977
- untracked(() => {
2978
- const element = this.$element();
2979
- let toApply = [];
2980
- if (classes) {
2981
- toApply = Object.keys(classes)
2982
- .filter(key => (classes[key] === true) || classes[key](element));
2983
- }
2984
- var classesNotYetApplied = toApply.filter(c => !this.classesApplied.includes(c));
2985
- var classesToRemove = this.classesApplied.filter(c => !toApply.includes(c));
2986
- classesToRemove.forEach(c => this.renderer.removeClass(this.el.nativeElement, c));
2987
- classesNotYetApplied.forEach(c => this.renderer.addClass(this.el.nativeElement, c));
2988
- this.classesApplied = toApply;
2989
- });
3168
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.3", ngImport: i0, type: TableStore, decorators: [{
3169
+ type: Injectable
3170
+ }], ctorParameters: () => [] });
3171
+ const resetable = [
3172
+ 'Sorting',
3173
+ 'Filters',
3174
+ 'Group By',
3175
+ 'Hidden Columns',
3176
+ 'Column Widths',
3177
+ 'Column Order',
3178
+ 'Row Height',
3179
+ 'Header Height',
3180
+ 'Page Size',
3181
+ 'Show All',
3182
+ ];
3183
+
3184
+ class MultiSortDirective extends MatSort {
3185
+ constructor() {
3186
+ super();
3187
+ this.state = inject(TableStore);
3188
+ this.state.setSort(this.sortChange.pipe(distinctUntilChanged((f, s) => f.active === s.active && f.direction === s.direction), map(sc => ({ key: sc.active, direction: sc.direction }))));
3189
+ this.state.on(this.state.sort$, (rules) => {
3190
+ const topRule = { active: rules[0]?.active || '', direction: rules[0]?.direction || '' };
3191
+ const topActiveChanged = topRule.active !== this.active || '';
3192
+ const topDirectionChanged = topRule.direction !== this.direction || '';
3193
+ if (topActiveChanged || topDirectionChanged) {
3194
+ this.active = topRule.active;
3195
+ this.direction = topRule.direction;
3196
+ this.sortChange.emit(topRule);
3197
+ }
2990
3198
  });
2991
3199
  }
2992
- #onClasses;
2993
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.3", ngImport: i0, type: ConditionalClassesDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
2994
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "20.0.3", type: ConditionalClassesDirective, isStandalone: true, selector: "[conditionalClasses]", inputs: { $element: { classPropertyName: "$element", publicName: "element", isSignal: true, isRequired: true, transformFunction: null }, $classes: { classPropertyName: "$classes", publicName: "conditionalClasses", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0 }); }
3200
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.3", ngImport: i0, type: MultiSortDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
3201
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.0.3", type: MultiSortDirective, isStandalone: true, selector: "[multiSort]", inputs: { disabled: ["matSortDisabled", "disabled"] }, providers: [
3202
+ { provide: MatSort, useExisting: MultiSortDirective }
3203
+ ], exportAs: ["multiSort"], usesInheritance: true, ngImport: i0 }); }
2995
3204
  }
2996
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.3", ngImport: i0, type: ConditionalClassesDirective, decorators: [{
3205
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.3", ngImport: i0, type: MultiSortDirective, decorators: [{
2997
3206
  type: Directive,
2998
3207
  args: [{
2999
- selector: '[conditionalClasses]',
3208
+ selector: '[multiSort]',
3209
+ exportAs: 'multiSort',
3210
+ inputs: ['disabled: matSortDisabled'],
3211
+ providers: [
3212
+ { provide: MatSort, useExisting: MultiSortDirective }
3213
+ ],
3000
3214
  }]
3001
- }] });
3215
+ }], ctorParameters: () => [] });
3216
+ function sortsAreSame(a, b) {
3217
+ if (a.length !== b.length) {
3218
+ return false;
3219
+ }
3220
+ for (let i = 0; i < a.length; i++) {
3221
+ if (a[i].active !== b[i].active || a[i].direction !== b[i].direction) {
3222
+ return false;
3223
+ }
3224
+ }
3225
+ return true;
3226
+ }
3002
3227
 
3003
- class UtilitiesModule {
3004
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.3", ngImport: i0, type: UtilitiesModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
3005
- static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.0.3", ngImport: i0, type: UtilitiesModule, imports: [SpaceCasePipe,
3006
- PhoneNumberPipe,
3007
- FunctionPipe,
3008
- StopPropagationDirective,
3009
- StylerDirective,
3010
- PreventEnterDirective,
3011
- AutoFocusDirective,
3012
- TrimWhitespaceDirective,
3013
- ClickSubjectDirective,
3014
- ClickEmitterDirective,
3015
- DialogDirective,
3016
- MatSlideToggleGroupDirective,
3017
- ConditionalClassesDirective], exports: [StopPropagationDirective,
3018
- PreventEnterDirective,
3019
- SpaceCasePipe,
3020
- PhoneNumberPipe,
3021
- FunctionPipe,
3022
- TrimWhitespaceDirective,
3023
- StylerDirective,
3024
- AutoFocusDirective,
3025
- ClickSubjectDirective,
3026
- ClickEmitterDirective,
3027
- DialogDirective,
3028
- MatSlideToggleGroupDirective,
3029
- ConditionalClassesDirective] }); }
3030
- static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.0.3", ngImport: i0, type: UtilitiesModule, providers: [
3031
- DialogService
3032
- ] }); }
3228
+ class DateFilterComponent {
3229
+ constructor() {
3230
+ this.FilterType = FilterType;
3231
+ }
3232
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.3", ngImport: i0, type: DateFilterComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
3233
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.0.3", type: DateFilterComponent, isStandalone: true, selector: "tb-date-filter", inputs: { info: "info", CurrentFilterType: "CurrentFilterType" }, ngImport: i0, template: "@if (CurrentFilterType !== FilterType.DateBetween && CurrentFilterType !== FilterType.IsNull)\r\n{\r\n <mat-form-field>\r\n <input matInput name=\"filterValue\" [ngModel]=\"info.filterValue\" [matDatepicker]=\"cal\"/>\r\n <mat-datepicker-toggle class=\"small-button date-toggle\" matSuffix preventEnter [for]=\"cal\" />\r\n <mat-datepicker #cal />\r\n </mat-form-field>\r\n}\r\n@if(CurrentFilterType === FilterType.DateBetween)\r\n{\r\n <ng-container ngModelGroup=\"filterValue\">\r\n <mat-form-field class=\"my-filter\" >\r\n <input matInput name=\"Start\" placeholder=\"From\" [ngModel]=\"info.filterValue?.Start\" [matDatepicker]=\"fromVal\"\r\n (click)=\"fromVal.open()\"/>\r\n <mat-datepicker-toggle matSuffix class=\"small-button date-toggle\" preventEnter [for]=\"fromVal\" />\r\n <mat-datepicker #fromVal />\r\n </mat-form-field>\r\n <mat-form-field>\r\n <input matInput name=\"End\" placeholder=\"To\" [ngModel]=\"info.filterValue?.End\" [matDatepicker]=\"toVal\" (click)=\"toVal.open()\"/>\r\n <mat-datepicker-toggle matSuffix class=\"small-button date-toggle\" preventEnter [for]=\"toVal\" />\r\n <mat-datepicker #toVal />\r\n </mat-form-field>\r\n </ng-container>\r\n}\r\n\r\n", styles: [".filter-name{color:var(tb-filter-name);margin:10px 0;font-weight:600;display:inline-block}.switch{display:inline-block}.head-row{display:flex;width:100%;align-items:center;justify-content:space-between}.filter-row{display:flex;align-items:center;gap:1rem}mat-card.filter-card::ng-deep mat-form-field{width:150px}mat-card.filter-card::ng-deep .mat-mdc-form-field-subscript-wrapper{line-height:0}mat-card.filter-card::ng-deep .mat-mdc-form-field-subscript-wrapper:before{height:0}.inline{display:inline-block}.small-button{height:18px;width:18px;font-size:18px;padding:0;margin:0}.small-button ::ng-deep *{line-height:initial;font-size:initial;height:18px;width:18px;font-size:18px;bottom:initial}.cancel-button{font-weight:700}.date-toggle ::ng-deep svg{position:absolute;left:0;top:0}\n"], dependencies: [{ kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i1$1.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "component", type: i1$1.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i1$1.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.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: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i2.NgModelGroup, selector: "[ngModelGroup]", inputs: ["ngModelGroup"], exportAs: ["ngModelGroup"] }, { kind: "ngmodule", type: MatDatepickerModule }, { kind: "component", type: i3.MatDatepicker, selector: "mat-datepicker", exportAs: ["matDatepicker"] }, { kind: "directive", type: i3.MatDatepickerInput, selector: "input[matDatepicker]", inputs: ["matDatepicker", "min", "max", "matDatepickerFilter"], exportAs: ["matDatepickerInput"] }, { kind: "component", type: i3.MatDatepickerToggle, selector: "mat-datepicker-toggle", inputs: ["for", "tabIndex", "aria-label", "disabled", "disableRipple"], exportAs: ["matDatepickerToggle"] }], viewProviders: [{ provide: ControlContainer, useExisting: NgForm }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
3033
3234
  }
3034
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.3", ngImport: i0, type: UtilitiesModule, decorators: [{
3035
- type: NgModule,
3036
- args: [{
3037
- exports: [
3038
- StopPropagationDirective,
3039
- PreventEnterDirective,
3040
- SpaceCasePipe,
3041
- PhoneNumberPipe,
3042
- FunctionPipe,
3043
- TrimWhitespaceDirective,
3044
- StylerDirective,
3045
- AutoFocusDirective,
3046
- ClickSubjectDirective,
3047
- ClickEmitterDirective,
3048
- DialogDirective,
3049
- MatSlideToggleGroupDirective,
3050
- ConditionalClassesDirective,
3051
- ],
3052
- imports: [
3053
- SpaceCasePipe,
3054
- PhoneNumberPipe,
3055
- FunctionPipe,
3056
- StopPropagationDirective,
3057
- StylerDirective,
3058
- PreventEnterDirective,
3059
- AutoFocusDirective,
3060
- TrimWhitespaceDirective,
3061
- ClickSubjectDirective,
3062
- ClickEmitterDirective,
3063
- DialogDirective,
3064
- MatSlideToggleGroupDirective,
3065
- ConditionalClassesDirective,
3066
- ],
3067
- providers: [
3068
- DialogService
3069
- ]
3070
- }]
3071
- }] });
3235
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.3", ngImport: i0, type: DateFilterComponent, decorators: [{
3236
+ type: Component,
3237
+ args: [{ selector: 'tb-date-filter', changeDetection: ChangeDetectionStrategy.OnPush, viewProviders: [{ provide: ControlContainer, useExisting: NgForm }], imports: [
3238
+ MatInputModule, FormsModule, MatDatepickerModule
3239
+ ], template: "@if (CurrentFilterType !== FilterType.DateBetween && CurrentFilterType !== FilterType.IsNull)\r\n{\r\n <mat-form-field>\r\n <input matInput name=\"filterValue\" [ngModel]=\"info.filterValue\" [matDatepicker]=\"cal\"/>\r\n <mat-datepicker-toggle class=\"small-button date-toggle\" matSuffix preventEnter [for]=\"cal\" />\r\n <mat-datepicker #cal />\r\n </mat-form-field>\r\n}\r\n@if(CurrentFilterType === FilterType.DateBetween)\r\n{\r\n <ng-container ngModelGroup=\"filterValue\">\r\n <mat-form-field class=\"my-filter\" >\r\n <input matInput name=\"Start\" placeholder=\"From\" [ngModel]=\"info.filterValue?.Start\" [matDatepicker]=\"fromVal\"\r\n (click)=\"fromVal.open()\"/>\r\n <mat-datepicker-toggle matSuffix class=\"small-button date-toggle\" preventEnter [for]=\"fromVal\" />\r\n <mat-datepicker #fromVal />\r\n </mat-form-field>\r\n <mat-form-field>\r\n <input matInput name=\"End\" placeholder=\"To\" [ngModel]=\"info.filterValue?.End\" [matDatepicker]=\"toVal\" (click)=\"toVal.open()\"/>\r\n <mat-datepicker-toggle matSuffix class=\"small-button date-toggle\" preventEnter [for]=\"toVal\" />\r\n <mat-datepicker #toVal />\r\n </mat-form-field>\r\n </ng-container>\r\n}\r\n\r\n", styles: [".filter-name{color:var(tb-filter-name);margin:10px 0;font-weight:600;display:inline-block}.switch{display:inline-block}.head-row{display:flex;width:100%;align-items:center;justify-content:space-between}.filter-row{display:flex;align-items:center;gap:1rem}mat-card.filter-card::ng-deep mat-form-field{width:150px}mat-card.filter-card::ng-deep .mat-mdc-form-field-subscript-wrapper{line-height:0}mat-card.filter-card::ng-deep .mat-mdc-form-field-subscript-wrapper:before{height:0}.inline{display:inline-block}.small-button{height:18px;width:18px;font-size:18px;padding:0;margin:0}.small-button ::ng-deep *{line-height:initial;font-size:initial;height:18px;width:18px;font-size:18px;bottom:initial}.cancel-button{font-weight:700}.date-toggle ::ng-deep svg{position:absolute;left:0;top:0}\n"] }]
3240
+ }], propDecorators: { info: [{
3241
+ type: Input
3242
+ }], CurrentFilterType: [{
3243
+ type: Input
3244
+ }] } });
3072
3245
 
3073
3246
  class InFilterComponent {
3074
3247
  constructor() {
@@ -3114,7 +3287,7 @@ class InFilterComponent {
3114
3287
  provide: NG_VALUE_ACCESSOR,
3115
3288
  useExisting: InFilterComponent,
3116
3289
  multi: true
3117
- }], ngImport: i0, template: "<div class=inline>\r\n @for (val of value; track $index)\r\n {\r\n <div>\r\n @if($type() === FieldType.Number || $type() === FieldType.Currency)\r\n {\r\n <input type=\"number\" [ngModel]=\"val\"\r\n [readonly]=\"$index + 1 < value.length\" [ngModelOptions]=\"{standalone:true}\" [autoFocus]=\"$index === value.length - 1\" (ngModelChange)=\"onValueChange($index, $event)\"/>\r\n }\r\n @else\r\n {\r\n <input #input type=\"string\"\r\n [ngModel]=\"val\" [readonly]=\"$index + 1 < value.length\" [ngModelOptions]=\"{standalone:true}\"\r\n [autoFocus]=\"$index === value.length - 1\" (ngModelChange)=\"onValueChange($index ,$event)\" />\r\n }\r\n </div>\r\n <button [disabled]=\"value.length <= 1\" (click)=\"removeInput($index)\">-</button>\r\n @if ($index === value.length - 1)\r\n {\r\n <button [disabled]=\"val == undefined || val === ''\" (click)=\"addInput()\">+</button>\r\n }\r\n }\r\n</div>\r\n", styles: [".inline{display:inline-block}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.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: i2.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: AutoFocusDirective, selector: "[autoFocus]", inputs: ["autoFocus"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
3290
+ }], ngImport: i0, template: "<div class=inline>\r\n @for (val of value; track $index)\r\n {\r\n <div>\r\n @if($type() === FieldType.Number || $type() === FieldType.Currency)\r\n {\r\n <input type=\"number\" [ngModel]=\"val\"\r\n [readonly]=\"$index + 1 < value.length\" [ngModelOptions]=\"{standalone:true}\"\r\n [autoFocus]=\"$index === value.length - 1\" (ngModelChange)=\"onValueChange($index, $event)\"/>\r\n }\r\n @else\r\n {\r\n <input #input type=\"string\"\r\n [ngModel]=\"val\" [readonly]=\"$index + 1 < value.length\" [ngModelOptions]=\"{standalone:true}\"\r\n [autoFocus]=\"$index === value.length - 1\" (ngModelChange)=\"onValueChange($index ,$event)\" />\r\n }\r\n </div>\r\n <button [disabled]=\"value.length <= 1\" (click)=\"removeInput($index)\">-</button>\r\n @if ($index === value.length - 1)\r\n {\r\n <button [disabled]=\"val == undefined || val === ''\" (click)=\"addInput()\">+</button>\r\n }\r\n }\r\n</div>\r\n", styles: [".inline{display:inline-block}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.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: i2.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: AutoFocusDirective, selector: "[autoFocus]", inputs: ["autoFocus"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
3118
3291
  }
3119
3292
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.3", ngImport: i0, type: InFilterComponent, decorators: [{
3120
3293
  type: Component,
@@ -3124,7 +3297,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.3", ngImpor
3124
3297
  multi: true
3125
3298
  }], imports: [
3126
3299
  FormsModule, AutoFocusDirective
3127
- ], template: "<div class=inline>\r\n @for (val of value; track $index)\r\n {\r\n <div>\r\n @if($type() === FieldType.Number || $type() === FieldType.Currency)\r\n {\r\n <input type=\"number\" [ngModel]=\"val\"\r\n [readonly]=\"$index + 1 < value.length\" [ngModelOptions]=\"{standalone:true}\" [autoFocus]=\"$index === value.length - 1\" (ngModelChange)=\"onValueChange($index, $event)\"/>\r\n }\r\n @else\r\n {\r\n <input #input type=\"string\"\r\n [ngModel]=\"val\" [readonly]=\"$index + 1 < value.length\" [ngModelOptions]=\"{standalone:true}\"\r\n [autoFocus]=\"$index === value.length - 1\" (ngModelChange)=\"onValueChange($index ,$event)\" />\r\n }\r\n </div>\r\n <button [disabled]=\"value.length <= 1\" (click)=\"removeInput($index)\">-</button>\r\n @if ($index === value.length - 1)\r\n {\r\n <button [disabled]=\"val == undefined || val === ''\" (click)=\"addInput()\">+</button>\r\n }\r\n }\r\n</div>\r\n", styles: [".inline{display:inline-block}\n"] }]
3300
+ ], template: "<div class=inline>\r\n @for (val of value; track $index)\r\n {\r\n <div>\r\n @if($type() === FieldType.Number || $type() === FieldType.Currency)\r\n {\r\n <input type=\"number\" [ngModel]=\"val\"\r\n [readonly]=\"$index + 1 < value.length\" [ngModelOptions]=\"{standalone:true}\"\r\n [autoFocus]=\"$index === value.length - 1\" (ngModelChange)=\"onValueChange($index, $event)\"/>\r\n }\r\n @else\r\n {\r\n <input #input type=\"string\"\r\n [ngModel]=\"val\" [readonly]=\"$index + 1 < value.length\" [ngModelOptions]=\"{standalone:true}\"\r\n [autoFocus]=\"$index === value.length - 1\" (ngModelChange)=\"onValueChange($index ,$event)\" />\r\n }\r\n </div>\r\n <button [disabled]=\"value.length <= 1\" (click)=\"removeInput($index)\">-</button>\r\n @if ($index === value.length - 1)\r\n {\r\n <button [disabled]=\"val == undefined || val === ''\" (click)=\"addInput()\">+</button>\r\n }\r\n }\r\n</div>\r\n", styles: [".inline{display:inline-block}\n"] }]
3128
3301
  }], ctorParameters: () => [] });
3129
3302
 
3130
3303
  class NumberFilterComponent {
@@ -3178,10 +3351,21 @@ class InListFilterComponent {
3178
3351
  this.$key = input.required({ alias: 'key' });
3179
3352
  this.$selectedKeys = signal([]);
3180
3353
  this.$metaData = computed(() => this.tableState.$getMetaData(this.$key())());
3354
+ this.$allValues = computed(() => {
3355
+ const filterable = this.$metaData()?.additional?.filterOptions?.filterableValues;
3356
+ return filterable === 'all values' || filterable?.allValues === true;
3357
+ });
3358
+ this.$specialBlank = computed(() => {
3359
+ const specialBlank = this.tableState.selectSignal(s => s.allFilters)()[this.$metaData().key]?.find(k => isBlankValueFilter(k));
3360
+ if (!specialBlank)
3361
+ return;
3362
+ return { key: specialBlank, value: 'BLANK' };
3363
+ });
3364
+ this.$specialBlankSelected = computed(() => this.$selectedKeys().some(k => isBlankValueFilter(k.value)));
3181
3365
  this.$keyValues = computed(() => {
3182
3366
  const metaData = this.$metaData();
3183
- if (metaData?.additional?.filterOptions?.filterableValues === 'all values') {
3184
- return this.tableState.selectSignal(s => s.allFilters)()[metaData.key].map(f => ({ key: f, value: f }));
3367
+ if (this.$allValues()) {
3368
+ return this.tableState.selectSignal(s => s.allFilters)()[metaData.key].filter(isNotBlankValueFilter).map(f => ({ key: f, value: f }));
3185
3369
  }
3186
3370
  else if (metaData?.additional?.filterOptions?.filterableValues) {
3187
3371
  return metaData.additional.filterOptions.filterableValues.map(value => ({ key: value, value }));
@@ -3229,6 +3413,14 @@ class InListFilterComponent {
3229
3413
  useExisting: InListFilterComponent,
3230
3414
  multi: true
3231
3415
  }], ngImport: i0, template: `
3416
+ @if($specialBlank(); as specialBlank)
3417
+ {
3418
+ <div>
3419
+ <mat-checkbox [checked]="$specialBlankSelected()" stop-propagation (change)='selectFilterChanged($event, specialBlank)' >
3420
+ {{specialBlank.value}} PIZAA
3421
+ </mat-checkbox>
3422
+ </div>
3423
+ }
3232
3424
  @switch ($metaData().fieldType)
3233
3425
  {
3234
3426
  @case (FieldType.Enum)
@@ -3294,6 +3486,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.3", ngImpor
3294
3486
  args: [{
3295
3487
  selector: 'tb-in-list-filter',
3296
3488
  template: `
3489
+ @if($specialBlank(); as specialBlank)
3490
+ {
3491
+ <div>
3492
+ <mat-checkbox [checked]="$specialBlankSelected()" stop-propagation (change)='selectFilterChanged($event, specialBlank)' >
3493
+ {{specialBlank.value}} PIZAA
3494
+ </mat-checkbox>
3495
+ </div>
3496
+ }
3297
3497
  @switch ($metaData().fieldType)
3298
3498
  {
3299
3499
  @case (FieldType.Enum)
@@ -3514,95 +3714,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.3", ngImpor
3514
3714
  args: [{ name: 'formatFilterType' }]
3515
3715
  }] });
3516
3716
 
3517
- function isPipe(o) {
3518
- return typeof (o.transform) === 'function';
3519
- }
3520
- function createTransformer(metaData, config, noIcons = false, forItem = false) {
3521
- const defaultFunc = getFactory(metaData.key);
3522
- if (metaData.map && !forItem) {
3523
- return (value) => {
3524
- return metaData.map(value);
3525
- };
3526
- }
3527
- if (metaData.mapItem) {
3528
- return (value) => {
3529
- return metaData.mapItem(defaultFunc(value));
3530
- };
3531
- }
3532
- if (metaData.transform) {
3533
- if (isPipe(metaData.transform)) {
3534
- return (value) => metaData.transform.transform(defaultFunc(value));
3535
- }
3536
- return metaData.fieldType === FieldType.Expression ? metaData.transform : (value) => metaData.transform(defaultFunc(value), value);
3537
- }
3538
- if (config.transformers && config.transformers[metaData.fieldType]) {
3539
- var transformer = config.transformers[metaData.fieldType];
3540
- return (value) => transformer(defaultFunc(value));
3541
- }
3542
- const defaultDateFormat = config.dateFormats?.dateFormat ?? 'shortDate';
3543
- const defaultDateTimeFormat = config.dateFormats?.dateTimeFormat ?? 'short';
3544
- switch (metaData.fieldType) {
3545
- case FieldType.Date:
3546
- const dateFormat = metaData.additional?.dateFormat ?? defaultDateFormat;
3547
- return (value) => dateFormatter(defaultFunc(value), dateFormat);
3548
- case FieldType.DateTime:
3549
- const dateTimeFormat = metaData.additional?.dateTimeOptions?.format ?? defaultDateTimeFormat;
3550
- return (value) => dateFormatter(defaultFunc(value), dateTimeFormat);
3551
- case FieldType.Currency:
3552
- return (value) => currencyFormatter(defaultFunc(value));
3553
- case FieldType.PhoneNumber:
3554
- return (value) => phoneFormatter(defaultFunc(value));
3555
- case FieldType.Enum:
3556
- return (value) => spaceCase(metaData.additional?.enumMap[defaultFunc(value)]);
3557
- case FieldType.Boolean:
3558
- if (noIcons) {
3559
- return defaultFunc;
3560
- }
3561
- let forTrue = 'check';
3562
- let forFalse = '';
3563
- if (metaData.additional?.boolean?.forTrue) {
3564
- forTrue = metaData?.additional.boolean.forTrue.icon;
3565
- }
3566
- if (metaData.additional?.boolean?.showForFalse === true) {
3567
- forFalse = 'clear';
3568
- }
3569
- else if (metaData.additional?.boolean?.showForFalse?.icon) {
3570
- forFalse = metaData.additional?.boolean?.showForFalse?.icon;
3571
- }
3572
- return (value) => defaultFunc(value) ? forTrue : forFalse;
3573
- }
3574
- return defaultFunc;
3575
- }
3576
- function createItemTransformer(metaData, config, noIcons = false, mutate = false) {
3577
- const transform = createTransformer(metaData, config, noIcons);
3578
- return (t) => {
3579
- if (!mutate) {
3580
- t = { ...t };
3581
- }
3582
- t[metaData.key] = transform(t);
3583
- };
3584
- }
3585
- function createItemTransformers(metaDatas, config, noIcons = false, mutate = false) {
3586
- const transformers = metaDatas.map(meta => createItemTransformer(meta, config, noIcons, true));
3587
- return (t) => {
3588
- if (!t)
3589
- return t;
3590
- if (!mutate) {
3591
- t = { ...t };
3592
- }
3593
- transformers.forEach(m => m(t));
3594
- return t;
3595
- };
3596
- }
3597
- function dateFormatter(date, format) {
3598
- if (!date)
3599
- return;
3600
- return formatDate(date, format, 'en-US');
3601
- }
3602
- function currencyFormatter(amt) {
3603
- return formatCurrency(amt, 'en-US', '$');
3604
- }
3605
-
3606
3717
  class FormatFilterValuePipe {
3607
3718
  constructor() {
3608
3719
  this.tableState = inject(TableStore);
@@ -3623,15 +3734,15 @@ const transform = (value, meta, filterType) => {
3623
3734
  }
3624
3735
  if (value && (filterType === FilterType.In)) {
3625
3736
  if (meta.fieldType === FieldType.Enum) {
3626
- return value.map((v) => spaceCase(meta.additional.enumMap[v])).join(', ') ?? value;
3737
+ return value.map((v) => mapSpecial(v) || spaceCase(meta.additional.enumMap[v])).join(', ') ?? value;
3627
3738
  }
3628
3739
  if (meta.fieldType === FieldType.Date || meta.fieldType === FieldType.DateTime) {
3629
- return value.map((v) => mapDate(v, meta, filterType)).join(', ') ?? value;
3740
+ return value.map((v) => mapSpecial(v) || mapDate(v, meta, filterType)).join(', ') ?? value;
3630
3741
  }
3631
3742
  if (meta.fieldType === FieldType.Number || meta.fieldType === FieldType.Currency) {
3632
- return value.map((v) => mapNumber(v, meta)).join(', ') ?? value;
3743
+ return value.map((v) => mapSpecial(v) || mapNumber(v, meta)).join(', ') ?? value;
3633
3744
  }
3634
- return value.join(', ') ?? value;
3745
+ return value.map(v => mapSpecial(v) || v).join(', ') ?? value;
3635
3746
  }
3636
3747
  if (filterType === FilterType.NumberBetween && (meta.fieldType === FieldType.Number || meta.fieldType === FieldType.Currency)) {
3637
3748
  return mapNumber(value.Start, meta) + ' - ' + mapNumber(value.End, meta);
@@ -3662,6 +3773,11 @@ function mapNumber(value, meta) {
3662
3773
  }
3663
3774
  return value;
3664
3775
  }
3776
+ function mapSpecial(value) {
3777
+ if (isBlankValueFilter(value))
3778
+ return 'BLANK';
3779
+ return undefined;
3780
+ }
3665
3781
 
3666
3782
  class FilterChipsComponent {
3667
3783
  constructor() {
@@ -3854,7 +3970,7 @@ class TableTemplateService {
3854
3970
  if (metaData.fieldType === FieldType.ImageUrl) {
3855
3971
  return this.initializationComponentInstance.$imageUrlTemplate();
3856
3972
  }
3857
- const useIcon = metaData.useIcon || metaData.fieldType === FieldType.Boolean;
3973
+ const useIcon = metaData.useIcon || (metaData.fieldType === FieldType.Boolean && metaData.useIcon !== false);
3858
3974
  if (metaData.fieldType === FieldType.Link || metaData.additional?.link) {
3859
3975
  const router = metaData.additional?.link?.useRouterLink;
3860
3976
  if (router) {
@@ -3946,14 +4062,14 @@ class ColumnHeaderMenuComponent {
3946
4062
  }
3947
4063
  }
3948
4064
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.3", ngImport: i0, type: ColumnHeaderMenuComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
3949
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.0.3", 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 filterFieldType = $filterFieldType();\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 ($fieldType() !== FieldType.NotMapped || !!$metaData().groupByLogic?.groupBy)\r\n {\r\n <button color=\"primary\" 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 color=\"primary\" mat-menu-item (click)=hideField(metaData.key)>\r\n <mat-icon color=\"primary\">visibility_off</mat-icon>\r\n <span>Hide Column</span>\r\n </button>\r\n <div (keydown)=\"$event.stopImmediatePropagation()\">\r\n @if (!(filterFieldType === FieldType.NotMapped))\r\n {\r\n <ng-form #myForm=\"ngForm\" class=\"tb-header-filter\" (keydown.enter)=\"onEnter(myForm.value, metaData)\">\r\n @if(currentFilterType === FilterType.Or || currentFilterType === FilterType.In)\r\n {\r\n <tb-in-list-filter name='filterValue' [key]='metaData.key' [ngModel]=\"undefined\"/>\r\n }\r\n @else if(filterFieldType === FieldType.Link || filterFieldType === FieldType.String || filterFieldType === FieldType.Array || filterFieldType === FieldType.Unknown || filterFieldType === FieldType.PhoneNumber)\r\n {\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\" class=\"header-filter-icon-button\" (click)=\"setStringFilterType()\">\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 (filterFieldType === FieldType.Number || filterFieldType === FieldType.Currency)\r\n {\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\" [class]=\"{'chosen-icon': currentFilterType === FilterType.NumberLessThan }\"\r\n (click)=\"setFilterType(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\" [class]=\"{'chosen-icon': currentFilterType === FilterType.NumberGreaterThan }\"\r\n (click)=\"setFilterType(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\" [class]=\"{'chosen-icon': currentFilterType === FilterType.NumberEquals }\"\r\n (click)=\"setFilterType(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 (filterFieldType === FieldType.Boolean)\r\n {\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 #ctrl=\"matRadioGroup\" #boolField='ngModel' stop-propagation class=\"font\" name=\"filterValue\" [ngModel]=\"undefined\" >\r\n <mat-radio-button class=\"filter-radio-button\" [value]=\"true\" (click)=\"boolField.control.setValue(true);\">True</mat-radio-button><br/>\r\n <mat-radio-button class=\"filter-radio-button\" [value]=\"false\" (click)=\"boolField.control.setValue(false)\">False</mat-radio-button><br/>\r\n </mat-radio-group>\r\n </div>\r\n }\r\n @else if (filterFieldType === FieldType.Date || filterFieldType === FieldType.DateTime)\r\n {\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\" [class]=\"{'chosen-icon': currentFilterType === FilterType.DateOnOrAfter }\"\r\n (click)=\"setFilterType(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\" [class]=\"{'chosen-icon': currentFilterType === FilterType.DateOnOrBefore }\"\r\n (click)=\"setFilterType(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\" [class]=\"{'chosen-icon': currentFilterType === FilterType.DateIsOn }\"\r\n (click)=\"setFilterType(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 preventEnter [for]=\"calendar\" />\r\n <mat-datepicker #calendar />\r\n </mat-form-field>\r\n }\r\n <button mat-button disableRipple [disabled]=\"myForm.value.filterValue == undefined\" (click)=\"onEnter(myForm.value, metaData)\">\r\n Apply\r\n </button>\r\n </ng-form>\r\n }\r\n </div>\r\n\r\n</mat-menu>\r\n", styles: [":host{--mat-button-filled-container-height: 24px;--mat-button-filled-touch-target-display: none;--mat-button-outlined-container-height: 24px;--mat-button-outlined-touch-target-display: none;--mat-button-protected-container-height: 24px;--mat-button-protected-touch-target-display: none;--mat-button-text-container-height: 24px;--mat-button-text-touch-target-display: none;--mat-button-tonal-container-height: 24px;--mat-button-tonal-touch-target-display: none}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{-webkit-appearance:none;margin:0}.menu-icon{font-size:16px;line-height:16px;vertical-align:top;height:16px;width:16px}.search-icon{margin-right:16px;vertical-align:middle;height:24px;width:24px;color:#0000008a;font-size:21px;line-height:1.125}tb-in-list-filter{display:block;max-height:max(50vh,400px);overflow-y:auto}.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$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i3$1.MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i3$1.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.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: i2.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i2.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", inputs: ["values", "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: i1$1.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i1$1.MatLabel, selector: "mat-label" }, { kind: "directive", type: i1$1.MatPrefix, selector: "[matPrefix], [matIconPrefix], [matTextPrefix]", inputs: ["matTextPrefix"] }, { kind: "directive", type: i1$1.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i4.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: i8.MatRadioGroup, selector: "mat-radio-group", inputs: ["color", "name", "labelPosition", "value", "selected", "disabled", "required", "disabledInteractive"], outputs: ["change"], exportAs: ["matRadioGroup"] }, { kind: "component", type: i8.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: i3.MatDatepicker, selector: "mat-datepicker", exportAs: ["matDatepicker"] }, { kind: "directive", type: i3.MatDatepickerInput, selector: "input[matDatepicker]", inputs: ["matDatepicker", "min", "max", "matDatepickerFilter"], exportAs: ["matDatepickerInput"] }, { kind: "component", type: i3.MatDatepickerToggle, selector: "mat-datepicker-toggle", inputs: ["for", "tabIndex", "aria-label", "disabled", "disableRipple"], exportAs: ["matDatepickerToggle"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
4065
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.0.3", 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 filterFieldType = $filterFieldType();\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 ($fieldType() !== FieldType.NotMapped || !!$metaData().groupByLogic?.groupBy)\r\n {\r\n <button color=\"primary\" 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 color=\"primary\" mat-menu-item (click)=hideField(metaData.key)>\r\n <mat-icon color=\"primary\">visibility_off</mat-icon>\r\n <span>Hide Column</span>\r\n </button>\r\n <div (keydown)=\"$event.stopImmediatePropagation()\">\r\n @if (!(filterFieldType === FieldType.NotMapped))\r\n {\r\n <ng-form #myForm=\"ngForm\" class=\"tb-header-filter\" (keydown.enter)=\"onEnter(myForm.value, metaData)\">\r\n @if(currentFilterType === FilterType.Or || currentFilterType === FilterType.In)\r\n {\r\n <tb-in-list-filter name='filterValue' [key]='metaData.key' [ngModel]=\"undefined\"/>\r\n }\r\n @else if(filterFieldType === FieldType.Link || filterFieldType === FieldType.String || filterFieldType === FieldType.Array || filterFieldType === FieldType.Unknown || filterFieldType === FieldType.PhoneNumber)\r\n {\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\" class=\"header-filter-icon-button\" (click)=\"setStringFilterType()\">\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 (filterFieldType === FieldType.Number || filterFieldType === FieldType.Currency)\r\n {\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\" [class]=\"{'chosen-icon': currentFilterType === FilterType.NumberLessThan }\"\r\n (click)=\"setFilterType(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\" [class]=\"{'chosen-icon': currentFilterType === FilterType.NumberGreaterThan }\"\r\n (click)=\"setFilterType(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\" [class]=\"{'chosen-icon': currentFilterType === FilterType.NumberEquals }\"\r\n (click)=\"setFilterType(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 (filterFieldType === FieldType.Boolean)\r\n {\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 #ctrl=\"matRadioGroup\" #boolField='ngModel' stop-propagation class=\"font\" name=\"filterValue\" [ngModel]=\"undefined\" >\r\n <mat-radio-button class=\"filter-radio-button\" [value]=\"true\" (click)=\"boolField.control.setValue(true);\">True</mat-radio-button><br/>\r\n <mat-radio-button class=\"filter-radio-button\" [value]=\"false\" (click)=\"boolField.control.setValue(false)\">False</mat-radio-button><br/>\r\n </mat-radio-group>\r\n </div>\r\n }\r\n @else if (filterFieldType === FieldType.Date || filterFieldType === FieldType.DateTime)\r\n {\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\" [class]=\"{'chosen-icon': currentFilterType === FilterType.DateOnOrAfter }\"\r\n (click)=\"setFilterType(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\" [class]=\"{'chosen-icon': currentFilterType === FilterType.DateOnOrBefore }\"\r\n (click)=\"setFilterType(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\" [class]=\"{'chosen-icon': currentFilterType === FilterType.DateIsOn }\"\r\n (click)=\"setFilterType(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 preventEnter [for]=\"calendar\" />\r\n <mat-datepicker #calendar />\r\n </mat-form-field>\r\n }\r\n <button mat-button disableRipple [disabled]=\"myForm.value.filterValue == undefined\" (click)=\"onEnter(myForm.value, metaData)\">\r\n Apply\r\n </button>\r\n </ng-form>\r\n }\r\n </div>\r\n\r\n</mat-menu>\r\n", styles: [":host{--mat-button-filled-container-height: 24px;--mat-button-filled-touch-target-display: none;--mat-button-outlined-container-height: 24px;--mat-button-outlined-touch-target-display: none;--mat-button-protected-container-height: 24px;--mat-button-protected-touch-target-display: none;--mat-button-text-container-height: 24px;--mat-button-text-touch-target-display: none;--mat-button-tonal-container-height: 24px;--mat-button-tonal-touch-target-display: none}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{-webkit-appearance:none;margin:0}.menu-icon{font-size:16px;line-height:16px;vertical-align:top;height:16px;width:16px}.search-icon{margin-right:16px;vertical-align:middle;height:24px;width:24px;color:#0000008a;font-size:21px;line-height:1.125}.font{font-size:14px}.filter-radio-button:first-of-type{padding-left:0}.filter-radio-button{padding:10px 40px;min-width:110px}.auto-width{width:260px;margin:5px;display:block;height:55px}.open-menu-icon-button{height:28px;width:28px;padding:6px}.header-filter-icon-button{height:18px;width:18px;font-size:18px;padding:0;margin:0 2px}.header-filter-icon-button ::ng-deep *{line-height:initial;font-size:initial;height:18px;width:18px;font-size:18px;bottom:initial}.header-filter-icon-button .chosen-icon,.header-filter-icon-button.chosen-icon ::ng-deep *{height:22px;width:22px;font-size:22px;color:green}mat-icon.mat-icon.suffix-icons.underline{height:20px;text-decoration:underline .1px solid}.chosen-icon mat-icon.mat-icon.suffix-icons.underline{height:24px}::ng-deep .mat-mdc-form-field-icon-prefix:has(.tb-header-prefix),.tb-header-prefix{padding:0;flex-basis:36%}.tb-header-filter ::ng-deep .mat-mdc-form-field-subscript-wrapper{line-height:0}.tb-header-filter ::ng-deep .mat-mdc-form-field-subscript-wrapper:before{height:0}.date-toggle ::ng-deep svg{position:absolute;left:0;top:0}\n"], dependencies: [{ kind: "ngmodule", type: MatMenuModule }, { kind: "component", type: i1$4.MatMenu, selector: "mat-menu", inputs: ["backdropClass", "aria-label", "aria-labelledby", "aria-describedby", "xPosition", "yPosition", "overlapTrigger", "hasBackdrop", "class", "classList"], outputs: ["closed", "close"], exportAs: ["matMenu"] }, { kind: "component", type: i1$4.MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i1$4.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i2$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i3$1.MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i3$1.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.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: i2.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i2.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", inputs: ["values", "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: i1$1.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i1$1.MatLabel, selector: "mat-label" }, { kind: "directive", type: i1$1.MatPrefix, selector: "[matPrefix], [matIconPrefix], [matTextPrefix]", inputs: ["matTextPrefix"] }, { kind: "directive", type: i1$1.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i4.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: i8.MatRadioGroup, selector: "mat-radio-group", inputs: ["color", "name", "labelPosition", "value", "selected", "disabled", "required", "disabledInteractive"], outputs: ["change"], exportAs: ["matRadioGroup"] }, { kind: "component", type: i8.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: i3.MatDatepicker, selector: "mat-datepicker", exportAs: ["matDatepicker"] }, { kind: "directive", type: i3.MatDatepickerInput, selector: "input[matDatepicker]", inputs: ["matDatepicker", "min", "max", "matDatepickerFilter"], exportAs: ["matDatepickerInput"] }, { kind: "component", type: i3.MatDatepickerToggle, selector: "mat-datepicker-toggle", inputs: ["for", "tabIndex", "aria-label", "disabled", "disableRipple"], exportAs: ["matDatepickerToggle"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
3950
4066
  }
3951
4067
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.3", ngImport: i0, type: ColumnHeaderMenuComponent, decorators: [{
3952
4068
  type: Component,
3953
4069
  args: [{ selector: 'tb-header-menu', changeDetection: ChangeDetectionStrategy.OnPush, imports: [
3954
4070
  MatMenuModule, MatIconModule, MatButtonModule, FormsModule, InListFilterComponent,
3955
4071
  MatInputModule, MatTooltipModule, StopPropagationDirective, MatRadioModule, MatDatepickerModule
3956
- ], template: "@let metaData = $metaData();\r\n@let filterFieldType = $filterFieldType();\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 ($fieldType() !== FieldType.NotMapped || !!$metaData().groupByLogic?.groupBy)\r\n {\r\n <button color=\"primary\" 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 color=\"primary\" mat-menu-item (click)=hideField(metaData.key)>\r\n <mat-icon color=\"primary\">visibility_off</mat-icon>\r\n <span>Hide Column</span>\r\n </button>\r\n <div (keydown)=\"$event.stopImmediatePropagation()\">\r\n @if (!(filterFieldType === FieldType.NotMapped))\r\n {\r\n <ng-form #myForm=\"ngForm\" class=\"tb-header-filter\" (keydown.enter)=\"onEnter(myForm.value, metaData)\">\r\n @if(currentFilterType === FilterType.Or || currentFilterType === FilterType.In)\r\n {\r\n <tb-in-list-filter name='filterValue' [key]='metaData.key' [ngModel]=\"undefined\"/>\r\n }\r\n @else if(filterFieldType === FieldType.Link || filterFieldType === FieldType.String || filterFieldType === FieldType.Array || filterFieldType === FieldType.Unknown || filterFieldType === FieldType.PhoneNumber)\r\n {\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\" class=\"header-filter-icon-button\" (click)=\"setStringFilterType()\">\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 (filterFieldType === FieldType.Number || filterFieldType === FieldType.Currency)\r\n {\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\" [class]=\"{'chosen-icon': currentFilterType === FilterType.NumberLessThan }\"\r\n (click)=\"setFilterType(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\" [class]=\"{'chosen-icon': currentFilterType === FilterType.NumberGreaterThan }\"\r\n (click)=\"setFilterType(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\" [class]=\"{'chosen-icon': currentFilterType === FilterType.NumberEquals }\"\r\n (click)=\"setFilterType(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 (filterFieldType === FieldType.Boolean)\r\n {\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 #ctrl=\"matRadioGroup\" #boolField='ngModel' stop-propagation class=\"font\" name=\"filterValue\" [ngModel]=\"undefined\" >\r\n <mat-radio-button class=\"filter-radio-button\" [value]=\"true\" (click)=\"boolField.control.setValue(true);\">True</mat-radio-button><br/>\r\n <mat-radio-button class=\"filter-radio-button\" [value]=\"false\" (click)=\"boolField.control.setValue(false)\">False</mat-radio-button><br/>\r\n </mat-radio-group>\r\n </div>\r\n }\r\n @else if (filterFieldType === FieldType.Date || filterFieldType === FieldType.DateTime)\r\n {\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\" [class]=\"{'chosen-icon': currentFilterType === FilterType.DateOnOrAfter }\"\r\n (click)=\"setFilterType(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\" [class]=\"{'chosen-icon': currentFilterType === FilterType.DateOnOrBefore }\"\r\n (click)=\"setFilterType(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\" [class]=\"{'chosen-icon': currentFilterType === FilterType.DateIsOn }\"\r\n (click)=\"setFilterType(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 preventEnter [for]=\"calendar\" />\r\n <mat-datepicker #calendar />\r\n </mat-form-field>\r\n }\r\n <button mat-button disableRipple [disabled]=\"myForm.value.filterValue == undefined\" (click)=\"onEnter(myForm.value, metaData)\">\r\n Apply\r\n </button>\r\n </ng-form>\r\n }\r\n </div>\r\n\r\n</mat-menu>\r\n", styles: [":host{--mat-button-filled-container-height: 24px;--mat-button-filled-touch-target-display: none;--mat-button-outlined-container-height: 24px;--mat-button-outlined-touch-target-display: none;--mat-button-protected-container-height: 24px;--mat-button-protected-touch-target-display: none;--mat-button-text-container-height: 24px;--mat-button-text-touch-target-display: none;--mat-button-tonal-container-height: 24px;--mat-button-tonal-touch-target-display: none}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{-webkit-appearance:none;margin:0}.menu-icon{font-size:16px;line-height:16px;vertical-align:top;height:16px;width:16px}.search-icon{margin-right:16px;vertical-align:middle;height:24px;width:24px;color:#0000008a;font-size:21px;line-height:1.125}tb-in-list-filter{display:block;max-height:max(50vh,400px);overflow-y:auto}.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"] }]
4072
+ ], template: "@let metaData = $metaData();\r\n@let filterFieldType = $filterFieldType();\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 ($fieldType() !== FieldType.NotMapped || !!$metaData().groupByLogic?.groupBy)\r\n {\r\n <button color=\"primary\" 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 color=\"primary\" mat-menu-item (click)=hideField(metaData.key)>\r\n <mat-icon color=\"primary\">visibility_off</mat-icon>\r\n <span>Hide Column</span>\r\n </button>\r\n <div (keydown)=\"$event.stopImmediatePropagation()\">\r\n @if (!(filterFieldType === FieldType.NotMapped))\r\n {\r\n <ng-form #myForm=\"ngForm\" class=\"tb-header-filter\" (keydown.enter)=\"onEnter(myForm.value, metaData)\">\r\n @if(currentFilterType === FilterType.Or || currentFilterType === FilterType.In)\r\n {\r\n <tb-in-list-filter name='filterValue' [key]='metaData.key' [ngModel]=\"undefined\"/>\r\n }\r\n @else if(filterFieldType === FieldType.Link || filterFieldType === FieldType.String || filterFieldType === FieldType.Array || filterFieldType === FieldType.Unknown || filterFieldType === FieldType.PhoneNumber)\r\n {\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\" class=\"header-filter-icon-button\" (click)=\"setStringFilterType()\">\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 (filterFieldType === FieldType.Number || filterFieldType === FieldType.Currency)\r\n {\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\" [class]=\"{'chosen-icon': currentFilterType === FilterType.NumberLessThan }\"\r\n (click)=\"setFilterType(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\" [class]=\"{'chosen-icon': currentFilterType === FilterType.NumberGreaterThan }\"\r\n (click)=\"setFilterType(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\" [class]=\"{'chosen-icon': currentFilterType === FilterType.NumberEquals }\"\r\n (click)=\"setFilterType(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 (filterFieldType === FieldType.Boolean)\r\n {\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 #ctrl=\"matRadioGroup\" #boolField='ngModel' stop-propagation class=\"font\" name=\"filterValue\" [ngModel]=\"undefined\" >\r\n <mat-radio-button class=\"filter-radio-button\" [value]=\"true\" (click)=\"boolField.control.setValue(true);\">True</mat-radio-button><br/>\r\n <mat-radio-button class=\"filter-radio-button\" [value]=\"false\" (click)=\"boolField.control.setValue(false)\">False</mat-radio-button><br/>\r\n </mat-radio-group>\r\n </div>\r\n }\r\n @else if (filterFieldType === FieldType.Date || filterFieldType === FieldType.DateTime)\r\n {\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\" [class]=\"{'chosen-icon': currentFilterType === FilterType.DateOnOrAfter }\"\r\n (click)=\"setFilterType(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\" [class]=\"{'chosen-icon': currentFilterType === FilterType.DateOnOrBefore }\"\r\n (click)=\"setFilterType(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\" [class]=\"{'chosen-icon': currentFilterType === FilterType.DateIsOn }\"\r\n (click)=\"setFilterType(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 preventEnter [for]=\"calendar\" />\r\n <mat-datepicker #calendar />\r\n </mat-form-field>\r\n }\r\n <button mat-button disableRipple [disabled]=\"myForm.value.filterValue == undefined\" (click)=\"onEnter(myForm.value, metaData)\">\r\n Apply\r\n </button>\r\n </ng-form>\r\n }\r\n </div>\r\n\r\n</mat-menu>\r\n", styles: [":host{--mat-button-filled-container-height: 24px;--mat-button-filled-touch-target-display: none;--mat-button-outlined-container-height: 24px;--mat-button-outlined-touch-target-display: none;--mat-button-protected-container-height: 24px;--mat-button-protected-touch-target-display: none;--mat-button-text-container-height: 24px;--mat-button-text-touch-target-display: none;--mat-button-tonal-container-height: 24px;--mat-button-tonal-touch-target-display: none}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{-webkit-appearance:none;margin:0}.menu-icon{font-size:16px;line-height:16px;vertical-align:top;height:16px;width:16px}.search-icon{margin-right:16px;vertical-align:middle;height:24px;width:24px;color:#0000008a;font-size:21px;line-height:1.125}.font{font-size:14px}.filter-radio-button:first-of-type{padding-left:0}.filter-radio-button{padding:10px 40px;min-width:110px}.auto-width{width:260px;margin:5px;display:block;height:55px}.open-menu-icon-button{height:28px;width:28px;padding:6px}.header-filter-icon-button{height:18px;width:18px;font-size:18px;padding:0;margin:0 2px}.header-filter-icon-button ::ng-deep *{line-height:initial;font-size:initial;height:18px;width:18px;font-size:18px;bottom:initial}.header-filter-icon-button .chosen-icon,.header-filter-icon-button.chosen-icon ::ng-deep *{height:22px;width:22px;font-size:22px;color:green}mat-icon.mat-icon.suffix-icons.underline{height:20px;text-decoration:underline .1px solid}.chosen-icon mat-icon.mat-icon.suffix-icons.underline{height:24px}::ng-deep .mat-mdc-form-field-icon-prefix:has(.tb-header-prefix),.tb-header-prefix{padding:0;flex-basis:36%}.tb-header-filter ::ng-deep .mat-mdc-form-field-subscript-wrapper{line-height:0}.tb-header-filter ::ng-deep .mat-mdc-form-field-subscript-wrapper:before{height:0}.date-toggle ::ng-deep svg{position:absolute;left:0;top:0}\n"] }]
3957
4073
  }] });
3958
4074
 
3959
4075
  class ColumnTotalPipe {
@@ -5658,6 +5774,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.3", ngImpor
5658
5774
 
5659
5775
  class TableHeaderMenuComponent {
5660
5776
  constructor() {
5777
+ this.menu = viewChild.required(MatMenu);
5661
5778
  this.exportToCsvService = inject(ExportToCsvService);
5662
5779
  this.tableContainer = inject(TableContainerComponent);
5663
5780
  this.state = this.tableContainer.state;
@@ -5678,11 +5795,11 @@ class TableHeaderMenuComponent {
5678
5795
  this.state.setUserDefinedHeaderHeight(+element.value);
5679
5796
  }
5680
5797
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.3", ngImport: i0, type: TableHeaderMenuComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
5681
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.0.3", type: TableHeaderMenuComponent, isStandalone: true, selector: "lib-table-header-menu", ngImport: i0, template: "<span [matTooltip]=\"!r.$set().length ? 'Nothing To Reset' : ''\">\r\n <button mat-menu-item [matMenuTriggerFor]=\"r.menu()\" [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{\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{\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 #pm class=\"profiles-menu\" [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\" \r\n placeholder=\"Set Size\"\r\n [value]=\"$rowHeightNum()\"\r\n [min]=\"10\"\r\n [max]=\"100\" (change)=\"updateHeight('row', i)\" />\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\"\r\n placeholder=\"Set Size\"\r\n [value]=\"$headerHeightNum()\"\r\n [min]=\"10\"\r\n [max]=\"100\" (change)=\"updateHeight('header', i2)\"/>\r\n </div>\r\n </div>\r\n}\r\n<lib-reset-menu #r/>\r\n\r\n", styles: [".input{appearance: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}.input::placeholder{font-size:12px}.height-input-wrapper{display:flex;gap:4px}\n"], dependencies: [{ kind: "ngmodule", type: MatMenuModule }, { 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]" }] }); }
5798
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.0.3", type: TableHeaderMenuComponent, isStandalone: true, selector: "lib-table-header-menu", viewQueries: [{ propertyName: "menu", first: true, predicate: MatMenu, descendants: true, isSignal: true }], ngImport: i0, template: "<span [matTooltip]=\"!r.$set().length ? 'Nothing To Reset' : ''\">\r\n <button #d=\"matMenuItem\" mat-menu-item [matMenuTriggerFor]=\"r.menu()\" [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{\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{\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 #pm class=\"profiles-menu\" [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\" \r\n placeholder=\"Set Size\"\r\n [value]=\"$rowHeightNum()\"\r\n [min]=\"10\"\r\n [max]=\"100\" (change)=\"updateHeight('row', i)\" />\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\"\r\n placeholder=\"Set Size\"\r\n [value]=\"$headerHeightNum()\"\r\n [min]=\"10\"\r\n [max]=\"100\" (change)=\"updateHeight('header', i2)\"/>\r\n </div>\r\n </div>\r\n}\r\n<lib-reset-menu #r/>\r\n\r\n", styles: [".input{appearance: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}.input::placeholder{font-size:12px}.height-input-wrapper{display:flex;gap:4px}\n"], dependencies: [{ kind: "ngmodule", type: MatMenuModule }, { 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]" }] }); }
5682
5799
  }
5683
5800
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.3", ngImport: i0, type: TableHeaderMenuComponent, decorators: [{
5684
5801
  type: Component,
5685
- args: [{ selector: 'lib-table-header-menu', imports: [MatMenuModule, MatIcon, ProfilesMenuComponent, ResetMenuComponent, MatTooltip, StopPropagationDirective], template: "<span [matTooltip]=\"!r.$set().length ? 'Nothing To Reset' : ''\">\r\n <button mat-menu-item [matMenuTriggerFor]=\"r.menu()\" [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{\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{\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 #pm class=\"profiles-menu\" [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\" \r\n placeholder=\"Set Size\"\r\n [value]=\"$rowHeightNum()\"\r\n [min]=\"10\"\r\n [max]=\"100\" (change)=\"updateHeight('row', i)\" />\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\"\r\n placeholder=\"Set Size\"\r\n [value]=\"$headerHeightNum()\"\r\n [min]=\"10\"\r\n [max]=\"100\" (change)=\"updateHeight('header', i2)\"/>\r\n </div>\r\n </div>\r\n}\r\n<lib-reset-menu #r/>\r\n\r\n", styles: [".input{appearance: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}.input::placeholder{font-size:12px}.height-input-wrapper{display:flex;gap:4px}\n"] }]
5802
+ args: [{ selector: 'lib-table-header-menu', imports: [MatMenuModule, MatIcon, ProfilesMenuComponent, ResetMenuComponent, MatTooltip, StopPropagationDirective], template: "<span [matTooltip]=\"!r.$set().length ? 'Nothing To Reset' : ''\">\r\n <button #d=\"matMenuItem\" mat-menu-item [matMenuTriggerFor]=\"r.menu()\" [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{\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{\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 #pm class=\"profiles-menu\" [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\" \r\n placeholder=\"Set Size\"\r\n [value]=\"$rowHeightNum()\"\r\n [min]=\"10\"\r\n [max]=\"100\" (change)=\"updateHeight('row', i)\" />\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\"\r\n placeholder=\"Set Size\"\r\n [value]=\"$headerHeightNum()\"\r\n [min]=\"10\"\r\n [max]=\"100\" (change)=\"updateHeight('header', i2)\"/>\r\n </div>\r\n </div>\r\n}\r\n<lib-reset-menu #r/>\r\n\r\n", styles: [".input{appearance: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}.input::placeholder{font-size:12px}.height-input-wrapper{display:flex;gap:4px}\n"] }]
5686
5803
  }] });
5687
5804
 
5688
5805
  class TableVirtualScrollStrategy {
@@ -5983,31 +6100,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.3", ngImpor
5983
6100
  }]
5984
6101
  }], ctorParameters: () => [] });
5985
6102
 
5986
- function buildInAllValuesFilter(config, previousMeta, currentMeta, data, metaTimestamp, dataTimestamp, currentAllFilters) {
5987
- const currentMetaDataOfFilterAll = currentMeta.filter(m => m.additional?.filterOptions?.filterableValues === 'all values');
5988
- if (dataTimestamp > metaTimestamp) {
5989
- return currentMetaDataOfFilterAll.reduce((dict, md) => {
5990
- dict[md.key] = buildFilter(data, md, config);
5991
- return dict;
5992
- }, {});
5993
- }
5994
- const previousMetaDataOfFilterAll = previousMeta.filter(m => m.additional?.filterOptions?.filterableValues === 'all values');
5995
- const newCurrent = currentMetaDataOfFilterAll.filter(c => previousMetaDataOfFilterAll.every(p => c.key !== p.key));
5996
- if (newCurrent.length) {
5997
- const c = { ...currentAllFilters };
5998
- newCurrent.forEach(md => c[md.key] = buildFilter(data, md, config));
5999
- return c;
6000
- }
6001
- return currentAllFilters;
6002
- }
6003
- function buildFilter(data, metaData, config) {
6004
- const map = createTransformer(metaData, config, true, true);
6005
- return [...new Map(data.map(v => {
6006
- const mappedV = map(v);
6007
- return [mappedV?.toString(), mappedV];
6008
- })).values()].filter(v => v != undefined).sort();
6009
- }
6010
-
6011
6103
  class TableContainerComponent {
6012
6104
  constructor() {
6013
6105
  this.state = inject(TableStore);
@@ -6357,7 +6449,7 @@ class TableContainerComponent {
6357
6449
  #setUpAllValuesFilters;
6358
6450
  static { this.headerId = 'tb-header-wrapper'; }
6359
6451
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.3", ngImport: i0, type: TableContainerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
6360
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.0.3", type: TableContainerComponent, isStandalone: true, selector: "tb-table-container", inputs: { $tableBuilder: { classPropertyName: "$tableBuilder", publicName: "tableBuilder", isSignal: true, isRequired: true, transformFunction: null }, $tableIdInput: { classPropertyName: "$tableIdInput", publicName: "tableId", isSignal: true, isRequired: false, transformFunction: null }, $trackByInput: { classPropertyName: "$trackByInput", publicName: "trackBy", isSignal: true, isRequired: false, transformFunction: null }, $inputFilters: { classPropertyName: "$inputFilters", publicName: "inputFilters", isSignal: true, isRequired: false, transformFunction: null }, $indexColumnInput: { classPropertyName: "$indexColumnInput", publicName: "indexColumn", isSignal: true, isRequired: false, transformFunction: null }, $selectionColumnInput: { classPropertyName: "$selectionColumnInput", publicName: "selectionColumn", isSignal: true, isRequired: false, transformFunction: null }, $stickyHeaderInput: { classPropertyName: "$stickyHeaderInput", publicName: "stickyHeader", isSignal: true, isRequired: false, transformFunction: null }, $stickyFooterInput: { classPropertyName: "$stickyFooterInput", publicName: "stickyFooter", isSignal: true, isRequired: false, transformFunction: null }, $groupHeaderTemplate: { classPropertyName: "$groupHeaderTemplate", publicName: "groupHeaderTemplate", isSignal: true, isRequired: false, transformFunction: null }, $groupHeaderHeight: { classPropertyName: "$groupHeaderHeight", publicName: "groupHeaderHeight", isSignal: true, isRequired: false, transformFunction: null }, $pageSize: { classPropertyName: "$pageSize", publicName: "pageSize", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { selection$: "selection", onStateReset$: "onStateReset", onSaveState$: "onSaveState", state$: "state", data$: "data" }, providers: [TableStore, ExportToCsvService, WrapperFilterStore, DataStore], queries: [{ propertyName: "$filterDirectives", predicate: TableFilterDirective, descendants: true, isSignal: true }, { propertyName: "$customFilterDirectives", predicate: TableCustomFilterDirective, descendants: true, isSignal: true }, { propertyName: "_$customRows", predicate: (MatRowDef), isSignal: true }, { propertyName: "$customCells", predicate: CustomCellDirective, isSignal: true }], viewQueries: [{ propertyName: "$paginatorComponent", first: true, predicate: PaginatorComponent, descendants: true, isSignal: true }, { propertyName: "$genericTable", first: true, predicate: GenericTableComponent, descendants: true, isSignal: true }, { propertyName: "$menu", first: true, predicate: MatMenu, descendants: true, isSignal: true }], ngImport: i0, template: "@let tableId = $tableId();\r\n@let tableSettings = state.$tableSettings();\r\n\r\n<ng-content select=\"[before]\" />\r\n<ng-container multiSort>\r\n <div class=\"tb-header-wrapper\" [id]=\"headerId\">\r\n <div class=\"title\">\r\n @if ((!$collapsedHeader()) || tableSettings.showTitleWhenHeaderCollapsed)\r\n {\r\n <ng-content select=\".tb-header-title\"/>\r\n }\r\n </div>\r\n @if(state.$groupByKeys().length)\r\n {\r\n <group-by-list />\r\n }\r\n <div class=\"flx-row-end\">\r\n <lib-filter-list />\r\n @if (!tableSettings.hideHeader)\r\n {\r\n @if (!$collapsedHeader())\r\n {\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' [xPosition]=\"'before'\">\r\n <lib-table-header-menu/>\r\n </mat-menu>\r\n\r\n }\r\n @else\r\n {\r\n <mat-icon color=\"primary\" class=\"flat-menu-button pointer\" [matMenuTriggerFor]=\"mainMenu\">more_horiz</mat-icon>\r\n <mat-menu #mainMenu='matMenu'>\r\n <div class=\"collapsed-head-row\">\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 class=\"collapse-icon header\" [matTooltip]=\"$collapsedHeader() ? 'expand' : 'collapse'\"\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 [columnInfos]='$myColumns()' [trackBy]=\"$trackBy()\" [dataSource]=\"dataSource\" (selection)='selection$.emit($event)' />\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 [columnInfos]='$myColumns()' [trackBy]=\"$trackBy()\" [dataSource]=\"dataSource\" (selection)='selection$.emit($event)' />\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 class=\"collapse-icon footer\" [matTooltip]=\"$collapsedFooter() ? 'expand' : 'collapse'\"\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 && !$collapsedHeader()) {<tb-profiles-menu [tableId]=\"tableId\"/>}\r\n </ng-template>\r\n\r\n</ng-container>\r\n", styles: [".tb-header-wrapper{display:flex;flex-direction:row;width:100%}.flx-row-end{display:flex;flex-direction:row;justify-content:flex-end;align-items:center;margin-left:auto}.flat-menu{line-height:initial;height:initial}.pointer{cursor:pointer}.add-key{width:90%}.paginator{display:flex;flex-direction:row;justify-content:flex-end;align-items:center;background-color:#fff;bottom:0;position:sticky;border-top:.5px solid rgba(0,0,0,.12)}.profiles-menu{visibility:hidden;width:0px;height:0px;display:block;overflow:hidden;position:absolute;top:50px}.collapsed-head-row{display:flex;justify-content:space-evenly}::ng-deep tb-generic-table .mat-mdc-row:nth-child(odd):not(.no-stripe){background-color:var(--tb-odd-row-background-color, #cdeefe)}\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], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { 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$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i4.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 }); }
6452
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.0.3", type: TableContainerComponent, isStandalone: true, selector: "tb-table-container", inputs: { $tableBuilder: { classPropertyName: "$tableBuilder", publicName: "tableBuilder", isSignal: true, isRequired: true, transformFunction: null }, $tableIdInput: { classPropertyName: "$tableIdInput", publicName: "tableId", isSignal: true, isRequired: false, transformFunction: null }, $trackByInput: { classPropertyName: "$trackByInput", publicName: "trackBy", isSignal: true, isRequired: false, transformFunction: null }, $inputFilters: { classPropertyName: "$inputFilters", publicName: "inputFilters", isSignal: true, isRequired: false, transformFunction: null }, $indexColumnInput: { classPropertyName: "$indexColumnInput", publicName: "indexColumn", isSignal: true, isRequired: false, transformFunction: null }, $selectionColumnInput: { classPropertyName: "$selectionColumnInput", publicName: "selectionColumn", isSignal: true, isRequired: false, transformFunction: null }, $stickyHeaderInput: { classPropertyName: "$stickyHeaderInput", publicName: "stickyHeader", isSignal: true, isRequired: false, transformFunction: null }, $stickyFooterInput: { classPropertyName: "$stickyFooterInput", publicName: "stickyFooter", isSignal: true, isRequired: false, transformFunction: null }, $groupHeaderTemplate: { classPropertyName: "$groupHeaderTemplate", publicName: "groupHeaderTemplate", isSignal: true, isRequired: false, transformFunction: null }, $groupHeaderHeight: { classPropertyName: "$groupHeaderHeight", publicName: "groupHeaderHeight", isSignal: true, isRequired: false, transformFunction: null }, $pageSize: { classPropertyName: "$pageSize", publicName: "pageSize", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { selection$: "selection", onStateReset$: "onStateReset", onSaveState$: "onSaveState", state$: "state", data$: "data" }, providers: [TableStore, ExportToCsvService, WrapperFilterStore, DataStore], queries: [{ propertyName: "$filterDirectives", predicate: TableFilterDirective, descendants: true, isSignal: true }, { propertyName: "$customFilterDirectives", predicate: TableCustomFilterDirective, descendants: true, isSignal: true }, { propertyName: "_$customRows", predicate: (MatRowDef), isSignal: true }, { propertyName: "$customCells", predicate: CustomCellDirective, isSignal: true }], viewQueries: [{ propertyName: "$paginatorComponent", first: true, predicate: PaginatorComponent, descendants: true, isSignal: true }, { propertyName: "$genericTable", first: true, predicate: GenericTableComponent, descendants: true, isSignal: true }, { propertyName: "$menu", first: true, predicate: MatMenu, descendants: true, isSignal: true }], ngImport: i0, template: "@let tableId = $tableId();\r\n@let tableSettings = state.$tableSettings();\r\n\r\n<ng-content select=\"[before]\" />\r\n<ng-container multiSort>\r\n <div class=\"tb-header-wrapper\" [id]=\"headerId\">\r\n <div class=\"title\">\r\n @if ((!$collapsedHeader()) || tableSettings.showTitleWhenHeaderCollapsed)\r\n {\r\n <ng-content select=\".tb-header-title\"/>\r\n @if (tableSettings.title)\r\n {\r\n @switch (tableSettings.title.level)\r\n {\r\n @case (1) { <h1 class=\"tb-container-title\" [style]=\"tableSettings.title.styles\">{{tableSettings.title.text}}</h1>}\r\n @case (2) { <h2 class=\"tb-container-title\" [style]=\"tableSettings.title.styles\">{{tableSettings.title.text}}</h2>}\r\n @case (4) { <h4 class=\"tb-container-title\" [style]=\"tableSettings.title.styles\">{{tableSettings.title.text}}</h4>}\r\n @case (5) { <h5 class=\"tb-container-title\" [style]=\"tableSettings.title.styles\">{{tableSettings.title.text}}</h5>}\r\n @case (6) { <h6 class=\"tb-container-title\" [style]=\"tableSettings.title.styles\">{{tableSettings.title.text}}</h6>}\r\n @default { <h3 class=\"tb-container-title\" [style]=\"tableSettings.title.styles\">{{tableSettings.title.text}}</h3>}\r\n }\r\n }\r\n }\r\n </div>\r\n @if(state.$groupByKeys().length)\r\n {\r\n <group-by-list />\r\n }\r\n <div class=\"flx-row-end\">\r\n <lib-filter-list />\r\n @if (!tableSettings.hideHeader)\r\n {\r\n @if (!$collapsedHeader())\r\n {\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' [xPosition]=\"'before'\">\r\n <lib-table-header-menu #l/>\r\n </mat-menu>\r\n\r\n }\r\n @else\r\n {\r\n <mat-icon color=\"primary\" class=\"flat-menu-button pointer\" [matMenuTriggerFor]=\"mainMenu\">more_horiz</mat-icon>\r\n <mat-menu #mainMenu='matMenu'>\r\n <div class=\"collapsed-head-row\">\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 class=\"collapse-icon header\" [matTooltip]=\"$collapsedHeader() ? 'expand' : 'collapse'\"\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 [columnInfos]='$myColumns()' [trackBy]=\"$trackBy()\" [dataSource]=\"dataSource\" (selection)='selection$.emit($event)' />\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 [columnInfos]='$myColumns()' [trackBy]=\"$trackBy()\" [dataSource]=\"dataSource\" (selection)='selection$.emit($event)' />\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 class=\"collapse-icon footer\" [matTooltip]=\"$collapsedFooter() ? 'expand' : 'collapse'\"\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 && !$collapsedHeader()) {<tb-profiles-menu [tableId]=\"tableId\"/>}\r\n </ng-template>\r\n\r\n</ng-container>\r\n", styles: [".tb-header-wrapper{display:flex;flex-direction:row;width:100%}.flx-row-end{display:flex;flex-direction:row;justify-content:flex-end;align-items:center;margin-left:auto}.flat-menu{line-height:initial;height:initial}.pointer{cursor:pointer}.add-key{width:90%}.paginator{display:flex;flex-direction:row;justify-content:flex-end;align-items:center;background-color:#fff;bottom:0;position:sticky;border-top:.5px solid rgba(0,0,0,.12)}.profiles-menu{visibility:hidden;width:0px;height:0px;display:block;overflow:hidden;position:absolute;top:50px}.collapsed-head-row{display:flex;justify-content:space-evenly}::ng-deep tb-generic-table .mat-mdc-row:nth-child(odd):not(.no-stripe){background-color:var(--tb-odd-row-background-color, #cdeefe)}.tb-container-title{padding-left:var(--tb-container-title-padding-left, 10px);margin:var(--tb-container-title-margin, 0)}\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], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { 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$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i4.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 }); }
6361
6453
  }
6362
6454
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.3", ngImport: i0, type: TableContainerComponent, decorators: [{
6363
6455
  type: Component,
@@ -6366,8 +6458,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.3", ngImpor
6366
6458
  PaginatorComponent,
6367
6459
  MultiSortDirective, GroupByListComponent, FilterChipsComponent, GenFilterDisplayerComponent, GenColDisplayerComponent,
6368
6460
  SortMenuComponent, GenericTableComponent, ProfilesMenuComponent, TableHeaderMenuComponent,
6369
- MatButtonModule, MatMenuModule, MatIconModule, MatTooltipModule, VirtualScrollContainer
6370
- ], template: "@let tableId = $tableId();\r\n@let tableSettings = state.$tableSettings();\r\n\r\n<ng-content select=\"[before]\" />\r\n<ng-container multiSort>\r\n <div class=\"tb-header-wrapper\" [id]=\"headerId\">\r\n <div class=\"title\">\r\n @if ((!$collapsedHeader()) || tableSettings.showTitleWhenHeaderCollapsed)\r\n {\r\n <ng-content select=\".tb-header-title\"/>\r\n }\r\n </div>\r\n @if(state.$groupByKeys().length)\r\n {\r\n <group-by-list />\r\n }\r\n <div class=\"flx-row-end\">\r\n <lib-filter-list />\r\n @if (!tableSettings.hideHeader)\r\n {\r\n @if (!$collapsedHeader())\r\n {\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' [xPosition]=\"'before'\">\r\n <lib-table-header-menu/>\r\n </mat-menu>\r\n\r\n }\r\n @else\r\n {\r\n <mat-icon color=\"primary\" class=\"flat-menu-button pointer\" [matMenuTriggerFor]=\"mainMenu\">more_horiz</mat-icon>\r\n <mat-menu #mainMenu='matMenu'>\r\n <div class=\"collapsed-head-row\">\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 class=\"collapse-icon header\" [matTooltip]=\"$collapsedHeader() ? 'expand' : 'collapse'\"\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 [columnInfos]='$myColumns()' [trackBy]=\"$trackBy()\" [dataSource]=\"dataSource\" (selection)='selection$.emit($event)' />\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 [columnInfos]='$myColumns()' [trackBy]=\"$trackBy()\" [dataSource]=\"dataSource\" (selection)='selection$.emit($event)' />\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 class=\"collapse-icon footer\" [matTooltip]=\"$collapsedFooter() ? 'expand' : 'collapse'\"\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 && !$collapsedHeader()) {<tb-profiles-menu [tableId]=\"tableId\"/>}\r\n </ng-template>\r\n\r\n</ng-container>\r\n", styles: [".tb-header-wrapper{display:flex;flex-direction:row;width:100%}.flx-row-end{display:flex;flex-direction:row;justify-content:flex-end;align-items:center;margin-left:auto}.flat-menu{line-height:initial;height:initial}.pointer{cursor:pointer}.add-key{width:90%}.paginator{display:flex;flex-direction:row;justify-content:flex-end;align-items:center;background-color:#fff;bottom:0;position:sticky;border-top:.5px solid rgba(0,0,0,.12)}.profiles-menu{visibility:hidden;width:0px;height:0px;display:block;overflow:hidden;position:absolute;top:50px}.collapsed-head-row{display:flex;justify-content:space-evenly}::ng-deep tb-generic-table .mat-mdc-row:nth-child(odd):not(.no-stripe){background-color:var(--tb-odd-row-background-color, #cdeefe)}\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"] }]
6461
+ MatButtonModule, MatMenuModule, MatIconModule, MatTooltipModule, VirtualScrollContainer,
6462
+ ], template: "@let tableId = $tableId();\r\n@let tableSettings = state.$tableSettings();\r\n\r\n<ng-content select=\"[before]\" />\r\n<ng-container multiSort>\r\n <div class=\"tb-header-wrapper\" [id]=\"headerId\">\r\n <div class=\"title\">\r\n @if ((!$collapsedHeader()) || tableSettings.showTitleWhenHeaderCollapsed)\r\n {\r\n <ng-content select=\".tb-header-title\"/>\r\n @if (tableSettings.title)\r\n {\r\n @switch (tableSettings.title.level)\r\n {\r\n @case (1) { <h1 class=\"tb-container-title\" [style]=\"tableSettings.title.styles\">{{tableSettings.title.text}}</h1>}\r\n @case (2) { <h2 class=\"tb-container-title\" [style]=\"tableSettings.title.styles\">{{tableSettings.title.text}}</h2>}\r\n @case (4) { <h4 class=\"tb-container-title\" [style]=\"tableSettings.title.styles\">{{tableSettings.title.text}}</h4>}\r\n @case (5) { <h5 class=\"tb-container-title\" [style]=\"tableSettings.title.styles\">{{tableSettings.title.text}}</h5>}\r\n @case (6) { <h6 class=\"tb-container-title\" [style]=\"tableSettings.title.styles\">{{tableSettings.title.text}}</h6>}\r\n @default { <h3 class=\"tb-container-title\" [style]=\"tableSettings.title.styles\">{{tableSettings.title.text}}</h3>}\r\n }\r\n }\r\n }\r\n </div>\r\n @if(state.$groupByKeys().length)\r\n {\r\n <group-by-list />\r\n }\r\n <div class=\"flx-row-end\">\r\n <lib-filter-list />\r\n @if (!tableSettings.hideHeader)\r\n {\r\n @if (!$collapsedHeader())\r\n {\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' [xPosition]=\"'before'\">\r\n <lib-table-header-menu #l/>\r\n </mat-menu>\r\n\r\n }\r\n @else\r\n {\r\n <mat-icon color=\"primary\" class=\"flat-menu-button pointer\" [matMenuTriggerFor]=\"mainMenu\">more_horiz</mat-icon>\r\n <mat-menu #mainMenu='matMenu'>\r\n <div class=\"collapsed-head-row\">\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 class=\"collapse-icon header\" [matTooltip]=\"$collapsedHeader() ? 'expand' : 'collapse'\"\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 [columnInfos]='$myColumns()' [trackBy]=\"$trackBy()\" [dataSource]=\"dataSource\" (selection)='selection$.emit($event)' />\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 [columnInfos]='$myColumns()' [trackBy]=\"$trackBy()\" [dataSource]=\"dataSource\" (selection)='selection$.emit($event)' />\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 class=\"collapse-icon footer\" [matTooltip]=\"$collapsedFooter() ? 'expand' : 'collapse'\"\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 && !$collapsedHeader()) {<tb-profiles-menu [tableId]=\"tableId\"/>}\r\n </ng-template>\r\n\r\n</ng-container>\r\n", styles: [".tb-header-wrapper{display:flex;flex-direction:row;width:100%}.flx-row-end{display:flex;flex-direction:row;justify-content:flex-end;align-items:center;margin-left:auto}.flat-menu{line-height:initial;height:initial}.pointer{cursor:pointer}.add-key{width:90%}.paginator{display:flex;flex-direction:row;justify-content:flex-end;align-items:center;background-color:#fff;bottom:0;position:sticky;border-top:.5px solid rgba(0,0,0,.12)}.profiles-menu{visibility:hidden;width:0px;height:0px;display:block;overflow:hidden;position:absolute;top:50px}.collapsed-head-row{display:flex;justify-content:space-evenly}::ng-deep tb-generic-table .mat-mdc-row:nth-child(odd):not(.no-stripe){background-color:var(--tb-odd-row-background-color, #cdeefe)}.tb-container-title{padding-left:var(--tb-container-title-padding-left, 10px);margin:var(--tb-container-title-margin, 0)}\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"] }]
6371
6463
  }] });
6372
6464
  function isFunction(a) {
6373
6465
  return typeof a === 'function';
@@ -6639,8 +6731,9 @@ let _ei;
6639
6731
  /**
6640
6732
  * Creates a selector that can dispatch an action if conditions are met.
6641
6733
  * Note: The props of the selector factory must include the props of the action.
6642
- * @param selectorFactory A method that returns selector.
6643
- * @param action The action that will be dispatched when conditions are met.
6734
+ * @param selectorFactory A method that returns a selector.
6735
+ * @param action A method that returns the action that will be dispatched when conditions are met. The method will be passed the args of the
6736
+ * selector factory and the result of the selector.
6644
6737
  * @param [dispatchIf = defaultFilter] Optional. A method that takes the result of the selector and returns a boolean. The actions gets dispatched
6645
6738
  * if true is returned. If no method is passed in than the action will be dispatched if the selector returns undefined or null.
6646
6739
  */
@@ -6653,6 +6746,11 @@ const createActionableSelector = (selectorFactory, action, dispatchIf = defaultF
6653
6746
  const actionable = createActionResultSelector(options);
6654
6747
  return (...props) => createSelector(actionable(...props), b => b.result);
6655
6748
  };
6749
+ /**
6750
+ * Creates a selector that can run an action if conditions are met.
6751
+ * The action will run in the environment injector context if no injector is added to the options
6752
+ * Note: The props of the selector factory must include the props of the action.
6753
+ */
6656
6754
  const createActionSelector = (options) => {
6657
6755
  const actionable = createActionResultSelector(options);
6658
6756
  return ((...props) => createSelector(actionable(...props), b => b.result));
@@ -6671,7 +6769,7 @@ const createActionResultSelector = (options) => {
6671
6769
  const needsDispatch = (options.dispatchIf || defaultFilter)(selected);
6672
6770
  if (needsDispatch && !_cache.isInCache(id, ...props)) {
6673
6771
  queueMicrotask(() => runInInjectionContext(options.injector || _ei, () => {
6674
- options.action(...props)();
6772
+ options.action(...[...props, selected])();
6675
6773
  }));
6676
6774
  }
6677
6775
  return ({
@@ -6690,7 +6788,7 @@ class AppStoreCache {
6690
6788
  b = { b };
6691
6789
  return ({ ...a, ...b });
6692
6790
  }, {});
6693
- let itemsInCache = this.cache[actionableSelectorId] = (this.cache[actionableSelectorId] || []);
6791
+ const itemsInCache = this.cache[actionableSelectorId] = (this.cache[actionableSelectorId] || []);
6694
6792
  if (itemsInCache.some(itemInCache => shallowEquals(itemInCache, props))) {
6695
6793
  return true;
6696
6794
  }