@one-paragon/angular-utilities 2.1.3 → 2.1.4

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.
@@ -4,9 +4,9 @@ import { shareReplay, switchAll, map, filter, tap, catchError, startWith, switch
4
4
  import * as i1 from 'rxjs';
5
5
  import { Subject, isObservable, 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';
6
6
  import { toObservable, toSignal, outputFromObservable } from '@angular/core/rxjs-interop';
7
- import { isFunction, merge as merge$1, get, sumBy, difference, groupBy, intersection, set } from 'lodash';
8
7
  import * as i3$2 from '@angular/material/sort';
9
8
  import { MatSort, MatSortModule } from '@angular/material/sort';
9
+ import { merge as merge$1, sumBy, difference, groupBy, intersection, set, get } from 'lodash';
10
10
  import { CdkColumnDef } from '@angular/cdk/table';
11
11
  import { coerceBooleanProperty } from '@angular/cdk/coercion';
12
12
  import { MatSlideToggle } from '@angular/material/slide-toggle';
@@ -725,7 +725,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.1", ngImpor
725
725
  type: Injectable
726
726
  }], ctorParameters: () => [] });
727
727
  function createRequestor(req, optionsOrProject, options) {
728
- const ops = isFunction(optionsOrProject) ? options : optionsOrProject;
728
+ const ops = typeof (optionsOrProject) === 'function' ? options : optionsOrProject;
729
729
  const injector = getInjector(ops);
730
730
  return runInInjectionContext(injector, () => {
731
731
  const requestStore = typeof (optionsOrProject) === 'function' ?
@@ -1794,6 +1794,89 @@ const BooleanFilterFuncs = {
1794
1794
  [FilterType.IsNull]: isNull,
1795
1795
  };
1796
1796
 
1797
+ function sortData(data, sorted) {
1798
+ return data.sort(compareT(sorted));
1799
+ }
1800
+ function filterData(data, filters, resetAll = false) {
1801
+ if (filters.length === 0) {
1802
+ if (resetAll) {
1803
+ for (let index = 0; index < data.length; index++) {
1804
+ const element = data[index];
1805
+ element[tbNoShowSymbol] = false;
1806
+ }
1807
+ }
1808
+ return data;
1809
+ }
1810
+ for (let index = 0; index < data.length; index++) {
1811
+ const element = data[index];
1812
+ const hide = !filters.every(filter => filter(element));
1813
+ if (hide || resetAll) {
1814
+ element[tbNoShowSymbol] = hide;
1815
+ }
1816
+ }
1817
+ return data;
1818
+ }
1819
+ const tbNoShowSymbol = Symbol('tb_no_show');
1820
+ function compareT(criteria) {
1821
+ const transforms = criteria.reduce((acc, c) => {
1822
+ acc[c.active] = {
1823
+ transform: c.sortBy ? c.sortBy : getFactory(c.active), nulls: c.nulls === 'first' ? -1 : 1
1824
+ };
1825
+ return acc;
1826
+ }, {});
1827
+ return function (a, b) {
1828
+ for (let index = 0; index < criteria.length; index++) {
1829
+ const c = criteria[index];
1830
+ const d = transforms[c.active];
1831
+ const nullValue = d.nulls;
1832
+ if (a == null) {
1833
+ if (b == null)
1834
+ return 0;
1835
+ return nullValue;
1836
+ }
1837
+ if (b == null)
1838
+ return -nullValue;
1839
+ const transform = d.transform;
1840
+ const aVal = transform(a);
1841
+ const bVal = transform(b);
1842
+ if (aVal == null) {
1843
+ if (bVal == null)
1844
+ return 0;
1845
+ return nullValue;
1846
+ }
1847
+ if (bVal == null)
1848
+ return -nullValue;
1849
+ if (aVal < bVal)
1850
+ return c.direction === 'asc' ? -1 : 1;
1851
+ if (aVal > bVal)
1852
+ return c.direction === 'asc' ? 1 : -1;
1853
+ }
1854
+ return 0;
1855
+ };
1856
+ }
1857
+ function getFactory(b) {
1858
+ if (typeof b !== 'string')
1859
+ return (a) => a[b];
1860
+ if (!b.includes('.'))
1861
+ return (a) => {
1862
+ if (!a)
1863
+ return a;
1864
+ return a[b];
1865
+ };
1866
+ const arr = b.split('.');
1867
+ return (a) => {
1868
+ let val = a;
1869
+ if (!a)
1870
+ return a;
1871
+ for (let index = 0; index < arr.length; index++) {
1872
+ val = val[arr[index]];
1873
+ if (typeof val !== 'object' && index + 1 < arr.length)
1874
+ return undefined;
1875
+ }
1876
+ return val;
1877
+ };
1878
+ }
1879
+
1797
1880
  const filterFactoryMap = {
1798
1881
  [FilterType.And]: (filter) => {
1799
1882
  const filters = createFilterFuncs(filter.filterValue);
@@ -1848,7 +1931,7 @@ function createFilterFunc(filter) {
1848
1931
  }
1849
1932
  }
1850
1933
  const cannotBeTrueForNull = !FalseyValueCanBeIncludedFilterTypes.includes(filter.filterType);
1851
- const getter = filter.filterBy || ((rowObj) => get(rowObj, filter.key));
1934
+ const getter = filter.filterBy || getFactory(filter.key);
1852
1935
  return (rowObj) => {
1853
1936
  const value = getter(rowObj);
1854
1937
  return ((value == undefined) && cannotBeTrueForNull)
@@ -3280,8 +3363,7 @@ function isPipe(o) {
3280
3363
  return typeof (o.transform) === 'function';
3281
3364
  }
3282
3365
  function createTransformer(metaData, config, noIcons = false, forItem = false) {
3283
- const nested = metaData.key.includes('.');
3284
- const defaultFunc = nested ? (value) => get(value, metaData.key) : (value) => value[metaData.key];
3366
+ const defaultFunc = getFactory(metaData.key);
3285
3367
  if (metaData.map && !forItem) {
3286
3368
  return (value) => {
3287
3369
  return metaData.map(value);
@@ -4317,7 +4399,7 @@ class ExportToCsvService {
4317
4399
  return res.join('\n');
4318
4400
  };
4319
4401
  metaToField = (meta, row) => {
4320
- let val = get(row, meta.key);
4402
+ let val = getFactory(meta.key)(row);
4321
4403
  if (val == null && !meta.transform)
4322
4404
  return val;
4323
4405
  if (meta.transform && meta.fieldType !== FieldType.Expression) {
@@ -4380,9 +4462,15 @@ function createLinkCreator(metaData) {
4380
4462
  const target = metaData.additional?.link?.target || '_blank';
4381
4463
  const useRouterLink = metaData.additional?.link?.useRouterLink || false;
4382
4464
  const hasRoute = !!metaData.additional?.link?.interpolatedRoute;
4465
+ const qp = useRouterLink ?
4466
+ metaData.additional.link.routerLinkOptions?.queryParams?.reduce((map, [key, value]) => {
4467
+ map[key] = typeof value === 'function' ? value : parseInterpolated(value);
4468
+ return map;
4469
+ }, {})
4470
+ : undefined;
4383
4471
  const routerLinkOptions = useRouterLink ? {
4384
4472
  queryParams: (element) => metaData.additional.link.routerLinkOptions?.queryParams?.reduce((map, [key, value]) => {
4385
- map[key] = typeof value === 'function' ? value(element) : parseInterpolated(value, element);
4473
+ map[key] = qp[key](element);
4386
4474
  return map;
4387
4475
  }, {}) ?? null,
4388
4476
  fragment: metaData.additional.link?.routerLinkOptions?.fragment,
@@ -4393,7 +4481,7 @@ function createLinkCreator(metaData) {
4393
4481
  if (hasRoute) {
4394
4482
  const value = metaData.additional.link.interpolatedRoute;
4395
4483
  return ({
4396
- link: (element) => typeof value === 'function' ? value(element) : parseInterpolated(value, element),
4484
+ link: typeof value === 'function' ? (element) => value(element) : parseInterpolated(value),
4397
4485
  target,
4398
4486
  useRouterLink,
4399
4487
  routerLinkOptions,
@@ -4412,10 +4500,33 @@ function createLinkCreator(metaData) {
4412
4500
  }
4413
4501
  }
4414
4502
  const key = (metaData) => metaData.additional.link?.urlKey ?
4415
- (element) => get(element, metaData.additional.link.urlKey)
4503
+ getFactory(metaData.additional.link.urlKey)
4416
4504
  :
4417
- (element) => get(element, metaData.key);
4418
- const parseInterpolated = (interpolatedString, element) => interpolatedString.replace(/{([^}]+)}/g, (_, key) => get(element, key));
4505
+ getFactory(metaData.key);
4506
+ function parseInterpolated(input) {
4507
+ // Match either content inside curly braces or content between curly braces
4508
+ const parts = input.split(/({[\w.]+})/);
4509
+ const result = parts
4510
+ .filter(part => part !== '') // Remove empty strings
4511
+ .map(part => {
4512
+ if (part.startsWith('{') && part.endsWith('}')) {
4513
+ // For interpolated values, remove the curly braces
4514
+ return {
4515
+ type: 'interpolated',
4516
+ val: getFactory(part.slice(1, -1))
4517
+ };
4518
+ }
4519
+ else {
4520
+ return {
4521
+ type: 'string',
4522
+ val: part
4523
+ };
4524
+ }
4525
+ });
4526
+ return function (val) {
4527
+ return result.map(part => part.type === 'string' ? part.val : part.val(val)).join('');
4528
+ };
4529
+ }
4419
4530
 
4420
4531
  class TableBuilderStateStore extends ComponentStore {
4421
4532
  constructor() {
@@ -4666,59 +4777,6 @@ function patchDirectiveFromState(directive, stateFilter) {
4666
4777
  }
4667
4778
  }
4668
4779
 
4669
- function sortData(data, sorted) {
4670
- return data.sort(compareT(sorted));
4671
- }
4672
- function filterData(data, filters, resetAll = false) {
4673
- if (filters.length === 0) {
4674
- if (resetAll) {
4675
- for (let index = 0; index < data.length; index++) {
4676
- const element = data[index];
4677
- element[tbNoShowSymbol] = false;
4678
- }
4679
- }
4680
- return data;
4681
- }
4682
- for (let index = 0; index < data.length; index++) {
4683
- const element = data[index];
4684
- const hide = !filters.every(filter => filter(element));
4685
- if (hide || resetAll) {
4686
- element[tbNoShowSymbol] = hide;
4687
- }
4688
- }
4689
- return data;
4690
- }
4691
- const tbNoShowSymbol = Symbol('tb_no_show');
4692
- function compareT(criteria) {
4693
- return function (a, b) {
4694
- for (let index = 0; index < criteria.length; index++) {
4695
- const c = criteria[index];
4696
- const nullValue = c.nulls === 'first' ? -1 : 1;
4697
- if (a == null) {
4698
- if (b == null)
4699
- return 0;
4700
- return nullValue;
4701
- }
4702
- if (b == null)
4703
- return -nullValue;
4704
- const aVal = c.sortBy ? c.sortBy(a) : a[c.active];
4705
- const bVal = c.sortBy ? c.sortBy(b) : b[c.active];
4706
- if (aVal == null) {
4707
- if (bVal == null)
4708
- return 0;
4709
- return nullValue;
4710
- }
4711
- if (bVal == null)
4712
- return -nullValue;
4713
- if (aVal < bVal)
4714
- return c.direction === 'asc' ? -1 : 1;
4715
- if (aVal > bVal)
4716
- return c.direction === 'asc' ? 1 : -1;
4717
- }
4718
- return 0;
4719
- };
4720
- }
4721
-
4722
4780
  const _sortAndFilterData = (data, sortState, filterState) => combineLatest([
4723
4781
  data.pipe(timestamp()),
4724
4782
  sortState.pipe(timestamp()),
@@ -4760,103 +4818,58 @@ const createDataCleaners = (metadatas, mutate = false) => {
4760
4818
  };
4761
4819
  const createCleaners = (metadatas) => {
4762
4820
  return metadatas.reduce((transforms, metaData) => {
4763
- const notNestedKey = metaData.key;
4821
+ const getter = getFactory(metaData.key);
4822
+ const setter = metaData.key.includes('.') ? (t, val) => set(t, metaData.key, val) : (t, val) => t[metaData.key] = val;
4764
4823
  switch (metaData.fieldType) {
4765
4824
  case FieldType.Currency:
4766
4825
  case FieldType.Number: {
4767
- const nested = metaData.key.includes('.');
4768
- if (nested) {
4769
- transforms.push((t) => {
4770
- const val = get(t, metaData.key);
4771
- const num = Number(val);
4772
- set(t, metaData.key, isNaN(num) || val == null ? null : num);
4773
- });
4774
- }
4775
- else {
4776
- transforms.push((t) => {
4777
- const val = t[notNestedKey];
4778
- const num = Number(val);
4779
- t[notNestedKey] = (isNaN(num) || val == null ? null : num);
4780
- });
4781
- }
4826
+ const transform = (t) => {
4827
+ const val = getter(t);
4828
+ const num = Number(val);
4829
+ setter(t, isNaN(num) || val == null ? null : num);
4830
+ };
4831
+ transforms.push(transform);
4782
4832
  break;
4783
4833
  }
4784
4834
  case FieldType.Date: {
4785
- const nested = metaData.key.includes('.');
4786
- if (nested) {
4787
- transforms.push((t) => {
4788
- const val = get(t, metaData.key);
4789
- const date = Date.parse(val);
4790
- if (isNaN(date)) {
4791
- set(t, metaData.key, null);
4792
- return;
4793
- }
4794
- const d = new Date(date);
4795
- d.setHours(0, 0, 0, 0);
4796
- set(t, metaData.key, d);
4797
- });
4798
- }
4799
- else {
4800
- transforms.push((t) => {
4801
- const val = t[notNestedKey];
4802
- const date = Date.parse(val);
4803
- if (isNaN(date)) {
4804
- t[notNestedKey] = null;
4805
- return;
4806
- }
4807
- const d = new Date(date);
4808
- d.setHours(0, 0, 0, 0);
4809
- t[notNestedKey] = d;
4810
- });
4811
- }
4835
+ const transform = (t) => {
4836
+ const val = getter(t);
4837
+ const date = Date.parse(val);
4838
+ let mappedDate;
4839
+ if (isNaN(date)) {
4840
+ mappedDate = null;
4841
+ }
4842
+ else {
4843
+ mappedDate = new Date(date);
4844
+ mappedDate.setHours(0, 0, 0, 0);
4845
+ }
4846
+ setter(t, mappedDate);
4847
+ };
4848
+ transforms.push(transform);
4812
4849
  break;
4813
4850
  }
4814
4851
  case FieldType.DateTime: {
4815
- const nested = metaData.key.includes('.');
4816
- if (nested) {
4817
- transforms.push((t) => {
4818
- const val = get(t, metaData.key);
4819
- const dateTime = Date.parse(val);
4820
- if (isNaN(dateTime)) {
4821
- set(t, metaData.key, null);
4822
- return;
4823
- }
4824
- const dt = new Date(dateTime);
4825
- if (metaData.additional?.dateTimeOptions?.includeMilliseconds) {
4826
- set(t, metaData.key, dt);
4827
- return;
4828
- }
4829
- if (metaData.additional?.dateTimeOptions?.includeSeconds) {
4830
- dt.setMilliseconds(0);
4831
- set(t, metaData.key, dt);
4832
- return;
4833
- }
4834
- dt.setSeconds(0, 0);
4835
- set(t, metaData.key, dt);
4836
- });
4837
- }
4838
- else {
4839
- transforms.push((t) => {
4840
- const val = t[notNestedKey];
4841
- const dateTime = Date.parse(val);
4842
- if (isNaN(dateTime)) {
4843
- t[notNestedKey] = null;
4844
- return;
4845
- }
4846
- const dt = new Date(dateTime);
4847
- if (metaData.additional?.dateTimeOptions?.includeMilliseconds) {
4848
- t[notNestedKey] = dt;
4849
- return;
4850
- }
4851
- if (metaData.additional?.dateTimeOptions?.includeSeconds) {
4852
- dt.setMilliseconds(0);
4853
- t[notNestedKey] = dt;
4854
- return;
4852
+ const transform = (t) => {
4853
+ const val = getter(t);
4854
+ const date = Date.parse(val);
4855
+ let mappedDate;
4856
+ if (isNaN(date)) {
4857
+ mappedDate = null;
4858
+ }
4859
+ else {
4860
+ mappedDate = new Date(date);
4861
+ if (!metaData.additional?.dateTimeOptions?.includeMilliseconds) {
4862
+ if (metaData.additional?.dateTimeOptions?.includeSeconds) {
4863
+ mappedDate.setMilliseconds(0);
4864
+ }
4865
+ else {
4866
+ mappedDate.setSeconds(0, 0);
4867
+ }
4855
4868
  }
4856
- dt.setSeconds(0, 0);
4857
- t[notNestedKey] = dt;
4858
- });
4859
- }
4869
+ }
4870
+ setter(t, mappedDate);
4871
+ };
4872
+ transforms.push(transform);
4860
4873
  }
4861
4874
  }
4862
4875
  return transforms;
@@ -5931,6 +5944,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.1", ngImpor
5931
5944
  MatButtonModule, MatMenuModule, MatIconModule, MatTooltipModule, VirtualScrollContainer
5932
5945
  ], template: "@let tableId = $tableId();\r\n@let tableSettings = state.$tableSettings();\r\n\r\n<ng-content select=\"[before]\" />\r\n<ng-container multiSort>\r\n <div class=\"tb-header-wrapper\" [id]=\"headerId\">\r\n <div class=\"title\">\r\n @if ((!$collapsedHeader()) || tableSettings.showTitleWhenHeaderCollapsed)\r\n {\r\n <ng-content select=\".tb-header-title\"/>\r\n }\r\n </div>\r\n @if(state.$groupByKeys().length){\r\n <group-by-list />\r\n }\r\n <div class=\"flx-row-end\">\r\n <lib-filter-list />\r\n @if (!tableSettings.hideHeader)\r\n {\r\n @if (!$collapsedHeader())\r\n {\r\n <ng-container *ngTemplateOutlet=\"headerMenu\"/>\r\n <button mat-icon-button color='primary' [matMenuTriggerFor]=\"l.menu()\">\r\n <mat-icon>more_vert</mat-icon>\r\n </button>\r\n\r\n <lib-table-header-menu #l/>\r\n\r\n }\r\n @else {\r\n <mat-icon color=\"primary\" [matMenuTriggerFor]=\"mainMenu\" class=\"flat-menu-button pointer\">more_horiz</mat-icon>\r\n <mat-menu #mainMenu='matMenu'>\r\n <div class=\"flex-column\">\r\n <ng-container *ngTemplateOutlet=\"headerMenu; injector menuInjector\"/>\r\n </div>\r\n <lib-table-header-menu />\r\n </mat-menu>\r\n }\r\n <mat-icon [matTooltip]=\"$collapsedHeader() ? 'expand' : 'collapse'\" class=\"collapse-icon header\"\r\n (click)=\"state.toggleCollapseHeader()\">\r\n {{$collapsedHeader() ? 'expand_less' : 'expand_more'}}\r\n </mat-icon>\r\n }\r\n\r\n </div>\r\n </div>\r\n\r\n @if($useVirtual())\r\n {\r\n <tb-virtual-scroll-container class=\"scrollable\">\r\n <tb-generic-table [rows]=\"$customRows()\" [data]=\"$data()!\" [displayDataLength]=\"$displayDataLength()\"\r\n (selection)='selection$.emit($event)' [columnInfos]='$myColumns()' [trackBy]=\"$trackBy()\" [dataSource]=\"dataSource\" />\r\n </tb-virtual-scroll-container>\r\n }\r\n @else\r\n {\r\n <tb-generic-table [rows]=\"$customRows()\" [data]=\"$data()!\" [displayDataLength]=\"$displayDataLength()\"\r\n (selection)='selection$.emit($event)' [columnInfos]='$myColumns()' [trackBy]=\"$trackBy()\" [dataSource]=\"dataSource\" />\r\n }\r\n @if(tableSettings.usePaginator)\r\n {\r\n <div class=\"paginator\">\r\n <tb-paginator #tbPaginator />\r\n\r\n <mat-icon [matTooltip]=\"$collapsedFooter() ? 'expand' : 'collapse'\" class=\"collapse-icon footer\"\r\n (click)=\"state.toggleCollapseFooter()\">\r\n {{$collapsedFooter() ? 'expand_more' : 'expand_less'}}\r\n </mat-icon>\r\n </div>\r\n }\r\n\r\n <ng-template #headerMenu>\r\n @if (!tableSettings.hideFilter) {<tb-filter-displayer/>}\r\n @if (!tableSettings.hideColumnSettings) {<tb-col-displayer/>}\r\n @if (!tableSettings.hideSort) {<tb-sort-menu/>}\r\n @if (!!tableId) {<tb-profiles-menu [tableId]=\"tableId\"/>}\r\n </ng-template>\r\n\r\n</ng-container>\r\n", styles: [".tb-header-wrapper{display:flex;flex-direction:row;width:100%}.flx-row-end{display:flex;flex-direction:row;justify-content:flex-end;align-items:center;margin-left:auto}.flat-menu{line-height:initial;height:initial}.pointer{cursor:pointer}.add-key{width:90%}.paginator{display:flex;flex-direction:row;justify-content:flex-end;align-items:center;background-color:#fff;bottom:0;position:sticky;border-top:.5px solid rgba(0,0,0,.12)}.profiles-menu{visibility:hidden;width:0px;height:0px;display:block;overflow:hidden;position:absolute;top:50px}\n", ".collapse-icon{font-size:16px;height:16px;color:#3f51b5;align-self:flex-start}.collapse-icon:hover{cursor:pointer}.hide{display:none}.paginator-row{display:flex;align-items:center}\n"] }]
5933
5946
  }] });
5947
+ function isFunction(a) {
5948
+ return typeof a === 'function';
5949
+ }
5934
5950
 
5935
5951
  class TableBuilderModule {
5936
5952
  static forRoot(config) {