@competer/primeng-table 19.1.9 → 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();
@@ -1650,7 +1965,9 @@ class ECSPrimengTable {
1650
1965
  }
1651
1966
  }
1652
1967
  ngOnDestroy() {
1968
+ this.cancelGlobalSearch();
1653
1969
  this.destroyed = true;
1970
+ this.treeState?.cancel();
1654
1971
  const options = this.tableOptions.statePersistence;
1655
1972
  const key = options?.key?.trim();
1656
1973
  if (!key || !this.stateScope)
@@ -1669,9 +1986,12 @@ class ECSPrimengTable {
1669
1986
  dataUrl: this.tableOptions.urlTableData ?? '',
1670
1987
  filters,
1671
1988
  multiSortMeta: structuredClone(this.dt.multiSortMeta ?? []),
1672
- globalSearchText: this.globalSearchText,
1989
+ globalSearchText: this.effectiveGlobalSearchText,
1673
1990
  currentPage: this.currentPage,
1674
- 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()
1675
1995
  });
1676
1996
  }
1677
1997
  restoreNavigationState() {
@@ -1687,7 +2007,7 @@ class ECSPrimengTable {
1687
2007
  if (!state)
1688
2008
  return false;
1689
2009
  if (state.configurationUrl !== this.tableOptions.urlTableConfiguration ||
1690
- state.dataUrl !== this.tableOptions.urlTableData) {
2010
+ state.dataUrl !== this.tableOptions.urlTableData || state.treeMode !== this.treeState?.mode) {
1691
2011
  this.stateScope.clear(key);
1692
2012
  return false;
1693
2013
  }
@@ -1701,7 +2021,9 @@ class ECSPrimengTable {
1701
2021
  ? state.currentRowsPerPage : this.currentRowsPerPage;
1702
2022
  this.currentPage = this.currentRowsPerPage === state.currentRowsPerPage
1703
2023
  ? Math.max(0, state.currentPage) : 0;
1704
- this.globalSearchText = state.globalSearchText;
2024
+ this.restoreGlobalSearch(state.globalSearchText);
2025
+ this.treeState?.restore(state.treeExpandedKeys, state.treeChildPages);
2026
+ this.treeStateRestored = !!this.treeState;
1705
2027
  if (this.globalSearchText) {
1706
2028
  filters['global'] = { value: this.globalSearchText, matchMode: 'contains' };
1707
2029
  }
@@ -1920,6 +2242,8 @@ class ECSPrimengTable {
1920
2242
  }
1921
2243
  this.columnSelectionCustomized = true;
1922
2244
  let viewData = viewToLoad.viewData;
2245
+ this.treeState?.restore(viewData.treeExpandedKeys, viewData.treeChildPages);
2246
+ this.treeStateRestored = !!this.treeState;
1923
2247
  this.columnsSelected = viewData.columnsShown
1924
2248
  .map(data => this.columns.find((col) => col.field === data.field))
1925
2249
  .filter((col) => col !== undefined)
@@ -1927,7 +2251,7 @@ class ECSPrimengTable {
1927
2251
  this.tableOptions.columns.shown = this.tableService.orderColumnsWithFrozens(this.columnsCantBeHidden.concat(this.columnsSelected));
1928
2252
  this.currentPage = viewData.currentPage;
1929
2253
  this.currentRowsPerPage = viewData.currentRowsPerPage;
1930
- this.globalSearchText = viewData.globalSearchText;
2254
+ this.restoreGlobalSearch(viewData.globalSearchText);
1931
2255
  this.tableOptions.isActive = false;
1932
2256
  this.tableLazyLoadEventInformation.multiSortMeta = [...(viewData.multiSortMeta ?? [])];
1933
2257
  this.dt.multiSortMeta = [...(viewData.multiSortMeta ?? [])];
@@ -1952,7 +2276,7 @@ class ECSPrimengTable {
1952
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"));
1953
2277
  return;
1954
2278
  }
1955
- let viewData = this.tableService.viewGenerateData(this.dt, this.globalSearchText, this.currentPage, this.currentRowsPerPage, this.modifyFiltersWithoutGlobalAndSelectedRows.bind(this));
2279
+ let viewData = this.generateViewData();
1956
2280
  let newView = {
1957
2281
  lastActive: false,
1958
2282
  viewAlias: viewAlias,
@@ -1997,7 +2321,7 @@ class ECSPrimengTable {
1997
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."));
1998
2322
  return;
1999
2323
  }
2000
- let viewData = this.tableService.viewGenerateData(this.dt, this.globalSearchText, this.currentPage, this.currentRowsPerPage, this.modifyFiltersWithoutGlobalAndSelectedRows.bind(this));
2324
+ let viewData = this.generateViewData();
2001
2325
  this.tableViewsList[index].viewData = viewData;
2002
2326
  this.viewsSave(1);
2003
2327
  }
@@ -2079,13 +2403,42 @@ class ECSPrimengTable {
2079
2403
  pageSize: this.currentRowsPerPage, // Set the number of rows per page
2080
2404
  sort: this.tableLazyLoadEventInformation.multiSortMeta, // Set the sorting information
2081
2405
  filter: filtersWithoutGlobalAndSelectedRows, // Set the filters excluding the global filter
2082
- globalFilter: this.globalSearchText, // Set the global filter text
2406
+ globalFilter: this.effectiveGlobalSearchText, // Use the applied query, not pending input
2083
2407
  columns: this.tableOptions.columns.shown.map(col => col.field), // Set the columns to show
2084
2408
  dateFormat: this.dateFormat,
2085
2409
  dateTimezone: this.dateTimezone,
2086
2410
  dateCulture: this.dateCulture,
2087
2411
  exportDateFormat: this.exportDateFormat
2088
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
+ }
2089
2442
  this.tableService.fetchTableData(this.tableOptions.urlTableData, requestData)
2090
2443
  .pipe(takeUntilDestroyed(this.destroyRef), finalize(() => {
2091
2444
  if (this.destroyed)
@@ -2098,9 +2451,6 @@ class ECSPrimengTable {
2098
2451
  });
2099
2452
  }
2100
2453
  modifyFiltersWithoutGlobalAndSelectedRows(filters, overrideOption = -1) {
2101
- if (this.globalSearchText === "") { // If the global search text is an empty string
2102
- this.globalSearchText = null; // Set it to null
2103
- }
2104
2454
  let filtersWithoutGlobalAndSelectedRows = structuredClone(filters ?? {}); // Create a copy of filters to delete the global.
2105
2455
  if (filtersWithoutGlobalAndSelectedRows.hasOwnProperty('global')) { // If there is an entry with the global filter
2106
2456
  delete filtersWithoutGlobalAndSelectedRows['global']; // Remove the global filter
@@ -2109,9 +2459,12 @@ class ECSPrimengTable {
2109
2459
  return filtersWithoutGlobalAndSelectedRows; // Return the filters without global array
2110
2460
  }
2111
2461
  resetTableView() {
2462
+ this.cancelGlobalSearch();
2112
2463
  const key = this.tableOptions.statePersistence?.key?.trim();
2113
2464
  if (key)
2114
2465
  this.stateScope?.clear(key);
2466
+ this.treeState?.restore();
2467
+ this.treeStateRestored = !!this.treeState;
2115
2468
  this.initialStateApplied = false;
2116
2469
  this.tableViewCurrentSelectedAlias = '';
2117
2470
  this.fetchTableConfiguration(true);
@@ -2181,7 +2534,76 @@ class ECSPrimengTable {
2181
2534
  this.totalRecordsNotFiltered = body.totalRecordsNotFiltered; // Update the total records not filtered
2182
2535
  this.currentPage = body.page; // Update the current page
2183
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
+ }
2184
2605
  clearFilters(dt, force = false, onlyGlobalFilter = false) {
2606
+ this.cancelGlobalSearch();
2185
2607
  let hasToClear = this.hasToClearFilters(dt, this.globalSearchText, force);
2186
2608
  if (hasToClear) {
2187
2609
  if (!onlyGlobalFilter) {
@@ -2205,8 +2627,17 @@ class ECSPrimengTable {
2205
2627
  });
2206
2628
  this.dt.filters = filters;
2207
2629
  }
2208
- this.globalSearchText = null;
2209
- 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('', '');
2210
2641
  }
2211
2642
  }
2212
2643
  clearSorts(dt, force = false) {
@@ -2332,9 +2763,62 @@ class ECSPrimengTable {
2332
2763
  isRowCheckboxSelected(rowID) {
2333
2764
  return this.selectedRowsCheckbox.includes(rowID);
2334
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
+ }
2335
2818
  onRowChekboxChange(event, rowID) {
2336
2819
  if (event.checked) { // Add the selected item
2337
- this.selectedRowsCheckbox.push(rowID);
2820
+ if (!this.selectedRowsCheckbox.includes(rowID))
2821
+ this.selectedRowsCheckbox.push(rowID);
2338
2822
  }
2339
2823
  else { // Remove the selected item
2340
2824
  this.selectedRowsCheckbox = this.selectedRowsCheckbox.filter(selectedId => selectedId !== rowID);
@@ -2459,7 +2943,7 @@ class ECSPrimengTable {
2459
2943
  pageSize: this.currentRowsPerPage, // Set the number of rows per page
2460
2944
  sort: this.tableLazyLoadEventInformation.multiSortMeta, // Set the sorting information
2461
2945
  filter: filtersWithoutGlobalAndSelectedRows, // Set the filters excluding the global filter
2462
- globalFilter: this.globalSearchText, // Set the global filter text
2946
+ globalFilter: this.effectiveGlobalSearchText, // Use the applied query, not pending input
2463
2947
  columns: this.tableOptions.columns.shown.map(col => col.field), // Set the columns to show
2464
2948
  dateFormat: this.dateFormat,
2465
2949
  dateTimezone: this.dateTimezone,
@@ -2471,6 +2955,8 @@ class ECSPrimengTable {
2471
2955
  filename: event.filename,
2472
2956
  useIconInBools: event.useIconInBools
2473
2957
  };
2958
+ if (this.treeState)
2959
+ Object.assign(requestData, { expandedKeys: [...this.treeState.expanded] });
2474
2960
  this.tableService.fetchExcelReport(this.tableOptions.excelReport.url, requestData).subscribe({
2475
2961
  next: (response) => {
2476
2962
  this.tableService.downloadFile(response.body, event.filename, 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
@@ -2505,7 +2991,7 @@ class ECSPrimengTable {
2505
2991
  });
2506
2992
  }
2507
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 });
2508
- 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 @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 <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}.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: 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 });
2509
2995
  }
2510
2996
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: ECSPrimengTable, decorators: [{
2511
2997
  type: Component,
@@ -2532,7 +3018,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.21", ngImpo
2532
3018
  ViewsManagement,
2533
3019
  PopoverModule,
2534
3020
  MenuModule
2535
- ], 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 @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 <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}.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"] }]
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"] }]
2536
3022
  }], ctorParameters: () => [{ type: ECSPrimengTableService }, { type: ECSPrimengTableNotificationService }], propDecorators: { tableOptions: [{
2537
3023
  type: Input
2538
3024
  }], onRowCheckboxChange: [{
@@ -2575,5 +3061,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.21", ngImpo
2575
3061
  * Generated bundle index. Do not edit.
2576
3062
  */
2577
3063
 
2578
- 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 };
2579
3065
  //# sourceMappingURL=competer-primeng-table.mjs.map