@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.
- package/README.md +73 -0
- package/fesm2022/competer-primeng-table.mjs +508 -22
- package/fesm2022/competer-primeng-table.mjs.map +1 -1
- package/lib/components/ecs-primeng-table/ecs-primeng-table.d.ts +30 -0
- package/lib/components/ecs-primeng-table/ecs-primeng-table.service.d.ts +1 -0
- package/lib/interfaces/table-options.interface.d.ts +13 -0
- package/lib/interfaces/table-view-data.interface.d.ts +2 -0
- package/lib/services/table-state.service.d.ts +3 -0
- package/lib/utils/tree-table-state.d.ts +66 -0
- package/package.json +1 -1
- package/public-api.d.ts +1 -0
|
@@ -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
|
|
30
|
+
import * as i14 from 'primeng/buttongroup';
|
|
30
31
|
import { ButtonGroupModule } from 'primeng/buttongroup';
|
|
31
|
-
import * as
|
|
32
|
+
import * as i15 from 'primeng/popover';
|
|
32
33
|
import { PopoverModule } from 'primeng/popover';
|
|
33
|
-
import * as
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
2209
|
-
|
|
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.
|
|
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.
|
|
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
|