@competer/primeng-table 19.1.8 → 19.2.0

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,7 +4,7 @@ import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
4
4
  import * as i1$2 from '@ngx-translate/core';
5
5
  import { TranslateService, TranslateDefaultParser, TranslatePipe } from '@ngx-translate/core';
6
6
  import { PrimeNG } from 'primeng/config';
7
- import { EMPTY, merge, Observable, finalize } from 'rxjs';
7
+ import { EMPTY, merge, Observable, finalize, firstValueFrom } from 'rxjs';
8
8
  import * as i1$1 from '@angular/common';
9
9
  import { CommonModule } from '@angular/common';
10
10
  import * as i9$1 from '@angular/forms';
@@ -25,12 +25,13 @@ import * as i11$1 from 'primeng/multiselect';
25
25
  import { MultiSelectModule } from 'primeng/multiselect';
26
26
  import * as i9 from 'primeng/checkbox';
27
27
  import { CheckboxModule } from 'primeng/checkbox';
28
+ import * as i13 from 'primeng/paginator';
28
29
  import { PaginatorModule } from 'primeng/paginator';
29
- import * as i13 from 'primeng/buttongroup';
30
+ import * as i14 from 'primeng/buttongroup';
30
31
  import { ButtonGroupModule } from 'primeng/buttongroup';
31
- import * as i14 from 'primeng/popover';
32
+ import * as i15 from 'primeng/popover';
32
33
  import { PopoverModule } from 'primeng/popover';
33
- import * as i15 from 'primeng/menu';
34
+ import * as i16 from 'primeng/menu';
34
35
  import { MenuModule } from 'primeng/menu';
35
36
  import * as i3 from 'primeng/skeleton';
36
37
  import { SkeletonModule } from 'primeng/skeleton';
@@ -219,6 +220,8 @@ const DEFAULT_TABLE_OPTIONS = {
219
220
  },
220
221
  checkboxSelector: {
221
222
  enabled: false,
223
+ selectAllEnabled: false,
224
+ urlSelectAll: undefined,
222
225
  header: "Selected",
223
226
  positionRight: false,
224
227
  width: 150,
@@ -240,6 +243,8 @@ const DEFAULT_TABLE_OPTIONS = {
240
243
  },
241
244
  globalFilter: {
242
245
  enabled: true,
246
+ minLength: 0,
247
+ debounceTime: 0,
243
248
  maxLength: 20
244
249
  },
245
250
  predefinedFilters: {},
@@ -301,6 +306,246 @@ function createTableOptions(overrides = {}) {
301
306
  return merged;
302
307
  }
303
308
 
309
+ class TreeTableState {
310
+ options;
311
+ expanded = new Set();
312
+ nodes = new Map();
313
+ children = new Map();
314
+ totals = new Map();
315
+ pages = new Map();
316
+ entries = new WeakMap();
317
+ roots = [];
318
+ allRoots = [];
319
+ version = 0;
320
+ pending = new Set();
321
+ restoredPages = {};
322
+ visible = [];
323
+ loading = false;
324
+ page = 0;
325
+ pageSize = 10;
326
+ totalRecords = 0;
327
+ totalRecordsNotFiltered = 0;
328
+ constructor(options) {
329
+ this.options = options;
330
+ if (!options.keyExpr?.trim() || !options.parentIdExpr?.trim() || !options.column?.trim()) {
331
+ throw new Error('Tree configuration requires keyExpr, parentIdExpr and column.');
332
+ }
333
+ if (!['all', 'onDemand', 'pagedChildren'].includes(this.mode)) {
334
+ throw new Error('Invalid tree loadMode.');
335
+ }
336
+ if (this.mode !== 'all' && !options.hasItemsExpr?.trim()) {
337
+ throw new Error('Remote tree loading requires hasItemsExpr.');
338
+ }
339
+ }
340
+ get mode() { return this.options.loadMode ?? 'onDemand'; }
341
+ get rootValue() { return this.options.rootValue === undefined ? 0 : this.options.rootValue; }
342
+ key(row) {
343
+ const key = row[this.options.keyExpr];
344
+ if ((typeof key !== 'string' && typeof key !== 'number') || key === '' ||
345
+ (typeof key === 'number' && !Number.isFinite(key))) {
346
+ throw new Error('Tree keys must be non-empty strings or finite numbers.');
347
+ }
348
+ return key;
349
+ }
350
+ restore(keys = [], pages = {}) {
351
+ this.expanded.clear();
352
+ keys.forEach(key => this.expanded.add(key));
353
+ this.restoredPages = { ...pages };
354
+ }
355
+ snapshotPages() {
356
+ return Object.fromEntries([...this.pages].map(([key, page]) => [JSON.stringify(key), page]));
357
+ }
358
+ depth(row) { return this.entries.get(row)?.depth ?? 0; }
359
+ isMore(row) { return !!this.entries.get(row)?.more; }
360
+ moreParent(row) { return this.entries.get(row)?.parent; }
361
+ isExpanded(row) { return this.expanded.has(this.key(row)); }
362
+ isLoading(row) { return this.pending.has(this.key(row)); }
363
+ hasChildren(row) {
364
+ if (this.mode === 'all')
365
+ return !!this.children.get(this.key(row))?.length;
366
+ return row[this.options.hasItemsExpr] === true;
367
+ }
368
+ cancel() { this.version++; this.loading = false; this.pending.clear(); }
369
+ async load(page, pageSize, fetch) {
370
+ const version = ++this.version;
371
+ this.loading = true;
372
+ this.pending.clear();
373
+ this.nodes.clear();
374
+ this.children.clear();
375
+ this.totals.clear();
376
+ this.pages.clear();
377
+ this.visible = [];
378
+ this.page = page;
379
+ this.pageSize = pageSize;
380
+ try {
381
+ const response = await fetch({ roots: true, parentId: this.rootValue, loadMode: this.mode, page, pageSize });
382
+ if (version !== this.version)
383
+ return false;
384
+ this.insert(response.data);
385
+ this.page = response.page;
386
+ this.totalRecords = response.totalRecords;
387
+ this.totalRecordsNotFiltered = response.totalRecordsNotFiltered;
388
+ if (this.mode === 'all') {
389
+ this.buildAll();
390
+ this.page = Math.min(Math.max(0, page), Math.max(0, Math.ceil(this.allRoots.length / pageSize) - 1));
391
+ this.roots = this.allRoots.slice(this.page * pageSize, (this.page + 1) * pageSize);
392
+ }
393
+ else {
394
+ this.roots = response.data.map(row => this.key(row));
395
+ }
396
+ response.ancestorKeys?.forEach(key => this.expanded.add(key));
397
+ const queue = [...this.roots];
398
+ for (let cursor = 0; cursor < queue.length; cursor++) {
399
+ const key = queue[cursor];
400
+ const row = this.nodes.get(key);
401
+ if (!this.expanded.has(key) || !this.hasChildren(row))
402
+ continue;
403
+ if (this.mode !== 'all') {
404
+ await this.fetchChildren(key, 0, fetch, version);
405
+ const targetPage = this.restoredPages[JSON.stringify(key)] ?? 0;
406
+ while (version === this.version && this.mode === 'pagedChildren' &&
407
+ (this.pages.get(key) ?? 0) < targetPage && this.hasMore(key)) {
408
+ await this.fetchChildren(key, (this.pages.get(key) ?? 0) + 1, fetch, version);
409
+ }
410
+ }
411
+ if (version !== this.version)
412
+ return false;
413
+ queue.push(...(this.children.get(key) ?? []));
414
+ }
415
+ this.restoredPages = {};
416
+ this.rebuild();
417
+ return true;
418
+ }
419
+ finally {
420
+ if (version === this.version)
421
+ this.loading = false;
422
+ }
423
+ }
424
+ async toggle(row, fetch) {
425
+ const key = this.key(row);
426
+ if (this.pending.has(key))
427
+ return;
428
+ if (this.expanded.delete(key)) {
429
+ this.rebuild();
430
+ return;
431
+ }
432
+ this.expanded.add(key);
433
+ const version = this.version;
434
+ try {
435
+ const queue = [key];
436
+ for (let cursor = 0; cursor < queue.length; cursor++) {
437
+ const current = queue[cursor];
438
+ if (this.mode !== 'all' && !this.children.has(current))
439
+ await this.fetchChildren(current, 0, fetch, version);
440
+ if (version !== this.version)
441
+ return;
442
+ for (const child of this.children.get(current) ?? []) {
443
+ if (this.expanded.has(child) && this.hasChildren(this.nodes.get(child)))
444
+ queue.push(child);
445
+ }
446
+ }
447
+ this.rebuild();
448
+ }
449
+ catch (error) {
450
+ if (version === this.version)
451
+ this.expanded.delete(key);
452
+ throw error;
453
+ }
454
+ }
455
+ async loadMore(row, fetch) {
456
+ const parent = this.moreParent(row);
457
+ if (parent === undefined || this.pending.has(parent))
458
+ return;
459
+ const version = this.version;
460
+ await this.fetchChildren(parent, (this.pages.get(parent) ?? 0) + 1, fetch, version);
461
+ if (version === this.version)
462
+ this.rebuild();
463
+ }
464
+ insert(rows) {
465
+ const keys = new Set();
466
+ for (const row of rows) {
467
+ const key = this.key(row);
468
+ if (keys.has(key) || this.nodes.has(key))
469
+ throw new Error('Duplicate tree key.');
470
+ keys.add(key);
471
+ }
472
+ for (const row of rows)
473
+ this.nodes.set(this.key(row), row);
474
+ }
475
+ buildAll() {
476
+ this.allRoots = [];
477
+ for (const [key, row] of this.nodes) {
478
+ const parent = row[this.options.parentIdExpr];
479
+ if (parent === this.rootValue)
480
+ this.allRoots.push(key);
481
+ else {
482
+ if (!this.nodes.has(parent))
483
+ throw new Error('Missing tree parent.');
484
+ const siblings = this.children.get(parent) ?? [];
485
+ siblings.push(key);
486
+ this.children.set(parent, siblings);
487
+ }
488
+ }
489
+ const seen = new Set();
490
+ const queue = [...this.allRoots];
491
+ for (let cursor = 0; cursor < queue.length; cursor++) {
492
+ const key = queue[cursor];
493
+ if (seen.has(key))
494
+ throw new Error('Tree cycle.');
495
+ seen.add(key);
496
+ queue.push(...(this.children.get(key) ?? []));
497
+ }
498
+ if (seen.size !== this.nodes.size)
499
+ throw new Error('Tree cycle.');
500
+ }
501
+ async fetchChildren(key, page, fetch, version) {
502
+ this.pending.add(key);
503
+ try {
504
+ const response = await fetch({ roots: false, parentId: key, loadMode: this.mode, page, pageSize: this.pageSize });
505
+ if (version !== this.version)
506
+ return;
507
+ for (const row of response.data) {
508
+ if (row[this.options.parentIdExpr] !== key)
509
+ throw new Error('Unexpected tree parent.');
510
+ }
511
+ this.insert(response.data);
512
+ this.children.set(key, [...(this.children.get(key) ?? []), ...response.data.map(row => this.key(row))]);
513
+ this.totals.set(key, response.totalRecords);
514
+ this.pages.set(key, response.page);
515
+ response.ancestorKeys?.forEach(ancestor => this.expanded.add(ancestor));
516
+ }
517
+ finally {
518
+ if (version === this.version)
519
+ this.pending.delete(key);
520
+ }
521
+ }
522
+ hasMore(key) {
523
+ return (this.children.get(key)?.length ?? 0) < (this.totals.get(key) ?? 0);
524
+ }
525
+ rebuild() {
526
+ this.entries = new WeakMap();
527
+ const result = [];
528
+ const stack = this.roots.map(key => ({ row: this.nodes.get(key), depth: 0 })).reverse();
529
+ while (stack.length) {
530
+ const entry = stack.pop();
531
+ this.entries.set(entry.row, entry);
532
+ result.push(entry.row);
533
+ if (entry.more)
534
+ continue;
535
+ const key = this.key(entry.row);
536
+ if (!this.expanded.has(key))
537
+ continue;
538
+ if (this.hasMore(key))
539
+ stack.push({ row: {}, depth: entry.depth + 1, parent: key, more: true });
540
+ const children = this.children.get(key) ?? [];
541
+ for (let index = children.length - 1; index >= 0; index--) {
542
+ stack.push({ row: this.nodes.get(children[index]), depth: entry.depth + 1, parent: key });
543
+ }
544
+ }
545
+ this.visible = result;
546
+ }
547
+ }
548
+
304
549
  /**
305
550
  * Abstract service for handling HTTP requests for **ECS Primeng table**.
306
551
  *
@@ -729,6 +974,9 @@ class ECSPrimengTableService {
729
974
  };
730
975
  return this.http.handleHttpPostRequest(setListEndpoint, postData);
731
976
  }
977
+ fetchSelectionKeys(endpoint, request) {
978
+ return this.http.handleHttpPostRequest(endpoint, request);
979
+ }
732
980
  viewGenerateData(dt, globalSearchText, currentPage, currentRowsPerPage, modifyFiltersFn) {
733
981
  let colsWidth = this.computeColumnWidths(dt);
734
982
  let tableWidth = this.computeTableWidth(dt);
@@ -1451,6 +1699,9 @@ class ECSPrimengTable {
1451
1699
  });
1452
1700
  }
1453
1701
  tableOptions = DEFAULT_TABLE_OPTIONS;
1702
+ treeState;
1703
+ treeQuery;
1704
+ treeStateRestored = false;
1454
1705
  onRowCheckboxChange = new EventEmitter(); // Emitter that returns the column selected and if it was selected or unselected
1455
1706
  onRowSelect = new EventEmitter;
1456
1707
  onRowUnselect = new EventEmitter;
@@ -1462,8 +1713,70 @@ class ECSPrimengTable {
1462
1713
  showExportModal = false;
1463
1714
  showColumnSelector = false;
1464
1715
  selectedRowsCheckbox = []; // An array to keep all the selected rows
1716
+ selectAllLoading = false;
1717
+ selectionQuery;
1718
+ selectionQueryKey = '';
1719
+ matchingSelectionKeys;
1465
1720
  dt; // Get the reference to the object table
1466
1721
  globalSearchText = null; // The text used by the global search
1722
+ appliedGlobalSearchText = null;
1723
+ globalSearchManaged = false;
1724
+ globalSearchTimer;
1725
+ /** The applied query stays separate from text being typed during the debounce. */
1726
+ get effectiveGlobalSearchText() {
1727
+ return this.globalSearchManaged ? this.appliedGlobalSearchText : this.globalSearchText;
1728
+ }
1729
+ cancelGlobalSearch() {
1730
+ if (this.globalSearchTimer !== undefined)
1731
+ clearTimeout(this.globalSearchTimer);
1732
+ this.globalSearchTimer = undefined;
1733
+ }
1734
+ restoreGlobalSearch(value) {
1735
+ this.cancelGlobalSearch();
1736
+ this.globalSearchText = value;
1737
+ this.appliedGlobalSearchText = value || null;
1738
+ this.globalSearchManaged = true;
1739
+ }
1740
+ globalSearchOption(value) {
1741
+ return typeof value === 'number' && Number.isFinite(value) ? Math.max(0, Math.floor(value)) : 0;
1742
+ }
1743
+ onGlobalSearchInput(value) {
1744
+ if (this.destroyed)
1745
+ return;
1746
+ this.cancelGlobalSearch();
1747
+ if (!this.globalSearchManaged)
1748
+ this.appliedGlobalSearchText = this.globalSearchText || null;
1749
+ this.globalSearchManaged = true;
1750
+ this.globalSearchText = value;
1751
+ const minLength = this.globalSearchOption(this.tableOptions.globalFilter?.minLength);
1752
+ const delay = this.globalSearchOption(this.tableOptions.globalFilter?.debounceTime);
1753
+ const trimmed = value.trim();
1754
+ const effective = trimmed.length >= minLength ? (trimmed || null) : null;
1755
+ if (effective === (this.appliedGlobalSearchText?.trim() || null))
1756
+ return;
1757
+ const apply = () => {
1758
+ this.globalSearchTimer = undefined;
1759
+ if (this.destroyed)
1760
+ return;
1761
+ this.appliedGlobalSearchText = effective;
1762
+ this.currentPage = 0;
1763
+ this.dt.first = 0;
1764
+ if (minLength === 0 && delay === 0) {
1765
+ // Keep PrimeNG's existing filtering behavior when the feature is not configured.
1766
+ this.dt.filterGlobal(value, 'contains');
1767
+ }
1768
+ else {
1769
+ // Own the global delay so it is not added to PrimeNG's column-filter delay.
1770
+ this.dt.filters = { ...this.dt.filters, global: { value: effective, matchMode: 'contains' } };
1771
+ this.fetchTableData({ ...this.tableLazyLoadEventInformation, first: 0,
1772
+ rows: this.currentRowsPerPage, filters: this.dt.filters });
1773
+ }
1774
+ };
1775
+ if (effective === null || delay === 0)
1776
+ apply();
1777
+ else
1778
+ this.globalSearchTimer = setTimeout(apply, delay);
1779
+ }
1467
1780
  tableViewsList = [];
1468
1781
  tableViews_menuItems = [];
1469
1782
  DataType = DataType;
@@ -1496,6 +1809,8 @@ class ECSPrimengTable {
1496
1809
  maxViews = 0;
1497
1810
  ngOnInit() {
1498
1811
  this.i18n.connectPrimeNG();
1812
+ if (this.tableOptions.tree)
1813
+ this.treeState = new TreeTableState(this.tableOptions.tree);
1499
1814
  this.validateStatePersistence();
1500
1815
  this.updateResponsiveViewport();
1501
1816
  this.fetchTableConfiguration();
@@ -1522,6 +1837,23 @@ class ECSPrimengTable {
1522
1837
  get actionColumnWidth() {
1523
1838
  return this.compactRows ? 56 : (this.tableOptions.rows?.action?.width ?? 150);
1524
1839
  }
1840
+ getColumnHeaderGroups(columns) {
1841
+ if (!columns.some(column => column.headerGroup?.trim()))
1842
+ return [];
1843
+ const groups = [];
1844
+ for (const column of columns) {
1845
+ const label = column.headerGroup?.trim() ?? '';
1846
+ const frozenColumnAlign = column.frozenColumnAlign ?? FrozenColumnAlign.Noone;
1847
+ const previous = groups[groups.length - 1];
1848
+ if (previous && previous.label === label && previous.frozenColumnAlign === frozenColumnAlign) {
1849
+ previous.colspan++;
1850
+ }
1851
+ else {
1852
+ groups.push({ field: column.field, label, colspan: 1, frozenColumnAlign });
1853
+ }
1854
+ }
1855
+ return groups;
1856
+ }
1525
1857
  isInitiallyVisible(column) {
1526
1858
  if (!column.canBeHidden)
1527
1859
  return true;
@@ -1633,7 +1965,9 @@ class ECSPrimengTable {
1633
1965
  }
1634
1966
  }
1635
1967
  ngOnDestroy() {
1968
+ this.cancelGlobalSearch();
1636
1969
  this.destroyed = true;
1970
+ this.treeState?.cancel();
1637
1971
  const options = this.tableOptions.statePersistence;
1638
1972
  const key = options?.key?.trim();
1639
1973
  if (!key || !this.stateScope)
@@ -1652,9 +1986,12 @@ class ECSPrimengTable {
1652
1986
  dataUrl: this.tableOptions.urlTableData ?? '',
1653
1987
  filters,
1654
1988
  multiSortMeta: structuredClone(this.dt.multiSortMeta ?? []),
1655
- globalSearchText: this.globalSearchText,
1989
+ globalSearchText: this.effectiveGlobalSearchText,
1656
1990
  currentPage: this.currentPage,
1657
- currentRowsPerPage: this.currentRowsPerPage
1991
+ currentRowsPerPage: this.currentRowsPerPage,
1992
+ treeMode: this.treeState?.mode,
1993
+ treeExpandedKeys: this.treeState ? [...this.treeState.expanded] : undefined,
1994
+ treeChildPages: this.treeState?.snapshotPages()
1658
1995
  });
1659
1996
  }
1660
1997
  restoreNavigationState() {
@@ -1670,7 +2007,7 @@ class ECSPrimengTable {
1670
2007
  if (!state)
1671
2008
  return false;
1672
2009
  if (state.configurationUrl !== this.tableOptions.urlTableConfiguration ||
1673
- state.dataUrl !== this.tableOptions.urlTableData) {
2010
+ state.dataUrl !== this.tableOptions.urlTableData || state.treeMode !== this.treeState?.mode) {
1674
2011
  this.stateScope.clear(key);
1675
2012
  return false;
1676
2013
  }
@@ -1684,7 +2021,9 @@ class ECSPrimengTable {
1684
2021
  ? state.currentRowsPerPage : this.currentRowsPerPage;
1685
2022
  this.currentPage = this.currentRowsPerPage === state.currentRowsPerPage
1686
2023
  ? Math.max(0, state.currentPage) : 0;
1687
- this.globalSearchText = state.globalSearchText;
2024
+ this.restoreGlobalSearch(state.globalSearchText);
2025
+ this.treeState?.restore(state.treeExpandedKeys, state.treeChildPages);
2026
+ this.treeStateRestored = !!this.treeState;
1688
2027
  if (this.globalSearchText) {
1689
2028
  filters['global'] = { value: this.globalSearchText, matchMode: 'contains' };
1690
2029
  }
@@ -1903,6 +2242,8 @@ class ECSPrimengTable {
1903
2242
  }
1904
2243
  this.columnSelectionCustomized = true;
1905
2244
  let viewData = viewToLoad.viewData;
2245
+ this.treeState?.restore(viewData.treeExpandedKeys, viewData.treeChildPages);
2246
+ this.treeStateRestored = !!this.treeState;
1906
2247
  this.columnsSelected = viewData.columnsShown
1907
2248
  .map(data => this.columns.find((col) => col.field === data.field))
1908
2249
  .filter((col) => col !== undefined)
@@ -1910,7 +2251,7 @@ class ECSPrimengTable {
1910
2251
  this.tableOptions.columns.shown = this.tableService.orderColumnsWithFrozens(this.columnsCantBeHidden.concat(this.columnsSelected));
1911
2252
  this.currentPage = viewData.currentPage;
1912
2253
  this.currentRowsPerPage = viewData.currentRowsPerPage;
1913
- this.globalSearchText = viewData.globalSearchText;
2254
+ this.restoreGlobalSearch(viewData.globalSearchText);
1914
2255
  this.tableOptions.isActive = false;
1915
2256
  this.tableLazyLoadEventInformation.multiSortMeta = [...(viewData.multiSortMeta ?? [])];
1916
2257
  this.dt.multiSortMeta = [...(viewData.multiSortMeta ?? [])];
@@ -1935,7 +2276,7 @@ class ECSPrimengTable {
1935
2276
  this.notification.showToast("error", this.i18n.text("NO MORE VIEWS ALLOWED"), this.i18n.text("You have created the maximum number of allowed views for this table"));
1936
2277
  return;
1937
2278
  }
1938
- let viewData = this.tableService.viewGenerateData(this.dt, this.globalSearchText, this.currentPage, this.currentRowsPerPage, this.modifyFiltersWithoutGlobalAndSelectedRows.bind(this));
2279
+ let viewData = this.generateViewData();
1939
2280
  let newView = {
1940
2281
  lastActive: false,
1941
2282
  viewAlias: viewAlias,
@@ -1980,7 +2321,7 @@ class ECSPrimengTable {
1980
2321
  this.notification.showToast("error", this.i18n.text("Table view not found"), this.i18n.text("The table view to update data from was not found."));
1981
2322
  return;
1982
2323
  }
1983
- let viewData = this.tableService.viewGenerateData(this.dt, this.globalSearchText, this.currentPage, this.currentRowsPerPage, this.modifyFiltersWithoutGlobalAndSelectedRows.bind(this));
2324
+ let viewData = this.generateViewData();
1984
2325
  this.tableViewsList[index].viewData = viewData;
1985
2326
  this.viewsSave(1);
1986
2327
  }
@@ -2062,13 +2403,42 @@ class ECSPrimengTable {
2062
2403
  pageSize: this.currentRowsPerPage, // Set the number of rows per page
2063
2404
  sort: this.tableLazyLoadEventInformation.multiSortMeta, // Set the sorting information
2064
2405
  filter: filtersWithoutGlobalAndSelectedRows, // Set the filters excluding the global filter
2065
- globalFilter: this.globalSearchText, // Set the global filter text
2406
+ globalFilter: this.effectiveGlobalSearchText, // Use the applied query, not pending input
2066
2407
  columns: this.tableOptions.columns.shown.map(col => col.field), // Set the columns to show
2067
2408
  dateFormat: this.dateFormat,
2068
2409
  dateTimezone: this.dateTimezone,
2069
2410
  dateCulture: this.dateCulture,
2070
2411
  exportDateFormat: this.exportDateFormat
2071
2412
  };
2413
+ const selectionKey = JSON.stringify({ ...requestData, page: 0, pageSize: 0, sort: null });
2414
+ if (selectionKey !== this.selectionQueryKey)
2415
+ this.matchingSelectionKeys = undefined;
2416
+ this.selectionQueryKey = selectionKey;
2417
+ this.selectionQuery = structuredClone(requestData);
2418
+ if (this.treeState) {
2419
+ const tree = this.treeState;
2420
+ if (!this.treeStateRestored)
2421
+ tree.restore([...tree.expanded], tree.snapshotPages());
2422
+ this.treeStateRestored = false;
2423
+ const structural = [tree.options.keyExpr, tree.options.parentIdExpr, tree.options.hasItemsExpr, 'rowID'];
2424
+ requestData.columns = [...new Set([...requestData.columns, ...structural.filter((field) => !!field)])];
2425
+ this.treeQuery = structuredClone(requestData);
2426
+ const loading = tree.load(this.currentPage, this.currentRowsPerPage, this.treeFetcher(requestData));
2427
+ this.tableOptions.data = [];
2428
+ loading.then(updated => {
2429
+ if (updated && !this.destroyed)
2430
+ this.syncTreeRows();
2431
+ }).catch(error => {
2432
+ if (!this.destroyed)
2433
+ this.tableService.handleTableError(error, 'Tree data error');
2434
+ }).finally(() => {
2435
+ if (!this.destroyed) {
2436
+ this.changeDetector?.markForCheck();
2437
+ this.onDataEndUpdate.emit();
2438
+ }
2439
+ });
2440
+ return;
2441
+ }
2072
2442
  this.tableService.fetchTableData(this.tableOptions.urlTableData, requestData)
2073
2443
  .pipe(takeUntilDestroyed(this.destroyRef), finalize(() => {
2074
2444
  if (this.destroyed)
@@ -2081,9 +2451,6 @@ class ECSPrimengTable {
2081
2451
  });
2082
2452
  }
2083
2453
  modifyFiltersWithoutGlobalAndSelectedRows(filters, overrideOption = -1) {
2084
- if (this.globalSearchText === "") { // If the global search text is an empty string
2085
- this.globalSearchText = null; // Set it to null
2086
- }
2087
2454
  let filtersWithoutGlobalAndSelectedRows = structuredClone(filters ?? {}); // Create a copy of filters to delete the global.
2088
2455
  if (filtersWithoutGlobalAndSelectedRows.hasOwnProperty('global')) { // If there is an entry with the global filter
2089
2456
  delete filtersWithoutGlobalAndSelectedRows['global']; // Remove the global filter
@@ -2092,9 +2459,12 @@ class ECSPrimengTable {
2092
2459
  return filtersWithoutGlobalAndSelectedRows; // Return the filters without global array
2093
2460
  }
2094
2461
  resetTableView() {
2462
+ this.cancelGlobalSearch();
2095
2463
  const key = this.tableOptions.statePersistence?.key?.trim();
2096
2464
  if (key)
2097
2465
  this.stateScope?.clear(key);
2466
+ this.treeState?.restore();
2467
+ this.treeStateRestored = !!this.treeState;
2098
2468
  this.initialStateApplied = false;
2099
2469
  this.tableViewCurrentSelectedAlias = '';
2100
2470
  this.fetchTableConfiguration(true);
@@ -2164,7 +2534,76 @@ class ECSPrimengTable {
2164
2534
  this.totalRecordsNotFiltered = body.totalRecordsNotFiltered; // Update the total records not filtered
2165
2535
  this.currentPage = body.page; // Update the current page
2166
2536
  }
2537
+ generateViewData() {
2538
+ const view = this.tableService.viewGenerateData(this.dt, this.effectiveGlobalSearchText, this.currentPage, this.currentRowsPerPage, this.modifyFiltersWithoutGlobalAndSelectedRows.bind(this));
2539
+ if (this.treeState) {
2540
+ view.treeExpandedKeys = [...this.treeState.expanded];
2541
+ view.treeChildPages = this.treeState.snapshotPages();
2542
+ }
2543
+ return view;
2544
+ }
2545
+ treeFetcher(query) {
2546
+ return async (request) => {
2547
+ const response = await firstValueFrom(this.tableService.fetchTableData(this.tableOptions.urlTableData, { ...structuredClone(query), ...request }).pipe(takeUntilDestroyed(this.destroyRef)));
2548
+ if (!response.body)
2549
+ throw new Error('Empty tree response.');
2550
+ return response.body;
2551
+ };
2552
+ }
2553
+ syncTreeRows() {
2554
+ const tree = this.treeState;
2555
+ this.tableOptions.data = tree.visible;
2556
+ this.totalRecords = tree.totalRecords;
2557
+ this.totalRecordsNotFiltered = tree.totalRecordsNotFiltered;
2558
+ this.currentPage = tree.page;
2559
+ this.changeDetector?.markForCheck();
2560
+ }
2561
+ async toggleTreeRow(event, row) {
2562
+ event.stopPropagation();
2563
+ if (!this.treeState || !this.treeQuery || this.treeState.loading)
2564
+ return;
2565
+ try {
2566
+ const update = this.treeState.toggle(row, this.treeFetcher(this.treeQuery));
2567
+ this.changeDetector?.markForCheck();
2568
+ await update;
2569
+ if (!this.destroyed)
2570
+ this.syncTreeRows();
2571
+ }
2572
+ catch (error) {
2573
+ if (!this.destroyed)
2574
+ this.tableService.handleTableError(error, 'Tree data error');
2575
+ }
2576
+ finally {
2577
+ if (!this.destroyed) {
2578
+ this.changeDetector?.markForCheck();
2579
+ this.onDataEndUpdate.emit();
2580
+ }
2581
+ }
2582
+ }
2583
+ async loadMoreTreeRows(event, row) {
2584
+ event.stopPropagation();
2585
+ if (!this.treeState || !this.treeQuery || this.treeState.loading)
2586
+ return;
2587
+ try {
2588
+ await this.treeState.loadMore(row, this.treeFetcher(this.treeQuery));
2589
+ if (!this.destroyed)
2590
+ this.syncTreeRows();
2591
+ }
2592
+ catch (error) {
2593
+ if (!this.destroyed)
2594
+ this.tableService.handleTableError(error, 'Tree data error');
2595
+ }
2596
+ }
2597
+ get treeColumn() {
2598
+ const columns = this.tableOptions.columns?.shown ?? [];
2599
+ return columns.find(column => column.field === this.treeState?.options.column)?.field ?? columns[0]?.field;
2600
+ }
2601
+ treePageChange(event) {
2602
+ this.fetchTableData({ ...this.tableLazyLoadEventInformation, first: event.first ?? 0,
2603
+ rows: event.rows ?? this.currentRowsPerPage });
2604
+ }
2167
2605
  clearFilters(dt, force = false, onlyGlobalFilter = false) {
2606
+ this.cancelGlobalSearch();
2168
2607
  let hasToClear = this.hasToClearFilters(dt, this.globalSearchText, force);
2169
2608
  if (hasToClear) {
2170
2609
  if (!onlyGlobalFilter) {
@@ -2188,8 +2627,17 @@ class ECSPrimengTable {
2188
2627
  });
2189
2628
  this.dt.filters = filters;
2190
2629
  }
2191
- this.globalSearchText = null;
2192
- dt.filterGlobal('', '');
2630
+ this.restoreGlobalSearch(null);
2631
+ if (this.globalSearchOption(this.tableOptions.globalFilter?.minLength) > 0 ||
2632
+ this.globalSearchOption(this.tableOptions.globalFilter?.debounceTime) > 0) {
2633
+ this.currentPage = 0;
2634
+ dt.first = 0;
2635
+ dt.filters = { ...dt.filters, global: { value: null, matchMode: 'contains' } };
2636
+ this.fetchTableData({ ...this.tableLazyLoadEventInformation, first: 0,
2637
+ rows: this.currentRowsPerPage, filters: dt.filters });
2638
+ }
2639
+ else
2640
+ dt.filterGlobal('', '');
2193
2641
  }
2194
2642
  }
2195
2643
  clearSorts(dt, force = false) {
@@ -2315,9 +2763,62 @@ class ECSPrimengTable {
2315
2763
  isRowCheckboxSelected(rowID) {
2316
2764
  return this.selectedRowsCheckbox.includes(rowID);
2317
2765
  }
2766
+ get allMatchingRowsSelected() {
2767
+ if (!this.matchingSelectionKeys?.length)
2768
+ return false;
2769
+ const selected = new Set(this.selectedRowsCheckbox);
2770
+ return this.matchingSelectionKeys.every(key => selected.has(key));
2771
+ }
2772
+ get matchingRowsPartiallySelected() {
2773
+ if (this.allMatchingRowsSelected)
2774
+ return false;
2775
+ if (!this.matchingSelectionKeys)
2776
+ return this.selectedRowsCheckbox.length > 0;
2777
+ const selected = new Set(this.selectedRowsCheckbox);
2778
+ return this.matchingSelectionKeys.some(key => selected.has(key));
2779
+ }
2780
+ async toggleAllMatchingRows(checked) {
2781
+ const options = this.tableOptions.rows?.checkboxSelector;
2782
+ if (!options?.enabled || !options.selectAllEnabled || !options.urlSelectAll ||
2783
+ !this.selectionQuery || this.selectAllLoading)
2784
+ return;
2785
+ const queryKey = this.selectionQueryKey;
2786
+ this.selectAllLoading = true;
2787
+ try {
2788
+ const response = await firstValueFrom(this.tableService.fetchSelectionKeys(options.urlSelectAll, structuredClone(this.selectionQuery)).pipe(takeUntilDestroyed(this.destroyRef)));
2789
+ if (this.destroyed || queryKey !== this.selectionQueryKey)
2790
+ return;
2791
+ if (!Array.isArray(response.body) || response.body.some(key => typeof key !== 'string' && typeof key !== 'number'))
2792
+ throw new Error('Invalid selection identifiers.');
2793
+ const disabledKeys = new Set((this.tableOptions.data ?? [])
2794
+ .filter(row => !(options.enabledCondition?.(row) ?? true)).map(row => row.rowID));
2795
+ const keys = [...new Set(response.body)].filter(key => !disabledKeys.has(key));
2796
+ this.matchingSelectionKeys = keys;
2797
+ const selected = new Set(this.selectedRowsCheckbox);
2798
+ const changed = keys.filter(key => selected.has(key) !== checked);
2799
+ for (const key of changed) {
2800
+ if (checked)
2801
+ selected.add(key);
2802
+ else
2803
+ selected.delete(key);
2804
+ }
2805
+ this.selectedRowsCheckbox = [...selected];
2806
+ for (const rowID of changed)
2807
+ this.onRowCheckboxChange.emit({ rowID, selected: checked });
2808
+ }
2809
+ catch (error) {
2810
+ if (!this.destroyed)
2811
+ this.tableService.handleTableError(error, 'Selection error');
2812
+ }
2813
+ finally {
2814
+ this.selectAllLoading = false;
2815
+ this.changeDetector?.markForCheck();
2816
+ }
2817
+ }
2318
2818
  onRowChekboxChange(event, rowID) {
2319
2819
  if (event.checked) { // Add the selected item
2320
- this.selectedRowsCheckbox.push(rowID);
2820
+ if (!this.selectedRowsCheckbox.includes(rowID))
2821
+ this.selectedRowsCheckbox.push(rowID);
2321
2822
  }
2322
2823
  else { // Remove the selected item
2323
2824
  this.selectedRowsCheckbox = this.selectedRowsCheckbox.filter(selectedId => selectedId !== rowID);
@@ -2442,7 +2943,7 @@ class ECSPrimengTable {
2442
2943
  pageSize: this.currentRowsPerPage, // Set the number of rows per page
2443
2944
  sort: this.tableLazyLoadEventInformation.multiSortMeta, // Set the sorting information
2444
2945
  filter: filtersWithoutGlobalAndSelectedRows, // Set the filters excluding the global filter
2445
- globalFilter: this.globalSearchText, // Set the global filter text
2946
+ globalFilter: this.effectiveGlobalSearchText, // Use the applied query, not pending input
2446
2947
  columns: this.tableOptions.columns.shown.map(col => col.field), // Set the columns to show
2447
2948
  dateFormat: this.dateFormat,
2448
2949
  dateTimezone: this.dateTimezone,
@@ -2454,6 +2955,8 @@ class ECSPrimengTable {
2454
2955
  filename: event.filename,
2455
2956
  useIconInBools: event.useIconInBools
2456
2957
  };
2958
+ if (this.treeState)
2959
+ Object.assign(requestData, { expandedKeys: [...this.treeState.expanded] });
2457
2960
  this.tableService.fetchExcelReport(this.tableOptions.excelReport.url, requestData).subscribe({
2458
2961
  next: (response) => {
2459
2962
  this.tableService.downloadFile(response.body, event.filename, 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
@@ -2488,7 +2991,7 @@ class ECSPrimengTable {
2488
2991
  });
2489
2992
  }
2490
2993
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: ECSPrimengTable, deps: [{ token: ECSPrimengTableService }, { token: ECSPrimengTableNotificationService }], target: i0.ɵɵFactoryTarget.Component });
2491
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.21", type: ECSPrimengTable, isStandalone: true, selector: "ecs-primeng-table", inputs: { tableOptions: "tableOptions" }, outputs: { onRowCheckboxChange: "onRowCheckboxChange", onRowSelect: "onRowSelect", onRowUnselect: "onRowUnselect", onDataEndUpdate: "onDataEndUpdate" }, host: { listeners: { "window:resize": "onResize()" } }, viewQueries: [{ propertyName: "dt", first: true, predicate: ["dt"], descendants: true }, { propertyName: "tableContainer", first: true, predicate: ["tableContainer"], descendants: true }, { propertyName: "headerContainer", first: true, predicate: ["headerContainer"], descendants: true }, { propertyName: "paginatorContainer", first: true, predicate: ["paginatorContainer"], descendants: true }, { propertyName: "responsiveHeaderMenu", first: true, predicate: ["responsiveHeaderMenu"], descendants: true }, { propertyName: "responsiveRowMenu", first: true, predicate: ["responsiveRowMenu"], descendants: true }], ngImport: i0, template: "<div #tableContainer>\r\n <p-table #dt\r\n size=\"small\" showGridlines stripedRows \r\n sortMode=\"multiple\"\r\n [resizableColumns]=\"true\" columnResizeMode=\"expand\"\r\n [reorderableColumns]=\"true\"\r\n [scrollable]=\"true\" [scrollHeight]=\"scrollHeightValue\"\r\n [columns]=\"tableOptions.columns?.shown ?? []\" [value]=\"tableOptions.data ?? []\" dataKey=\"rowID\" \r\n [paginator]=\"true\" paginatorDropdownAppendTo=\"body\" [first]=\"currentPage * currentRowsPerPage\" [rows]=\"currentRowsPerPage\" [totalRecords]=\"totalRecords\"\r\n [rowsPerPageOptions]=\"allowedRowsPerPage\" [showCurrentPageReport]=\"false\" (onPage)=\"pageChange($event)\"\r\n [metaKeySelection]=\"true\" [selectionMode]=\"tableOptions.rows?.singleSelector?.enabled ? 'single' : null\" [metaKeySelection]=\"tableOptions.rows?.singleSelector?.metakey\" [(selection)]=\"rowSelection\" (onRowSelect)=\"rowSelect($event)\" (onRowUnselect)=\"rowUnselect($event)\"\r\n [lazy]=\"true\" (onLazyLoad)=\"fetchTableData($event)\">\r\n\r\n <!--TEMPLATE FOR THE ACTIONS HEADER COLUMN-->\r\n <ng-template #actionColumnHeaderTemplate>\r\n @if ((tableOptions.rows?.action?.buttons?.length ?? 0) > 0) {\r\n <th [ngStyle]=\"{\r\n 'text-align': 'center',\r\n 'vertical-align': 'middle',\r\n 'max-width': actionColumnWidth + 'px',\r\n 'min-width': actionColumnWidth + 'px',\r\n 'width': actionColumnWidth + 'px'\r\n }\"\r\n pResizableColumn [pResizableColumnDisabled]=\"!tableOptions.rows?.action?.resizable\" pFrozenColumn [frozen]=\"tableOptions.rows?.action?.frozen ?? false\"\r\n [alignFrozen]=\"getFrozenColumnAlignAsText(tableOptions.rows?.action?.positionRight ? FrozenColumnAlign.Right : FrozenColumnAlign.Left)\" id=\"actions-header\"\r\n [attr.scope]=\"'col'\">\r\n {{ (tableOptions.rows?.action?.header ?? '') | ecsTranslate }}\r\n </th>\r\n }\r\n </ng-template>\r\n\r\n <!--TEMPLATE FOR THE ACTIONS ROW COLUMN-->\r\n <ng-template #actionColumnTemplate let-rowData=\"rowData\">\r\n @if ((tableOptions.rows?.action?.buttons?.length ?? 0) > 0) {\r\n <td \r\n [ngStyle]=\"{\r\n 'text-align': (getDataAlignHorizontalAsText(tableOptions.rows?.action?.horizontalAlignment ?? DataAlignHorizontal.Center)),\r\n 'vertical-align': (getDataAlignVerticalAsText(tableOptions.rows?.action?.verticalAlignment ?? DataAlignVertical.Middle)),\r\n 'max-width': actionColumnWidth + 'px',\r\n 'min-width': actionColumnWidth + 'px',\r\n 'width': actionColumnWidth + 'px'\r\n }\"\r\n pFrozenColumn [frozen]=\"tableOptions.rows?.action?.frozen ?? false\"\r\n [alignFrozen]=\"getFrozenColumnAlignAsText(tableOptions.rows?.action?.positionRight ? FrozenColumnAlign.Right : FrozenColumnAlign.Left)\">\r\n @if (compactRows) {\r\n @if (hasRowMenuActions(rowData)) {\r\n <button pButton type=\"button\" icon=\"pi pi-ellipsis-v\" [attr.aria-label]=\"(tableOptions.responsive?.rowMenuLabel || 'Row actions') | ecsTranslate\"\r\n aria-haspopup=\"menu\" [attr.aria-expanded]=\"responsiveRowMenu.visible && rowMenuRow === rowData\"\r\n (click)=\"openRowMenu($event, rowData)\" class=\"ecs-responsive-trigger\"></button>\r\n }\r\n } @else {\r\n @for (button of tableOptions.rows?.action?.buttons; track button; let last = $last) {\r\n <ecs-table-button [button]=\"button\" [rowData]=\"rowData\" [isActionButton]=\"true\" [isLastActionButton]=\"last\"/>\r\n }\r\n }\r\n </td>\r\n }\r\n </ng-template>\r\n\r\n <!-- TEMPLATE FOR THE ROW CHECKBOX SELECTOR HEADER COLUMN -->\r\n <ng-template #rowSelectorColumnHeaderTemplate>\r\n <th \r\n [ngStyle]=\"{\r\n 'text-align': 'center',\r\n 'vertical-align': 'middle',\r\n 'max-width': (tableOptions.rows?.checkboxSelector?.width ?? 150) + 'px',\r\n 'min-width': (tableOptions.rows?.checkboxSelector?.width ?? 150) + 'px',\r\n 'width': (tableOptions.rows?.checkboxSelector?.width ?? 150) + 'px'\r\n }\"\r\n id=\"rowSelector-header\" [attr.scope]=\"'col'\" pResizableColumn [pResizableColumnDisabled]=\"!tableOptions.rows?.checkboxSelector?.resizable\" pFrozenColumn \r\n [frozen]=\"tableOptions.rows?.checkboxSelector?.frozen ?? false\" [alignFrozen]=\"getFrozenColumnAlignAsText(tableOptions.rows?.checkboxSelector?.positionRight ? FrozenColumnAlign.Right : FrozenColumnAlign.Left)\">\r\n <div style=\"display: flex; justify-content: space-between; align-items: center;\">\r\n {{ (tableOptions.rows?.checkboxSelector?.header ?? '') | ecsTranslate }}\r\n <p-columnFilter type=\"boolean\" field=\"selector\" display=\"menu\" [showButtons]=\"false\"/>\r\n </div>\r\n </th>\r\n </ng-template>\r\n\r\n <!--TEMPLATE FOR THE ROW CHECKBOX SELECTOR COLUMN-->\r\n <ng-template #rowSelectorColumnTemplate let-rowData=\"rowData\">\r\n <td \r\n [ngStyle]=\"{\r\n 'text-align': (getDataAlignHorizontalAsText(tableOptions.rows?.checkboxSelector?.horizontalAlignment ?? DataAlignHorizontal.Center)),\r\n 'vertical-align': (getDataAlignVerticalAsText(tableOptions.rows?.checkboxSelector?.verticalAlignment ?? DataAlignVertical.Middle)),\r\n 'max-width': (tableOptions.rows?.checkboxSelector?.width ?? 150) + 'px',\r\n 'min-width': (tableOptions.rows?.checkboxSelector?.width ?? 150) + 'px',\r\n 'width': (tableOptions.rows?.checkboxSelector?.width ?? 150) + 'px'\r\n }\"\r\n pFrozenColumn [frozen]=\"tableOptions.rows?.checkboxSelector?.frozen ?? false\" \r\n [alignFrozen]=\"getFrozenColumnAlignAsText(tableOptions.rows?.checkboxSelector?.positionRight ? FrozenColumnAlign.Right : FrozenColumnAlign.Left)\">\r\n <p-checkbox \r\n [disabled]=\"!(tableOptions.rows?.checkboxSelector?.enabledCondition?.(rowData) ?? true)\"\r\n [binary]=\"true\"\r\n [ngModel]=\"isRowCheckboxSelected(rowData.rowID)\"\r\n (onChange)=\"onRowChekboxChange($event, rowData.rowID)\"/>\r\n </td>\r\n </ng-template>\r\n\r\n\r\n <!-- LOGIC FOR DRAWING TABLE ACTIONS ABOVE THE HEADER -->\r\n <ng-template #caption>\r\n <div #headerContainer [class.ecs-compact-header]=\"compactHeader\" style=\"display: flex; justify-content: space-between; align-items: center;\">\r\n @if (compactHeader) {\r\n @if (tableOptions.globalFilter?.enabled) {\r\n <p-iconField iconPosition=\"left\" class=\"ecs-responsive-search\">\r\n <p-inputIcon><i class=\"pi pi-search\"></i></p-inputIcon>\r\n <input pInputText type=\"text\" [attr.aria-label]=\"'Search keyword' | ecsTranslate\" [placeholder]=\"'Search keyword' | ecsTranslate\" autocomplete=\"off\"\r\n [maxlength]=\"tableOptions.globalFilter?.maxLength ?? null\" [(ngModel)]=\"globalSearchText\"\r\n (input)=\"dt.filterGlobal($any($event.target).value, 'contains')\"/>\r\n @if (globalSearchText) {\r\n <p-inputIcon position=\"right\"><button type=\"button\" class=\"ecs-clear-search\" [attr.aria-label]=\"'Clear search' | ecsTranslate\" (click)=\"clearFilters(dt, true, true)\"><i class=\"pi pi-times\"></i></button></p-inputIcon>\r\n }\r\n </p-iconField>\r\n }\r\n @if (tableOptions.description?.text) {\r\n <i [class]=\"tableOptions.description!.icon\" [pTooltip]=\"(tableOptions.description!.text) | ecsTranslate\" [escape]=\"false\"></i>\r\n }\r\n <button pButton type=\"button\" icon=\"pi pi-bars\" [attr.aria-label]=\"(tableOptions.responsive?.headerMenuLabel || 'Table actions') | ecsTranslate\"\r\n aria-haspopup=\"menu\" [attr.aria-expanded]=\"responsiveHeaderMenu.visible\"\r\n (click)=\"openHeaderMenu($event)\" class=\"ecs-responsive-trigger ecs-header-menu-trigger\"></button>\r\n } @else {\r\n\r\n <div style=\"display: flex; align-items: center; gap: 10px;\">\r\n <!--CHOOSE COLUMNS TO SHOW-->\r\n @if (tableOptions.columns?.selectorEnabled) {\r\n <p-button [icon]=\"tableOptions.columns?.selectorIcon ?? 'pi pi-pen-to-square'\" (onClick)=\"columnSelectorShow()\" [pTooltip]=\"'Modify columns' | ecsTranslate\"\r\n [showDelay]=\"700\" tooltipPosition=\"top\" styleClass=\"p-button-icon-only\"/>\r\n }\r\n <!--CLEAR SORTS AND FILTERS-->\r\n @if (tableOptions.header?.clearSortsEnabled) {\r\n <p-button [icon]=\"tableOptions.header?.clearSortsIcon ?? 'pi pi-sort-alt-slash'\" (onClick)=\"clearSorts(dt)\" [disabled]=\"!hasToClearSorts(dt)\"\r\n [pTooltip]=\"'Clear sorts' | ecsTranslate\" [showDelay]=\"700\" tooltipPosition=\"top\" styleClass=\"p-button-icon-only\"/>\r\n }\r\n @if (tableOptions.header?.clearFiltersEnabled) {\r\n <p-button\r\n [icon]=\"tableOptions.header?.clearFiltersIcon ?? 'pi pi-filter-slash'\" (onClick)=\"clearFilters(dt)\" [disabled]=\"!hasToClearFilters(dt, globalSearchText)\"\r\n [pTooltip]=\"'Clear filters' | ecsTranslate\" [showDelay]=\"700\" tooltipPosition=\"top\" styleClass=\"p-button-icon-only\"/>\r\n }\r\n\r\n <!--TABLE DESCRIPTION-->\r\n @if(tableOptions.description?.text){ <!-- If a table description text is provided -->\r\n @if(!tableOptions.description!.tooltip){ <!-- The table description must be shown as text next to the icon -->\r\n <i [class]=\"tableOptions.description!.icon\"></i>\r\n <span [innerHTML]=\"(tableOptions.description!.text) | ecsTranslate\"></span>\r\n } @else {\r\n <i [escape]=\"false\" [pTooltip]=\"(tableOptions.description!.text) | ecsTranslate\" tooltipPosition=\"right\" [class]=\"tableOptions.description!.icon\"></i>\r\n }\r\n }\r\n </div>\r\n\r\n <!--TABLE VIEWS-->\r\n @if(tableViewsEnabled()){\r\n <div style=\"display: flex; align-items: center; gap: 10px;\">\r\n <p-buttongroup>\r\n <p-button (click)=\"viewsModalShow=true;\"\r\n [label]=\"tableViewCurrentSelectedAlias \r\n ? tableViewCurrentSelectedAlias \r\n : ((tableOptions.views?.noViewSelectedText || '--- Select a view ---') | ecsTranslate)\"\r\n [class]=\"'viewButton' + (tableOptions.views?.selectViewButtonClass ? ' ' + tableOptions.views!.selectViewButtonClass : '')\"/>\r\n <p-button (click)=\"viewLoad(tableViewCurrentSelectedAlias!)\" [disabled]=\"!tableViewCurrentSelectedAlias\" [pTooltip]=\"'Apply view again' | ecsTranslate\" [showDelay]=\"700\" tooltipPosition=\"top\"\r\n [icon]=\"tableOptions.views?.reloadViewButtonIcon || 'pi pi-refresh'\"\r\n [class]=\"tableOptions.views?.reloadViewButtonClass || ''\"/>\r\n </p-buttongroup>\r\n </div>\r\n }\r\n\r\n <div style=\"display: flex; align-items: center; gap: 10px;\">\r\n <!--GLOBAL FILTER-->\r\n @if (tableOptions.globalFilter?.enabled) {\r\n <p-iconField iconPosition=\"left\" class=\"ml-auto\" [ngClass]=\"{'p-input-icon-right': globalSearchText}\">\r\n <p-inputIcon>\r\n <i class=\"pi pi-search\"></i>\r\n </p-inputIcon>\r\n <input pInputText type=\"text\" \r\n (input)=\"dt.filterGlobal($any($event.target).value, 'contains')\" autocomplete=\"off\" \r\n [maxlength]=\"tableOptions.globalFilter?.maxLength ?? null\" [placeholder]=\"'Search keyword' | ecsTranslate\" [(ngModel)]=\"globalSearchText\"\r\n style=\"width: 220px;\"/>\r\n <!-- Right icon (only if there is text) -->\r\n @if (globalSearchText) {\r\n <p-inputIcon position=\"right\">\r\n <i class=\"pi pi-times\" style=\"cursor: pointer;\" (click)=\"clearFilters(dt, true, true); $event.stopPropagation()\"></i>\r\n </p-inputIcon>\r\n }\r\n </p-iconField>\r\n }\r\n\r\n <!--EXPORT DATA-->\r\n @if (tableOptions.excelReport?.url?.trim()) {\r\n <p-button icon=\"pi pi-file-excel\" (onClick)=\"openExcelExport()\"\r\n [pTooltip]=\"'Export to Excel' | ecsTranslate\" [showDelay]=\"700\" tooltipPosition=\"top\" styleClass=\"p-button-icon-only\"/>\r\n }\r\n\r\n <!--RESET TABLE VIEW-->\r\n @if(tableOptions.resetTableView?.enabled){\r\n <p-button [icon]=\"tableOptions.resetTableView?.icon ?? 'pi pi-eraser'\" (click)=\"resetTableView()\" [pTooltip]=\"'Reset table view' | ecsTranslate\" [showDelay]=\"700\"\r\n tooltipPosition=\"top\" styleClass=\"p-button-icon-only\"/>\r\n }\r\n\r\n <!--REFRESH DATA-->\r\n <p-button icon=\"pi pi-refresh\" (onClick)=\"refreshData($event)\" [pTooltip]=\"'Refresh data' | ecsTranslate\" [showDelay]=\"700\"\r\n tooltipPosition=\"top\" styleClass=\"p-button-icon-only\"/>\r\n \r\n <!-- HEADER ACTION BUTTONS -->\r\n @if ((tableOptions.header?.buttons?.length ?? 0) > 0) {\r\n <td style=\"display: flex; justify-content: center; align-items: center; gap: 10px;\">\r\n @for (button of tableOptions.header?.buttons; track $index) {\r\n <ecs-table-button [button]=\"button\" [rowData]=\"null\"/>\r\n }\r\n </td>\r\n }\r\n </div>\r\n }\r\n </div>\r\n </ng-template>\r\n\r\n <!-- LOGIC FOR DRAWING TABLE HEADERS -->\r\n <ng-template #header let-columns>\r\n <tr>\r\n @if (!tableOptions.rows?.action?.positionRight) {\r\n <ng-container *ngTemplateOutlet=\"actionColumnHeaderTemplate\"></ng-container>\r\n }\r\n @if (tableOptions.rows?.checkboxSelector?.enabled && !tableOptions.rows?.checkboxSelector?.positionRight) {\r\n <ng-container [ngTemplateOutlet]=\"rowSelectorColumnHeaderTemplate\"></ng-container>\r\n }\r\n @for (col of columns; track col.header) {\r\n <th [ngStyle]=\"getColumnStyle(col, true)\"\r\n pResizableColumn [pResizableColumnDisabled]=\"!col.canBeResized ? true : false\"\r\n pReorderableColumn [pReorderableColumnDisabled]=\"!col.canBeReordered ? true : false\"\r\n pFrozenColumn [frozen]=\"col.frozenColumnAlign === FrozenColumnAlign.Left || col.frozenColumnAlign === FrozenColumnAlign.Right\" [alignFrozen]=\"getFrozenColumnAlignAsText(col.frozenColumnAlign)\"\r\n [pSortableColumn]=\"col.field\" [pSortableColumnDisabled]=\"!col.canBeSorted ? true : false\"\r\n style=\"text-align: center;\"\r\n [id]=\"col.field + '-header'\" [attr.scope]=\"'col'\">\r\n <div style=\"display: flex; justify-content: space-between; align-items: center; width: 100%;\">\r\n <div style=\"margin-right: 15px;\">\r\n <span>{{ col.header | translate }}</span>\r\n </div>\r\n <div style=\"display: flex; align-items: center; gap: 5px;\">\r\n @if (col.canBeSorted) {\r\n <p-sortIcon [field]=\"col.field\"></p-sortIcon>\r\n }\r\n @if(col.canBeFiltered){\r\n @if (!col.filterPredefinedValuesName || col.filterPredefinedValuesName.length === 0) {\r\n <p-columnFilter [type]=\"getDataTypeAsText(col.dataType)\" [field]=\"col.field\" display=\"menu\" [showButtons]=\"false\"/>\r\n } @else {\r\n <p-columnFilter\r\n [type]=\"getDataTypeAsText(col.dataType)\" [field]=\"col.field\" display=\"menu\"\r\n [showButtons]=\"false\" matchMode=\"in\" operator=\"or\" [showMatchModes]=\"false\"\r\n [showOperator]=\"false\" [showAddButton]=\"false\" [showClearButton]=\"false\" [showApplyButton]=\"false\">\r\n <ng-template #filter>\r\n <p-multiSelect\r\n [style]=\"{ minWidth: '400px' }\" [(ngModel)]=\"predefinedFiltersSelectedValuesCollection[col.filterPredefinedValuesName]\"\r\n [options]=\"getPredefinedFilterValues(col.filterPredefinedValuesName)\" [placeholder]=\"'Any value' | ecsTranslate\"\r\n (onChange)=\"onPredefinedFilterChange(col.field, $event.value)\" optionLabel=\"name\">\r\n <ng-template #item let-option >\r\n <div style=\"display: inline-block; vertical-align: middle;\">\r\n <ecs-table-predefined-filters [option]=\"option\" [col]=\"col\" [selectable]=\"false\" [rowData]=\"null\"/>\r\n </div>\r\n </ng-template>\r\n </p-multiSelect>\r\n </ng-template>\r\n </p-columnFilter>\r\n }\r\n }\r\n @if (col.columnDescription && col.columnDescription.length > 0) {\r\n <i [pTooltip]=\"(col.columnDescription) | ecsTranslate\" tooltipPosition=\"top\" [class]=\"tableOptions.columnDescriptionIcon || 'pi pi-info-circle'\"></i>\r\n }\r\n </div>\r\n </div>\r\n </th>\r\n }\r\n @if (tableOptions.rows?.checkboxSelector?.enabled && tableOptions.rows?.checkboxSelector?.positionRight) {\r\n <ng-container [ngTemplateOutlet]=\"rowSelectorColumnHeaderTemplate\"></ng-container>\r\n }\r\n @if (tableOptions.rows?.action?.positionRight) {\r\n <ng-container *ngTemplateOutlet=\"actionColumnHeaderTemplate\"></ng-container>\r\n }\r\n </tr>\r\n </ng-template>\r\n\r\n <!-- LOGIC FOR DRAWING TABLE DATA WHEN THERE IS CONTENTS -->\r\n <ng-template #body let-rowData let-columns=\"columns\"> \r\n <tr [pSelectableRow]=\"rowData\" [ngClass]=\"tableOptions.rows?.class?.(rowData)\" [ngStyle]=\"tableOptions.rows?.style?.(rowData)\">\r\n @if (!tableOptions.rows?.action?.positionRight) {\r\n <ng-container *ngTemplateOutlet=\"actionColumnTemplate; context: { rowData: rowData }\"></ng-container>\r\n }\r\n @if (tableOptions.rows?.checkboxSelector?.enabled && !tableOptions.rows?.checkboxSelector?.positionRight) {\r\n <ng-container [ngTemplateOutlet]=\"rowSelectorColumnTemplate\" [ngTemplateOutletContext]=\"{ rowData: rowData }\"></ng-container>\r\n }\r\n @for (col of columns; track col.field) {\r\n <td (mousedown)=\"col.dataType !== DataType.Boolean && copyToClipboardStart($event)\" (mouseup)=\"copyToClipboardCancel()\"\r\n [ngStyle]=\"getColumnStyle(col)\" pFrozenColumn [frozen]=\"col.frozenColumnAlign === FrozenColumnAlign.Left || col.frozenColumnAlign === FrozenColumnAlign.Right\" \r\n [alignFrozen]=\"getFrozenColumnAlignAsText(col.frozenColumnAlign)\" [style.text-align]=\"getDataAlignHorizontalAsText(col.dataAlignHorizontal)\" [style.vertical-align]=\"getDataAlignVerticalAsText(col.dataAlignVertical)\">\r\n <ecs-table-cell [col]=\"col\" [rowData]=\"rowData\" [globalSearchText]=\"globalSearchText\" \r\n [dateFormat]=\"dateFormat\" [dateTimezone]=\"dateTimezone\" [dateCulture]=\"dateCulture\"\r\n [predefinedFiltersCollection]=\"tableOptions.predefinedFilters\"/>\r\n </td>\r\n }\r\n @if (tableOptions.rows?.checkboxSelector?.enabled && tableOptions.rows?.checkboxSelector?.positionRight) {\r\n <ng-container [ngTemplateOutlet]=\"rowSelectorColumnTemplate\" [ngTemplateOutletContext]=\"{ rowData: rowData }\"></ng-container>\r\n }\r\n @if (tableOptions.rows?.action?.positionRight) {\r\n <ng-container *ngTemplateOutlet=\"actionColumnTemplate; context: { rowData: rowData }\"></ng-container>\r\n }\r\n </tr>\r\n </ng-template>\r\n\r\n <!-- LOGIC FOR DRAWING TABLE DATA WHEN THERE IS NO CONTENTS -->\r\n <ng-template #emptymessage>\r\n <tr>\r\n <td colspan=\"999\">{{ 'No data found for the current filter criteria.' | ecsTranslate }}</td>\r\n </tr>\r\n </ng-template>\r\n\r\n <!-- SHOW CUSTOM RECORDS REPORT -->\r\n <ng-template #paginatorleft>\r\n <div #paginatorContainer>\r\n <div style=\"display: flex; align-items: center; gap: 10px;\">\r\n @if(tableOptions.legend?.content){\r\n <ecs-table-button [button]=\"tableOptions.legend?.button\" [rowData]=\"null\" [overrideAction]=\"op.toggle.bind(op)\"/>\r\n <p-popover #op>\r\n <div [innerHTML]=\"(tableOptions.legend?.content) | ecsTranslate\"></div>\r\n </p-popover>\r\n }\r\n <span>{{ 'Showing {{count}} records of {{total}} available records' | ecsTranslate: { count: totalRecords, total: totalRecordsNotFiltered } }}</span>\r\n </div>\r\n </div>\r\n </ng-template>\r\n </p-table>\r\n</div>\r\n<ecs-column-selector [visible]=\"showColumnSelector\" [columnModalData]=\"columnModalData\" [filteredColumnData]=\"filteredColumnData\" [orderByHeader]=\"tableOptions.columns?.selectorOrderByColumnName === true\" (visibleChange)=\"showColumnSelector=false\" (applyChanges)=\"applyColumnModalChanges($event)\"/>\r\n<ecs-export-excel [visible]=\"showExportModal\" [rowCheckboxSelectorActive]=\"tableOptions.rows?.checkboxSelector?.enabled ?? false\" [excelReportTitle]=\"excelReportTitle\" [allowTitleUserEdit]=\"tableOptions.excelReport?.titleAllowUserEdit ?? false\" (visibleChange)=\"showExportModal=false\" (exportToExcel)=\"generateExcelReport($event)\"/>\r\n<ecs-views-management [visible]=\"viewsModalShow\" [tableViews_menuItems]=\"tableViews_menuItems\" \r\n (onViewSelect)=\"viewLoad($event)\" (onViewCreate)=\"viewCreate($event)\" (onViewDelete)=\"viewDelete($event)\" (onViewEditAlias)=\"viewEditAlias($event)\" (onViewUpdateData)=\"viewUpdateData($event)\" (onViewUpdateActiveStartup)=\"viewUpdateActiveStartup($event)\"\r\n (visibleChange)=\"viewsModalShow=false\"/>\r\n<!-- Body-level overlays avoid clipping inside scrollable and frozen table cells. -->\r\n<p-menu #responsiveHeaderMenu [model]=\"headerMenuItems\" [popup]=\"true\" appendTo=\"body\" styleClass=\"ecs-responsive-menu\"/>\r\n<p-menu #responsiveRowMenu [model]=\"rowMenuItems\" [popup]=\"true\" appendTo=\"body\" styleClass=\"ecs-responsive-menu\"/>\r\n", styles: [".highlighted-text{background-color:#ff0;color:#000;border-radius:2px}.excel-export-tooltip .bool-icon{text-shadow:0 0 2px white,0 0 3px white}.excel-export-tooltip .bool-true{color:green}.excel-export-tooltip .bool-false{color:red}.p-datatable-column-filter-button.p-button-icon-only.p-button-rounded,.p-datatable-column-filter-clear-button.p-button-icon-only.p-button-rounded{height:var(--p-icon-size)!important;width:var(--p-icon-size)!important;border-radius:0!important}.viewButton{width:200px}.viewButton .p-button{width:100%;justify-content:center}.viewButton .p-button-label{display:block;width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;text-align:center}.ecs-compact-header{gap:.5rem;min-width:0}.ecs-header-menu-trigger{margin-left:auto;flex:0 0 auto}.ecs-responsive-trigger{min-width:44px;min-height:44px}.ecs-responsive-search{flex:1 1 220px;min-width:0;max-width:320px}.ecs-responsive-search input{width:100%;padding-right:2.5rem}.ecs-clear-search{border:0;background:transparent;color:inherit;cursor:pointer}.ecs-responsive-menu{max-width:calc(100vw - 16px);max-height:calc(100dvh - 32px);overflow-y:auto}.ecs-responsive-menu .p-menu-item-link{min-height:44px;white-space:normal}\n"], dependencies: [{ kind: "pipe", type: ECSTableTranslatePipe, name: "ecsTranslate" }, { kind: "pipe", type: TranslatePipe, name: "translate" }, { kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1$1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i1$1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i9$1.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: i9$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i9$1.MaxLengthValidator, selector: "[maxlength][formControlName],[maxlength][formControl],[maxlength][ngModel]", inputs: ["maxlength"] }, { kind: "directive", type: i9$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: TableModule }, { kind: "component", type: i5.Table, selector: "p-table", inputs: ["frozenColumns", "frozenValue", "style", "styleClass", "tableStyle", "tableStyleClass", "paginator", "pageLinks", "rowsPerPageOptions", "alwaysShowPaginator", "paginatorPosition", "paginatorStyleClass", "paginatorDropdownAppendTo", "paginatorDropdownScrollHeight", "currentPageReportTemplate", "showCurrentPageReport", "showJumpToPageDropdown", "showJumpToPageInput", "showFirstLastIcon", "showPageLinks", "defaultSortOrder", "sortMode", "resetPageOnSort", "selectionMode", "selectionPageOnly", "contextMenuSelection", "contextMenuSelectionMode", "dataKey", "metaKeySelection", "rowSelectable", "rowTrackBy", "lazy", "lazyLoadOnInit", "compareSelectionBy", "csvSeparator", "exportFilename", "filters", "globalFilterFields", "filterDelay", "filterLocale", "expandedRowKeys", "editingRowKeys", "rowExpandMode", "scrollable", "scrollDirection", "rowGroupMode", "scrollHeight", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "virtualScrollDelay", "frozenWidth", "responsive", "contextMenu", "resizableColumns", "columnResizeMode", "reorderableColumns", "loading", "loadingIcon", "showLoader", "rowHover", "customSort", "showInitialSortBadge", "autoLayout", "exportFunction", "exportHeader", "stateKey", "stateStorage", "editMode", "groupRowsBy", "size", "showGridlines", "stripedRows", "groupRowsByOrder", "responsiveLayout", "breakpoint", "paginatorLocale", "value", "columns", "first", "rows", "totalRecords", "sortField", "sortOrder", "multiSortMeta", "selection", "virtualRowHeight", "selectAll"], outputs: ["contextMenuSelectionChange", "selectAllChange", "selectionChange", "onRowSelect", "onRowUnselect", "onPage", "onSort", "onFilter", "onLazyLoad", "onRowExpand", "onRowCollapse", "onContextMenuSelect", "onColResize", "onColReorder", "onRowReorder", "onEditInit", "onEditComplete", "onEditCancel", "onHeaderCheckboxToggle", "sortFunction", "firstChange", "rowsChange", "onStateSave", "onStateRestore"] }, { kind: "directive", type: i5.SortableColumn, selector: "[pSortableColumn]", inputs: ["pSortableColumn", "pSortableColumnDisabled"] }, { kind: "directive", type: i5.FrozenColumn, selector: "[pFrozenColumn]", inputs: ["frozen", "alignFrozen"] }, { kind: "directive", type: i5.SelectableRow, selector: "[pSelectableRow]", inputs: ["pSelectableRow", "pSelectableRowIndex", "pSelectableRowDisabled"] }, { kind: "directive", type: i5.ResizableColumn, selector: "[pResizableColumn]", inputs: ["pResizableColumnDisabled"] }, { kind: "directive", type: i5.ReorderableColumn, selector: "[pReorderableColumn]", inputs: ["pReorderableColumnDisabled"] }, { kind: "component", type: i5.SortIcon, selector: "p-sortIcon", inputs: ["field"] }, { kind: "component", type: i5.ColumnFilter, selector: "p-columnFilter", inputs: ["field", "type", "display", "showMenu", "matchMode", "operator", "showOperator", "showClearButton", "showApplyButton", "showMatchModes", "showAddButton", "hideOnClear", "placeholder", "matchModeOptions", "maxConstraints", "minFractionDigits", "maxFractionDigits", "prefix", "suffix", "locale", "localeMatcher", "currency", "currencyDisplay", "useGrouping", "showButtons", "ariaLabel", "filterButtonProps"], outputs: ["onShow", "onHide"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "directive", type: i6.ButtonDirective, selector: "[pButton]", inputs: ["iconPos", "loadingIcon", "loading", "severity", "raised", "rounded", "text", "outlined", "size", "plain", "fluid", "label", "icon", "buttonProps"] }, { kind: "component", type: i6.Button, selector: "p-button", inputs: ["type", "iconPos", "icon", "badge", "label", "disabled", "loading", "loadingIcon", "raised", "rounded", "text", "plain", "severity", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "fluid", "buttonProps"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i7.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "appendTo", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "pTooltip", "tooltipDisabled", "tooltipOptions"] }, { kind: "ngmodule", type: InputTextModule }, { kind: "directive", type: i8.InputText, selector: "[pInputText]", inputs: ["variant", "fluid", "pSize"] }, { kind: "ngmodule", type: IconFieldModule }, { kind: "component", type: i11.IconField, selector: "p-iconfield, p-iconField, p-icon-field", inputs: ["iconPosition", "styleClass"] }, { kind: "ngmodule", type: InputIconModule }, { kind: "component", type: i10.InputIcon, selector: "p-inputicon, p-inputIcon", inputs: ["styleClass"] }, { kind: "ngmodule", type: MultiSelectModule }, { kind: "component", type: i11$1.MultiSelect, selector: "p-multiSelect, p-multiselect, p-multi-select", inputs: ["id", "ariaLabel", "style", "styleClass", "panelStyle", "panelStyleClass", "inputId", "disabled", "fluid", "readonly", "group", "filter", "filterPlaceHolder", "filterLocale", "overlayVisible", "tabindex", "variant", "appendTo", "dataKey", "name", "ariaLabelledBy", "displaySelectedLabel", "maxSelectedLabels", "selectionLimit", "selectedItemsLabel", "showToggleAll", "emptyFilterMessage", "emptyMessage", "resetFilterOnHide", "dropdownIcon", "chipIcon", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "showHeader", "filterBy", "scrollHeight", "lazy", "virtualScroll", "loading", "virtualScrollItemSize", "loadingIcon", "virtualScrollOptions", "overlayOptions", "ariaFilterLabel", "filterMatchMode", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "autofocusFilter", "display", "autocomplete", "size", "showClear", "autofocus", "autoZIndex", "baseZIndex", "showTransitionOptions", "hideTransitionOptions", "defaultLabel", "placeholder", "options", "filterValue", "itemSize", "selectAll", "focusOnHover", "filterFields", "selectOnFocus", "autoOptionFocus", "highlightOnSelect"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onClear", "onPanelShow", "onPanelHide", "onLazyLoad", "onRemove", "onSelectAllChange"] }, { kind: "ngmodule", type: CheckboxModule }, { kind: "component", type: i9.Checkbox, selector: "p-checkbox, p-checkBox, p-check-box", inputs: ["value", "name", "disabled", "binary", "ariaLabelledBy", "ariaLabel", "tabindex", "inputId", "style", "inputStyle", "styleClass", "inputClass", "indeterminate", "size", "formControl", "checkboxIcon", "readonly", "required", "autofocus", "trueValue", "falseValue", "variant"], outputs: ["onChange", "onFocus", "onBlur"] }, { kind: "ngmodule", type: PaginatorModule }, { kind: "component", type: TableCell, selector: "ecs-table-cell", inputs: ["col", "rowData", "globalSearchText", "predefinedFiltersCollection", "dateFormat", "dateTimezone", "dateCulture"] }, { kind: "component", type: TablePredefinedFilters, selector: "ecs-table-predefined-filters", inputs: ["option", "col", "selectable", "rowData", "globalSearchText"] }, { kind: "component", type: TableButton, selector: "ecs-table-button", inputs: ["button", "rowData", "isActionButton", "isLastActionButton", "overrideAction"] }, { kind: "component", type: ColumnSelector, selector: "ecs-column-selector", inputs: ["orderByHeader", "visible", "columnModalData", "filteredColumnData"], outputs: ["visibleChange", "applyChanges"] }, { kind: "component", type: ExportExcel, selector: "ecs-export-excel", inputs: ["visible", "rowCheckboxSelectorActive", "excelReportTitle", "allowTitleUserEdit"], outputs: ["exportToExcel", "visibleChange"] }, { kind: "ngmodule", type: ButtonGroupModule }, { kind: "component", type: i13.ButtonGroup, selector: "p-buttonGroup, p-buttongroup, p-button-group" }, { kind: "component", type: ViewsManagement, selector: "ecs-views-management", inputs: ["visible", "tableViews_menuItems"], outputs: ["onViewSelect", "onViewDelete", "onViewUpdateData", "onViewUpdateActiveStartup", "onViewEditAlias", "onViewCreate", "visibleChange"] }, { kind: "ngmodule", type: PopoverModule }, { kind: "component", type: i14.Popover, selector: "p-popover", inputs: ["ariaLabel", "ariaLabelledBy", "dismissable", "style", "styleClass", "appendTo", "autoZIndex", "ariaCloseLabel", "baseZIndex", "focusOnShow", "showTransitionOptions", "hideTransitionOptions"], outputs: ["onShow", "onHide"] }, { kind: "ngmodule", type: MenuModule }, { kind: "component", type: i15.Menu, selector: "p-menu", inputs: ["model", "popup", "style", "styleClass", "appendTo", "autoZIndex", "baseZIndex", "showTransitionOptions", "hideTransitionOptions", "ariaLabel", "ariaLabelledBy", "id", "tabindex"], outputs: ["onShow", "onHide", "onBlur", "onFocus"] }], encapsulation: i0.ViewEncapsulation.None });
2994
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.21", type: ECSPrimengTable, isStandalone: true, selector: "ecs-primeng-table", inputs: { tableOptions: "tableOptions" }, outputs: { onRowCheckboxChange: "onRowCheckboxChange", onRowSelect: "onRowSelect", onRowUnselect: "onRowUnselect", onDataEndUpdate: "onDataEndUpdate" }, host: { listeners: { "window:resize": "onResize()" } }, viewQueries: [{ propertyName: "dt", first: true, predicate: ["dt"], descendants: true }, { propertyName: "tableContainer", first: true, predicate: ["tableContainer"], descendants: true }, { propertyName: "headerContainer", first: true, predicate: ["headerContainer"], descendants: true }, { propertyName: "paginatorContainer", first: true, predicate: ["paginatorContainer"], descendants: true }, { propertyName: "responsiveHeaderMenu", first: true, predicate: ["responsiveHeaderMenu"], descendants: true }, { propertyName: "responsiveRowMenu", first: true, predicate: ["responsiveRowMenu"], descendants: true }], ngImport: i0, template: "<div #tableContainer>\r\n <p-table #dt\r\n size=\"small\" showGridlines stripedRows \r\n sortMode=\"multiple\"\r\n [resizableColumns]=\"true\" columnResizeMode=\"expand\"\r\n [reorderableColumns]=\"true\"\r\n [scrollable]=\"true\" [scrollHeight]=\"scrollHeightValue\"\r\n [columns]=\"tableOptions.columns?.shown ?? []\" [value]=\"tableOptions.data ?? []\" dataKey=\"rowID\" \r\n [paginator]=\"!treeState\" [loading]=\"treeState?.loading ?? false\" paginatorDropdownAppendTo=\"body\" [first]=\"currentPage * currentRowsPerPage\" [rows]=\"currentRowsPerPage\" [totalRecords]=\"totalRecords\"\r\n [rowsPerPageOptions]=\"allowedRowsPerPage\" [showCurrentPageReport]=\"false\" (onPage)=\"pageChange($event)\"\r\n [metaKeySelection]=\"true\" [selectionMode]=\"tableOptions.rows?.singleSelector?.enabled ? 'single' : null\" [metaKeySelection]=\"tableOptions.rows?.singleSelector?.metakey\" [(selection)]=\"rowSelection\" (onRowSelect)=\"rowSelect($event)\" (onRowUnselect)=\"rowUnselect($event)\"\r\n [lazy]=\"true\" (onLazyLoad)=\"fetchTableData($event)\">\r\n\r\n <!--TEMPLATE FOR THE ACTIONS HEADER COLUMN-->\r\n <ng-template #actionColumnHeaderTemplate>\r\n @if ((tableOptions.rows?.action?.buttons?.length ?? 0) > 0) {\r\n <th [ngStyle]=\"{\r\n 'text-align': 'center',\r\n 'vertical-align': 'middle',\r\n 'max-width': actionColumnWidth + 'px',\r\n 'min-width': actionColumnWidth + 'px',\r\n 'width': actionColumnWidth + 'px'\r\n }\"\r\n pResizableColumn [pResizableColumnDisabled]=\"!tableOptions.rows?.action?.resizable\" pFrozenColumn [frozen]=\"tableOptions.rows?.action?.frozen ?? false\"\r\n [alignFrozen]=\"getFrozenColumnAlignAsText(tableOptions.rows?.action?.positionRight ? FrozenColumnAlign.Right : FrozenColumnAlign.Left)\" id=\"actions-header\"\r\n [attr.scope]=\"'col'\">\r\n {{ (tableOptions.rows?.action?.header ?? '') | ecsTranslate }}\r\n </th>\r\n }\r\n </ng-template>\r\n\r\n <!--TEMPLATE FOR THE ACTIONS ROW COLUMN-->\r\n <ng-template #actionColumnTemplate let-rowData=\"rowData\">\r\n @if ((tableOptions.rows?.action?.buttons?.length ?? 0) > 0) {\r\n <td \r\n [ngStyle]=\"{\r\n 'text-align': (getDataAlignHorizontalAsText(tableOptions.rows?.action?.horizontalAlignment ?? DataAlignHorizontal.Center)),\r\n 'vertical-align': (getDataAlignVerticalAsText(tableOptions.rows?.action?.verticalAlignment ?? DataAlignVertical.Middle)),\r\n 'max-width': actionColumnWidth + 'px',\r\n 'min-width': actionColumnWidth + 'px',\r\n 'width': actionColumnWidth + 'px'\r\n }\"\r\n pFrozenColumn [frozen]=\"tableOptions.rows?.action?.frozen ?? false\"\r\n [alignFrozen]=\"getFrozenColumnAlignAsText(tableOptions.rows?.action?.positionRight ? FrozenColumnAlign.Right : FrozenColumnAlign.Left)\">\r\n @if (compactRows) {\r\n @if (hasRowMenuActions(rowData)) {\r\n <button pButton type=\"button\" icon=\"pi pi-ellipsis-v\" [attr.aria-label]=\"(tableOptions.responsive?.rowMenuLabel || 'Row actions') | ecsTranslate\"\r\n aria-haspopup=\"menu\" [attr.aria-expanded]=\"responsiveRowMenu.visible && rowMenuRow === rowData\"\r\n (click)=\"openRowMenu($event, rowData)\" class=\"ecs-responsive-trigger\"></button>\r\n }\r\n } @else {\r\n @for (button of tableOptions.rows?.action?.buttons; track button; let last = $last) {\r\n <ecs-table-button [button]=\"button\" [rowData]=\"rowData\" [isActionButton]=\"true\" [isLastActionButton]=\"last\"/>\r\n }\r\n }\r\n </td>\r\n }\r\n </ng-template>\r\n\r\n <!-- TEMPLATE FOR THE ROW CHECKBOX SELECTOR HEADER COLUMN -->\r\n <ng-template #rowSelectorColumnHeaderTemplate>\r\n <th \r\n [ngStyle]=\"{\r\n 'text-align': 'center',\r\n 'vertical-align': 'middle',\r\n 'max-width': (tableOptions.rows?.checkboxSelector?.width ?? 150) + 'px',\r\n 'min-width': (tableOptions.rows?.checkboxSelector?.width ?? 150) + 'px',\r\n 'width': (tableOptions.rows?.checkboxSelector?.width ?? 150) + 'px'\r\n }\"\r\n id=\"rowSelector-header\" [attr.scope]=\"'col'\" pResizableColumn [pResizableColumnDisabled]=\"!tableOptions.rows?.checkboxSelector?.resizable\" pFrozenColumn \r\n [frozen]=\"tableOptions.rows?.checkboxSelector?.frozen ?? false\" [alignFrozen]=\"getFrozenColumnAlignAsText(tableOptions.rows?.checkboxSelector?.positionRight ? FrozenColumnAlign.Right : FrozenColumnAlign.Left)\">\r\n <div style=\"display: flex; justify-content: space-between; align-items: center;\">\r\n @if (tableOptions.rows?.checkboxSelector?.selectAllEnabled) {\r\n <p-checkbox [binary]=\"true\" [ngModel]=\"allMatchingRowsSelected\"\r\n [indeterminate]=\"matchingRowsPartiallySelected\"\r\n [disabled]=\"selectAllLoading || !tableOptions.rows?.checkboxSelector?.urlSelectAll\"\r\n [ariaLabel]=\"'Select all filtered rows' | ecsTranslate\"\r\n [pTooltip]=\"'Select all filtered rows' | ecsTranslate\"\r\n (onChange)=\"toggleAllMatchingRows($event.checked)\"/>\r\n }\r\n {{ (tableOptions.rows?.checkboxSelector?.header ?? '') | ecsTranslate }}\r\n <p-columnFilter type=\"boolean\" field=\"selector\" display=\"menu\" [showButtons]=\"false\"/>\r\n </div>\r\n </th>\r\n </ng-template>\r\n\r\n <!--TEMPLATE FOR THE ROW CHECKBOX SELECTOR COLUMN-->\r\n <ng-template #rowSelectorColumnTemplate let-rowData=\"rowData\">\r\n <td \r\n [ngStyle]=\"{\r\n 'text-align': (getDataAlignHorizontalAsText(tableOptions.rows?.checkboxSelector?.horizontalAlignment ?? DataAlignHorizontal.Center)),\r\n 'vertical-align': (getDataAlignVerticalAsText(tableOptions.rows?.checkboxSelector?.verticalAlignment ?? DataAlignVertical.Middle)),\r\n 'max-width': (tableOptions.rows?.checkboxSelector?.width ?? 150) + 'px',\r\n 'min-width': (tableOptions.rows?.checkboxSelector?.width ?? 150) + 'px',\r\n 'width': (tableOptions.rows?.checkboxSelector?.width ?? 150) + 'px'\r\n }\"\r\n pFrozenColumn [frozen]=\"tableOptions.rows?.checkboxSelector?.frozen ?? false\" \r\n [alignFrozen]=\"getFrozenColumnAlignAsText(tableOptions.rows?.checkboxSelector?.positionRight ? FrozenColumnAlign.Right : FrozenColumnAlign.Left)\">\r\n <p-checkbox \r\n [disabled]=\"!(tableOptions.rows?.checkboxSelector?.enabledCondition?.(rowData) ?? true)\"\r\n [binary]=\"true\"\r\n [ngModel]=\"isRowCheckboxSelected(rowData.rowID)\"\r\n (onChange)=\"onRowChekboxChange($event, rowData.rowID)\"/>\r\n </td>\r\n </ng-template>\r\n\r\n\r\n <!-- LOGIC FOR DRAWING TABLE ACTIONS ABOVE THE HEADER -->\r\n <ng-template #caption>\r\n <div #headerContainer [class.ecs-compact-header]=\"compactHeader\" style=\"display: flex; justify-content: space-between; align-items: center;\">\r\n @if (compactHeader) {\r\n @if (tableOptions.globalFilter?.enabled) {\r\n <p-iconField iconPosition=\"left\" class=\"ecs-responsive-search\">\r\n <p-inputIcon><i class=\"pi pi-search\"></i></p-inputIcon>\r\n <input pInputText type=\"text\" [attr.aria-label]=\"'Search keyword' | ecsTranslate\" [placeholder]=\"'Search keyword' | ecsTranslate\" autocomplete=\"off\"\r\n [maxlength]=\"tableOptions.globalFilter?.maxLength ?? null\" [ngModel]=\"globalSearchText\"\r\n (ngModelChange)=\"onGlobalSearchInput($event)\"/>\r\n @if (globalSearchText) {\r\n <p-inputIcon position=\"right\"><button type=\"button\" class=\"ecs-clear-search\" [attr.aria-label]=\"'Clear search' | ecsTranslate\" (click)=\"clearFilters(dt, true, true)\"><i class=\"pi pi-times\"></i></button></p-inputIcon>\r\n }\r\n </p-iconField>\r\n }\r\n @if (tableOptions.description?.text) {\r\n <i [class]=\"tableOptions.description!.icon\" [pTooltip]=\"(tableOptions.description!.text) | ecsTranslate\" [escape]=\"false\"></i>\r\n }\r\n <button pButton type=\"button\" icon=\"pi pi-bars\" [attr.aria-label]=\"(tableOptions.responsive?.headerMenuLabel || 'Table actions') | ecsTranslate\"\r\n aria-haspopup=\"menu\" [attr.aria-expanded]=\"responsiveHeaderMenu.visible\"\r\n (click)=\"openHeaderMenu($event)\" class=\"ecs-responsive-trigger ecs-header-menu-trigger\"></button>\r\n } @else {\r\n\r\n <div style=\"display: flex; align-items: center; gap: 10px;\">\r\n <!--CHOOSE COLUMNS TO SHOW-->\r\n @if (tableOptions.columns?.selectorEnabled) {\r\n <p-button [icon]=\"tableOptions.columns?.selectorIcon ?? 'pi pi-pen-to-square'\" (onClick)=\"columnSelectorShow()\" [pTooltip]=\"'Modify columns' | ecsTranslate\"\r\n [showDelay]=\"700\" tooltipPosition=\"top\" styleClass=\"p-button-icon-only\"/>\r\n }\r\n <!--CLEAR SORTS AND FILTERS-->\r\n @if (tableOptions.header?.clearSortsEnabled) {\r\n <p-button [icon]=\"tableOptions.header?.clearSortsIcon ?? 'pi pi-sort-alt-slash'\" (onClick)=\"clearSorts(dt)\" [disabled]=\"!hasToClearSorts(dt)\"\r\n [pTooltip]=\"'Clear sorts' | ecsTranslate\" [showDelay]=\"700\" tooltipPosition=\"top\" styleClass=\"p-button-icon-only\"/>\r\n }\r\n @if (tableOptions.header?.clearFiltersEnabled) {\r\n <p-button\r\n [icon]=\"tableOptions.header?.clearFiltersIcon ?? 'pi pi-filter-slash'\" (onClick)=\"clearFilters(dt)\" [disabled]=\"!hasToClearFilters(dt, globalSearchText)\"\r\n [pTooltip]=\"'Clear filters' | ecsTranslate\" [showDelay]=\"700\" tooltipPosition=\"top\" styleClass=\"p-button-icon-only\"/>\r\n }\r\n\r\n <!--TABLE DESCRIPTION-->\r\n @if(tableOptions.description?.text){ <!-- If a table description text is provided -->\r\n @if(!tableOptions.description!.tooltip){ <!-- The table description must be shown as text next to the icon -->\r\n <i [class]=\"tableOptions.description!.icon\"></i>\r\n <span [innerHTML]=\"(tableOptions.description!.text) | ecsTranslate\"></span>\r\n } @else {\r\n <i [escape]=\"false\" [pTooltip]=\"(tableOptions.description!.text) | ecsTranslate\" tooltipPosition=\"right\" [class]=\"tableOptions.description!.icon\"></i>\r\n }\r\n }\r\n </div>\r\n\r\n <!--TABLE VIEWS-->\r\n @if(tableViewsEnabled()){\r\n <div style=\"display: flex; align-items: center; gap: 10px;\">\r\n <p-buttongroup>\r\n <p-button (click)=\"viewsModalShow=true;\"\r\n [label]=\"tableViewCurrentSelectedAlias \r\n ? tableViewCurrentSelectedAlias \r\n : ((tableOptions.views?.noViewSelectedText || '--- Select a view ---') | ecsTranslate)\"\r\n [class]=\"'viewButton' + (tableOptions.views?.selectViewButtonClass ? ' ' + tableOptions.views!.selectViewButtonClass : '')\"/>\r\n <p-button (click)=\"viewLoad(tableViewCurrentSelectedAlias!)\" [disabled]=\"!tableViewCurrentSelectedAlias\" [pTooltip]=\"'Apply view again' | ecsTranslate\" [showDelay]=\"700\" tooltipPosition=\"top\"\r\n [icon]=\"tableOptions.views?.reloadViewButtonIcon || 'pi pi-refresh'\"\r\n [class]=\"tableOptions.views?.reloadViewButtonClass || ''\"/>\r\n </p-buttongroup>\r\n </div>\r\n }\r\n\r\n <div style=\"display: flex; align-items: center; gap: 10px;\">\r\n <!--GLOBAL FILTER-->\r\n @if (tableOptions.globalFilter?.enabled) {\r\n <p-iconField iconPosition=\"left\" class=\"ml-auto\" [ngClass]=\"{'p-input-icon-right': globalSearchText}\">\r\n <p-inputIcon>\r\n <i class=\"pi pi-search\"></i>\r\n </p-inputIcon>\r\n <input pInputText type=\"text\" \r\n (ngModelChange)=\"onGlobalSearchInput($event)\" autocomplete=\"off\"\r\n [maxlength]=\"tableOptions.globalFilter?.maxLength ?? null\" [placeholder]=\"'Search keyword' | ecsTranslate\" [ngModel]=\"globalSearchText\"\r\n style=\"width: 220px;\"/>\r\n <!-- Right icon (only if there is text) -->\r\n @if (globalSearchText) {\r\n <p-inputIcon position=\"right\">\r\n <i class=\"pi pi-times\" style=\"cursor: pointer;\" (click)=\"clearFilters(dt, true, true); $event.stopPropagation()\"></i>\r\n </p-inputIcon>\r\n }\r\n </p-iconField>\r\n }\r\n\r\n <!--EXPORT DATA-->\r\n @if (tableOptions.excelReport?.url?.trim()) {\r\n <p-button icon=\"pi pi-file-excel\" (onClick)=\"openExcelExport()\"\r\n [pTooltip]=\"'Export to Excel' | ecsTranslate\" [showDelay]=\"700\" tooltipPosition=\"top\" styleClass=\"p-button-icon-only\"/>\r\n }\r\n\r\n <!--RESET TABLE VIEW-->\r\n @if(tableOptions.resetTableView?.enabled){\r\n <p-button [icon]=\"tableOptions.resetTableView?.icon ?? 'pi pi-eraser'\" (click)=\"resetTableView()\" [pTooltip]=\"'Reset table view' | ecsTranslate\" [showDelay]=\"700\"\r\n tooltipPosition=\"top\" styleClass=\"p-button-icon-only\"/>\r\n }\r\n\r\n <!--REFRESH DATA-->\r\n <p-button icon=\"pi pi-refresh\" (onClick)=\"refreshData($event)\" [pTooltip]=\"'Refresh data' | ecsTranslate\" [showDelay]=\"700\"\r\n tooltipPosition=\"top\" styleClass=\"p-button-icon-only\"/>\r\n \r\n <!-- HEADER ACTION BUTTONS -->\r\n @if ((tableOptions.header?.buttons?.length ?? 0) > 0) {\r\n <td style=\"display: flex; justify-content: center; align-items: center; gap: 10px;\">\r\n @for (button of tableOptions.header?.buttons; track $index) {\r\n <ecs-table-button [button]=\"button\" [rowData]=\"null\"/>\r\n }\r\n </td>\r\n }\r\n </div>\r\n }\r\n </div>\r\n </ng-template>\r\n\r\n <!-- LOGIC FOR DRAWING TABLE HEADERS -->\r\n <ng-template #header let-columns>\r\n @let headerGroups = getColumnHeaderGroups(columns);\r\n @if (headerGroups.length) {\r\n <tr class=\"ecs-column-groups\">\r\n @if ((tableOptions.rows?.action?.buttons?.length ?? 0) > 0 && !tableOptions.rows?.action?.positionRight) {\r\n <td aria-hidden=\"true\" pFrozenColumn [frozen]=\"tableOptions.rows?.action?.frozen ?? false\" alignFrozen=\"left\"\r\n [style.width.px]=\"actionColumnWidth\" [style.min-width.px]=\"actionColumnWidth\"></td>\r\n }\r\n @if (tableOptions.rows?.checkboxSelector?.enabled && !tableOptions.rows?.checkboxSelector?.positionRight) {\r\n <td aria-hidden=\"true\" pFrozenColumn [frozen]=\"tableOptions.rows?.checkboxSelector?.frozen ?? false\" alignFrozen=\"left\"\r\n [style.width.px]=\"tableOptions.rows?.checkboxSelector?.width ?? 150\" [style.min-width.px]=\"tableOptions.rows?.checkboxSelector?.width ?? 150\"></td>\r\n }\r\n @for (group of headerGroups; track group.field) {\r\n <td [attr.colspan]=\"group.colspan\" role=\"columnheader\" [attr.aria-colspan]=\"group.colspan\" style=\"text-align: center; vertical-align: middle;\"\r\n pFrozenColumn [frozen]=\"group.frozenColumnAlign !== FrozenColumnAlign.Noone\"\r\n [alignFrozen]=\"getFrozenColumnAlignAsText(group.frozenColumnAlign)\">\r\n {{ group.label | translate }}\r\n </td>\r\n }\r\n @if (tableOptions.rows?.checkboxSelector?.enabled && tableOptions.rows?.checkboxSelector?.positionRight) {\r\n <td aria-hidden=\"true\" pFrozenColumn [frozen]=\"tableOptions.rows?.checkboxSelector?.frozen ?? false\" alignFrozen=\"right\"\r\n [style.width.px]=\"tableOptions.rows?.checkboxSelector?.width ?? 150\" [style.min-width.px]=\"tableOptions.rows?.checkboxSelector?.width ?? 150\"></td>\r\n }\r\n @if ((tableOptions.rows?.action?.buttons?.length ?? 0) > 0 && tableOptions.rows?.action?.positionRight) {\r\n <td aria-hidden=\"true\" pFrozenColumn [frozen]=\"tableOptions.rows?.action?.frozen ?? false\" alignFrozen=\"right\"\r\n [style.width.px]=\"actionColumnWidth\" [style.min-width.px]=\"actionColumnWidth\"></td>\r\n }\r\n </tr>\r\n }\r\n <tr>\r\n @if (!tableOptions.rows?.action?.positionRight) {\r\n <ng-container *ngTemplateOutlet=\"actionColumnHeaderTemplate\"></ng-container>\r\n }\r\n @if (tableOptions.rows?.checkboxSelector?.enabled && !tableOptions.rows?.checkboxSelector?.positionRight) {\r\n <ng-container [ngTemplateOutlet]=\"rowSelectorColumnHeaderTemplate\"></ng-container>\r\n }\r\n @for (col of columns; track col.header) {\r\n <th [ngStyle]=\"getColumnStyle(col, true)\"\r\n pResizableColumn [pResizableColumnDisabled]=\"!col.canBeResized ? true : false\"\r\n pReorderableColumn [pReorderableColumnDisabled]=\"!col.canBeReordered ? true : false\"\r\n pFrozenColumn [frozen]=\"col.frozenColumnAlign === FrozenColumnAlign.Left || col.frozenColumnAlign === FrozenColumnAlign.Right\" [alignFrozen]=\"getFrozenColumnAlignAsText(col.frozenColumnAlign)\"\r\n [pSortableColumn]=\"col.field\" [pSortableColumnDisabled]=\"!col.canBeSorted ? true : false\"\r\n style=\"text-align: center;\"\r\n [id]=\"col.field + '-header'\" [attr.scope]=\"'col'\">\r\n <div style=\"display: flex; justify-content: space-between; align-items: center; width: 100%;\">\r\n <div style=\"margin-right: 15px;\">\r\n <span>{{ col.header | translate }}</span>\r\n </div>\r\n <div style=\"display: flex; align-items: center; gap: 5px;\">\r\n @if (col.canBeSorted) {\r\n <p-sortIcon [field]=\"col.field\"></p-sortIcon>\r\n }\r\n @if(col.canBeFiltered){\r\n @if (!col.filterPredefinedValuesName || col.filterPredefinedValuesName.length === 0) {\r\n <p-columnFilter [type]=\"getDataTypeAsText(col.dataType)\" [field]=\"col.field\" display=\"menu\" [showButtons]=\"false\"/>\r\n } @else {\r\n <p-columnFilter\r\n [type]=\"getDataTypeAsText(col.dataType)\" [field]=\"col.field\" display=\"menu\"\r\n [showButtons]=\"false\" matchMode=\"in\" operator=\"or\" [showMatchModes]=\"false\"\r\n [showOperator]=\"false\" [showAddButton]=\"false\" [showClearButton]=\"false\" [showApplyButton]=\"false\">\r\n <ng-template #filter>\r\n <p-multiSelect\r\n [style]=\"{ minWidth: '400px' }\" [(ngModel)]=\"predefinedFiltersSelectedValuesCollection[col.filterPredefinedValuesName]\"\r\n [options]=\"getPredefinedFilterValues(col.filterPredefinedValuesName)\" [placeholder]=\"'Any value' | ecsTranslate\"\r\n (onChange)=\"onPredefinedFilterChange(col.field, $event.value)\" optionLabel=\"name\">\r\n <ng-template #item let-option >\r\n <div style=\"display: inline-block; vertical-align: middle;\">\r\n <ecs-table-predefined-filters [option]=\"option\" [col]=\"col\" [selectable]=\"false\" [rowData]=\"null\"/>\r\n </div>\r\n </ng-template>\r\n </p-multiSelect>\r\n </ng-template>\r\n </p-columnFilter>\r\n }\r\n }\r\n @if (col.columnDescription && col.columnDescription.length > 0) {\r\n <i [pTooltip]=\"(col.columnDescription) | ecsTranslate\" tooltipPosition=\"top\" [class]=\"tableOptions.columnDescriptionIcon || 'pi pi-info-circle'\"></i>\r\n }\r\n </div>\r\n </div>\r\n </th>\r\n }\r\n @if (tableOptions.rows?.checkboxSelector?.enabled && tableOptions.rows?.checkboxSelector?.positionRight) {\r\n <ng-container [ngTemplateOutlet]=\"rowSelectorColumnHeaderTemplate\"></ng-container>\r\n }\r\n @if (tableOptions.rows?.action?.positionRight) {\r\n <ng-container *ngTemplateOutlet=\"actionColumnHeaderTemplate\"></ng-container>\r\n }\r\n </tr>\r\n </ng-template>\r\n\r\n <!-- LOGIC FOR DRAWING TABLE DATA WHEN THERE IS CONTENTS -->\r\n <ng-template #body let-rowData let-columns=\"columns\"> \r\n @if (treeState?.isMore(rowData)) {\r\n <tr class=\"ecs-tree-more-row\">\r\n <td colspan=\"999\">\r\n <p-button icon=\"pi pi-plus\" [text]=\"true\" [label]=\"'Load more children' | ecsTranslate\"\r\n (onClick)=\"loadMoreTreeRows($event, rowData)\" />\r\n </td>\r\n </tr>\r\n } @else {\r\n <tr [pSelectableRow]=\"rowData\" [ngClass]=\"tableOptions.rows?.class?.(rowData)\" [ngStyle]=\"tableOptions.rows?.style?.(rowData)\"\r\n [attr.aria-level]=\"treeState ? treeState.depth(rowData) + 1 : null\"\r\n [attr.aria-expanded]=\"treeState?.hasChildren(rowData) ? treeState?.isExpanded(rowData) : null\">\r\n @if (!tableOptions.rows?.action?.positionRight) {\r\n <ng-container *ngTemplateOutlet=\"actionColumnTemplate; context: { rowData: rowData }\"></ng-container>\r\n }\r\n @if (tableOptions.rows?.checkboxSelector?.enabled && !tableOptions.rows?.checkboxSelector?.positionRight) {\r\n <ng-container [ngTemplateOutlet]=\"rowSelectorColumnTemplate\" [ngTemplateOutletContext]=\"{ rowData: rowData }\"></ng-container>\r\n }\r\n @for (col of columns; track col.field) {\r\n <td (mousedown)=\"col.dataType !== DataType.Boolean && copyToClipboardStart($event)\" (mouseup)=\"copyToClipboardCancel()\"\r\n [ngStyle]=\"getColumnStyle(col)\" pFrozenColumn [frozen]=\"col.frozenColumnAlign === FrozenColumnAlign.Left || col.frozenColumnAlign === FrozenColumnAlign.Right\" \r\n [alignFrozen]=\"getFrozenColumnAlignAsText(col.frozenColumnAlign)\" [style.text-align]=\"getDataAlignHorizontalAsText(col.dataAlignHorizontal)\" [style.vertical-align]=\"getDataAlignVerticalAsText(col.dataAlignVertical)\">\r\n @if (treeState && col.field === treeColumn) {\r\n <div class=\"ecs-tree-cell\" [style.padding-inline-start.px]=\"treeState.depth(rowData) * 20\">\r\n <button type=\"button\" class=\"ecs-tree-toggle\" [class.ecs-tree-leaf]=\"!treeState.hasChildren(rowData)\"\r\n [disabled]=\"!treeState.hasChildren(rowData) || treeState.isLoading(rowData) || treeState.loading\"\r\n [attr.aria-label]=\"(treeState.isExpanded(rowData) ? 'Collapse node' : 'Expand node') | ecsTranslate\"\r\n [attr.aria-expanded]=\"treeState.hasChildren(rowData) ? treeState.isExpanded(rowData) : null\"\r\n [pTooltip]=\"(treeState.isExpanded(rowData) ? 'Collapse node' : 'Expand node') | ecsTranslate\"\r\n (mousedown)=\"$event.stopPropagation()\" (mouseup)=\"$event.stopPropagation()\"\r\n (click)=\"toggleTreeRow($event, rowData)\">\r\n <i [class]=\"treeState.isLoading(rowData) ? 'pi pi-spinner pi-spin' : treeState.isExpanded(rowData) ? 'pi pi-chevron-down' : 'pi pi-chevron-right'\" aria-hidden=\"true\"></i>\r\n </button>\r\n <ecs-table-cell [col]=\"col\" [rowData]=\"rowData\" [globalSearchText]=\"effectiveGlobalSearchText\"\r\n [dateFormat]=\"dateFormat\" [dateTimezone]=\"dateTimezone\" [dateCulture]=\"dateCulture\"\r\n [predefinedFiltersCollection]=\"tableOptions.predefinedFilters\" />\r\n </div>\r\n } @else {\r\n <ecs-table-cell [col]=\"col\" [rowData]=\"rowData\" [globalSearchText]=\"effectiveGlobalSearchText\"\r\n [dateFormat]=\"dateFormat\" [dateTimezone]=\"dateTimezone\" [dateCulture]=\"dateCulture\"\r\n [predefinedFiltersCollection]=\"tableOptions.predefinedFilters\"/>\r\n }\r\n </td>\r\n }\r\n @if (tableOptions.rows?.checkboxSelector?.enabled && tableOptions.rows?.checkboxSelector?.positionRight) {\r\n <ng-container [ngTemplateOutlet]=\"rowSelectorColumnTemplate\" [ngTemplateOutletContext]=\"{ rowData: rowData }\"></ng-container>\r\n }\r\n @if (tableOptions.rows?.action?.positionRight) {\r\n <ng-container *ngTemplateOutlet=\"actionColumnTemplate; context: { rowData: rowData }\"></ng-container>\r\n }\r\n </tr>\r\n }\r\n </ng-template>\r\n\r\n <!-- LOGIC FOR DRAWING TABLE DATA WHEN THERE IS NO CONTENTS -->\r\n <ng-template #emptymessage>\r\n <tr>\r\n <td colspan=\"999\">{{ 'No data found for the current filter criteria.' | ecsTranslate }}</td>\r\n </tr>\r\n </ng-template>\r\n\r\n <!-- SHOW CUSTOM RECORDS REPORT -->\r\n <ng-template #paginatorleft>\r\n <div #paginatorContainer>\r\n <div style=\"display: flex; align-items: center; gap: 10px;\">\r\n @if(tableOptions.legend?.content){\r\n <ecs-table-button [button]=\"tableOptions.legend?.button\" [rowData]=\"null\" [overrideAction]=\"op.toggle.bind(op)\"/>\r\n <p-popover #op>\r\n <div [innerHTML]=\"(tableOptions.legend?.content) | ecsTranslate\"></div>\r\n </p-popover>\r\n }\r\n <span>{{ 'Showing {{count}} records of {{total}} available records' | ecsTranslate: { count: totalRecords, total: totalRecordsNotFiltered } }}</span>\r\n </div>\r\n </div>\r\n </ng-template>\r\n </p-table>\r\n @if (treeState) {\r\n <div #paginatorContainer class=\"ecs-tree-paginator\">\r\n @if (tableOptions.legend?.content) {\r\n <ecs-table-button [button]=\"tableOptions.legend?.button\" [rowData]=\"null\" [overrideAction]=\"treeLegend.toggle.bind(treeLegend)\" />\r\n <p-popover #treeLegend><div [innerHTML]=\"(tableOptions.legend?.content) | ecsTranslate\"></div></p-popover>\r\n }\r\n <span>{{ 'Showing {{count}} root nodes of {{total}} available root nodes' | ecsTranslate: { count: totalRecords, total: totalRecordsNotFiltered } }}</span>\r\n <p-paginator [first]=\"currentPage * currentRowsPerPage\" [rows]=\"currentRowsPerPage\" [totalRecords]=\"totalRecords\"\r\n [rowsPerPageOptions]=\"allowedRowsPerPage\" dropdownAppendTo=\"body\" (onPageChange)=\"treePageChange($event)\" />\r\n </div>\r\n }\r\n</div>\r\n<ecs-column-selector [visible]=\"showColumnSelector\" [columnModalData]=\"columnModalData\" [filteredColumnData]=\"filteredColumnData\" [orderByHeader]=\"tableOptions.columns?.selectorOrderByColumnName === true\" (visibleChange)=\"showColumnSelector=false\" (applyChanges)=\"applyColumnModalChanges($event)\"/>\r\n<ecs-export-excel [visible]=\"showExportModal\" [rowCheckboxSelectorActive]=\"tableOptions.rows?.checkboxSelector?.enabled ?? false\" [excelReportTitle]=\"excelReportTitle\" [allowTitleUserEdit]=\"tableOptions.excelReport?.titleAllowUserEdit ?? false\" (visibleChange)=\"showExportModal=false\" (exportToExcel)=\"generateExcelReport($event)\"/>\r\n<ecs-views-management [visible]=\"viewsModalShow\" [tableViews_menuItems]=\"tableViews_menuItems\" \r\n (onViewSelect)=\"viewLoad($event)\" (onViewCreate)=\"viewCreate($event)\" (onViewDelete)=\"viewDelete($event)\" (onViewEditAlias)=\"viewEditAlias($event)\" (onViewUpdateData)=\"viewUpdateData($event)\" (onViewUpdateActiveStartup)=\"viewUpdateActiveStartup($event)\"\r\n (visibleChange)=\"viewsModalShow=false\"/>\r\n<!-- Body-level overlays avoid clipping inside scrollable and frozen table cells. -->\r\n<p-menu #responsiveHeaderMenu [model]=\"headerMenuItems\" [popup]=\"true\" appendTo=\"body\" styleClass=\"ecs-responsive-menu\"/>\r\n<p-menu #responsiveRowMenu [model]=\"rowMenuItems\" [popup]=\"true\" appendTo=\"body\" styleClass=\"ecs-responsive-menu\"/>\r\n", styles: [".highlighted-text{background-color:#ff0;color:#000;border-radius:2px}.excel-export-tooltip .bool-icon{text-shadow:0 0 2px white,0 0 3px white}.excel-export-tooltip .bool-true{color:green}.excel-export-tooltip .bool-false{color:red}.p-datatable-column-filter-button.p-button-icon-only.p-button-rounded,.p-datatable-column-filter-clear-button.p-button-icon-only.p-button-rounded{height:var(--p-icon-size)!important;width:var(--p-icon-size)!important;border-radius:0!important}.viewButton{width:200px}.viewButton .p-button{width:100%;justify-content:center}.viewButton .p-button-label{display:block;width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;text-align:center}.ecs-compact-header{gap:.5rem;min-width:0}.ecs-header-menu-trigger{margin-left:auto;flex:0 0 auto}.ecs-responsive-trigger{min-width:44px;min-height:44px}.ecs-responsive-search{flex:1 1 220px;min-width:0;max-width:320px}.ecs-responsive-search input{width:100%;padding-right:2.5rem}.ecs-clear-search{border:0;background:transparent;color:inherit;cursor:pointer}.ecs-responsive-menu{max-width:calc(100vw - 16px);max-height:calc(100dvh - 32px);overflow-y:auto}.ecs-responsive-menu .p-menu-item-link{min-height:44px;white-space:normal}.ecs-tree-cell{display:flex;align-items:center;gap:4px;min-width:0}.ecs-tree-cell>ecs-table-cell{flex:1;min-width:0}.ecs-tree-toggle{width:32px;height:32px;flex:0 0 32px;border:0;background:transparent;color:inherit;cursor:pointer}.ecs-tree-toggle:focus-visible{outline:2px solid var(--p-primary-color);outline-offset:1px}.ecs-tree-leaf{visibility:hidden}.ecs-tree-paginator{display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:8px}.p-datatable-thead>.ecs-column-groups>td{padding:var(--p-datatable-header-cell-padding);background:var(--p-datatable-header-cell-background);color:var(--p-datatable-header-cell-color);font-weight:var(--p-datatable-column-title-font-weight);border:1px solid var(--p-datatable-header-cell-border-color);white-space:normal;overflow-wrap:anywhere}\n"], dependencies: [{ kind: "pipe", type: ECSTableTranslatePipe, name: "ecsTranslate" }, { kind: "pipe", type: TranslatePipe, name: "translate" }, { kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1$1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i1$1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i9$1.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: i9$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i9$1.MaxLengthValidator, selector: "[maxlength][formControlName],[maxlength][formControl],[maxlength][ngModel]", inputs: ["maxlength"] }, { kind: "directive", type: i9$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: TableModule }, { kind: "component", type: i5.Table, selector: "p-table", inputs: ["frozenColumns", "frozenValue", "style", "styleClass", "tableStyle", "tableStyleClass", "paginator", "pageLinks", "rowsPerPageOptions", "alwaysShowPaginator", "paginatorPosition", "paginatorStyleClass", "paginatorDropdownAppendTo", "paginatorDropdownScrollHeight", "currentPageReportTemplate", "showCurrentPageReport", "showJumpToPageDropdown", "showJumpToPageInput", "showFirstLastIcon", "showPageLinks", "defaultSortOrder", "sortMode", "resetPageOnSort", "selectionMode", "selectionPageOnly", "contextMenuSelection", "contextMenuSelectionMode", "dataKey", "metaKeySelection", "rowSelectable", "rowTrackBy", "lazy", "lazyLoadOnInit", "compareSelectionBy", "csvSeparator", "exportFilename", "filters", "globalFilterFields", "filterDelay", "filterLocale", "expandedRowKeys", "editingRowKeys", "rowExpandMode", "scrollable", "scrollDirection", "rowGroupMode", "scrollHeight", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "virtualScrollDelay", "frozenWidth", "responsive", "contextMenu", "resizableColumns", "columnResizeMode", "reorderableColumns", "loading", "loadingIcon", "showLoader", "rowHover", "customSort", "showInitialSortBadge", "autoLayout", "exportFunction", "exportHeader", "stateKey", "stateStorage", "editMode", "groupRowsBy", "size", "showGridlines", "stripedRows", "groupRowsByOrder", "responsiveLayout", "breakpoint", "paginatorLocale", "value", "columns", "first", "rows", "totalRecords", "sortField", "sortOrder", "multiSortMeta", "selection", "virtualRowHeight", "selectAll"], outputs: ["contextMenuSelectionChange", "selectAllChange", "selectionChange", "onRowSelect", "onRowUnselect", "onPage", "onSort", "onFilter", "onLazyLoad", "onRowExpand", "onRowCollapse", "onContextMenuSelect", "onColResize", "onColReorder", "onRowReorder", "onEditInit", "onEditComplete", "onEditCancel", "onHeaderCheckboxToggle", "sortFunction", "firstChange", "rowsChange", "onStateSave", "onStateRestore"] }, { kind: "directive", type: i5.SortableColumn, selector: "[pSortableColumn]", inputs: ["pSortableColumn", "pSortableColumnDisabled"] }, { kind: "directive", type: i5.FrozenColumn, selector: "[pFrozenColumn]", inputs: ["frozen", "alignFrozen"] }, { kind: "directive", type: i5.SelectableRow, selector: "[pSelectableRow]", inputs: ["pSelectableRow", "pSelectableRowIndex", "pSelectableRowDisabled"] }, { kind: "directive", type: i5.ResizableColumn, selector: "[pResizableColumn]", inputs: ["pResizableColumnDisabled"] }, { kind: "directive", type: i5.ReorderableColumn, selector: "[pReorderableColumn]", inputs: ["pReorderableColumnDisabled"] }, { kind: "component", type: i5.SortIcon, selector: "p-sortIcon", inputs: ["field"] }, { kind: "component", type: i5.ColumnFilter, selector: "p-columnFilter", inputs: ["field", "type", "display", "showMenu", "matchMode", "operator", "showOperator", "showClearButton", "showApplyButton", "showMatchModes", "showAddButton", "hideOnClear", "placeholder", "matchModeOptions", "maxConstraints", "minFractionDigits", "maxFractionDigits", "prefix", "suffix", "locale", "localeMatcher", "currency", "currencyDisplay", "useGrouping", "showButtons", "ariaLabel", "filterButtonProps"], outputs: ["onShow", "onHide"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "directive", type: i6.ButtonDirective, selector: "[pButton]", inputs: ["iconPos", "loadingIcon", "loading", "severity", "raised", "rounded", "text", "outlined", "size", "plain", "fluid", "label", "icon", "buttonProps"] }, { kind: "component", type: i6.Button, selector: "p-button", inputs: ["type", "iconPos", "icon", "badge", "label", "disabled", "loading", "loadingIcon", "raised", "rounded", "text", "plain", "severity", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "fluid", "buttonProps"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i7.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "appendTo", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "pTooltip", "tooltipDisabled", "tooltipOptions"] }, { kind: "ngmodule", type: InputTextModule }, { kind: "directive", type: i8.InputText, selector: "[pInputText]", inputs: ["variant", "fluid", "pSize"] }, { kind: "ngmodule", type: IconFieldModule }, { kind: "component", type: i11.IconField, selector: "p-iconfield, p-iconField, p-icon-field", inputs: ["iconPosition", "styleClass"] }, { kind: "ngmodule", type: InputIconModule }, { kind: "component", type: i10.InputIcon, selector: "p-inputicon, p-inputIcon", inputs: ["styleClass"] }, { kind: "ngmodule", type: MultiSelectModule }, { kind: "component", type: i11$1.MultiSelect, selector: "p-multiSelect, p-multiselect, p-multi-select", inputs: ["id", "ariaLabel", "style", "styleClass", "panelStyle", "panelStyleClass", "inputId", "disabled", "fluid", "readonly", "group", "filter", "filterPlaceHolder", "filterLocale", "overlayVisible", "tabindex", "variant", "appendTo", "dataKey", "name", "ariaLabelledBy", "displaySelectedLabel", "maxSelectedLabels", "selectionLimit", "selectedItemsLabel", "showToggleAll", "emptyFilterMessage", "emptyMessage", "resetFilterOnHide", "dropdownIcon", "chipIcon", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "showHeader", "filterBy", "scrollHeight", "lazy", "virtualScroll", "loading", "virtualScrollItemSize", "loadingIcon", "virtualScrollOptions", "overlayOptions", "ariaFilterLabel", "filterMatchMode", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "autofocusFilter", "display", "autocomplete", "size", "showClear", "autofocus", "autoZIndex", "baseZIndex", "showTransitionOptions", "hideTransitionOptions", "defaultLabel", "placeholder", "options", "filterValue", "itemSize", "selectAll", "focusOnHover", "filterFields", "selectOnFocus", "autoOptionFocus", "highlightOnSelect"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onClear", "onPanelShow", "onPanelHide", "onLazyLoad", "onRemove", "onSelectAllChange"] }, { kind: "ngmodule", type: CheckboxModule }, { kind: "component", type: i9.Checkbox, selector: "p-checkbox, p-checkBox, p-check-box", inputs: ["value", "name", "disabled", "binary", "ariaLabelledBy", "ariaLabel", "tabindex", "inputId", "style", "inputStyle", "styleClass", "inputClass", "indeterminate", "size", "formControl", "checkboxIcon", "readonly", "required", "autofocus", "trueValue", "falseValue", "variant"], outputs: ["onChange", "onFocus", "onBlur"] }, { kind: "ngmodule", type: PaginatorModule }, { kind: "component", type: i13.Paginator, selector: "p-paginator", inputs: ["pageLinkSize", "style", "styleClass", "alwaysShow", "dropdownAppendTo", "templateLeft", "templateRight", "appendTo", "dropdownScrollHeight", "currentPageReportTemplate", "showCurrentPageReport", "showFirstLastIcon", "totalRecords", "rows", "rowsPerPageOptions", "showJumpToPageDropdown", "showJumpToPageInput", "jumpToPageItemTemplate", "showPageLinks", "locale", "dropdownItemTemplate", "first"], outputs: ["onPageChange"] }, { kind: "component", type: TableCell, selector: "ecs-table-cell", inputs: ["col", "rowData", "globalSearchText", "predefinedFiltersCollection", "dateFormat", "dateTimezone", "dateCulture"] }, { kind: "component", type: TablePredefinedFilters, selector: "ecs-table-predefined-filters", inputs: ["option", "col", "selectable", "rowData", "globalSearchText"] }, { kind: "component", type: TableButton, selector: "ecs-table-button", inputs: ["button", "rowData", "isActionButton", "isLastActionButton", "overrideAction"] }, { kind: "component", type: ColumnSelector, selector: "ecs-column-selector", inputs: ["orderByHeader", "visible", "columnModalData", "filteredColumnData"], outputs: ["visibleChange", "applyChanges"] }, { kind: "component", type: ExportExcel, selector: "ecs-export-excel", inputs: ["visible", "rowCheckboxSelectorActive", "excelReportTitle", "allowTitleUserEdit"], outputs: ["exportToExcel", "visibleChange"] }, { kind: "ngmodule", type: ButtonGroupModule }, { kind: "component", type: i14.ButtonGroup, selector: "p-buttonGroup, p-buttongroup, p-button-group" }, { kind: "component", type: ViewsManagement, selector: "ecs-views-management", inputs: ["visible", "tableViews_menuItems"], outputs: ["onViewSelect", "onViewDelete", "onViewUpdateData", "onViewUpdateActiveStartup", "onViewEditAlias", "onViewCreate", "visibleChange"] }, { kind: "ngmodule", type: PopoverModule }, { kind: "component", type: i15.Popover, selector: "p-popover", inputs: ["ariaLabel", "ariaLabelledBy", "dismissable", "style", "styleClass", "appendTo", "autoZIndex", "ariaCloseLabel", "baseZIndex", "focusOnShow", "showTransitionOptions", "hideTransitionOptions"], outputs: ["onShow", "onHide"] }, { kind: "ngmodule", type: MenuModule }, { kind: "component", type: i16.Menu, selector: "p-menu", inputs: ["model", "popup", "style", "styleClass", "appendTo", "autoZIndex", "baseZIndex", "showTransitionOptions", "hideTransitionOptions", "ariaLabel", "ariaLabelledBy", "id", "tabindex"], outputs: ["onShow", "onHide", "onBlur", "onFocus"] }], encapsulation: i0.ViewEncapsulation.None });
2492
2995
  }
2493
2996
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: ECSPrimengTable, decorators: [{
2494
2997
  type: Component,
@@ -2515,7 +3018,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.21", ngImpo
2515
3018
  ViewsManagement,
2516
3019
  PopoverModule,
2517
3020
  MenuModule
2518
- ], standalone: true, encapsulation: ViewEncapsulation.None, template: "<div #tableContainer>\r\n <p-table #dt\r\n size=\"small\" showGridlines stripedRows \r\n sortMode=\"multiple\"\r\n [resizableColumns]=\"true\" columnResizeMode=\"expand\"\r\n [reorderableColumns]=\"true\"\r\n [scrollable]=\"true\" [scrollHeight]=\"scrollHeightValue\"\r\n [columns]=\"tableOptions.columns?.shown ?? []\" [value]=\"tableOptions.data ?? []\" dataKey=\"rowID\" \r\n [paginator]=\"true\" paginatorDropdownAppendTo=\"body\" [first]=\"currentPage * currentRowsPerPage\" [rows]=\"currentRowsPerPage\" [totalRecords]=\"totalRecords\"\r\n [rowsPerPageOptions]=\"allowedRowsPerPage\" [showCurrentPageReport]=\"false\" (onPage)=\"pageChange($event)\"\r\n [metaKeySelection]=\"true\" [selectionMode]=\"tableOptions.rows?.singleSelector?.enabled ? 'single' : null\" [metaKeySelection]=\"tableOptions.rows?.singleSelector?.metakey\" [(selection)]=\"rowSelection\" (onRowSelect)=\"rowSelect($event)\" (onRowUnselect)=\"rowUnselect($event)\"\r\n [lazy]=\"true\" (onLazyLoad)=\"fetchTableData($event)\">\r\n\r\n <!--TEMPLATE FOR THE ACTIONS HEADER COLUMN-->\r\n <ng-template #actionColumnHeaderTemplate>\r\n @if ((tableOptions.rows?.action?.buttons?.length ?? 0) > 0) {\r\n <th [ngStyle]=\"{\r\n 'text-align': 'center',\r\n 'vertical-align': 'middle',\r\n 'max-width': actionColumnWidth + 'px',\r\n 'min-width': actionColumnWidth + 'px',\r\n 'width': actionColumnWidth + 'px'\r\n }\"\r\n pResizableColumn [pResizableColumnDisabled]=\"!tableOptions.rows?.action?.resizable\" pFrozenColumn [frozen]=\"tableOptions.rows?.action?.frozen ?? false\"\r\n [alignFrozen]=\"getFrozenColumnAlignAsText(tableOptions.rows?.action?.positionRight ? FrozenColumnAlign.Right : FrozenColumnAlign.Left)\" id=\"actions-header\"\r\n [attr.scope]=\"'col'\">\r\n {{ (tableOptions.rows?.action?.header ?? '') | ecsTranslate }}\r\n </th>\r\n }\r\n </ng-template>\r\n\r\n <!--TEMPLATE FOR THE ACTIONS ROW COLUMN-->\r\n <ng-template #actionColumnTemplate let-rowData=\"rowData\">\r\n @if ((tableOptions.rows?.action?.buttons?.length ?? 0) > 0) {\r\n <td \r\n [ngStyle]=\"{\r\n 'text-align': (getDataAlignHorizontalAsText(tableOptions.rows?.action?.horizontalAlignment ?? DataAlignHorizontal.Center)),\r\n 'vertical-align': (getDataAlignVerticalAsText(tableOptions.rows?.action?.verticalAlignment ?? DataAlignVertical.Middle)),\r\n 'max-width': actionColumnWidth + 'px',\r\n 'min-width': actionColumnWidth + 'px',\r\n 'width': actionColumnWidth + 'px'\r\n }\"\r\n pFrozenColumn [frozen]=\"tableOptions.rows?.action?.frozen ?? false\"\r\n [alignFrozen]=\"getFrozenColumnAlignAsText(tableOptions.rows?.action?.positionRight ? FrozenColumnAlign.Right : FrozenColumnAlign.Left)\">\r\n @if (compactRows) {\r\n @if (hasRowMenuActions(rowData)) {\r\n <button pButton type=\"button\" icon=\"pi pi-ellipsis-v\" [attr.aria-label]=\"(tableOptions.responsive?.rowMenuLabel || 'Row actions') | ecsTranslate\"\r\n aria-haspopup=\"menu\" [attr.aria-expanded]=\"responsiveRowMenu.visible && rowMenuRow === rowData\"\r\n (click)=\"openRowMenu($event, rowData)\" class=\"ecs-responsive-trigger\"></button>\r\n }\r\n } @else {\r\n @for (button of tableOptions.rows?.action?.buttons; track button; let last = $last) {\r\n <ecs-table-button [button]=\"button\" [rowData]=\"rowData\" [isActionButton]=\"true\" [isLastActionButton]=\"last\"/>\r\n }\r\n }\r\n </td>\r\n }\r\n </ng-template>\r\n\r\n <!-- TEMPLATE FOR THE ROW CHECKBOX SELECTOR HEADER COLUMN -->\r\n <ng-template #rowSelectorColumnHeaderTemplate>\r\n <th \r\n [ngStyle]=\"{\r\n 'text-align': 'center',\r\n 'vertical-align': 'middle',\r\n 'max-width': (tableOptions.rows?.checkboxSelector?.width ?? 150) + 'px',\r\n 'min-width': (tableOptions.rows?.checkboxSelector?.width ?? 150) + 'px',\r\n 'width': (tableOptions.rows?.checkboxSelector?.width ?? 150) + 'px'\r\n }\"\r\n id=\"rowSelector-header\" [attr.scope]=\"'col'\" pResizableColumn [pResizableColumnDisabled]=\"!tableOptions.rows?.checkboxSelector?.resizable\" pFrozenColumn \r\n [frozen]=\"tableOptions.rows?.checkboxSelector?.frozen ?? false\" [alignFrozen]=\"getFrozenColumnAlignAsText(tableOptions.rows?.checkboxSelector?.positionRight ? FrozenColumnAlign.Right : FrozenColumnAlign.Left)\">\r\n <div style=\"display: flex; justify-content: space-between; align-items: center;\">\r\n {{ (tableOptions.rows?.checkboxSelector?.header ?? '') | ecsTranslate }}\r\n <p-columnFilter type=\"boolean\" field=\"selector\" display=\"menu\" [showButtons]=\"false\"/>\r\n </div>\r\n </th>\r\n </ng-template>\r\n\r\n <!--TEMPLATE FOR THE ROW CHECKBOX SELECTOR COLUMN-->\r\n <ng-template #rowSelectorColumnTemplate let-rowData=\"rowData\">\r\n <td \r\n [ngStyle]=\"{\r\n 'text-align': (getDataAlignHorizontalAsText(tableOptions.rows?.checkboxSelector?.horizontalAlignment ?? DataAlignHorizontal.Center)),\r\n 'vertical-align': (getDataAlignVerticalAsText(tableOptions.rows?.checkboxSelector?.verticalAlignment ?? DataAlignVertical.Middle)),\r\n 'max-width': (tableOptions.rows?.checkboxSelector?.width ?? 150) + 'px',\r\n 'min-width': (tableOptions.rows?.checkboxSelector?.width ?? 150) + 'px',\r\n 'width': (tableOptions.rows?.checkboxSelector?.width ?? 150) + 'px'\r\n }\"\r\n pFrozenColumn [frozen]=\"tableOptions.rows?.checkboxSelector?.frozen ?? false\" \r\n [alignFrozen]=\"getFrozenColumnAlignAsText(tableOptions.rows?.checkboxSelector?.positionRight ? FrozenColumnAlign.Right : FrozenColumnAlign.Left)\">\r\n <p-checkbox \r\n [disabled]=\"!(tableOptions.rows?.checkboxSelector?.enabledCondition?.(rowData) ?? true)\"\r\n [binary]=\"true\"\r\n [ngModel]=\"isRowCheckboxSelected(rowData.rowID)\"\r\n (onChange)=\"onRowChekboxChange($event, rowData.rowID)\"/>\r\n </td>\r\n </ng-template>\r\n\r\n\r\n <!-- LOGIC FOR DRAWING TABLE ACTIONS ABOVE THE HEADER -->\r\n <ng-template #caption>\r\n <div #headerContainer [class.ecs-compact-header]=\"compactHeader\" style=\"display: flex; justify-content: space-between; align-items: center;\">\r\n @if (compactHeader) {\r\n @if (tableOptions.globalFilter?.enabled) {\r\n <p-iconField iconPosition=\"left\" class=\"ecs-responsive-search\">\r\n <p-inputIcon><i class=\"pi pi-search\"></i></p-inputIcon>\r\n <input pInputText type=\"text\" [attr.aria-label]=\"'Search keyword' | ecsTranslate\" [placeholder]=\"'Search keyword' | ecsTranslate\" autocomplete=\"off\"\r\n [maxlength]=\"tableOptions.globalFilter?.maxLength ?? null\" [(ngModel)]=\"globalSearchText\"\r\n (input)=\"dt.filterGlobal($any($event.target).value, 'contains')\"/>\r\n @if (globalSearchText) {\r\n <p-inputIcon position=\"right\"><button type=\"button\" class=\"ecs-clear-search\" [attr.aria-label]=\"'Clear search' | ecsTranslate\" (click)=\"clearFilters(dt, true, true)\"><i class=\"pi pi-times\"></i></button></p-inputIcon>\r\n }\r\n </p-iconField>\r\n }\r\n @if (tableOptions.description?.text) {\r\n <i [class]=\"tableOptions.description!.icon\" [pTooltip]=\"(tableOptions.description!.text) | ecsTranslate\" [escape]=\"false\"></i>\r\n }\r\n <button pButton type=\"button\" icon=\"pi pi-bars\" [attr.aria-label]=\"(tableOptions.responsive?.headerMenuLabel || 'Table actions') | ecsTranslate\"\r\n aria-haspopup=\"menu\" [attr.aria-expanded]=\"responsiveHeaderMenu.visible\"\r\n (click)=\"openHeaderMenu($event)\" class=\"ecs-responsive-trigger ecs-header-menu-trigger\"></button>\r\n } @else {\r\n\r\n <div style=\"display: flex; align-items: center; gap: 10px;\">\r\n <!--CHOOSE COLUMNS TO SHOW-->\r\n @if (tableOptions.columns?.selectorEnabled) {\r\n <p-button [icon]=\"tableOptions.columns?.selectorIcon ?? 'pi pi-pen-to-square'\" (onClick)=\"columnSelectorShow()\" [pTooltip]=\"'Modify columns' | ecsTranslate\"\r\n [showDelay]=\"700\" tooltipPosition=\"top\" styleClass=\"p-button-icon-only\"/>\r\n }\r\n <!--CLEAR SORTS AND FILTERS-->\r\n @if (tableOptions.header?.clearSortsEnabled) {\r\n <p-button [icon]=\"tableOptions.header?.clearSortsIcon ?? 'pi pi-sort-alt-slash'\" (onClick)=\"clearSorts(dt)\" [disabled]=\"!hasToClearSorts(dt)\"\r\n [pTooltip]=\"'Clear sorts' | ecsTranslate\" [showDelay]=\"700\" tooltipPosition=\"top\" styleClass=\"p-button-icon-only\"/>\r\n }\r\n @if (tableOptions.header?.clearFiltersEnabled) {\r\n <p-button\r\n [icon]=\"tableOptions.header?.clearFiltersIcon ?? 'pi pi-filter-slash'\" (onClick)=\"clearFilters(dt)\" [disabled]=\"!hasToClearFilters(dt, globalSearchText)\"\r\n [pTooltip]=\"'Clear filters' | ecsTranslate\" [showDelay]=\"700\" tooltipPosition=\"top\" styleClass=\"p-button-icon-only\"/>\r\n }\r\n\r\n <!--TABLE DESCRIPTION-->\r\n @if(tableOptions.description?.text){ <!-- If a table description text is provided -->\r\n @if(!tableOptions.description!.tooltip){ <!-- The table description must be shown as text next to the icon -->\r\n <i [class]=\"tableOptions.description!.icon\"></i>\r\n <span [innerHTML]=\"(tableOptions.description!.text) | ecsTranslate\"></span>\r\n } @else {\r\n <i [escape]=\"false\" [pTooltip]=\"(tableOptions.description!.text) | ecsTranslate\" tooltipPosition=\"right\" [class]=\"tableOptions.description!.icon\"></i>\r\n }\r\n }\r\n </div>\r\n\r\n <!--TABLE VIEWS-->\r\n @if(tableViewsEnabled()){\r\n <div style=\"display: flex; align-items: center; gap: 10px;\">\r\n <p-buttongroup>\r\n <p-button (click)=\"viewsModalShow=true;\"\r\n [label]=\"tableViewCurrentSelectedAlias \r\n ? tableViewCurrentSelectedAlias \r\n : ((tableOptions.views?.noViewSelectedText || '--- Select a view ---') | ecsTranslate)\"\r\n [class]=\"'viewButton' + (tableOptions.views?.selectViewButtonClass ? ' ' + tableOptions.views!.selectViewButtonClass : '')\"/>\r\n <p-button (click)=\"viewLoad(tableViewCurrentSelectedAlias!)\" [disabled]=\"!tableViewCurrentSelectedAlias\" [pTooltip]=\"'Apply view again' | ecsTranslate\" [showDelay]=\"700\" tooltipPosition=\"top\"\r\n [icon]=\"tableOptions.views?.reloadViewButtonIcon || 'pi pi-refresh'\"\r\n [class]=\"tableOptions.views?.reloadViewButtonClass || ''\"/>\r\n </p-buttongroup>\r\n </div>\r\n }\r\n\r\n <div style=\"display: flex; align-items: center; gap: 10px;\">\r\n <!--GLOBAL FILTER-->\r\n @if (tableOptions.globalFilter?.enabled) {\r\n <p-iconField iconPosition=\"left\" class=\"ml-auto\" [ngClass]=\"{'p-input-icon-right': globalSearchText}\">\r\n <p-inputIcon>\r\n <i class=\"pi pi-search\"></i>\r\n </p-inputIcon>\r\n <input pInputText type=\"text\" \r\n (input)=\"dt.filterGlobal($any($event.target).value, 'contains')\" autocomplete=\"off\" \r\n [maxlength]=\"tableOptions.globalFilter?.maxLength ?? null\" [placeholder]=\"'Search keyword' | ecsTranslate\" [(ngModel)]=\"globalSearchText\"\r\n style=\"width: 220px;\"/>\r\n <!-- Right icon (only if there is text) -->\r\n @if (globalSearchText) {\r\n <p-inputIcon position=\"right\">\r\n <i class=\"pi pi-times\" style=\"cursor: pointer;\" (click)=\"clearFilters(dt, true, true); $event.stopPropagation()\"></i>\r\n </p-inputIcon>\r\n }\r\n </p-iconField>\r\n }\r\n\r\n <!--EXPORT DATA-->\r\n @if (tableOptions.excelReport?.url?.trim()) {\r\n <p-button icon=\"pi pi-file-excel\" (onClick)=\"openExcelExport()\"\r\n [pTooltip]=\"'Export to Excel' | ecsTranslate\" [showDelay]=\"700\" tooltipPosition=\"top\" styleClass=\"p-button-icon-only\"/>\r\n }\r\n\r\n <!--RESET TABLE VIEW-->\r\n @if(tableOptions.resetTableView?.enabled){\r\n <p-button [icon]=\"tableOptions.resetTableView?.icon ?? 'pi pi-eraser'\" (click)=\"resetTableView()\" [pTooltip]=\"'Reset table view' | ecsTranslate\" [showDelay]=\"700\"\r\n tooltipPosition=\"top\" styleClass=\"p-button-icon-only\"/>\r\n }\r\n\r\n <!--REFRESH DATA-->\r\n <p-button icon=\"pi pi-refresh\" (onClick)=\"refreshData($event)\" [pTooltip]=\"'Refresh data' | ecsTranslate\" [showDelay]=\"700\"\r\n tooltipPosition=\"top\" styleClass=\"p-button-icon-only\"/>\r\n \r\n <!-- HEADER ACTION BUTTONS -->\r\n @if ((tableOptions.header?.buttons?.length ?? 0) > 0) {\r\n <td style=\"display: flex; justify-content: center; align-items: center; gap: 10px;\">\r\n @for (button of tableOptions.header?.buttons; track $index) {\r\n <ecs-table-button [button]=\"button\" [rowData]=\"null\"/>\r\n }\r\n </td>\r\n }\r\n </div>\r\n }\r\n </div>\r\n </ng-template>\r\n\r\n <!-- LOGIC FOR DRAWING TABLE HEADERS -->\r\n <ng-template #header let-columns>\r\n <tr>\r\n @if (!tableOptions.rows?.action?.positionRight) {\r\n <ng-container *ngTemplateOutlet=\"actionColumnHeaderTemplate\"></ng-container>\r\n }\r\n @if (tableOptions.rows?.checkboxSelector?.enabled && !tableOptions.rows?.checkboxSelector?.positionRight) {\r\n <ng-container [ngTemplateOutlet]=\"rowSelectorColumnHeaderTemplate\"></ng-container>\r\n }\r\n @for (col of columns; track col.header) {\r\n <th [ngStyle]=\"getColumnStyle(col, true)\"\r\n pResizableColumn [pResizableColumnDisabled]=\"!col.canBeResized ? true : false\"\r\n pReorderableColumn [pReorderableColumnDisabled]=\"!col.canBeReordered ? true : false\"\r\n pFrozenColumn [frozen]=\"col.frozenColumnAlign === FrozenColumnAlign.Left || col.frozenColumnAlign === FrozenColumnAlign.Right\" [alignFrozen]=\"getFrozenColumnAlignAsText(col.frozenColumnAlign)\"\r\n [pSortableColumn]=\"col.field\" [pSortableColumnDisabled]=\"!col.canBeSorted ? true : false\"\r\n style=\"text-align: center;\"\r\n [id]=\"col.field + '-header'\" [attr.scope]=\"'col'\">\r\n <div style=\"display: flex; justify-content: space-between; align-items: center; width: 100%;\">\r\n <div style=\"margin-right: 15px;\">\r\n <span>{{ col.header | translate }}</span>\r\n </div>\r\n <div style=\"display: flex; align-items: center; gap: 5px;\">\r\n @if (col.canBeSorted) {\r\n <p-sortIcon [field]=\"col.field\"></p-sortIcon>\r\n }\r\n @if(col.canBeFiltered){\r\n @if (!col.filterPredefinedValuesName || col.filterPredefinedValuesName.length === 0) {\r\n <p-columnFilter [type]=\"getDataTypeAsText(col.dataType)\" [field]=\"col.field\" display=\"menu\" [showButtons]=\"false\"/>\r\n } @else {\r\n <p-columnFilter\r\n [type]=\"getDataTypeAsText(col.dataType)\" [field]=\"col.field\" display=\"menu\"\r\n [showButtons]=\"false\" matchMode=\"in\" operator=\"or\" [showMatchModes]=\"false\"\r\n [showOperator]=\"false\" [showAddButton]=\"false\" [showClearButton]=\"false\" [showApplyButton]=\"false\">\r\n <ng-template #filter>\r\n <p-multiSelect\r\n [style]=\"{ minWidth: '400px' }\" [(ngModel)]=\"predefinedFiltersSelectedValuesCollection[col.filterPredefinedValuesName]\"\r\n [options]=\"getPredefinedFilterValues(col.filterPredefinedValuesName)\" [placeholder]=\"'Any value' | ecsTranslate\"\r\n (onChange)=\"onPredefinedFilterChange(col.field, $event.value)\" optionLabel=\"name\">\r\n <ng-template #item let-option >\r\n <div style=\"display: inline-block; vertical-align: middle;\">\r\n <ecs-table-predefined-filters [option]=\"option\" [col]=\"col\" [selectable]=\"false\" [rowData]=\"null\"/>\r\n </div>\r\n </ng-template>\r\n </p-multiSelect>\r\n </ng-template>\r\n </p-columnFilter>\r\n }\r\n }\r\n @if (col.columnDescription && col.columnDescription.length > 0) {\r\n <i [pTooltip]=\"(col.columnDescription) | ecsTranslate\" tooltipPosition=\"top\" [class]=\"tableOptions.columnDescriptionIcon || 'pi pi-info-circle'\"></i>\r\n }\r\n </div>\r\n </div>\r\n </th>\r\n }\r\n @if (tableOptions.rows?.checkboxSelector?.enabled && tableOptions.rows?.checkboxSelector?.positionRight) {\r\n <ng-container [ngTemplateOutlet]=\"rowSelectorColumnHeaderTemplate\"></ng-container>\r\n }\r\n @if (tableOptions.rows?.action?.positionRight) {\r\n <ng-container *ngTemplateOutlet=\"actionColumnHeaderTemplate\"></ng-container>\r\n }\r\n </tr>\r\n </ng-template>\r\n\r\n <!-- LOGIC FOR DRAWING TABLE DATA WHEN THERE IS CONTENTS -->\r\n <ng-template #body let-rowData let-columns=\"columns\"> \r\n <tr [pSelectableRow]=\"rowData\" [ngClass]=\"tableOptions.rows?.class?.(rowData)\" [ngStyle]=\"tableOptions.rows?.style?.(rowData)\">\r\n @if (!tableOptions.rows?.action?.positionRight) {\r\n <ng-container *ngTemplateOutlet=\"actionColumnTemplate; context: { rowData: rowData }\"></ng-container>\r\n }\r\n @if (tableOptions.rows?.checkboxSelector?.enabled && !tableOptions.rows?.checkboxSelector?.positionRight) {\r\n <ng-container [ngTemplateOutlet]=\"rowSelectorColumnTemplate\" [ngTemplateOutletContext]=\"{ rowData: rowData }\"></ng-container>\r\n }\r\n @for (col of columns; track col.field) {\r\n <td (mousedown)=\"col.dataType !== DataType.Boolean && copyToClipboardStart($event)\" (mouseup)=\"copyToClipboardCancel()\"\r\n [ngStyle]=\"getColumnStyle(col)\" pFrozenColumn [frozen]=\"col.frozenColumnAlign === FrozenColumnAlign.Left || col.frozenColumnAlign === FrozenColumnAlign.Right\" \r\n [alignFrozen]=\"getFrozenColumnAlignAsText(col.frozenColumnAlign)\" [style.text-align]=\"getDataAlignHorizontalAsText(col.dataAlignHorizontal)\" [style.vertical-align]=\"getDataAlignVerticalAsText(col.dataAlignVertical)\">\r\n <ecs-table-cell [col]=\"col\" [rowData]=\"rowData\" [globalSearchText]=\"globalSearchText\" \r\n [dateFormat]=\"dateFormat\" [dateTimezone]=\"dateTimezone\" [dateCulture]=\"dateCulture\"\r\n [predefinedFiltersCollection]=\"tableOptions.predefinedFilters\"/>\r\n </td>\r\n }\r\n @if (tableOptions.rows?.checkboxSelector?.enabled && tableOptions.rows?.checkboxSelector?.positionRight) {\r\n <ng-container [ngTemplateOutlet]=\"rowSelectorColumnTemplate\" [ngTemplateOutletContext]=\"{ rowData: rowData }\"></ng-container>\r\n }\r\n @if (tableOptions.rows?.action?.positionRight) {\r\n <ng-container *ngTemplateOutlet=\"actionColumnTemplate; context: { rowData: rowData }\"></ng-container>\r\n }\r\n </tr>\r\n </ng-template>\r\n\r\n <!-- LOGIC FOR DRAWING TABLE DATA WHEN THERE IS NO CONTENTS -->\r\n <ng-template #emptymessage>\r\n <tr>\r\n <td colspan=\"999\">{{ 'No data found for the current filter criteria.' | ecsTranslate }}</td>\r\n </tr>\r\n </ng-template>\r\n\r\n <!-- SHOW CUSTOM RECORDS REPORT -->\r\n <ng-template #paginatorleft>\r\n <div #paginatorContainer>\r\n <div style=\"display: flex; align-items: center; gap: 10px;\">\r\n @if(tableOptions.legend?.content){\r\n <ecs-table-button [button]=\"tableOptions.legend?.button\" [rowData]=\"null\" [overrideAction]=\"op.toggle.bind(op)\"/>\r\n <p-popover #op>\r\n <div [innerHTML]=\"(tableOptions.legend?.content) | ecsTranslate\"></div>\r\n </p-popover>\r\n }\r\n <span>{{ 'Showing {{count}} records of {{total}} available records' | ecsTranslate: { count: totalRecords, total: totalRecordsNotFiltered } }}</span>\r\n </div>\r\n </div>\r\n </ng-template>\r\n </p-table>\r\n</div>\r\n<ecs-column-selector [visible]=\"showColumnSelector\" [columnModalData]=\"columnModalData\" [filteredColumnData]=\"filteredColumnData\" [orderByHeader]=\"tableOptions.columns?.selectorOrderByColumnName === true\" (visibleChange)=\"showColumnSelector=false\" (applyChanges)=\"applyColumnModalChanges($event)\"/>\r\n<ecs-export-excel [visible]=\"showExportModal\" [rowCheckboxSelectorActive]=\"tableOptions.rows?.checkboxSelector?.enabled ?? false\" [excelReportTitle]=\"excelReportTitle\" [allowTitleUserEdit]=\"tableOptions.excelReport?.titleAllowUserEdit ?? false\" (visibleChange)=\"showExportModal=false\" (exportToExcel)=\"generateExcelReport($event)\"/>\r\n<ecs-views-management [visible]=\"viewsModalShow\" [tableViews_menuItems]=\"tableViews_menuItems\" \r\n (onViewSelect)=\"viewLoad($event)\" (onViewCreate)=\"viewCreate($event)\" (onViewDelete)=\"viewDelete($event)\" (onViewEditAlias)=\"viewEditAlias($event)\" (onViewUpdateData)=\"viewUpdateData($event)\" (onViewUpdateActiveStartup)=\"viewUpdateActiveStartup($event)\"\r\n (visibleChange)=\"viewsModalShow=false\"/>\r\n<!-- Body-level overlays avoid clipping inside scrollable and frozen table cells. -->\r\n<p-menu #responsiveHeaderMenu [model]=\"headerMenuItems\" [popup]=\"true\" appendTo=\"body\" styleClass=\"ecs-responsive-menu\"/>\r\n<p-menu #responsiveRowMenu [model]=\"rowMenuItems\" [popup]=\"true\" appendTo=\"body\" styleClass=\"ecs-responsive-menu\"/>\r\n", styles: [".highlighted-text{background-color:#ff0;color:#000;border-radius:2px}.excel-export-tooltip .bool-icon{text-shadow:0 0 2px white,0 0 3px white}.excel-export-tooltip .bool-true{color:green}.excel-export-tooltip .bool-false{color:red}.p-datatable-column-filter-button.p-button-icon-only.p-button-rounded,.p-datatable-column-filter-clear-button.p-button-icon-only.p-button-rounded{height:var(--p-icon-size)!important;width:var(--p-icon-size)!important;border-radius:0!important}.viewButton{width:200px}.viewButton .p-button{width:100%;justify-content:center}.viewButton .p-button-label{display:block;width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;text-align:center}.ecs-compact-header{gap:.5rem;min-width:0}.ecs-header-menu-trigger{margin-left:auto;flex:0 0 auto}.ecs-responsive-trigger{min-width:44px;min-height:44px}.ecs-responsive-search{flex:1 1 220px;min-width:0;max-width:320px}.ecs-responsive-search input{width:100%;padding-right:2.5rem}.ecs-clear-search{border:0;background:transparent;color:inherit;cursor:pointer}.ecs-responsive-menu{max-width:calc(100vw - 16px);max-height:calc(100dvh - 32px);overflow-y:auto}.ecs-responsive-menu .p-menu-item-link{min-height:44px;white-space:normal}\n"] }]
3021
+ ], standalone: true, encapsulation: ViewEncapsulation.None, template: "<div #tableContainer>\r\n <p-table #dt\r\n size=\"small\" showGridlines stripedRows \r\n sortMode=\"multiple\"\r\n [resizableColumns]=\"true\" columnResizeMode=\"expand\"\r\n [reorderableColumns]=\"true\"\r\n [scrollable]=\"true\" [scrollHeight]=\"scrollHeightValue\"\r\n [columns]=\"tableOptions.columns?.shown ?? []\" [value]=\"tableOptions.data ?? []\" dataKey=\"rowID\" \r\n [paginator]=\"!treeState\" [loading]=\"treeState?.loading ?? false\" paginatorDropdownAppendTo=\"body\" [first]=\"currentPage * currentRowsPerPage\" [rows]=\"currentRowsPerPage\" [totalRecords]=\"totalRecords\"\r\n [rowsPerPageOptions]=\"allowedRowsPerPage\" [showCurrentPageReport]=\"false\" (onPage)=\"pageChange($event)\"\r\n [metaKeySelection]=\"true\" [selectionMode]=\"tableOptions.rows?.singleSelector?.enabled ? 'single' : null\" [metaKeySelection]=\"tableOptions.rows?.singleSelector?.metakey\" [(selection)]=\"rowSelection\" (onRowSelect)=\"rowSelect($event)\" (onRowUnselect)=\"rowUnselect($event)\"\r\n [lazy]=\"true\" (onLazyLoad)=\"fetchTableData($event)\">\r\n\r\n <!--TEMPLATE FOR THE ACTIONS HEADER COLUMN-->\r\n <ng-template #actionColumnHeaderTemplate>\r\n @if ((tableOptions.rows?.action?.buttons?.length ?? 0) > 0) {\r\n <th [ngStyle]=\"{\r\n 'text-align': 'center',\r\n 'vertical-align': 'middle',\r\n 'max-width': actionColumnWidth + 'px',\r\n 'min-width': actionColumnWidth + 'px',\r\n 'width': actionColumnWidth + 'px'\r\n }\"\r\n pResizableColumn [pResizableColumnDisabled]=\"!tableOptions.rows?.action?.resizable\" pFrozenColumn [frozen]=\"tableOptions.rows?.action?.frozen ?? false\"\r\n [alignFrozen]=\"getFrozenColumnAlignAsText(tableOptions.rows?.action?.positionRight ? FrozenColumnAlign.Right : FrozenColumnAlign.Left)\" id=\"actions-header\"\r\n [attr.scope]=\"'col'\">\r\n {{ (tableOptions.rows?.action?.header ?? '') | ecsTranslate }}\r\n </th>\r\n }\r\n </ng-template>\r\n\r\n <!--TEMPLATE FOR THE ACTIONS ROW COLUMN-->\r\n <ng-template #actionColumnTemplate let-rowData=\"rowData\">\r\n @if ((tableOptions.rows?.action?.buttons?.length ?? 0) > 0) {\r\n <td \r\n [ngStyle]=\"{\r\n 'text-align': (getDataAlignHorizontalAsText(tableOptions.rows?.action?.horizontalAlignment ?? DataAlignHorizontal.Center)),\r\n 'vertical-align': (getDataAlignVerticalAsText(tableOptions.rows?.action?.verticalAlignment ?? DataAlignVertical.Middle)),\r\n 'max-width': actionColumnWidth + 'px',\r\n 'min-width': actionColumnWidth + 'px',\r\n 'width': actionColumnWidth + 'px'\r\n }\"\r\n pFrozenColumn [frozen]=\"tableOptions.rows?.action?.frozen ?? false\"\r\n [alignFrozen]=\"getFrozenColumnAlignAsText(tableOptions.rows?.action?.positionRight ? FrozenColumnAlign.Right : FrozenColumnAlign.Left)\">\r\n @if (compactRows) {\r\n @if (hasRowMenuActions(rowData)) {\r\n <button pButton type=\"button\" icon=\"pi pi-ellipsis-v\" [attr.aria-label]=\"(tableOptions.responsive?.rowMenuLabel || 'Row actions') | ecsTranslate\"\r\n aria-haspopup=\"menu\" [attr.aria-expanded]=\"responsiveRowMenu.visible && rowMenuRow === rowData\"\r\n (click)=\"openRowMenu($event, rowData)\" class=\"ecs-responsive-trigger\"></button>\r\n }\r\n } @else {\r\n @for (button of tableOptions.rows?.action?.buttons; track button; let last = $last) {\r\n <ecs-table-button [button]=\"button\" [rowData]=\"rowData\" [isActionButton]=\"true\" [isLastActionButton]=\"last\"/>\r\n }\r\n }\r\n </td>\r\n }\r\n </ng-template>\r\n\r\n <!-- TEMPLATE FOR THE ROW CHECKBOX SELECTOR HEADER COLUMN -->\r\n <ng-template #rowSelectorColumnHeaderTemplate>\r\n <th \r\n [ngStyle]=\"{\r\n 'text-align': 'center',\r\n 'vertical-align': 'middle',\r\n 'max-width': (tableOptions.rows?.checkboxSelector?.width ?? 150) + 'px',\r\n 'min-width': (tableOptions.rows?.checkboxSelector?.width ?? 150) + 'px',\r\n 'width': (tableOptions.rows?.checkboxSelector?.width ?? 150) + 'px'\r\n }\"\r\n id=\"rowSelector-header\" [attr.scope]=\"'col'\" pResizableColumn [pResizableColumnDisabled]=\"!tableOptions.rows?.checkboxSelector?.resizable\" pFrozenColumn \r\n [frozen]=\"tableOptions.rows?.checkboxSelector?.frozen ?? false\" [alignFrozen]=\"getFrozenColumnAlignAsText(tableOptions.rows?.checkboxSelector?.positionRight ? FrozenColumnAlign.Right : FrozenColumnAlign.Left)\">\r\n <div style=\"display: flex; justify-content: space-between; align-items: center;\">\r\n @if (tableOptions.rows?.checkboxSelector?.selectAllEnabled) {\r\n <p-checkbox [binary]=\"true\" [ngModel]=\"allMatchingRowsSelected\"\r\n [indeterminate]=\"matchingRowsPartiallySelected\"\r\n [disabled]=\"selectAllLoading || !tableOptions.rows?.checkboxSelector?.urlSelectAll\"\r\n [ariaLabel]=\"'Select all filtered rows' | ecsTranslate\"\r\n [pTooltip]=\"'Select all filtered rows' | ecsTranslate\"\r\n (onChange)=\"toggleAllMatchingRows($event.checked)\"/>\r\n }\r\n {{ (tableOptions.rows?.checkboxSelector?.header ?? '') | ecsTranslate }}\r\n <p-columnFilter type=\"boolean\" field=\"selector\" display=\"menu\" [showButtons]=\"false\"/>\r\n </div>\r\n </th>\r\n </ng-template>\r\n\r\n <!--TEMPLATE FOR THE ROW CHECKBOX SELECTOR COLUMN-->\r\n <ng-template #rowSelectorColumnTemplate let-rowData=\"rowData\">\r\n <td \r\n [ngStyle]=\"{\r\n 'text-align': (getDataAlignHorizontalAsText(tableOptions.rows?.checkboxSelector?.horizontalAlignment ?? DataAlignHorizontal.Center)),\r\n 'vertical-align': (getDataAlignVerticalAsText(tableOptions.rows?.checkboxSelector?.verticalAlignment ?? DataAlignVertical.Middle)),\r\n 'max-width': (tableOptions.rows?.checkboxSelector?.width ?? 150) + 'px',\r\n 'min-width': (tableOptions.rows?.checkboxSelector?.width ?? 150) + 'px',\r\n 'width': (tableOptions.rows?.checkboxSelector?.width ?? 150) + 'px'\r\n }\"\r\n pFrozenColumn [frozen]=\"tableOptions.rows?.checkboxSelector?.frozen ?? false\" \r\n [alignFrozen]=\"getFrozenColumnAlignAsText(tableOptions.rows?.checkboxSelector?.positionRight ? FrozenColumnAlign.Right : FrozenColumnAlign.Left)\">\r\n <p-checkbox \r\n [disabled]=\"!(tableOptions.rows?.checkboxSelector?.enabledCondition?.(rowData) ?? true)\"\r\n [binary]=\"true\"\r\n [ngModel]=\"isRowCheckboxSelected(rowData.rowID)\"\r\n (onChange)=\"onRowChekboxChange($event, rowData.rowID)\"/>\r\n </td>\r\n </ng-template>\r\n\r\n\r\n <!-- LOGIC FOR DRAWING TABLE ACTIONS ABOVE THE HEADER -->\r\n <ng-template #caption>\r\n <div #headerContainer [class.ecs-compact-header]=\"compactHeader\" style=\"display: flex; justify-content: space-between; align-items: center;\">\r\n @if (compactHeader) {\r\n @if (tableOptions.globalFilter?.enabled) {\r\n <p-iconField iconPosition=\"left\" class=\"ecs-responsive-search\">\r\n <p-inputIcon><i class=\"pi pi-search\"></i></p-inputIcon>\r\n <input pInputText type=\"text\" [attr.aria-label]=\"'Search keyword' | ecsTranslate\" [placeholder]=\"'Search keyword' | ecsTranslate\" autocomplete=\"off\"\r\n [maxlength]=\"tableOptions.globalFilter?.maxLength ?? null\" [ngModel]=\"globalSearchText\"\r\n (ngModelChange)=\"onGlobalSearchInput($event)\"/>\r\n @if (globalSearchText) {\r\n <p-inputIcon position=\"right\"><button type=\"button\" class=\"ecs-clear-search\" [attr.aria-label]=\"'Clear search' | ecsTranslate\" (click)=\"clearFilters(dt, true, true)\"><i class=\"pi pi-times\"></i></button></p-inputIcon>\r\n }\r\n </p-iconField>\r\n }\r\n @if (tableOptions.description?.text) {\r\n <i [class]=\"tableOptions.description!.icon\" [pTooltip]=\"(tableOptions.description!.text) | ecsTranslate\" [escape]=\"false\"></i>\r\n }\r\n <button pButton type=\"button\" icon=\"pi pi-bars\" [attr.aria-label]=\"(tableOptions.responsive?.headerMenuLabel || 'Table actions') | ecsTranslate\"\r\n aria-haspopup=\"menu\" [attr.aria-expanded]=\"responsiveHeaderMenu.visible\"\r\n (click)=\"openHeaderMenu($event)\" class=\"ecs-responsive-trigger ecs-header-menu-trigger\"></button>\r\n } @else {\r\n\r\n <div style=\"display: flex; align-items: center; gap: 10px;\">\r\n <!--CHOOSE COLUMNS TO SHOW-->\r\n @if (tableOptions.columns?.selectorEnabled) {\r\n <p-button [icon]=\"tableOptions.columns?.selectorIcon ?? 'pi pi-pen-to-square'\" (onClick)=\"columnSelectorShow()\" [pTooltip]=\"'Modify columns' | ecsTranslate\"\r\n [showDelay]=\"700\" tooltipPosition=\"top\" styleClass=\"p-button-icon-only\"/>\r\n }\r\n <!--CLEAR SORTS AND FILTERS-->\r\n @if (tableOptions.header?.clearSortsEnabled) {\r\n <p-button [icon]=\"tableOptions.header?.clearSortsIcon ?? 'pi pi-sort-alt-slash'\" (onClick)=\"clearSorts(dt)\" [disabled]=\"!hasToClearSorts(dt)\"\r\n [pTooltip]=\"'Clear sorts' | ecsTranslate\" [showDelay]=\"700\" tooltipPosition=\"top\" styleClass=\"p-button-icon-only\"/>\r\n }\r\n @if (tableOptions.header?.clearFiltersEnabled) {\r\n <p-button\r\n [icon]=\"tableOptions.header?.clearFiltersIcon ?? 'pi pi-filter-slash'\" (onClick)=\"clearFilters(dt)\" [disabled]=\"!hasToClearFilters(dt, globalSearchText)\"\r\n [pTooltip]=\"'Clear filters' | ecsTranslate\" [showDelay]=\"700\" tooltipPosition=\"top\" styleClass=\"p-button-icon-only\"/>\r\n }\r\n\r\n <!--TABLE DESCRIPTION-->\r\n @if(tableOptions.description?.text){ <!-- If a table description text is provided -->\r\n @if(!tableOptions.description!.tooltip){ <!-- The table description must be shown as text next to the icon -->\r\n <i [class]=\"tableOptions.description!.icon\"></i>\r\n <span [innerHTML]=\"(tableOptions.description!.text) | ecsTranslate\"></span>\r\n } @else {\r\n <i [escape]=\"false\" [pTooltip]=\"(tableOptions.description!.text) | ecsTranslate\" tooltipPosition=\"right\" [class]=\"tableOptions.description!.icon\"></i>\r\n }\r\n }\r\n </div>\r\n\r\n <!--TABLE VIEWS-->\r\n @if(tableViewsEnabled()){\r\n <div style=\"display: flex; align-items: center; gap: 10px;\">\r\n <p-buttongroup>\r\n <p-button (click)=\"viewsModalShow=true;\"\r\n [label]=\"tableViewCurrentSelectedAlias \r\n ? tableViewCurrentSelectedAlias \r\n : ((tableOptions.views?.noViewSelectedText || '--- Select a view ---') | ecsTranslate)\"\r\n [class]=\"'viewButton' + (tableOptions.views?.selectViewButtonClass ? ' ' + tableOptions.views!.selectViewButtonClass : '')\"/>\r\n <p-button (click)=\"viewLoad(tableViewCurrentSelectedAlias!)\" [disabled]=\"!tableViewCurrentSelectedAlias\" [pTooltip]=\"'Apply view again' | ecsTranslate\" [showDelay]=\"700\" tooltipPosition=\"top\"\r\n [icon]=\"tableOptions.views?.reloadViewButtonIcon || 'pi pi-refresh'\"\r\n [class]=\"tableOptions.views?.reloadViewButtonClass || ''\"/>\r\n </p-buttongroup>\r\n </div>\r\n }\r\n\r\n <div style=\"display: flex; align-items: center; gap: 10px;\">\r\n <!--GLOBAL FILTER-->\r\n @if (tableOptions.globalFilter?.enabled) {\r\n <p-iconField iconPosition=\"left\" class=\"ml-auto\" [ngClass]=\"{'p-input-icon-right': globalSearchText}\">\r\n <p-inputIcon>\r\n <i class=\"pi pi-search\"></i>\r\n </p-inputIcon>\r\n <input pInputText type=\"text\" \r\n (ngModelChange)=\"onGlobalSearchInput($event)\" autocomplete=\"off\"\r\n [maxlength]=\"tableOptions.globalFilter?.maxLength ?? null\" [placeholder]=\"'Search keyword' | ecsTranslate\" [ngModel]=\"globalSearchText\"\r\n style=\"width: 220px;\"/>\r\n <!-- Right icon (only if there is text) -->\r\n @if (globalSearchText) {\r\n <p-inputIcon position=\"right\">\r\n <i class=\"pi pi-times\" style=\"cursor: pointer;\" (click)=\"clearFilters(dt, true, true); $event.stopPropagation()\"></i>\r\n </p-inputIcon>\r\n }\r\n </p-iconField>\r\n }\r\n\r\n <!--EXPORT DATA-->\r\n @if (tableOptions.excelReport?.url?.trim()) {\r\n <p-button icon=\"pi pi-file-excel\" (onClick)=\"openExcelExport()\"\r\n [pTooltip]=\"'Export to Excel' | ecsTranslate\" [showDelay]=\"700\" tooltipPosition=\"top\" styleClass=\"p-button-icon-only\"/>\r\n }\r\n\r\n <!--RESET TABLE VIEW-->\r\n @if(tableOptions.resetTableView?.enabled){\r\n <p-button [icon]=\"tableOptions.resetTableView?.icon ?? 'pi pi-eraser'\" (click)=\"resetTableView()\" [pTooltip]=\"'Reset table view' | ecsTranslate\" [showDelay]=\"700\"\r\n tooltipPosition=\"top\" styleClass=\"p-button-icon-only\"/>\r\n }\r\n\r\n <!--REFRESH DATA-->\r\n <p-button icon=\"pi pi-refresh\" (onClick)=\"refreshData($event)\" [pTooltip]=\"'Refresh data' | ecsTranslate\" [showDelay]=\"700\"\r\n tooltipPosition=\"top\" styleClass=\"p-button-icon-only\"/>\r\n \r\n <!-- HEADER ACTION BUTTONS -->\r\n @if ((tableOptions.header?.buttons?.length ?? 0) > 0) {\r\n <td style=\"display: flex; justify-content: center; align-items: center; gap: 10px;\">\r\n @for (button of tableOptions.header?.buttons; track $index) {\r\n <ecs-table-button [button]=\"button\" [rowData]=\"null\"/>\r\n }\r\n </td>\r\n }\r\n </div>\r\n }\r\n </div>\r\n </ng-template>\r\n\r\n <!-- LOGIC FOR DRAWING TABLE HEADERS -->\r\n <ng-template #header let-columns>\r\n @let headerGroups = getColumnHeaderGroups(columns);\r\n @if (headerGroups.length) {\r\n <tr class=\"ecs-column-groups\">\r\n @if ((tableOptions.rows?.action?.buttons?.length ?? 0) > 0 && !tableOptions.rows?.action?.positionRight) {\r\n <td aria-hidden=\"true\" pFrozenColumn [frozen]=\"tableOptions.rows?.action?.frozen ?? false\" alignFrozen=\"left\"\r\n [style.width.px]=\"actionColumnWidth\" [style.min-width.px]=\"actionColumnWidth\"></td>\r\n }\r\n @if (tableOptions.rows?.checkboxSelector?.enabled && !tableOptions.rows?.checkboxSelector?.positionRight) {\r\n <td aria-hidden=\"true\" pFrozenColumn [frozen]=\"tableOptions.rows?.checkboxSelector?.frozen ?? false\" alignFrozen=\"left\"\r\n [style.width.px]=\"tableOptions.rows?.checkboxSelector?.width ?? 150\" [style.min-width.px]=\"tableOptions.rows?.checkboxSelector?.width ?? 150\"></td>\r\n }\r\n @for (group of headerGroups; track group.field) {\r\n <td [attr.colspan]=\"group.colspan\" role=\"columnheader\" [attr.aria-colspan]=\"group.colspan\" style=\"text-align: center; vertical-align: middle;\"\r\n pFrozenColumn [frozen]=\"group.frozenColumnAlign !== FrozenColumnAlign.Noone\"\r\n [alignFrozen]=\"getFrozenColumnAlignAsText(group.frozenColumnAlign)\">\r\n {{ group.label | translate }}\r\n </td>\r\n }\r\n @if (tableOptions.rows?.checkboxSelector?.enabled && tableOptions.rows?.checkboxSelector?.positionRight) {\r\n <td aria-hidden=\"true\" pFrozenColumn [frozen]=\"tableOptions.rows?.checkboxSelector?.frozen ?? false\" alignFrozen=\"right\"\r\n [style.width.px]=\"tableOptions.rows?.checkboxSelector?.width ?? 150\" [style.min-width.px]=\"tableOptions.rows?.checkboxSelector?.width ?? 150\"></td>\r\n }\r\n @if ((tableOptions.rows?.action?.buttons?.length ?? 0) > 0 && tableOptions.rows?.action?.positionRight) {\r\n <td aria-hidden=\"true\" pFrozenColumn [frozen]=\"tableOptions.rows?.action?.frozen ?? false\" alignFrozen=\"right\"\r\n [style.width.px]=\"actionColumnWidth\" [style.min-width.px]=\"actionColumnWidth\"></td>\r\n }\r\n </tr>\r\n }\r\n <tr>\r\n @if (!tableOptions.rows?.action?.positionRight) {\r\n <ng-container *ngTemplateOutlet=\"actionColumnHeaderTemplate\"></ng-container>\r\n }\r\n @if (tableOptions.rows?.checkboxSelector?.enabled && !tableOptions.rows?.checkboxSelector?.positionRight) {\r\n <ng-container [ngTemplateOutlet]=\"rowSelectorColumnHeaderTemplate\"></ng-container>\r\n }\r\n @for (col of columns; track col.header) {\r\n <th [ngStyle]=\"getColumnStyle(col, true)\"\r\n pResizableColumn [pResizableColumnDisabled]=\"!col.canBeResized ? true : false\"\r\n pReorderableColumn [pReorderableColumnDisabled]=\"!col.canBeReordered ? true : false\"\r\n pFrozenColumn [frozen]=\"col.frozenColumnAlign === FrozenColumnAlign.Left || col.frozenColumnAlign === FrozenColumnAlign.Right\" [alignFrozen]=\"getFrozenColumnAlignAsText(col.frozenColumnAlign)\"\r\n [pSortableColumn]=\"col.field\" [pSortableColumnDisabled]=\"!col.canBeSorted ? true : false\"\r\n style=\"text-align: center;\"\r\n [id]=\"col.field + '-header'\" [attr.scope]=\"'col'\">\r\n <div style=\"display: flex; justify-content: space-between; align-items: center; width: 100%;\">\r\n <div style=\"margin-right: 15px;\">\r\n <span>{{ col.header | translate }}</span>\r\n </div>\r\n <div style=\"display: flex; align-items: center; gap: 5px;\">\r\n @if (col.canBeSorted) {\r\n <p-sortIcon [field]=\"col.field\"></p-sortIcon>\r\n }\r\n @if(col.canBeFiltered){\r\n @if (!col.filterPredefinedValuesName || col.filterPredefinedValuesName.length === 0) {\r\n <p-columnFilter [type]=\"getDataTypeAsText(col.dataType)\" [field]=\"col.field\" display=\"menu\" [showButtons]=\"false\"/>\r\n } @else {\r\n <p-columnFilter\r\n [type]=\"getDataTypeAsText(col.dataType)\" [field]=\"col.field\" display=\"menu\"\r\n [showButtons]=\"false\" matchMode=\"in\" operator=\"or\" [showMatchModes]=\"false\"\r\n [showOperator]=\"false\" [showAddButton]=\"false\" [showClearButton]=\"false\" [showApplyButton]=\"false\">\r\n <ng-template #filter>\r\n <p-multiSelect\r\n [style]=\"{ minWidth: '400px' }\" [(ngModel)]=\"predefinedFiltersSelectedValuesCollection[col.filterPredefinedValuesName]\"\r\n [options]=\"getPredefinedFilterValues(col.filterPredefinedValuesName)\" [placeholder]=\"'Any value' | ecsTranslate\"\r\n (onChange)=\"onPredefinedFilterChange(col.field, $event.value)\" optionLabel=\"name\">\r\n <ng-template #item let-option >\r\n <div style=\"display: inline-block; vertical-align: middle;\">\r\n <ecs-table-predefined-filters [option]=\"option\" [col]=\"col\" [selectable]=\"false\" [rowData]=\"null\"/>\r\n </div>\r\n </ng-template>\r\n </p-multiSelect>\r\n </ng-template>\r\n </p-columnFilter>\r\n }\r\n }\r\n @if (col.columnDescription && col.columnDescription.length > 0) {\r\n <i [pTooltip]=\"(col.columnDescription) | ecsTranslate\" tooltipPosition=\"top\" [class]=\"tableOptions.columnDescriptionIcon || 'pi pi-info-circle'\"></i>\r\n }\r\n </div>\r\n </div>\r\n </th>\r\n }\r\n @if (tableOptions.rows?.checkboxSelector?.enabled && tableOptions.rows?.checkboxSelector?.positionRight) {\r\n <ng-container [ngTemplateOutlet]=\"rowSelectorColumnHeaderTemplate\"></ng-container>\r\n }\r\n @if (tableOptions.rows?.action?.positionRight) {\r\n <ng-container *ngTemplateOutlet=\"actionColumnHeaderTemplate\"></ng-container>\r\n }\r\n </tr>\r\n </ng-template>\r\n\r\n <!-- LOGIC FOR DRAWING TABLE DATA WHEN THERE IS CONTENTS -->\r\n <ng-template #body let-rowData let-columns=\"columns\"> \r\n @if (treeState?.isMore(rowData)) {\r\n <tr class=\"ecs-tree-more-row\">\r\n <td colspan=\"999\">\r\n <p-button icon=\"pi pi-plus\" [text]=\"true\" [label]=\"'Load more children' | ecsTranslate\"\r\n (onClick)=\"loadMoreTreeRows($event, rowData)\" />\r\n </td>\r\n </tr>\r\n } @else {\r\n <tr [pSelectableRow]=\"rowData\" [ngClass]=\"tableOptions.rows?.class?.(rowData)\" [ngStyle]=\"tableOptions.rows?.style?.(rowData)\"\r\n [attr.aria-level]=\"treeState ? treeState.depth(rowData) + 1 : null\"\r\n [attr.aria-expanded]=\"treeState?.hasChildren(rowData) ? treeState?.isExpanded(rowData) : null\">\r\n @if (!tableOptions.rows?.action?.positionRight) {\r\n <ng-container *ngTemplateOutlet=\"actionColumnTemplate; context: { rowData: rowData }\"></ng-container>\r\n }\r\n @if (tableOptions.rows?.checkboxSelector?.enabled && !tableOptions.rows?.checkboxSelector?.positionRight) {\r\n <ng-container [ngTemplateOutlet]=\"rowSelectorColumnTemplate\" [ngTemplateOutletContext]=\"{ rowData: rowData }\"></ng-container>\r\n }\r\n @for (col of columns; track col.field) {\r\n <td (mousedown)=\"col.dataType !== DataType.Boolean && copyToClipboardStart($event)\" (mouseup)=\"copyToClipboardCancel()\"\r\n [ngStyle]=\"getColumnStyle(col)\" pFrozenColumn [frozen]=\"col.frozenColumnAlign === FrozenColumnAlign.Left || col.frozenColumnAlign === FrozenColumnAlign.Right\" \r\n [alignFrozen]=\"getFrozenColumnAlignAsText(col.frozenColumnAlign)\" [style.text-align]=\"getDataAlignHorizontalAsText(col.dataAlignHorizontal)\" [style.vertical-align]=\"getDataAlignVerticalAsText(col.dataAlignVertical)\">\r\n @if (treeState && col.field === treeColumn) {\r\n <div class=\"ecs-tree-cell\" [style.padding-inline-start.px]=\"treeState.depth(rowData) * 20\">\r\n <button type=\"button\" class=\"ecs-tree-toggle\" [class.ecs-tree-leaf]=\"!treeState.hasChildren(rowData)\"\r\n [disabled]=\"!treeState.hasChildren(rowData) || treeState.isLoading(rowData) || treeState.loading\"\r\n [attr.aria-label]=\"(treeState.isExpanded(rowData) ? 'Collapse node' : 'Expand node') | ecsTranslate\"\r\n [attr.aria-expanded]=\"treeState.hasChildren(rowData) ? treeState.isExpanded(rowData) : null\"\r\n [pTooltip]=\"(treeState.isExpanded(rowData) ? 'Collapse node' : 'Expand node') | ecsTranslate\"\r\n (mousedown)=\"$event.stopPropagation()\" (mouseup)=\"$event.stopPropagation()\"\r\n (click)=\"toggleTreeRow($event, rowData)\">\r\n <i [class]=\"treeState.isLoading(rowData) ? 'pi pi-spinner pi-spin' : treeState.isExpanded(rowData) ? 'pi pi-chevron-down' : 'pi pi-chevron-right'\" aria-hidden=\"true\"></i>\r\n </button>\r\n <ecs-table-cell [col]=\"col\" [rowData]=\"rowData\" [globalSearchText]=\"effectiveGlobalSearchText\"\r\n [dateFormat]=\"dateFormat\" [dateTimezone]=\"dateTimezone\" [dateCulture]=\"dateCulture\"\r\n [predefinedFiltersCollection]=\"tableOptions.predefinedFilters\" />\r\n </div>\r\n } @else {\r\n <ecs-table-cell [col]=\"col\" [rowData]=\"rowData\" [globalSearchText]=\"effectiveGlobalSearchText\"\r\n [dateFormat]=\"dateFormat\" [dateTimezone]=\"dateTimezone\" [dateCulture]=\"dateCulture\"\r\n [predefinedFiltersCollection]=\"tableOptions.predefinedFilters\"/>\r\n }\r\n </td>\r\n }\r\n @if (tableOptions.rows?.checkboxSelector?.enabled && tableOptions.rows?.checkboxSelector?.positionRight) {\r\n <ng-container [ngTemplateOutlet]=\"rowSelectorColumnTemplate\" [ngTemplateOutletContext]=\"{ rowData: rowData }\"></ng-container>\r\n }\r\n @if (tableOptions.rows?.action?.positionRight) {\r\n <ng-container *ngTemplateOutlet=\"actionColumnTemplate; context: { rowData: rowData }\"></ng-container>\r\n }\r\n </tr>\r\n }\r\n </ng-template>\r\n\r\n <!-- LOGIC FOR DRAWING TABLE DATA WHEN THERE IS NO CONTENTS -->\r\n <ng-template #emptymessage>\r\n <tr>\r\n <td colspan=\"999\">{{ 'No data found for the current filter criteria.' | ecsTranslate }}</td>\r\n </tr>\r\n </ng-template>\r\n\r\n <!-- SHOW CUSTOM RECORDS REPORT -->\r\n <ng-template #paginatorleft>\r\n <div #paginatorContainer>\r\n <div style=\"display: flex; align-items: center; gap: 10px;\">\r\n @if(tableOptions.legend?.content){\r\n <ecs-table-button [button]=\"tableOptions.legend?.button\" [rowData]=\"null\" [overrideAction]=\"op.toggle.bind(op)\"/>\r\n <p-popover #op>\r\n <div [innerHTML]=\"(tableOptions.legend?.content) | ecsTranslate\"></div>\r\n </p-popover>\r\n }\r\n <span>{{ 'Showing {{count}} records of {{total}} available records' | ecsTranslate: { count: totalRecords, total: totalRecordsNotFiltered } }}</span>\r\n </div>\r\n </div>\r\n </ng-template>\r\n </p-table>\r\n @if (treeState) {\r\n <div #paginatorContainer class=\"ecs-tree-paginator\">\r\n @if (tableOptions.legend?.content) {\r\n <ecs-table-button [button]=\"tableOptions.legend?.button\" [rowData]=\"null\" [overrideAction]=\"treeLegend.toggle.bind(treeLegend)\" />\r\n <p-popover #treeLegend><div [innerHTML]=\"(tableOptions.legend?.content) | ecsTranslate\"></div></p-popover>\r\n }\r\n <span>{{ 'Showing {{count}} root nodes of {{total}} available root nodes' | ecsTranslate: { count: totalRecords, total: totalRecordsNotFiltered } }}</span>\r\n <p-paginator [first]=\"currentPage * currentRowsPerPage\" [rows]=\"currentRowsPerPage\" [totalRecords]=\"totalRecords\"\r\n [rowsPerPageOptions]=\"allowedRowsPerPage\" dropdownAppendTo=\"body\" (onPageChange)=\"treePageChange($event)\" />\r\n </div>\r\n }\r\n</div>\r\n<ecs-column-selector [visible]=\"showColumnSelector\" [columnModalData]=\"columnModalData\" [filteredColumnData]=\"filteredColumnData\" [orderByHeader]=\"tableOptions.columns?.selectorOrderByColumnName === true\" (visibleChange)=\"showColumnSelector=false\" (applyChanges)=\"applyColumnModalChanges($event)\"/>\r\n<ecs-export-excel [visible]=\"showExportModal\" [rowCheckboxSelectorActive]=\"tableOptions.rows?.checkboxSelector?.enabled ?? false\" [excelReportTitle]=\"excelReportTitle\" [allowTitleUserEdit]=\"tableOptions.excelReport?.titleAllowUserEdit ?? false\" (visibleChange)=\"showExportModal=false\" (exportToExcel)=\"generateExcelReport($event)\"/>\r\n<ecs-views-management [visible]=\"viewsModalShow\" [tableViews_menuItems]=\"tableViews_menuItems\" \r\n (onViewSelect)=\"viewLoad($event)\" (onViewCreate)=\"viewCreate($event)\" (onViewDelete)=\"viewDelete($event)\" (onViewEditAlias)=\"viewEditAlias($event)\" (onViewUpdateData)=\"viewUpdateData($event)\" (onViewUpdateActiveStartup)=\"viewUpdateActiveStartup($event)\"\r\n (visibleChange)=\"viewsModalShow=false\"/>\r\n<!-- Body-level overlays avoid clipping inside scrollable and frozen table cells. -->\r\n<p-menu #responsiveHeaderMenu [model]=\"headerMenuItems\" [popup]=\"true\" appendTo=\"body\" styleClass=\"ecs-responsive-menu\"/>\r\n<p-menu #responsiveRowMenu [model]=\"rowMenuItems\" [popup]=\"true\" appendTo=\"body\" styleClass=\"ecs-responsive-menu\"/>\r\n", styles: [".highlighted-text{background-color:#ff0;color:#000;border-radius:2px}.excel-export-tooltip .bool-icon{text-shadow:0 0 2px white,0 0 3px white}.excel-export-tooltip .bool-true{color:green}.excel-export-tooltip .bool-false{color:red}.p-datatable-column-filter-button.p-button-icon-only.p-button-rounded,.p-datatable-column-filter-clear-button.p-button-icon-only.p-button-rounded{height:var(--p-icon-size)!important;width:var(--p-icon-size)!important;border-radius:0!important}.viewButton{width:200px}.viewButton .p-button{width:100%;justify-content:center}.viewButton .p-button-label{display:block;width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;text-align:center}.ecs-compact-header{gap:.5rem;min-width:0}.ecs-header-menu-trigger{margin-left:auto;flex:0 0 auto}.ecs-responsive-trigger{min-width:44px;min-height:44px}.ecs-responsive-search{flex:1 1 220px;min-width:0;max-width:320px}.ecs-responsive-search input{width:100%;padding-right:2.5rem}.ecs-clear-search{border:0;background:transparent;color:inherit;cursor:pointer}.ecs-responsive-menu{max-width:calc(100vw - 16px);max-height:calc(100dvh - 32px);overflow-y:auto}.ecs-responsive-menu .p-menu-item-link{min-height:44px;white-space:normal}.ecs-tree-cell{display:flex;align-items:center;gap:4px;min-width:0}.ecs-tree-cell>ecs-table-cell{flex:1;min-width:0}.ecs-tree-toggle{width:32px;height:32px;flex:0 0 32px;border:0;background:transparent;color:inherit;cursor:pointer}.ecs-tree-toggle:focus-visible{outline:2px solid var(--p-primary-color);outline-offset:1px}.ecs-tree-leaf{visibility:hidden}.ecs-tree-paginator{display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:8px}.p-datatable-thead>.ecs-column-groups>td{padding:var(--p-datatable-header-cell-padding);background:var(--p-datatable-header-cell-background);color:var(--p-datatable-header-cell-color);font-weight:var(--p-datatable-column-title-font-weight);border:1px solid var(--p-datatable-header-cell-border-color);white-space:normal;overflow-wrap:anywhere}\n"] }]
2519
3022
  }], ctorParameters: () => [{ type: ECSPrimengTableService }, { type: ECSPrimengTableNotificationService }], propDecorators: { tableOptions: [{
2520
3023
  type: Input
2521
3024
  }], onRowCheckboxChange: [{
@@ -2558,5 +3061,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.21", ngImpo
2558
3061
  * Generated bundle index. Do not edit.
2559
3062
  */
2560
3063
 
2561
- export { CellDisplay, CellOverflowBehaviour, DEFAULT_TABLE_OPTIONS, DataAlignHorizontal, DataAlignVertical, DataType, DeviceType, ECSPrimengTable, ECSPrimengTableHttpService, ECSPrimengTableI18nService, ECSPrimengTableNotificationService, ECSPrimengTableService, ECSPrimengTableStateService, FrozenColumnAlign, TableViewSaveMode, createTableOptions };
3064
+ export { CellDisplay, CellOverflowBehaviour, DEFAULT_TABLE_OPTIONS, DataAlignHorizontal, DataAlignVertical, DataType, DeviceType, ECSPrimengTable, ECSPrimengTableHttpService, ECSPrimengTableI18nService, ECSPrimengTableNotificationService, ECSPrimengTableService, ECSPrimengTableStateService, FrozenColumnAlign, TableViewSaveMode, TreeTableState, createTableOptions };
2562
3065
  //# sourceMappingURL=competer-primeng-table.mjs.map