@tekus/design-system 5.41.0 → 5.42.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/fesm2022/tekus-design-system-components-carousel.mjs +17 -3
- package/fesm2022/tekus-design-system-components-carousel.mjs.map +1 -1
- package/fesm2022/tekus-design-system-components-checkbox.mjs +2 -2
- package/fesm2022/tekus-design-system-components-checkbox.mjs.map +1 -1
- package/fesm2022/tekus-design-system-components-color-picker.mjs +119 -71
- package/fesm2022/tekus-design-system-components-color-picker.mjs.map +1 -1
- package/fesm2022/tekus-design-system-components-column-picker.mjs +210 -0
- package/fesm2022/tekus-design-system-components-column-picker.mjs.map +1 -0
- package/fesm2022/tekus-design-system-components-dropdown.mjs +1 -1
- package/fesm2022/tekus-design-system-components-dropdown.mjs.map +1 -1
- package/fesm2022/tekus-design-system-components-icon.mjs +10 -0
- package/fesm2022/tekus-design-system-components-icon.mjs.map +1 -1
- package/fesm2022/tekus-design-system-components-link-group.mjs +74 -0
- package/fesm2022/tekus-design-system-components-link-group.mjs.map +1 -0
- package/fesm2022/tekus-design-system-components-panel.mjs +1 -1
- package/fesm2022/tekus-design-system-components-panel.mjs.map +1 -1
- package/fesm2022/tekus-design-system-components-skeleton.mjs +79 -0
- package/fesm2022/tekus-design-system-components-skeleton.mjs.map +1 -0
- package/fesm2022/tekus-design-system-components-table.mjs +234 -11
- package/fesm2022/tekus-design-system-components-table.mjs.map +1 -1
- package/fesm2022/tekus-design-system-components-tabs.mjs +1 -1
- package/fesm2022/tekus-design-system-components-tabs.mjs.map +1 -1
- package/fesm2022/tekus-design-system-components-toolbar.mjs +33 -3
- package/fesm2022/tekus-design-system-components-toolbar.mjs.map +1 -1
- package/fesm2022/tekus-design-system-components-tooltip.mjs +16 -3
- package/fesm2022/tekus-design-system-components-tooltip.mjs.map +1 -1
- package/package.json +13 -1
- package/types/tekus-design-system-components-carousel.d.ts +8 -1
- package/types/tekus-design-system-components-color-picker.d.ts +41 -7
- package/types/tekus-design-system-components-column-picker.d.ts +116 -0
- package/types/tekus-design-system-components-link-group.d.ts +119 -0
- package/types/tekus-design-system-components-skeleton.d.ts +68 -0
- package/types/tekus-design-system-components-table.d.ts +186 -10
- package/types/tekus-design-system-components-toolbar.d.ts +37 -2
- package/types/tekus-design-system-components-tooltip.d.ts +12 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import {
|
|
2
|
+
import { model, viewChild, input, output, computed, signal, inject, ElementRef, Injector, effect, afterNextRender, ChangeDetectionStrategy, Component } from '@angular/core';
|
|
3
3
|
import { NgTemplateOutlet } from '@angular/common';
|
|
4
4
|
import * as i1 from 'primeng/table';
|
|
5
5
|
import { TableModule } from 'primeng/table';
|
|
@@ -15,8 +15,11 @@ import { CounterComponent } from '@tekus/design-system/components/counter';
|
|
|
15
15
|
import { BadgeComponent } from '@tekus/design-system/components/badge';
|
|
16
16
|
import { ToggleComponent } from '@tekus/design-system/components/toggle';
|
|
17
17
|
import { TooltipComponent } from '@tekus/design-system/components/tooltip';
|
|
18
|
+
import { LinkGroupComponent } from '@tekus/design-system/components/link-group';
|
|
19
|
+
import { SkeletonComponent } from '@tekus/design-system/components/skeleton';
|
|
18
20
|
import * as i2 from 'primeng/api';
|
|
19
21
|
|
|
22
|
+
const isObject = (value) => typeof value === 'object' && value !== null;
|
|
20
23
|
/**
|
|
21
24
|
* @component TableComponent
|
|
22
25
|
* @description
|
|
@@ -31,10 +34,11 @@ import * as i2 from 'primeng/api';
|
|
|
31
34
|
class TableComponent {
|
|
32
35
|
constructor() {
|
|
33
36
|
/**
|
|
34
|
-
* @property {
|
|
37
|
+
* @property {ModelSignal<T[]>} data
|
|
35
38
|
* @description
|
|
36
39
|
* Array of data objects to display in the table rows.
|
|
37
40
|
* Each object corresponds to one row; properties are mapped to columns via the `columns` input.
|
|
41
|
+
* Supports two-way binding `[(data)]` to synchronize row reordering.
|
|
38
42
|
*
|
|
39
43
|
* @default []
|
|
40
44
|
*
|
|
@@ -44,7 +48,7 @@ class TableComponent {
|
|
|
44
48
|
* { id: 2, name: 'Jane', status: 'inactive' }
|
|
45
49
|
* ]"
|
|
46
50
|
*/
|
|
47
|
-
this.data =
|
|
51
|
+
this.data = model([], ...(ngDevMode ? [{ debugName: "data" }] : /* istanbul ignore next */ []));
|
|
48
52
|
/**
|
|
49
53
|
* @property {viewChild} tableRef
|
|
50
54
|
* @description
|
|
@@ -68,6 +72,46 @@ class TableComponent {
|
|
|
68
72
|
* ]"
|
|
69
73
|
*/
|
|
70
74
|
this.columns = input([], ...(ngDevMode ? [{ debugName: "columns" }] : /* istanbul ignore next */ []));
|
|
75
|
+
/**
|
|
76
|
+
* @property {InputSignal<boolean>} reorderableRows
|
|
77
|
+
* @description
|
|
78
|
+
* Whether row reordering is enabled.
|
|
79
|
+
* When true, an extra leading column with a `grip-vertical` handle is rendered for each row.
|
|
80
|
+
* Rows are moved by dragging the handle, or with ArrowUp / ArrowDown while it is focused.
|
|
81
|
+
* Reordering is paused (handle disabled) while a sort or a column filter is active,
|
|
82
|
+
* because the visible order would not match the underlying `data` order.
|
|
83
|
+
* Set it before the rows render: PrimeNG binds the drag listeners when each row is created.
|
|
84
|
+
* @default false
|
|
85
|
+
*/
|
|
86
|
+
this.reorderableRows = input(false, ...(ngDevMode ? [{ debugName: "reorderableRows" }] : /* istanbul ignore next */ []));
|
|
87
|
+
/**
|
|
88
|
+
* @property {InputSignal<string>} reorderHandleLabel
|
|
89
|
+
* @description
|
|
90
|
+
* Accessible name of the row reorder handle and of its column header.
|
|
91
|
+
* @default 'Reordenar fila'
|
|
92
|
+
*/
|
|
93
|
+
this.reorderHandleLabel = input('Reordenar fila', ...(ngDevMode ? [{ debugName: "reorderHandleLabel" }] : /* istanbul ignore next */ []));
|
|
94
|
+
/**
|
|
95
|
+
* @property {InputSignal<string>} reorderMovedLabel
|
|
96
|
+
* @description
|
|
97
|
+
* Screen reader announcement after a row is moved.
|
|
98
|
+
* `{0}` is replaced by the new position and `{1}` by the total of rows.
|
|
99
|
+
* @default 'Fila movida a la posición {0} de {1}'
|
|
100
|
+
*/
|
|
101
|
+
this.reorderMovedLabel = input('Fila movida a la posición {0} de {1}', ...(ngDevMode ? [{ debugName: "reorderMovedLabel" }] : /* istanbul ignore next */ []));
|
|
102
|
+
/**
|
|
103
|
+
* @property {InputSignal<string | undefined>} imageLoadingLabel
|
|
104
|
+
* @description
|
|
105
|
+
* Optional screen reader text of an image cell in `loading` state, in the
|
|
106
|
+
* app's language. Without it the loading skeleton is decorative.
|
|
107
|
+
*/
|
|
108
|
+
this.imageLoadingLabel = input(...(ngDevMode ? [undefined, { debugName: "imageLoadingLabel" }] : /* istanbul ignore next */ []));
|
|
109
|
+
/**
|
|
110
|
+
* @property {OutputEmitterRef<TableRowReorderEvent<T>>} rowReorder
|
|
111
|
+
* @description
|
|
112
|
+
* Emitted when a row is moved, by drag-and-drop or keyboard.
|
|
113
|
+
*/
|
|
114
|
+
this.rowReorder = output();
|
|
71
115
|
/**
|
|
72
116
|
* @property {InputSignal<'single' | 'multiple' | undefined>} selectionMode
|
|
73
117
|
* @description
|
|
@@ -86,6 +130,30 @@ class TableComponent {
|
|
|
86
130
|
* Property name to uniquely identify a row.
|
|
87
131
|
*/
|
|
88
132
|
this.dataKey = input(undefined, ...(ngDevMode ? [{ debugName: "dataKey" }] : /* istanbul ignore next */ []));
|
|
133
|
+
/**
|
|
134
|
+
* @property {InputSignal<string[]>} hiddenColumns
|
|
135
|
+
* @description
|
|
136
|
+
* Optional. `field` of the columns to hide. The consumer owns this list
|
|
137
|
+
* (e.g. bound to `tk-toolbar`'s `[(hiddenColumns)]` and preloaded from a saved
|
|
138
|
+
* preference). Fields that do not match a column are ignored, and columns
|
|
139
|
+
* without `field` (selection, actions) are always shown.
|
|
140
|
+
* Hiding a column does not clear its active filter.
|
|
141
|
+
* @default []
|
|
142
|
+
*/
|
|
143
|
+
this.hiddenColumns = input([], ...(ngDevMode ? [{ debugName: "hiddenColumns" }] : /* istanbul ignore next */ []));
|
|
144
|
+
/**
|
|
145
|
+
* @computed visibleColumns
|
|
146
|
+
* @description
|
|
147
|
+
* Columns actually rendered: `columns` minus `hiddenColumns`.
|
|
148
|
+
*/
|
|
149
|
+
this.visibleColumns = computed(() => {
|
|
150
|
+
const hidden = this.hiddenColumns();
|
|
151
|
+
const all = this.columns();
|
|
152
|
+
if (!hidden.length) {
|
|
153
|
+
return all;
|
|
154
|
+
}
|
|
155
|
+
return all.filter(col => !col.field || !hidden.includes(col.field));
|
|
156
|
+
}, ...(ngDevMode ? [{ debugName: "visibleColumns" }] : /* istanbul ignore next */ []));
|
|
89
157
|
/**
|
|
90
158
|
* @property {InputSignal<string | null>} minTableWidth
|
|
91
159
|
* @description
|
|
@@ -97,8 +165,24 @@ class TableComponent {
|
|
|
97
165
|
*/
|
|
98
166
|
this.minTableWidth = input('60rem', ...(ngDevMode ? [{ debugName: "minTableWidth" }] : /* istanbul ignore next */ []));
|
|
99
167
|
this.initialData = signal([], ...(ngDevMode ? [{ debugName: "initialData" }] : /* istanbul ignore next */ []));
|
|
168
|
+
/**
|
|
169
|
+
* @property imageStatuses
|
|
170
|
+
* @description
|
|
171
|
+
* Load outcome of each image cell, per row object and column field. Keyed by
|
|
172
|
+
* the row (not the src) so rows sharing an image URL keep their own state,
|
|
173
|
+
* and a new row object always gets a fresh attempt.
|
|
174
|
+
*/
|
|
175
|
+
this.imageStatuses = new WeakMap();
|
|
176
|
+
/** Bumped on every image load/error so the template re-reads the statuses */
|
|
177
|
+
this.imageStatusVersion = signal(0, ...(ngDevMode ? [{ debugName: "imageStatusVersion" }] : /* istanbul ignore next */ []));
|
|
100
178
|
this.internalData = signal([], ...(ngDevMode ? [{ debugName: "internalData" }] : /* istanbul ignore next */ []));
|
|
101
179
|
this.isSorted = signal(null, ...(ngDevMode ? [{ debugName: "isSorted" }] : /* istanbul ignore next */ []));
|
|
180
|
+
/** Text of the polite live region announced after a row is moved */
|
|
181
|
+
this.reorderAnnouncement = signal('', ...(ngDevMode ? [{ debugName: "reorderAnnouncement" }] : /* istanbul ignore next */ []));
|
|
182
|
+
/** Row offset applied by each reorder handle key */
|
|
183
|
+
this.reorderKeyDelta = { ArrowUp: -1, ArrowDown: 1 };
|
|
184
|
+
this.host = inject(ElementRef);
|
|
185
|
+
this.injector = inject(Injector);
|
|
102
186
|
/** Tracks which column's filter overlay is currently open */
|
|
103
187
|
this.activeFilterColumn = signal(null, ...(ngDevMode ? [{ debugName: "activeFilterColumn" }] : /* istanbul ignore next */ []));
|
|
104
188
|
/** Stores the selected filter value per column field (null = no filter) */
|
|
@@ -138,6 +222,16 @@ class TableComponent {
|
|
|
138
222
|
const allSelected = this.isAllSelected();
|
|
139
223
|
return !allSelected && selected.length > 0;
|
|
140
224
|
}, ...(ngDevMode ? [{ debugName: "isPartiallySelected" }] : /* istanbul ignore next */ []));
|
|
225
|
+
/**
|
|
226
|
+
* @computed canReorderRows
|
|
227
|
+
* @description
|
|
228
|
+
* Rows can only be moved while the visible order matches `data`: reordering
|
|
229
|
+
* a sorted or filtered view would drop the hidden rows from the model or be
|
|
230
|
+
* undone by the next sort pass.
|
|
231
|
+
*/
|
|
232
|
+
this.canReorderRows = computed(() => this.reorderableRows() &&
|
|
233
|
+
!this.sortField() &&
|
|
234
|
+
!Object.values(this.columnFilters()).some(value => value != null), ...(ngDevMode ? [{ debugName: "canReorderRows" }] : /* istanbul ignore next */ []));
|
|
141
235
|
this.actionGroupCache = new Map();
|
|
142
236
|
/**
|
|
143
237
|
* @effect data → initialData sync
|
|
@@ -212,6 +306,61 @@ class TableComponent {
|
|
|
212
306
|
updateSelection(value) {
|
|
213
307
|
this.selection.set([...value]);
|
|
214
308
|
}
|
|
309
|
+
/**
|
|
310
|
+
* @method onRowReorder
|
|
311
|
+
* @description
|
|
312
|
+
* Handles row reorder event from PrimeNG Table and synchronizes data.
|
|
313
|
+
* @param event {{ dragIndex?: number; dropIndex?: number }}
|
|
314
|
+
*/
|
|
315
|
+
onRowReorder(event) {
|
|
316
|
+
if (event.dragIndex == null || event.dropIndex == null) {
|
|
317
|
+
return;
|
|
318
|
+
}
|
|
319
|
+
this.moveRow(event.dragIndex, event.dropIndex);
|
|
320
|
+
}
|
|
321
|
+
/**
|
|
322
|
+
* @method onReorderHandleKeydown
|
|
323
|
+
* @description
|
|
324
|
+
* Moves the row one position with ArrowUp / ArrowDown and keeps focus on its handle.
|
|
325
|
+
* Stops propagation so PrimeNG's selectable row does not treat the keys as row navigation or selection.
|
|
326
|
+
*/
|
|
327
|
+
onReorderHandleKeydown(event, rowIndex) {
|
|
328
|
+
event.stopPropagation();
|
|
329
|
+
const delta = this.reorderKeyDelta[event.key];
|
|
330
|
+
if (!delta) {
|
|
331
|
+
return;
|
|
332
|
+
}
|
|
333
|
+
event.preventDefault();
|
|
334
|
+
const target = rowIndex + delta;
|
|
335
|
+
if (!this.moveRow(rowIndex, target)) {
|
|
336
|
+
return;
|
|
337
|
+
}
|
|
338
|
+
afterNextRender(() => {
|
|
339
|
+
const handles = this.host.nativeElement.querySelectorAll('.tk-table__row-reorder-handle button');
|
|
340
|
+
handles[target]?.focus();
|
|
341
|
+
}, { injector: this.injector });
|
|
342
|
+
}
|
|
343
|
+
/**
|
|
344
|
+
* Moves a row inside `data` (not the PrimeNG-mutated `internalData`), syncs the
|
|
345
|
+
* model and emits `rowReorder`. Returns false when the move is not allowed.
|
|
346
|
+
*/
|
|
347
|
+
moveRow(fromIndex, toIndex) {
|
|
348
|
+
const rows = this.data();
|
|
349
|
+
if (!this.canReorderRows() ||
|
|
350
|
+
fromIndex === toIndex ||
|
|
351
|
+
fromIndex < 0 || toIndex < 0 ||
|
|
352
|
+
fromIndex >= rows.length || toIndex >= rows.length) {
|
|
353
|
+
return false;
|
|
354
|
+
}
|
|
355
|
+
const reordered = [...rows];
|
|
356
|
+
reordered.splice(toIndex, 0, reordered.splice(fromIndex, 1)[0]);
|
|
357
|
+
this.data.set(reordered);
|
|
358
|
+
this.reorderAnnouncement.set(this.reorderMovedLabel()
|
|
359
|
+
.replace('{0}', String(toIndex + 1))
|
|
360
|
+
.replace('{1}', String(reordered.length)));
|
|
361
|
+
this.rowReorder.emit({ dragIndex: fromIndex, dropIndex: toIndex, data: reordered });
|
|
362
|
+
return true;
|
|
363
|
+
}
|
|
215
364
|
getActionGroup(actions, row) {
|
|
216
365
|
if (!actions)
|
|
217
366
|
return [];
|
|
@@ -526,18 +675,90 @@ class TableComponent {
|
|
|
526
675
|
/**
|
|
527
676
|
* @method onImageError
|
|
528
677
|
* @description
|
|
529
|
-
* Handles image load errors
|
|
678
|
+
* Handles image load errors: switches to the column's `imageFallback` once;
|
|
679
|
+
* if there is none, or it fails too, the cell shows the error placeholder.
|
|
530
680
|
* Called from the template's (error) binding on image-type columns.
|
|
531
681
|
* @param event {Event} - The native error event from the <img> element.
|
|
532
|
-
* @param
|
|
682
|
+
* @param col {TableColumn<T>} - The image column definition.
|
|
683
|
+
* @param row {T} - The data row being rendered.
|
|
684
|
+
*/
|
|
685
|
+
onImageError(event, col, row) {
|
|
686
|
+
const img = event.target;
|
|
687
|
+
const fallback = col.imageFallback;
|
|
688
|
+
if (fallback && img.getAttribute('src') !== fallback) {
|
|
689
|
+
img.src = fallback;
|
|
690
|
+
return;
|
|
691
|
+
}
|
|
692
|
+
this.setImageStatus(col, row, 'failed');
|
|
693
|
+
}
|
|
694
|
+
/**
|
|
695
|
+
* @method onImageLoad
|
|
696
|
+
* @description
|
|
697
|
+
* Marks an image cell as loaded so its skeleton is removed.
|
|
698
|
+
* @param col {TableColumn<T>} - The image column definition.
|
|
699
|
+
* @param row {T} - The data row being rendered.
|
|
533
700
|
*/
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
701
|
+
onImageLoad(col, row) {
|
|
702
|
+
this.setImageStatus(col, row, 'loaded');
|
|
703
|
+
}
|
|
704
|
+
/**
|
|
705
|
+
* @method getImageState
|
|
706
|
+
* @description
|
|
707
|
+
* State of an image cell: the column's `imageState` when it is `loading` or
|
|
708
|
+
* `error`; otherwise `error` if the image failed to load, else `default`.
|
|
709
|
+
* A `loading` or `error` state from the column clears the load outcome, so
|
|
710
|
+
* the image is retried (with a skeleton) when the cell goes back to `default`.
|
|
711
|
+
* @param col {TableColumn<T>} - The image column definition.
|
|
712
|
+
* @param row {T} - The data row being rendered.
|
|
713
|
+
*/
|
|
714
|
+
getImageState(col, row) {
|
|
715
|
+
this.imageStatusVersion();
|
|
716
|
+
const state = col.imageState?.(row) ?? 'default';
|
|
717
|
+
if (state !== 'default') {
|
|
718
|
+
// Plain write, not a signal: safe during render and seen by the next one
|
|
719
|
+
this.clearImageStatus(col, row);
|
|
720
|
+
return state;
|
|
721
|
+
}
|
|
722
|
+
return this.getImageStatus(col, row) === 'failed' ? 'error' : 'default';
|
|
723
|
+
}
|
|
724
|
+
/**
|
|
725
|
+
* @method isImageLoaded
|
|
726
|
+
* @description
|
|
727
|
+
* Whether the image of a cell finished loading. A cell without src counts
|
|
728
|
+
* as loaded, so it never shows an endless skeleton.
|
|
729
|
+
* @param col {TableColumn<T>} - The image column definition.
|
|
730
|
+
* @param row {T} - The data row being rendered.
|
|
731
|
+
*/
|
|
732
|
+
isImageLoaded(col, row) {
|
|
733
|
+
this.imageStatusVersion();
|
|
734
|
+
return !this.getImageSrc(col, row) || this.getImageStatus(col, row) === 'loaded';
|
|
735
|
+
}
|
|
736
|
+
getImageSrc(col, row) {
|
|
737
|
+
const value = col.field ? row[col.field] : undefined;
|
|
738
|
+
return typeof value === 'string' ? value : '';
|
|
739
|
+
}
|
|
740
|
+
getImageStatus(col, row) {
|
|
741
|
+
const src = this.getImageSrc(col, row);
|
|
742
|
+
const entry = col.field && src && isObject(row) ? this.imageStatuses.get(row)?.get(col.field) : undefined;
|
|
743
|
+
return entry?.src === src ? entry.status : null;
|
|
744
|
+
}
|
|
745
|
+
setImageStatus(col, row, status) {
|
|
746
|
+
const src = this.getImageSrc(col, row);
|
|
747
|
+
if (!col.field || !src || !isObject(row)) {
|
|
748
|
+
return;
|
|
749
|
+
}
|
|
750
|
+
const cells = this.imageStatuses.get(row) ?? new Map();
|
|
751
|
+
cells.set(col.field, { src, status });
|
|
752
|
+
this.imageStatuses.set(row, cells);
|
|
753
|
+
this.imageStatusVersion.update(version => version + 1);
|
|
754
|
+
}
|
|
755
|
+
clearImageStatus(col, row) {
|
|
756
|
+
if (col.field && isObject(row)) {
|
|
757
|
+
this.imageStatuses.get(row)?.delete(col.field);
|
|
537
758
|
}
|
|
538
759
|
}
|
|
539
760
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: TableComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
540
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.17", type: TableComponent, isStandalone: true, selector: "tk-table", inputs: { data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: false, transformFunction: null }, columns: { classPropertyName: "columns", publicName: "columns", isSignal: true, isRequired: false, transformFunction: null }, selectionMode: { classPropertyName: "selectionMode", publicName: "selectionMode", isSignal: true, isRequired: false, transformFunction: null }, selection: { classPropertyName: "selection", publicName: "selection", isSignal: true, isRequired: false, transformFunction: null }, dataKey: { classPropertyName: "dataKey", publicName: "dataKey", isSignal: true, isRequired: false, transformFunction: null }, minTableWidth: { classPropertyName: "minTableWidth", publicName: "minTableWidth", isSignal: true, isRequired: false, transformFunction: null }, columnFilters: { classPropertyName: "columnFilters", publicName: "columnFilters", isSignal: true, isRequired: false, transformFunction: null }, sortField: { classPropertyName: "sortField", publicName: "sortField", isSignal: true, isRequired: false, transformFunction: null }, sortOrder: { classPropertyName: "sortOrder", publicName: "sortOrder", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { selection: "selectionChange", columnFilters: "columnFiltersChange", sortField: "sortFieldChange", sortOrder: "sortOrderChange" }, viewQueries: [{ propertyName: "tableRef", first: true, predicate: ["tableRef"], descendants: true, isSignal: true }], ngImport: i0, template: "<p-table #tableRef [selection]=\"selection()\" (selectionChange)=\"updateSelection($any($event))\"\n [selectionMode]=\"selectionMode()\" [dataKey]=\"dataKey()\" [value]=\"internalData()\" [customSort]=\"true\"\n (sortFunction)=\"customSort($event)\" [tableStyle]=\"minTableWidth() ? { 'min-width': minTableWidth() } : {}\" responsiveLayout=\"scroll\">\n <!-- HEADER -->\n <ng-template pTemplate=\"header\">\n <tr>\n @for (col of columns(); track col.header) {\n <th [id]=\"col.field\" [style.width]=\"col.width\"\n [pSortableColumn]=\"col.sortable ? col.field : undefined\"\n [class.tk-table__header--active]=\"activeFilterColumn() === col.field || isColumnFiltered(col.field!)\">\n <div class=\"tk-table__header-content\">\n @if (col.type === 'selection' && selectionMode() === 'multiple') {\n <div class=\"tk-table__actions hide-validation-messages\">\n <tk-checkbox [binary]=\"true\" [model]=\"isAllSelected()\" [indeterminate]=\"isPartiallySelected()\"\n (click)=\"$event.stopPropagation()\" (keypress)=\"$event.stopPropagation()\"\n (modelChange)=\"toggleAll($event)\"></tk-checkbox>\n </div>\n } @else if (col.type !== 'selection') {\n <span class=\"tk-table__header-label\">{{ col.header }}</span>\n @if (col.sortable) {\n <p-sortIcon [field]=\"col.field\"></p-sortIcon>\n }\n @if (col.filterable && col.field) {\n <button\n class=\"tk-table__filter-trigger\"\n [class.tk-table__filter-trigger--active]=\"isColumnFiltered(col.field)\"\n (click)=\"toggleFilterOverlay(col.field, $event)\"\n type=\"button\"\n [attr.aria-label]=\"'Filter ' + col.header\">\n <tk-icon icon=\"filter\" size=\"sm\"></tk-icon>\n </button>\n }\n }\n </div>\n </th>\n }\n </tr>\n </ng-template>\n\n <!-- BODY -->\n <ng-template pTemplate=\"body\" let-row>\n <tr [pSelectableRow]=\"row\">\n @for (col of columns(); track col.header) {\n <!-- SELECTION -->\n @if (col.type === 'selection') {\n <td>\n @if (selectionMode() === 'multiple') {\n <tk-checkbox [model]=\"selection()\" [value]=\"row\" (click)=\"$event.stopPropagation()\"\n (keypress)=\"$event.stopPropagation()\" (modelChange)=\"updateSelection($any($event))\"></tk-checkbox>\n }\n </td>\n }\n\n <!-- CHECKBOX (Boolean field) -->\n @if (col.type === 'checkbox') {\n <td>\n <tk-checkbox [binary]=\"true\" [(model)]=\"row[col.field!]\" (click)=\"$event.stopPropagation()\"\n (keypress)=\"$event.stopPropagation()\"></tk-checkbox>\n </td>\n }\n\n <!-- COUNTER (editable integer field) -->\n @if (col.type === 'counter') {\n <td>\n <tk-counter\n [value]=\"$any(row[col.field!]) ?? 0\"\n [min]=\"col.counterMin ?? 0\"\n [max]=\"col.counterMax ?? 99\"\n [step]=\"col.counterStep ?? 1\"\n [disabled]=\"isCounterDisabled(col, row)\"\n [ariaLabel]=\"col.counterAriaLabel ? col.counterAriaLabel(row) : col.header\"\n [decreaseLabel]=\"col.counterDecreaseLabel ?? 'Decrease'\"\n [increaseLabel]=\"col.counterIncreaseLabel ?? 'Increase'\"\n (valueChange)=\"onCounterChange(col, row, $event)\"\n (click)=\"$event.stopPropagation()\"\n (keypress)=\"$event.stopPropagation()\"\n (keydown)=\"$event.stopPropagation()\"></tk-counter>\n </td>\n }\n\n <!-- TOGGLE (Boolean field, switch) -->\n @if (col.type === 'toggle') {\n <td>\n @if (col.toggleTooltip) {\n <tk-tooltip [content]=\"col.toggleTooltip(row, $any(row[col.field!]) ?? false)\">\n <ng-container [ngTemplateOutlet]=\"toggleSwitch\" />\n </tk-tooltip>\n } @else {\n <ng-container [ngTemplateOutlet]=\"toggleSwitch\" />\n }\n <ng-template #toggleSwitch>\n <tk-toggle\n [model]=\"$any(row[col.field!]) ?? false\"\n [disabled]=\"isToggleDisabled(col, row)\"\n [label]=\"col.toggleLabel ? col.toggleLabel(row) : ''\"\n (modelChange)=\"onToggleChange(col, row, $event)\"\n (click)=\"$event.stopPropagation()\"\n (keypress)=\"$event.stopPropagation()\"\n (keydown)=\"$event.stopPropagation()\"></tk-toggle>\n </ng-template>\n </td>\n }\n\n <!-- TEXT (default) -->\n @if (!col.type || col.type === 'text') {\n <td\n [class.tk-table__cell--truncate]=\"col.truncate\"\n [style.max-width]=\"col.truncate ? (col.width ?? '200px') : null\">\n @if (col.icon) {\n <span class=\"tk-table__cell-icon-text\">\n <tk-icon [icon]=\"col.icon(row)\" [color]=\"col.iconColor ? col.iconColor(row) : undefined\" size=\"sm\" />\n <span>{{ row[col.field!] }}</span>\n </span>\n } @else {\n {{ row[col.field!] }}\n }\n </td>\n }\n\n <!-- TAG -->\n @if (col.type === 'tag') {\n <td>\n <tk-tag [value]=\"row[col.field!]\" [severity]=\"col.tagSeverity!(row)\" />\n </td>\n }\n\n <!-- ACTIONS -->\n @if (col.type === 'actions') {\n <td>\n <div class=\"tk-table__actions\">\n @for (action of col.actions!; track action.icon) {\n <tk-button [icon]=\"action.icon\" severity=\"secondary\" (click)=\"$event.stopPropagation()\"\n (keypress)=\"$event.stopPropagation()\" (clicked)=\"action?.action(row)\"></tk-button>\n }\n </div>\n </td>\n }\n\n <!-- ACTION GROUP -->\n @if (col.type === 'action-group') {\n <td>\n <div class=\"tk-table__actions\">\n <tk-action-group\n [actions]=\"getActionGroup(col.actionGroup!, row)\"\n [maxVisible]=\"col.actionGroupMaxVisible ?? 2\"\n [disabled]=\"col.actionGroupDisabled ?? false\"\n (click)=\"$event.stopPropagation()\"\n (keypress)=\"$event.stopPropagation()\"\n ></tk-action-group>\n </div>\n </td>\n }\n\n <!-- CONNECTION STATUS -->\n @if (col.type === 'connection-status') {\n <td>\n <tk-time-ago\n [dateTime]=\"row[col.field!]\"\n [severity]=\"col.connectionStatusSeverity ? col.connectionStatusSeverity(row) : 'success'\"\n [tooltipText]=\"col.connectionStatusTooltipText ? col.connectionStatusTooltipText(row) : undefined\" />\n </td>\n }\n\n <!-- IMAGE -->\n @if (col.type === 'image') {\n <td>\n <div class=\"tk-table__cell-img-wrapper\">\n @let imageCount = getImageCount(col, row);\n @if (imageCount > 1) {\n <tk-badge\n [value]=\"imageCount + ''\"\n [severity]=\"col.imageCountSeverity ? col.imageCountSeverity(row) : 'primary'\"\n [overlay]=\"true\">\n <ng-container [ngTemplateOutlet]=\"cellImg\" />\n </tk-badge>\n } @else {\n <ng-container [ngTemplateOutlet]=\"cellImg\" />\n }\n </div>\n <ng-template #cellImg>\n <img\n class=\"tk-table__cell-img\"\n [class.tk-table__cell-img--clickable]=\"!!col.imageAction\"\n [src]=\"row[col.field!]\"\n [alt]=\"col.imageAlt ? col.imageAlt(row) : ''\"\n [style.width]=\"col.imageWidth ?? '40px'\"\n [style.height]=\"col.imageHeight ?? '40px'\"\n [attr.tabindex]=\"col.imageAction ? 0 : null\"\n [attr.role]=\"col.imageAction ? 'button' : null\"\n (click)=\"handleImageClick($event, col, row)\"\n (keydown.enter)=\"col.imageAction && col.imageAction(row)\"\n (error)=\"onImageError($event, col.imageFallback)\"\n />\n </ng-template>\n </td>\n }\n }\n </tr>\n </ng-template>\n</p-table>\n\n<!-- Filter Overlay rendered outside the table to avoid overflow clipping -->\n@if (activeFilterColumn()) {\n<div class=\"tk-table__filter-backdrop\"\n tabindex=\"-1\"\n (click)=\"closeFilterOverlay()\"\n (keydown.escape)=\"closeFilterOverlay()\"></div>\n<div\n class=\"tk-table__filter-overlay\"\n tabindex=\"-1\"\n [style.top.px]=\"filterOverlayPosition().top\"\n [style.left.px]=\"filterOverlayPosition().left\"\n (click)=\"$event.stopPropagation()\"\n (keydown.escape)=\"closeFilterOverlay()\">\n <div class=\"tk-table__filter-list\">\n @for (option of getUniqueColumnValues(activeFilterColumn()!); track option) {\n <button\n class=\"tk-table__filter-option\"\n [class.tk-table__filter-option--selected]=\"getActiveFilterValue(activeFilterColumn()!) === option\"\n type=\"button\"\n [attr.aria-pressed]=\"getActiveFilterValue(activeFilterColumn()!) === option\"\n (click)=\"selectFilterValue(activeFilterColumn()!, option)\">\n {{ option }}\n </button>\n }\n </div>\n @if (isColumnFiltered(activeFilterColumn()!)) {\n <div class=\"tk-table__filter-clear\">\n <button\n class=\"tk-table__filter-clear-btn\"\n type=\"button\"\n (click)=\"clearFilter(activeFilterColumn()!)\">\n Clear filter\n </button>\n </div>\n }\n</div>\n}", styles: [":host{display:block;min-width:0}:host ::ng-deep .p-datatable-column-sorted{background-color:var(--tk-primary-100, #b7b0d2)!important;color:var(--tk-primary-700, #10004f)!important}:host ::ng-deep .p-datatable-column-sorted svg{color:var(--tk-primary-700, #10004f)!important}:host ::ng-deep .p-datatable-sortable-column{font-size:var(--tk-font-size-sm, .875rem);color:var(--tk-surface-950, #191a1b);padding:.625rem}:host ::ng-deep .p-datatable-sortable-column svg{color:var(--tk-surface-500, #424243)}:host ::ng-deep .p-button-secondary{background-color:var(--tk-surface-0, #ffffff);border:1px solid var(--tk-surface-0, #ffffff)}:host ::ng-deep .p-datatable-tbody td{color:var(--tk-surface-950, #191a1b);font-size:var(--tk-font-size-sm, .875rem);padding:.625rem}:host ::ng-deep .tk-table__cell--truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.tk-table__cell-icon-text{display:inline-flex;align-items:center;gap:var(--tk-spacing-gap-xs, .25rem)}.tk-table__cell-img-wrapper{display:inline-flex}.tk-table__cell-img{display:block;object-fit:cover}.tk-table__cell-img--clickable{cursor:pointer}.tk-table__actions{display:flex;gap:var(--tk-spacing-gap-xs, .25rem)}.tk-table__header-content{display:flex;align-items:center;gap:.25rem;width:100%}.tk-table__header-label{white-space:nowrap}.tk-table__header--active{background-color:var(--tk-primary-100, #b7b0d2)!important}.tk-table__filter-trigger{display:inline-flex;align-items:center;justify-content:center;width:1.5rem;height:1.5rem;border:none;background:transparent;border-radius:var(--tk-border-radius-xs, 4px);cursor:pointer;color:var(--tk-surface-500, #8a8a8b);transition:background-color .2s,color .2s;padding:0;margin-left:auto}.tk-table__filter-trigger:hover{background-color:var(--tk-surface-200, #e4e4e4);color:var(--tk-surface-700, #424243)}.tk-table__filter-trigger--active{color:var(--tk-primary-700, #10004f);background-color:var(--tk-primary-50, #e8e6f1)}.tk-table__filter-trigger--active:hover{background-color:var(--tk-primary-100, #b7b0d2);color:var(--tk-primary-700, #10004f)}.tk-table__filter-backdrop{position:fixed;top:0;left:0;width:100%;height:100%;z-index:999;background:transparent}.tk-table__filter-overlay{position:fixed;z-index:1000;min-width:10rem;max-height:15rem;background-color:var(--tk-surface-0, #ffffff);border:1px solid var(--tk-surface-200, #e4e4e4);border-radius:var(--tk-border-radius-s, 8px);box-shadow:0 4px 16px #0000001f;overflow:hidden;display:flex;flex-direction:column;animation:tk-filter-fade-in .15s ease-out}.tk-table__filter-list{margin:0;padding:.25rem 0;overflow-y:auto;max-height:12rem;display:flex;flex-direction:column}.tk-table__filter-option{display:block;width:100%;padding:.5rem .75rem;font-size:.875rem;color:var(--tk-surface-950, #191a1b);cursor:pointer;transition:background-color .15s;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;border:none;background:transparent;text-align:left}.tk-table__filter-option:hover{background-color:var(--tk-surface-100, #f2f1f1)}.tk-table__filter-option--selected{background-color:var(--tk-primary-50, #e8e6f1);color:var(--tk-primary-700, #10004f);font-weight:600}.tk-table__filter-option--selected:hover{background-color:var(--tk-primary-100, #b7b0d2)}.tk-table__filter-clear{border-top:1px solid var(--tk-surface-200, #e4e4e4);padding:.375rem .75rem;display:flex;justify-content:center}.tk-table__filter-clear-btn{background:transparent;border:none;color:var(--tk-primary-500, #16006f);font-size:.8125rem;font-weight:600;cursor:pointer;padding:.25rem .5rem;border-radius:var(--tk-border-radius-xs, 4px);transition:background-color .15s}.tk-table__filter-clear-btn:hover{background-color:var(--tk-primary-50, #e8e6f1)}:host ::ng-deep .p-datatable-thead>tr>th{position:relative}@keyframes tk-filter-fade-in{0%{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:translateY(0)}}\n"], dependencies: [{ kind: "ngmodule", type: TableModule }, { kind: "component", type: i1.Table, selector: "p-table", inputs: ["frozenColumns", "frozenValue", "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", "rowGroupMode", "scrollHeight", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "virtualScrollDelay", "frozenWidth", "contextMenu", "resizableColumns", "columnResizeMode", "reorderableColumns", "loading", "loadingIcon", "showLoader", "rowHover", "customSort", "showInitialSortBadge", "exportFunction", "exportHeader", "stateKey", "stateStorage", "editMode", "groupRowsBy", "size", "showGridlines", "stripedRows", "groupRowsByOrder", "responsiveLayout", "breakpoint", "paginatorLocale", "value", "columns", "first", "rows", "totalRecords", "sortField", "sortOrder", "multiSortMeta", "selection", "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: i2.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "directive", type: i1.SortableColumn, selector: "[pSortableColumn]", inputs: ["pSortableColumn", "pSortableColumnDisabled"] }, { kind: "directive", type: i1.SelectableRow, selector: "[pSelectableRow]", inputs: ["pSelectableRow", "pSelectableRowIndex", "pSelectableRowDisabled"] }, { kind: "component", type: i1.SortIcon, selector: "p-sortIcon", inputs: ["field"] }, { kind: "ngmodule", type: TagModule }, { kind: "ngmodule", type: ButtonModule }, { kind: "component", type: TagComponent, selector: "tk-tag", inputs: ["value", "severity", "truncationLimit"] }, { kind: "component", type: ButtonComponent, selector: "tk-button", inputs: ["label", "disabled", "type", "severity", "variant", "link", "icon", "iconPosition", "tooltipText", "full", "ariaLabel", "size"], outputs: ["clicked"] }, { kind: "component", type: CheckboxComponent, selector: "tk-checkbox", inputs: ["model", "value", "label", "name", "inputId", "binary", "control", "errorMessage", "hint", "indeterminate", "disabled"], outputs: ["modelChange", "indeterminateChange", "disabledChange"] }, { kind: "component", type: ActionGroupComponent, selector: "tk-action-group", inputs: ["actions", "maxVisible", "disabled"] }, { kind: "component", type: IconComponent, selector: "tk-icon", inputs: ["icon", "styleIcon", "color", "size", "disabled"] }, { kind: "component", type: TimeAgoComponent, selector: "tk-time-ago", inputs: ["dateTime", "severity", "tooltipText", "tooltipFormat"] }, { kind: "component", type: CounterComponent, selector: "tk-counter", inputs: ["value", "min", "max", "step", "disabled", "readonly", "control", "decreaseLabel", "increaseLabel", "ariaLabel", "ariaLabelledby"], outputs: ["valueChange", "disabledChange"] }, { kind: "component", type: BadgeComponent, selector: "tk-badge", inputs: ["value", "severity", "overlay"] }, { kind: "component", type: ToggleComponent, selector: "tk-toggle", inputs: ["model", "label", "name", "inputId", "control", "errorMessage", "hint", "disabled"], outputs: ["modelChange", "disabledChange"] }, { kind: "component", type: TooltipComponent, selector: "tk-tooltip", inputs: ["content", "position"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
761
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.17", type: TableComponent, isStandalone: true, selector: "tk-table", inputs: { data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: false, transformFunction: null }, columns: { classPropertyName: "columns", publicName: "columns", isSignal: true, isRequired: false, transformFunction: null }, reorderableRows: { classPropertyName: "reorderableRows", publicName: "reorderableRows", isSignal: true, isRequired: false, transformFunction: null }, reorderHandleLabel: { classPropertyName: "reorderHandleLabel", publicName: "reorderHandleLabel", isSignal: true, isRequired: false, transformFunction: null }, reorderMovedLabel: { classPropertyName: "reorderMovedLabel", publicName: "reorderMovedLabel", isSignal: true, isRequired: false, transformFunction: null }, imageLoadingLabel: { classPropertyName: "imageLoadingLabel", publicName: "imageLoadingLabel", isSignal: true, isRequired: false, transformFunction: null }, selectionMode: { classPropertyName: "selectionMode", publicName: "selectionMode", isSignal: true, isRequired: false, transformFunction: null }, selection: { classPropertyName: "selection", publicName: "selection", isSignal: true, isRequired: false, transformFunction: null }, dataKey: { classPropertyName: "dataKey", publicName: "dataKey", isSignal: true, isRequired: false, transformFunction: null }, hiddenColumns: { classPropertyName: "hiddenColumns", publicName: "hiddenColumns", isSignal: true, isRequired: false, transformFunction: null }, minTableWidth: { classPropertyName: "minTableWidth", publicName: "minTableWidth", isSignal: true, isRequired: false, transformFunction: null }, columnFilters: { classPropertyName: "columnFilters", publicName: "columnFilters", isSignal: true, isRequired: false, transformFunction: null }, sortField: { classPropertyName: "sortField", publicName: "sortField", isSignal: true, isRequired: false, transformFunction: null }, sortOrder: { classPropertyName: "sortOrder", publicName: "sortOrder", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { data: "dataChange", rowReorder: "rowReorder", selection: "selectionChange", columnFilters: "columnFiltersChange", sortField: "sortFieldChange", sortOrder: "sortOrderChange" }, viewQueries: [{ propertyName: "tableRef", first: true, predicate: ["tableRef"], descendants: true, isSignal: true }], ngImport: i0, template: "<p-table #tableRef [selection]=\"selection()\" (selectionChange)=\"updateSelection($any($event))\"\n [selectionMode]=\"selectionMode()\" [dataKey]=\"dataKey()\" [value]=\"internalData()\" [customSort]=\"true\"\n (sortFunction)=\"customSort($event)\" [tableStyle]=\"minTableWidth() ? { 'min-width': minTableWidth() } : {}\" responsiveLayout=\"scroll\"\n (onRowReorder)=\"onRowReorder($event)\">\n <!-- HEADER -->\n <ng-template pTemplate=\"header\">\n <tr>\n @if (reorderableRows()) {\n <th class=\"tk-table__row-reorder-th\" scope=\"col\">\n <span class=\"tk-table__sr-only\">{{ reorderHandleLabel() }}</span>\n </th>\n }\n @for (col of visibleColumns(); track col.field ?? $index) {\n <th [id]=\"col.field\" [style.width]=\"col.width\"\n [pSortableColumn]=\"col.sortable ? col.field : undefined\"\n [class.tk-table__header--active]=\"activeFilterColumn() === col.field || isColumnFiltered(col.field!)\">\n <div class=\"tk-table__header-content\">\n @if (col.type === 'selection' && selectionMode() === 'multiple') {\n <div class=\"tk-table__actions hide-validation-messages\">\n <tk-checkbox [binary]=\"true\" [model]=\"isAllSelected()\" [indeterminate]=\"isPartiallySelected()\"\n (click)=\"$event.stopPropagation()\" (keypress)=\"$event.stopPropagation()\"\n (modelChange)=\"toggleAll($event)\"></tk-checkbox>\n </div>\n } @else if (col.type !== 'selection') {\n <span class=\"tk-table__header-label\">{{ col.header }}</span>\n @if (col.sortable) {\n <p-sortIcon [field]=\"col.field\"></p-sortIcon>\n }\n @if (col.filterable && col.field) {\n <button\n class=\"tk-table__filter-trigger\"\n [class.tk-table__filter-trigger--active]=\"isColumnFiltered(col.field)\"\n (click)=\"toggleFilterOverlay(col.field, $event)\"\n type=\"button\"\n [attr.aria-label]=\"'Filter ' + col.header\">\n <tk-icon icon=\"filter\" size=\"sm\"></tk-icon>\n </button>\n }\n }\n </div>\n </th>\n }\n </tr>\n </ng-template>\n\n <!-- BODY -->\n <ng-template pTemplate=\"body\" let-row let-rowIndex=\"rowIndex\">\n <tr [pSelectableRow]=\"row\" [pReorderableRow]=\"rowIndex\" [pReorderableRowDisabled]=\"!reorderableRows()\">\n @if (reorderableRows()) {\n <td class=\"tk-table__row-reorder-td\">\n <!-- Without pReorderableRowHandle PrimeNG never makes the row draggable -->\n @if (canReorderRows()) {\n <tk-button\n class=\"tk-table__row-reorder-handle\"\n pReorderableRowHandle\n icon=\"grip-vertical\"\n severity=\"secondary\"\n variant=\"text\"\n size=\"small\"\n [ariaLabel]=\"reorderHandleLabel()\"\n (click)=\"$event.stopPropagation()\"\n (keydown)=\"onReorderHandleKeydown($event, rowIndex)\" />\n } @else {\n <tk-button\n class=\"tk-table__row-reorder-handle\"\n icon=\"grip-vertical\"\n severity=\"secondary\"\n variant=\"text\"\n size=\"small\"\n [ariaLabel]=\"reorderHandleLabel()\"\n [disabled]=\"true\"\n (click)=\"$event.stopPropagation()\"\n (keydown)=\"$event.stopPropagation()\" />\n }\n </td>\n }\n @for (col of visibleColumns(); track col.field ?? $index) {\n <!-- SELECTION -->\n @if (col.type === 'selection') {\n <td>\n @if (selectionMode() === 'multiple') {\n <tk-checkbox [model]=\"selection()\" [value]=\"row\" (click)=\"$event.stopPropagation()\"\n (keypress)=\"$event.stopPropagation()\" (modelChange)=\"updateSelection($any($event))\"></tk-checkbox>\n }\n </td>\n }\n\n <!-- CHECKBOX (Boolean field) -->\n @if (col.type === 'checkbox') {\n <td>\n <tk-checkbox [binary]=\"true\" [(model)]=\"row[col.field!]\" (click)=\"$event.stopPropagation()\"\n (keypress)=\"$event.stopPropagation()\"></tk-checkbox>\n </td>\n }\n\n <!-- COUNTER (editable integer field) -->\n @if (col.type === 'counter') {\n <td>\n <tk-counter\n [value]=\"$any(row[col.field!]) ?? 0\"\n [min]=\"col.counterMin ?? 0\"\n [max]=\"col.counterMax ?? 99\"\n [step]=\"col.counterStep ?? 1\"\n [disabled]=\"isCounterDisabled(col, row)\"\n [ariaLabel]=\"col.counterAriaLabel ? col.counterAriaLabel(row) : col.header\"\n [decreaseLabel]=\"col.counterDecreaseLabel ?? 'Decrease'\"\n [increaseLabel]=\"col.counterIncreaseLabel ?? 'Increase'\"\n (valueChange)=\"onCounterChange(col, row, $event)\"\n (click)=\"$event.stopPropagation()\"\n (keypress)=\"$event.stopPropagation()\"\n (keydown)=\"$event.stopPropagation()\"></tk-counter>\n </td>\n }\n\n <!-- TOGGLE (Boolean field, switch) -->\n @if (col.type === 'toggle') {\n <td>\n @if (col.toggleTooltip) {\n <tk-tooltip [content]=\"col.toggleTooltip(row, $any(row[col.field!]) ?? false)\">\n <ng-container [ngTemplateOutlet]=\"toggleSwitch\" />\n </tk-tooltip>\n } @else {\n <ng-container [ngTemplateOutlet]=\"toggleSwitch\" />\n }\n <ng-template #toggleSwitch>\n <tk-toggle\n [model]=\"$any(row[col.field!]) ?? false\"\n [disabled]=\"isToggleDisabled(col, row)\"\n [label]=\"col.toggleLabel ? col.toggleLabel(row) : ''\"\n (modelChange)=\"onToggleChange(col, row, $event)\"\n (click)=\"$event.stopPropagation()\"\n (keypress)=\"$event.stopPropagation()\"\n (keydown)=\"$event.stopPropagation()\"></tk-toggle>\n </ng-template>\n </td>\n }\n\n <!-- TEXT (default) -->\n @if (!col.type || col.type === 'text') {\n <td\n [class.tk-table__cell--truncate]=\"col.truncate\"\n [style.max-width]=\"col.truncate ? (col.width ?? '200px') : null\">\n @if (col.icon) {\n <span class=\"tk-table__cell-icon-text\">\n <tk-icon [icon]=\"col.icon(row)\" [color]=\"col.iconColor ? col.iconColor(row) : undefined\" size=\"sm\" />\n <span>{{ row[col.field!] }}</span>\n </span>\n } @else {\n {{ row[col.field!] }}\n }\n </td>\n }\n\n <!-- TAG -->\n @if (col.type === 'tag') {\n <td>\n <tk-tag [value]=\"row[col.field!]\" [severity]=\"col.tagSeverity!(row)\" />\n </td>\n }\n\n <!-- ACTIONS -->\n @if (col.type === 'actions') {\n <td>\n <div class=\"tk-table__actions\">\n @for (action of col.actions!; track action.icon) {\n <tk-button [icon]=\"action.icon\" severity=\"secondary\" (click)=\"$event.stopPropagation()\"\n (keypress)=\"$event.stopPropagation()\" (clicked)=\"action?.action(row)\"></tk-button>\n }\n </div>\n </td>\n }\n\n <!-- ACTION GROUP -->\n @if (col.type === 'action-group') {\n <td>\n <div class=\"tk-table__actions\">\n <tk-action-group\n [actions]=\"getActionGroup(col.actionGroup!, row)\"\n [maxVisible]=\"col.actionGroupMaxVisible ?? 2\"\n [disabled]=\"col.actionGroupDisabled ?? false\"\n (click)=\"$event.stopPropagation()\"\n (keypress)=\"$event.stopPropagation()\"\n ></tk-action-group>\n </div>\n </td>\n }\n\n <!-- CONNECTION STATUS -->\n @if (col.type === 'connection-status') {\n <td>\n <tk-time-ago\n [dateTime]=\"row[col.field!]\"\n [severity]=\"col.connectionStatusSeverity ? col.connectionStatusSeverity(row) : 'success'\"\n [tooltipText]=\"col.connectionStatusTooltipText ? col.connectionStatusTooltipText(row) : undefined\" />\n </td>\n }\n\n <!-- IMAGE -->\n @if (col.type === 'image') {\n <td>\n @let imageState = getImageState(col, row);\n @let imageWidth = col.imageWidth ?? '40px';\n @let imageHeight = col.imageHeight ?? '40px';\n <div class=\"tk-table__cell-img-wrapper\">\n @let imageCount = getImageCount(col, row);\n @if (imageCount > 1) {\n <tk-badge\n [value]=\"imageCount + ''\"\n [severity]=\"col.imageCountSeverity ? col.imageCountSeverity(row) : 'primary'\"\n [overlay]=\"true\">\n <ng-container [ngTemplateOutlet]=\"cellImg\" />\n </tk-badge>\n } @else {\n <ng-container [ngTemplateOutlet]=\"cellImg\" />\n }\n </div>\n <ng-template #cellImg>\n @switch (imageState) {\n @case ('loading') {\n <tk-skeleton\n class=\"tk-table__cell-img-skeleton\"\n [width]=\"imageWidth\"\n [height]=\"imageHeight\"\n [ariaLabel]=\"imageLoadingLabel()\" />\n }\n @case ('error') {\n @let errorTooltip = col.imageErrorTooltip ? col.imageErrorTooltip(row) : '';\n @if (errorTooltip) {\n <tk-tooltip [content]=\"errorTooltip\">\n <ng-container [ngTemplateOutlet]=\"imgError\" [ngTemplateOutletContext]=\"{ $implicit: errorTooltip }\" />\n </tk-tooltip>\n } @else {\n <ng-container [ngTemplateOutlet]=\"imgError\" [ngTemplateOutletContext]=\"{ $implicit: col.imageAlt ? col.imageAlt(row) : '' }\" />\n }\n <ng-template #imgError let-label>\n @let errorAction = imageCount > 1 && !!col.imageAction;\n <span\n class=\"tk-table__cell-img-error\"\n [class.tk-table__cell-img-error--clickable]=\"errorAction\"\n [style.width]=\"imageWidth\"\n [style.height]=\"imageHeight\"\n [attr.tabindex]=\"errorAction ? 0 : null\"\n [attr.role]=\"errorAction ? 'button' : null\"\n (click)=\"errorAction && handleImageClick($event, col, row)\"\n (keydown.enter)=\"errorAction && col.imageAction!(row)\">\n <tk-icon aria-hidden=\"true\" icon=\"triangle-exclamation\" styleIcon=\"regular\" />\n @if (label) {\n <span class=\"tk-table__sr-only\">{{ label }}</span>\n }\n </span>\n </ng-template>\n }\n @default {\n @let imageLoaded = isImageLoaded(col, row);\n <span class=\"tk-table__cell-img-frame\">\n @if (!imageLoaded) {\n <tk-skeleton class=\"tk-table__cell-img-skeleton tk-table__cell-img-skeleton--overlay\" height=\"100%\" />\n }\n <img\n class=\"tk-table__cell-img\"\n [class.tk-table__cell-img--clickable]=\"!!col.imageAction\"\n [class.tk-table__cell-img--pending]=\"!imageLoaded\"\n [src]=\"row[col.field!]\"\n [alt]=\"col.imageAlt ? col.imageAlt(row) : ''\"\n [style.width]=\"imageWidth\"\n [style.height]=\"imageHeight\"\n [attr.tabindex]=\"col.imageAction ? 0 : null\"\n [attr.role]=\"col.imageAction ? 'button' : null\"\n (click)=\"handleImageClick($event, col, row)\"\n (keydown.enter)=\"col.imageAction && col.imageAction(row)\"\n (load)=\"onImageLoad(col, row)\"\n (error)=\"onImageError($event, col, row)\"\n />\n </span>\n }\n }\n </ng-template>\n </td>\n }\n\n <!-- LINKS -->\n @if (col.type === 'links') {\n <td>\n <tk-link-group\n class=\"tk-table__cell-links\"\n [links]=\"col.links ? col.links(row) : []\"\n (click)=\"$event.stopPropagation()\"\n (keydown)=\"$event.stopPropagation()\" />\n </td>\n }\n }\n </tr>\n </ng-template>\n</p-table>\n\n@if (reorderableRows()) {\n<span class=\"tk-table__sr-only\" aria-live=\"polite\">{{ reorderAnnouncement() }}</span>\n}\n\n<!-- Filter Overlay rendered outside the table to avoid overflow clipping -->\n@if (activeFilterColumn()) {\n<div class=\"tk-table__filter-backdrop\"\n tabindex=\"-1\"\n (click)=\"closeFilterOverlay()\"\n (keydown.escape)=\"closeFilterOverlay()\"></div>\n<div\n class=\"tk-table__filter-overlay\"\n tabindex=\"-1\"\n [style.top.px]=\"filterOverlayPosition().top\"\n [style.left.px]=\"filterOverlayPosition().left\"\n (click)=\"$event.stopPropagation()\"\n (keydown.escape)=\"closeFilterOverlay()\">\n <div class=\"tk-table__filter-list\">\n @for (option of getUniqueColumnValues(activeFilterColumn()!); track option) {\n <button\n class=\"tk-table__filter-option\"\n [class.tk-table__filter-option--selected]=\"getActiveFilterValue(activeFilterColumn()!) === option\"\n type=\"button\"\n [attr.aria-pressed]=\"getActiveFilterValue(activeFilterColumn()!) === option\"\n (click)=\"selectFilterValue(activeFilterColumn()!, option)\">\n {{ option }}\n </button>\n }\n </div>\n @if (isColumnFiltered(activeFilterColumn()!)) {\n <div class=\"tk-table__filter-clear\">\n <button\n class=\"tk-table__filter-clear-btn\"\n type=\"button\"\n (click)=\"clearFilter(activeFilterColumn()!)\">\n Clear filter\n </button>\n </div>\n }\n</div>\n}", styles: [":host{display:block;min-width:0}:host ::ng-deep .p-datatable-column-sorted{background-color:var(--tk-primary-100, #b7b0d2)!important;color:var(--tk-primary-700, #10004f)!important}:host ::ng-deep .p-datatable-column-sorted svg{color:var(--tk-primary-700, #10004f)!important}:host ::ng-deep .p-datatable-sortable-column{font-size:var(--tk-font-size-sm, .875rem);color:var(--tk-surface-950, #191a1b);padding:.625rem}:host ::ng-deep .p-datatable-sortable-column svg{color:var(--tk-surface-500, #424243)}:host ::ng-deep .p-button-secondary{background-color:var(--tk-surface-0, #ffffff);border:1px solid var(--tk-surface-0, #ffffff)}:host ::ng-deep .p-datatable-tbody td{color:var(--tk-surface-950, #191a1b);font-size:var(--tk-font-size-sm, .875rem);padding:.625rem}:host ::ng-deep .tk-table__cell--truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}:host ::ng-deep .p-datatable-row-reorder-indicator-up,:host ::ng-deep .p-datatable-row-reorder-indicator-down{position:absolute;color:var(--tk-primary-500, #16006f);z-index:10}.tk-table__cell-icon-text{display:inline-flex;align-items:center;gap:var(--tk-spacing-gap-xs, .25rem)}.tk-table__cell-img-wrapper{display:inline-flex}.tk-table__cell-img{display:block;object-fit:cover}.tk-table__cell-img--clickable{cursor:pointer}.tk-table__cell-img--pending{opacity:0}.tk-table__cell-img-frame{position:relative;display:inline-flex}.tk-table__cell-img-skeleton--overlay{position:absolute;inset:0}.tk-table__cell-img-error{position:relative;display:inline-flex;align-items:center;justify-content:center;border-radius:var(--tk-borderRadius-xs, .25rem);background:var(--tk-color-feedback-danger-muted, #ffddd4);color:var(--tk-color-feedback-danger-strong, #cf2604)}.tk-table__cell-img-error--clickable{cursor:pointer}.tk-table__cell-links{max-width:100%}.tk-table__actions{display:flex;gap:var(--tk-spacing-gap-xs, .25rem)}.tk-table__header-content{display:flex;align-items:center;gap:.25rem;width:100%}.tk-table__header-label{white-space:nowrap}.tk-table__header--active{background-color:var(--tk-primary-100, #b7b0d2)!important}.tk-table__row-reorder-th,.tk-table__row-reorder-td{width:3rem!important;text-align:center;padding:.625rem .25rem!important}.tk-table__sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.tk-table__row-reorder-handle ::ng-deep .p-button:not(:disabled){cursor:grab}.tk-table__row-reorder-handle ::ng-deep .p-button:not(:disabled):active{cursor:grabbing}.tk-table__filter-trigger{display:inline-flex;align-items:center;justify-content:center;width:1.5rem;height:1.5rem;border:none;background:transparent;border-radius:var(--tk-border-radius-xs, 4px);cursor:pointer;color:var(--tk-surface-500, #8a8a8b);transition:background-color .2s,color .2s;padding:0;margin-left:auto}.tk-table__filter-trigger:hover{background-color:var(--tk-surface-200, #e4e4e4);color:var(--tk-surface-700, #424243)}.tk-table__filter-trigger--active{color:var(--tk-primary-700, #10004f);background-color:var(--tk-primary-50, #e8e6f1)}.tk-table__filter-trigger--active:hover{background-color:var(--tk-primary-100, #b7b0d2);color:var(--tk-primary-700, #10004f)}.tk-table__filter-backdrop{position:fixed;top:0;left:0;width:100%;height:100%;z-index:999;background:transparent}.tk-table__filter-overlay{position:fixed;z-index:1000;min-width:10rem;max-height:15rem;background-color:var(--tk-surface-0, #ffffff);border:1px solid var(--tk-surface-200, #e4e4e4);border-radius:var(--tk-border-radius-s, 8px);box-shadow:0 4px 16px #0000001f;overflow:hidden;display:flex;flex-direction:column;animation:tk-filter-fade-in .15s ease-out}.tk-table__filter-list{margin:0;padding:.25rem 0;overflow-y:auto;max-height:12rem;display:flex;flex-direction:column}.tk-table__filter-option{display:block;width:100%;padding:.5rem .75rem;font-size:.875rem;color:var(--tk-surface-950, #191a1b);cursor:pointer;transition:background-color .15s;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;border:none;background:transparent;text-align:left}.tk-table__filter-option:hover{background-color:var(--tk-surface-100, #f2f1f1)}.tk-table__filter-option--selected{background-color:var(--tk-primary-50, #e8e6f1);color:var(--tk-primary-700, #10004f);font-weight:600}.tk-table__filter-option--selected:hover{background-color:var(--tk-primary-100, #b7b0d2)}.tk-table__filter-clear{border-top:1px solid var(--tk-surface-200, #e4e4e4);padding:.375rem .75rem;display:flex;justify-content:center}.tk-table__filter-clear-btn{background:transparent;border:none;color:var(--tk-primary-500, #16006f);font-size:.8125rem;font-weight:600;cursor:pointer;padding:.25rem .5rem;border-radius:var(--tk-border-radius-xs, 4px);transition:background-color .15s}.tk-table__filter-clear-btn:hover{background-color:var(--tk-primary-50, #e8e6f1)}:host ::ng-deep .p-datatable-thead>tr>th{position:relative}@keyframes tk-filter-fade-in{0%{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:translateY(0)}}\n"], dependencies: [{ kind: "ngmodule", type: TableModule }, { kind: "component", type: i1.Table, selector: "p-table", inputs: ["frozenColumns", "frozenValue", "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", "rowGroupMode", "scrollHeight", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "virtualScrollDelay", "frozenWidth", "contextMenu", "resizableColumns", "columnResizeMode", "reorderableColumns", "loading", "loadingIcon", "showLoader", "rowHover", "customSort", "showInitialSortBadge", "exportFunction", "exportHeader", "stateKey", "stateStorage", "editMode", "groupRowsBy", "size", "showGridlines", "stripedRows", "groupRowsByOrder", "responsiveLayout", "breakpoint", "paginatorLocale", "value", "columns", "first", "rows", "totalRecords", "sortField", "sortOrder", "multiSortMeta", "selection", "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: i2.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "directive", type: i1.SortableColumn, selector: "[pSortableColumn]", inputs: ["pSortableColumn", "pSortableColumnDisabled"] }, { kind: "directive", type: i1.SelectableRow, selector: "[pSelectableRow]", inputs: ["pSelectableRow", "pSelectableRowIndex", "pSelectableRowDisabled"] }, { kind: "component", type: i1.SortIcon, selector: "p-sortIcon", inputs: ["field"] }, { kind: "directive", type: i1.ReorderableRowHandle, selector: "[pReorderableRowHandle]" }, { kind: "directive", type: i1.ReorderableRow, selector: "[pReorderableRow]", inputs: ["pReorderableRow", "pReorderableRowDisabled"] }, { kind: "ngmodule", type: TagModule }, { kind: "ngmodule", type: ButtonModule }, { kind: "component", type: TagComponent, selector: "tk-tag", inputs: ["value", "severity", "truncationLimit"] }, { kind: "component", type: ButtonComponent, selector: "tk-button", inputs: ["label", "disabled", "type", "severity", "variant", "link", "icon", "iconPosition", "tooltipText", "full", "ariaLabel", "size"], outputs: ["clicked"] }, { kind: "component", type: CheckboxComponent, selector: "tk-checkbox", inputs: ["model", "value", "label", "name", "inputId", "binary", "control", "errorMessage", "hint", "indeterminate", "disabled"], outputs: ["modelChange", "indeterminateChange", "disabledChange"] }, { kind: "component", type: ActionGroupComponent, selector: "tk-action-group", inputs: ["actions", "maxVisible", "disabled"] }, { kind: "component", type: IconComponent, selector: "tk-icon", inputs: ["icon", "styleIcon", "color", "size", "disabled"] }, { kind: "component", type: TimeAgoComponent, selector: "tk-time-ago", inputs: ["dateTime", "severity", "tooltipText", "tooltipFormat"] }, { kind: "component", type: CounterComponent, selector: "tk-counter", inputs: ["value", "min", "max", "step", "disabled", "readonly", "control", "decreaseLabel", "increaseLabel", "ariaLabel", "ariaLabelledby"], outputs: ["valueChange", "disabledChange"] }, { kind: "component", type: BadgeComponent, selector: "tk-badge", inputs: ["value", "severity", "overlay"] }, { kind: "component", type: ToggleComponent, selector: "tk-toggle", inputs: ["model", "label", "name", "inputId", "control", "errorMessage", "hint", "disabled"], outputs: ["modelChange", "disabledChange"] }, { kind: "component", type: TooltipComponent, selector: "tk-tooltip", inputs: ["content", "position", "lineClamp"] }, { kind: "component", type: LinkGroupComponent, selector: "tk-link-group", inputs: ["links"] }, { kind: "component", type: SkeletonComponent, selector: "tk-skeleton", inputs: ["width", "height", "shape", "size", "borderRadius", "animation", "ariaLabel"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
541
762
|
}
|
|
542
763
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: TableComponent, decorators: [{
|
|
543
764
|
type: Component,
|
|
@@ -555,9 +776,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImpo
|
|
|
555
776
|
BadgeComponent,
|
|
556
777
|
ToggleComponent,
|
|
557
778
|
TooltipComponent,
|
|
779
|
+
LinkGroupComponent,
|
|
780
|
+
SkeletonComponent,
|
|
558
781
|
NgTemplateOutlet,
|
|
559
|
-
], template: "<p-table #tableRef [selection]=\"selection()\" (selectionChange)=\"updateSelection($any($event))\"\n [selectionMode]=\"selectionMode()\" [dataKey]=\"dataKey()\" [value]=\"internalData()\" [customSort]=\"true\"\n (sortFunction)=\"customSort($event)\" [tableStyle]=\"minTableWidth() ? { 'min-width': minTableWidth() } : {}\" responsiveLayout=\"scroll\">\n <!-- HEADER -->\n <ng-template pTemplate=\"header\">\n <tr>\n @for (col of columns(); track col.header) {\n <th [id]=\"col.field\" [style.width]=\"col.width\"\n [pSortableColumn]=\"col.sortable ? col.field : undefined\"\n [class.tk-table__header--active]=\"activeFilterColumn() === col.field || isColumnFiltered(col.field!)\">\n <div class=\"tk-table__header-content\">\n @if (col.type === 'selection' && selectionMode() === 'multiple') {\n <div class=\"tk-table__actions hide-validation-messages\">\n <tk-checkbox [binary]=\"true\" [model]=\"isAllSelected()\" [indeterminate]=\"isPartiallySelected()\"\n (click)=\"$event.stopPropagation()\" (keypress)=\"$event.stopPropagation()\"\n (modelChange)=\"toggleAll($event)\"></tk-checkbox>\n </div>\n } @else if (col.type !== 'selection') {\n <span class=\"tk-table__header-label\">{{ col.header }}</span>\n @if (col.sortable) {\n <p-sortIcon [field]=\"col.field\"></p-sortIcon>\n }\n @if (col.filterable && col.field) {\n <button\n class=\"tk-table__filter-trigger\"\n [class.tk-table__filter-trigger--active]=\"isColumnFiltered(col.field)\"\n (click)=\"toggleFilterOverlay(col.field, $event)\"\n type=\"button\"\n [attr.aria-label]=\"'Filter ' + col.header\">\n <tk-icon icon=\"filter\" size=\"sm\"></tk-icon>\n </button>\n }\n }\n </div>\n </th>\n }\n </tr>\n </ng-template>\n\n <!-- BODY -->\n <ng-template pTemplate=\"body\" let-row>\n <tr [pSelectableRow]=\"row\">\n @for (col of columns(); track col.header) {\n <!-- SELECTION -->\n @if (col.type === 'selection') {\n <td>\n @if (selectionMode() === 'multiple') {\n <tk-checkbox [model]=\"selection()\" [value]=\"row\" (click)=\"$event.stopPropagation()\"\n (keypress)=\"$event.stopPropagation()\" (modelChange)=\"updateSelection($any($event))\"></tk-checkbox>\n }\n </td>\n }\n\n <!-- CHECKBOX (Boolean field) -->\n @if (col.type === 'checkbox') {\n <td>\n <tk-checkbox [binary]=\"true\" [(model)]=\"row[col.field!]\" (click)=\"$event.stopPropagation()\"\n (keypress)=\"$event.stopPropagation()\"></tk-checkbox>\n </td>\n }\n\n <!-- COUNTER (editable integer field) -->\n @if (col.type === 'counter') {\n <td>\n <tk-counter\n [value]=\"$any(row[col.field!]) ?? 0\"\n [min]=\"col.counterMin ?? 0\"\n [max]=\"col.counterMax ?? 99\"\n [step]=\"col.counterStep ?? 1\"\n [disabled]=\"isCounterDisabled(col, row)\"\n [ariaLabel]=\"col.counterAriaLabel ? col.counterAriaLabel(row) : col.header\"\n [decreaseLabel]=\"col.counterDecreaseLabel ?? 'Decrease'\"\n [increaseLabel]=\"col.counterIncreaseLabel ?? 'Increase'\"\n (valueChange)=\"onCounterChange(col, row, $event)\"\n (click)=\"$event.stopPropagation()\"\n (keypress)=\"$event.stopPropagation()\"\n (keydown)=\"$event.stopPropagation()\"></tk-counter>\n </td>\n }\n\n <!-- TOGGLE (Boolean field, switch) -->\n @if (col.type === 'toggle') {\n <td>\n @if (col.toggleTooltip) {\n <tk-tooltip [content]=\"col.toggleTooltip(row, $any(row[col.field!]) ?? false)\">\n <ng-container [ngTemplateOutlet]=\"toggleSwitch\" />\n </tk-tooltip>\n } @else {\n <ng-container [ngTemplateOutlet]=\"toggleSwitch\" />\n }\n <ng-template #toggleSwitch>\n <tk-toggle\n [model]=\"$any(row[col.field!]) ?? false\"\n [disabled]=\"isToggleDisabled(col, row)\"\n [label]=\"col.toggleLabel ? col.toggleLabel(row) : ''\"\n (modelChange)=\"onToggleChange(col, row, $event)\"\n (click)=\"$event.stopPropagation()\"\n (keypress)=\"$event.stopPropagation()\"\n (keydown)=\"$event.stopPropagation()\"></tk-toggle>\n </ng-template>\n </td>\n }\n\n <!-- TEXT (default) -->\n @if (!col.type || col.type === 'text') {\n <td\n [class.tk-table__cell--truncate]=\"col.truncate\"\n [style.max-width]=\"col.truncate ? (col.width ?? '200px') : null\">\n @if (col.icon) {\n <span class=\"tk-table__cell-icon-text\">\n <tk-icon [icon]=\"col.icon(row)\" [color]=\"col.iconColor ? col.iconColor(row) : undefined\" size=\"sm\" />\n <span>{{ row[col.field!] }}</span>\n </span>\n } @else {\n {{ row[col.field!] }}\n }\n </td>\n }\n\n <!-- TAG -->\n @if (col.type === 'tag') {\n <td>\n <tk-tag [value]=\"row[col.field!]\" [severity]=\"col.tagSeverity!(row)\" />\n </td>\n }\n\n <!-- ACTIONS -->\n @if (col.type === 'actions') {\n <td>\n <div class=\"tk-table__actions\">\n @for (action of col.actions!; track action.icon) {\n <tk-button [icon]=\"action.icon\" severity=\"secondary\" (click)=\"$event.stopPropagation()\"\n (keypress)=\"$event.stopPropagation()\" (clicked)=\"action?.action(row)\"></tk-button>\n }\n </div>\n </td>\n }\n\n <!-- ACTION GROUP -->\n @if (col.type === 'action-group') {\n <td>\n <div class=\"tk-table__actions\">\n <tk-action-group\n [actions]=\"getActionGroup(col.actionGroup!, row)\"\n [maxVisible]=\"col.actionGroupMaxVisible ?? 2\"\n [disabled]=\"col.actionGroupDisabled ?? false\"\n (click)=\"$event.stopPropagation()\"\n (keypress)=\"$event.stopPropagation()\"\n ></tk-action-group>\n </div>\n </td>\n }\n\n <!-- CONNECTION STATUS -->\n @if (col.type === 'connection-status') {\n <td>\n <tk-time-ago\n [dateTime]=\"row[col.field!]\"\n [severity]=\"col.connectionStatusSeverity ? col.connectionStatusSeverity(row) : 'success'\"\n [tooltipText]=\"col.connectionStatusTooltipText ? col.connectionStatusTooltipText(row) : undefined\" />\n </td>\n }\n\n <!-- IMAGE -->\n @if (col.type === 'image') {\n <td>\n <div class=\"tk-table__cell-img-wrapper\">\n @let imageCount = getImageCount(col, row);\n @if (imageCount > 1) {\n <tk-badge\n [value]=\"imageCount + ''\"\n [severity]=\"col.imageCountSeverity ? col.imageCountSeverity(row) : 'primary'\"\n [overlay]=\"true\">\n <ng-container [ngTemplateOutlet]=\"cellImg\" />\n </tk-badge>\n } @else {\n <ng-container [ngTemplateOutlet]=\"cellImg\" />\n }\n </div>\n <ng-template #cellImg>\n <img\n class=\"tk-table__cell-img\"\n [class.tk-table__cell-img--clickable]=\"!!col.imageAction\"\n [src]=\"row[col.field!]\"\n [alt]=\"col.imageAlt ? col.imageAlt(row) : ''\"\n [style.width]=\"col.imageWidth ?? '40px'\"\n [style.height]=\"col.imageHeight ?? '40px'\"\n [attr.tabindex]=\"col.imageAction ? 0 : null\"\n [attr.role]=\"col.imageAction ? 'button' : null\"\n (click)=\"handleImageClick($event, col, row)\"\n (keydown.enter)=\"col.imageAction && col.imageAction(row)\"\n (error)=\"onImageError($event, col.imageFallback)\"\n />\n </ng-template>\n </td>\n }\n }\n </tr>\n </ng-template>\n</p-table>\n\n<!-- Filter Overlay rendered outside the table to avoid overflow clipping -->\n@if (activeFilterColumn()) {\n<div class=\"tk-table__filter-backdrop\"\n tabindex=\"-1\"\n (click)=\"closeFilterOverlay()\"\n (keydown.escape)=\"closeFilterOverlay()\"></div>\n<div\n class=\"tk-table__filter-overlay\"\n tabindex=\"-1\"\n [style.top.px]=\"filterOverlayPosition().top\"\n [style.left.px]=\"filterOverlayPosition().left\"\n (click)=\"$event.stopPropagation()\"\n (keydown.escape)=\"closeFilterOverlay()\">\n <div class=\"tk-table__filter-list\">\n @for (option of getUniqueColumnValues(activeFilterColumn()!); track option) {\n <button\n class=\"tk-table__filter-option\"\n [class.tk-table__filter-option--selected]=\"getActiveFilterValue(activeFilterColumn()!) === option\"\n type=\"button\"\n [attr.aria-pressed]=\"getActiveFilterValue(activeFilterColumn()!) === option\"\n (click)=\"selectFilterValue(activeFilterColumn()!, option)\">\n {{ option }}\n </button>\n }\n </div>\n @if (isColumnFiltered(activeFilterColumn()!)) {\n <div class=\"tk-table__filter-clear\">\n <button\n class=\"tk-table__filter-clear-btn\"\n type=\"button\"\n (click)=\"clearFilter(activeFilterColumn()!)\">\n Clear filter\n </button>\n </div>\n }\n</div>\n}", styles: [":host{display:block;min-width:0}:host ::ng-deep .p-datatable-column-sorted{background-color:var(--tk-primary-100, #b7b0d2)!important;color:var(--tk-primary-700, #10004f)!important}:host ::ng-deep .p-datatable-column-sorted svg{color:var(--tk-primary-700, #10004f)!important}:host ::ng-deep .p-datatable-sortable-column{font-size:var(--tk-font-size-sm, .875rem);color:var(--tk-surface-950, #191a1b);padding:.625rem}:host ::ng-deep .p-datatable-sortable-column svg{color:var(--tk-surface-500, #424243)}:host ::ng-deep .p-button-secondary{background-color:var(--tk-surface-0, #ffffff);border:1px solid var(--tk-surface-0, #ffffff)}:host ::ng-deep .p-datatable-tbody td{color:var(--tk-surface-950, #191a1b);font-size:var(--tk-font-size-sm, .875rem);padding:.625rem}:host ::ng-deep .tk-table__cell--truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.tk-table__cell-icon-text{display:inline-flex;align-items:center;gap:var(--tk-spacing-gap-xs, .25rem)}.tk-table__cell-img-wrapper{display:inline-flex}.tk-table__cell-img{display:block;object-fit:cover}.tk-table__cell-img--clickable{cursor:pointer}.tk-table__actions{display:flex;gap:var(--tk-spacing-gap-xs, .25rem)}.tk-table__header-content{display:flex;align-items:center;gap:.25rem;width:100%}.tk-table__header-label{white-space:nowrap}.tk-table__header--active{background-color:var(--tk-primary-100, #b7b0d2)!important}.tk-table__filter-trigger{display:inline-flex;align-items:center;justify-content:center;width:1.5rem;height:1.5rem;border:none;background:transparent;border-radius:var(--tk-border-radius-xs, 4px);cursor:pointer;color:var(--tk-surface-500, #8a8a8b);transition:background-color .2s,color .2s;padding:0;margin-left:auto}.tk-table__filter-trigger:hover{background-color:var(--tk-surface-200, #e4e4e4);color:var(--tk-surface-700, #424243)}.tk-table__filter-trigger--active{color:var(--tk-primary-700, #10004f);background-color:var(--tk-primary-50, #e8e6f1)}.tk-table__filter-trigger--active:hover{background-color:var(--tk-primary-100, #b7b0d2);color:var(--tk-primary-700, #10004f)}.tk-table__filter-backdrop{position:fixed;top:0;left:0;width:100%;height:100%;z-index:999;background:transparent}.tk-table__filter-overlay{position:fixed;z-index:1000;min-width:10rem;max-height:15rem;background-color:var(--tk-surface-0, #ffffff);border:1px solid var(--tk-surface-200, #e4e4e4);border-radius:var(--tk-border-radius-s, 8px);box-shadow:0 4px 16px #0000001f;overflow:hidden;display:flex;flex-direction:column;animation:tk-filter-fade-in .15s ease-out}.tk-table__filter-list{margin:0;padding:.25rem 0;overflow-y:auto;max-height:12rem;display:flex;flex-direction:column}.tk-table__filter-option{display:block;width:100%;padding:.5rem .75rem;font-size:.875rem;color:var(--tk-surface-950, #191a1b);cursor:pointer;transition:background-color .15s;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;border:none;background:transparent;text-align:left}.tk-table__filter-option:hover{background-color:var(--tk-surface-100, #f2f1f1)}.tk-table__filter-option--selected{background-color:var(--tk-primary-50, #e8e6f1);color:var(--tk-primary-700, #10004f);font-weight:600}.tk-table__filter-option--selected:hover{background-color:var(--tk-primary-100, #b7b0d2)}.tk-table__filter-clear{border-top:1px solid var(--tk-surface-200, #e4e4e4);padding:.375rem .75rem;display:flex;justify-content:center}.tk-table__filter-clear-btn{background:transparent;border:none;color:var(--tk-primary-500, #16006f);font-size:.8125rem;font-weight:600;cursor:pointer;padding:.25rem .5rem;border-radius:var(--tk-border-radius-xs, 4px);transition:background-color .15s}.tk-table__filter-clear-btn:hover{background-color:var(--tk-primary-50, #e8e6f1)}:host ::ng-deep .p-datatable-thead>tr>th{position:relative}@keyframes tk-filter-fade-in{0%{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:translateY(0)}}\n"] }]
|
|
560
|
-
}], ctorParameters: () => [], propDecorators: { data: [{ type: i0.Input, args: [{ isSignal: true, alias: "data", required: false }] }], tableRef: [{ type: i0.ViewChild, args: ['tableRef', { isSignal: true }] }], columns: [{ type: i0.Input, args: [{ isSignal: true, alias: "columns", required: false }] }], selectionMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectionMode", required: false }] }], selection: [{ type: i0.Input, args: [{ isSignal: true, alias: "selection", required: false }] }, { type: i0.Output, args: ["selectionChange"] }], dataKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "dataKey", required: false }] }], minTableWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "minTableWidth", required: false }] }], columnFilters: [{ type: i0.Input, args: [{ isSignal: true, alias: "columnFilters", required: false }] }, { type: i0.Output, args: ["columnFiltersChange"] }], sortField: [{ type: i0.Input, args: [{ isSignal: true, alias: "sortField", required: false }] }, { type: i0.Output, args: ["sortFieldChange"] }], sortOrder: [{ type: i0.Input, args: [{ isSignal: true, alias: "sortOrder", required: false }] }, { type: i0.Output, args: ["sortOrderChange"] }] } });
|
|
782
|
+
], template: "<p-table #tableRef [selection]=\"selection()\" (selectionChange)=\"updateSelection($any($event))\"\n [selectionMode]=\"selectionMode()\" [dataKey]=\"dataKey()\" [value]=\"internalData()\" [customSort]=\"true\"\n (sortFunction)=\"customSort($event)\" [tableStyle]=\"minTableWidth() ? { 'min-width': minTableWidth() } : {}\" responsiveLayout=\"scroll\"\n (onRowReorder)=\"onRowReorder($event)\">\n <!-- HEADER -->\n <ng-template pTemplate=\"header\">\n <tr>\n @if (reorderableRows()) {\n <th class=\"tk-table__row-reorder-th\" scope=\"col\">\n <span class=\"tk-table__sr-only\">{{ reorderHandleLabel() }}</span>\n </th>\n }\n @for (col of visibleColumns(); track col.field ?? $index) {\n <th [id]=\"col.field\" [style.width]=\"col.width\"\n [pSortableColumn]=\"col.sortable ? col.field : undefined\"\n [class.tk-table__header--active]=\"activeFilterColumn() === col.field || isColumnFiltered(col.field!)\">\n <div class=\"tk-table__header-content\">\n @if (col.type === 'selection' && selectionMode() === 'multiple') {\n <div class=\"tk-table__actions hide-validation-messages\">\n <tk-checkbox [binary]=\"true\" [model]=\"isAllSelected()\" [indeterminate]=\"isPartiallySelected()\"\n (click)=\"$event.stopPropagation()\" (keypress)=\"$event.stopPropagation()\"\n (modelChange)=\"toggleAll($event)\"></tk-checkbox>\n </div>\n } @else if (col.type !== 'selection') {\n <span class=\"tk-table__header-label\">{{ col.header }}</span>\n @if (col.sortable) {\n <p-sortIcon [field]=\"col.field\"></p-sortIcon>\n }\n @if (col.filterable && col.field) {\n <button\n class=\"tk-table__filter-trigger\"\n [class.tk-table__filter-trigger--active]=\"isColumnFiltered(col.field)\"\n (click)=\"toggleFilterOverlay(col.field, $event)\"\n type=\"button\"\n [attr.aria-label]=\"'Filter ' + col.header\">\n <tk-icon icon=\"filter\" size=\"sm\"></tk-icon>\n </button>\n }\n }\n </div>\n </th>\n }\n </tr>\n </ng-template>\n\n <!-- BODY -->\n <ng-template pTemplate=\"body\" let-row let-rowIndex=\"rowIndex\">\n <tr [pSelectableRow]=\"row\" [pReorderableRow]=\"rowIndex\" [pReorderableRowDisabled]=\"!reorderableRows()\">\n @if (reorderableRows()) {\n <td class=\"tk-table__row-reorder-td\">\n <!-- Without pReorderableRowHandle PrimeNG never makes the row draggable -->\n @if (canReorderRows()) {\n <tk-button\n class=\"tk-table__row-reorder-handle\"\n pReorderableRowHandle\n icon=\"grip-vertical\"\n severity=\"secondary\"\n variant=\"text\"\n size=\"small\"\n [ariaLabel]=\"reorderHandleLabel()\"\n (click)=\"$event.stopPropagation()\"\n (keydown)=\"onReorderHandleKeydown($event, rowIndex)\" />\n } @else {\n <tk-button\n class=\"tk-table__row-reorder-handle\"\n icon=\"grip-vertical\"\n severity=\"secondary\"\n variant=\"text\"\n size=\"small\"\n [ariaLabel]=\"reorderHandleLabel()\"\n [disabled]=\"true\"\n (click)=\"$event.stopPropagation()\"\n (keydown)=\"$event.stopPropagation()\" />\n }\n </td>\n }\n @for (col of visibleColumns(); track col.field ?? $index) {\n <!-- SELECTION -->\n @if (col.type === 'selection') {\n <td>\n @if (selectionMode() === 'multiple') {\n <tk-checkbox [model]=\"selection()\" [value]=\"row\" (click)=\"$event.stopPropagation()\"\n (keypress)=\"$event.stopPropagation()\" (modelChange)=\"updateSelection($any($event))\"></tk-checkbox>\n }\n </td>\n }\n\n <!-- CHECKBOX (Boolean field) -->\n @if (col.type === 'checkbox') {\n <td>\n <tk-checkbox [binary]=\"true\" [(model)]=\"row[col.field!]\" (click)=\"$event.stopPropagation()\"\n (keypress)=\"$event.stopPropagation()\"></tk-checkbox>\n </td>\n }\n\n <!-- COUNTER (editable integer field) -->\n @if (col.type === 'counter') {\n <td>\n <tk-counter\n [value]=\"$any(row[col.field!]) ?? 0\"\n [min]=\"col.counterMin ?? 0\"\n [max]=\"col.counterMax ?? 99\"\n [step]=\"col.counterStep ?? 1\"\n [disabled]=\"isCounterDisabled(col, row)\"\n [ariaLabel]=\"col.counterAriaLabel ? col.counterAriaLabel(row) : col.header\"\n [decreaseLabel]=\"col.counterDecreaseLabel ?? 'Decrease'\"\n [increaseLabel]=\"col.counterIncreaseLabel ?? 'Increase'\"\n (valueChange)=\"onCounterChange(col, row, $event)\"\n (click)=\"$event.stopPropagation()\"\n (keypress)=\"$event.stopPropagation()\"\n (keydown)=\"$event.stopPropagation()\"></tk-counter>\n </td>\n }\n\n <!-- TOGGLE (Boolean field, switch) -->\n @if (col.type === 'toggle') {\n <td>\n @if (col.toggleTooltip) {\n <tk-tooltip [content]=\"col.toggleTooltip(row, $any(row[col.field!]) ?? false)\">\n <ng-container [ngTemplateOutlet]=\"toggleSwitch\" />\n </tk-tooltip>\n } @else {\n <ng-container [ngTemplateOutlet]=\"toggleSwitch\" />\n }\n <ng-template #toggleSwitch>\n <tk-toggle\n [model]=\"$any(row[col.field!]) ?? false\"\n [disabled]=\"isToggleDisabled(col, row)\"\n [label]=\"col.toggleLabel ? col.toggleLabel(row) : ''\"\n (modelChange)=\"onToggleChange(col, row, $event)\"\n (click)=\"$event.stopPropagation()\"\n (keypress)=\"$event.stopPropagation()\"\n (keydown)=\"$event.stopPropagation()\"></tk-toggle>\n </ng-template>\n </td>\n }\n\n <!-- TEXT (default) -->\n @if (!col.type || col.type === 'text') {\n <td\n [class.tk-table__cell--truncate]=\"col.truncate\"\n [style.max-width]=\"col.truncate ? (col.width ?? '200px') : null\">\n @if (col.icon) {\n <span class=\"tk-table__cell-icon-text\">\n <tk-icon [icon]=\"col.icon(row)\" [color]=\"col.iconColor ? col.iconColor(row) : undefined\" size=\"sm\" />\n <span>{{ row[col.field!] }}</span>\n </span>\n } @else {\n {{ row[col.field!] }}\n }\n </td>\n }\n\n <!-- TAG -->\n @if (col.type === 'tag') {\n <td>\n <tk-tag [value]=\"row[col.field!]\" [severity]=\"col.tagSeverity!(row)\" />\n </td>\n }\n\n <!-- ACTIONS -->\n @if (col.type === 'actions') {\n <td>\n <div class=\"tk-table__actions\">\n @for (action of col.actions!; track action.icon) {\n <tk-button [icon]=\"action.icon\" severity=\"secondary\" (click)=\"$event.stopPropagation()\"\n (keypress)=\"$event.stopPropagation()\" (clicked)=\"action?.action(row)\"></tk-button>\n }\n </div>\n </td>\n }\n\n <!-- ACTION GROUP -->\n @if (col.type === 'action-group') {\n <td>\n <div class=\"tk-table__actions\">\n <tk-action-group\n [actions]=\"getActionGroup(col.actionGroup!, row)\"\n [maxVisible]=\"col.actionGroupMaxVisible ?? 2\"\n [disabled]=\"col.actionGroupDisabled ?? false\"\n (click)=\"$event.stopPropagation()\"\n (keypress)=\"$event.stopPropagation()\"\n ></tk-action-group>\n </div>\n </td>\n }\n\n <!-- CONNECTION STATUS -->\n @if (col.type === 'connection-status') {\n <td>\n <tk-time-ago\n [dateTime]=\"row[col.field!]\"\n [severity]=\"col.connectionStatusSeverity ? col.connectionStatusSeverity(row) : 'success'\"\n [tooltipText]=\"col.connectionStatusTooltipText ? col.connectionStatusTooltipText(row) : undefined\" />\n </td>\n }\n\n <!-- IMAGE -->\n @if (col.type === 'image') {\n <td>\n @let imageState = getImageState(col, row);\n @let imageWidth = col.imageWidth ?? '40px';\n @let imageHeight = col.imageHeight ?? '40px';\n <div class=\"tk-table__cell-img-wrapper\">\n @let imageCount = getImageCount(col, row);\n @if (imageCount > 1) {\n <tk-badge\n [value]=\"imageCount + ''\"\n [severity]=\"col.imageCountSeverity ? col.imageCountSeverity(row) : 'primary'\"\n [overlay]=\"true\">\n <ng-container [ngTemplateOutlet]=\"cellImg\" />\n </tk-badge>\n } @else {\n <ng-container [ngTemplateOutlet]=\"cellImg\" />\n }\n </div>\n <ng-template #cellImg>\n @switch (imageState) {\n @case ('loading') {\n <tk-skeleton\n class=\"tk-table__cell-img-skeleton\"\n [width]=\"imageWidth\"\n [height]=\"imageHeight\"\n [ariaLabel]=\"imageLoadingLabel()\" />\n }\n @case ('error') {\n @let errorTooltip = col.imageErrorTooltip ? col.imageErrorTooltip(row) : '';\n @if (errorTooltip) {\n <tk-tooltip [content]=\"errorTooltip\">\n <ng-container [ngTemplateOutlet]=\"imgError\" [ngTemplateOutletContext]=\"{ $implicit: errorTooltip }\" />\n </tk-tooltip>\n } @else {\n <ng-container [ngTemplateOutlet]=\"imgError\" [ngTemplateOutletContext]=\"{ $implicit: col.imageAlt ? col.imageAlt(row) : '' }\" />\n }\n <ng-template #imgError let-label>\n @let errorAction = imageCount > 1 && !!col.imageAction;\n <span\n class=\"tk-table__cell-img-error\"\n [class.tk-table__cell-img-error--clickable]=\"errorAction\"\n [style.width]=\"imageWidth\"\n [style.height]=\"imageHeight\"\n [attr.tabindex]=\"errorAction ? 0 : null\"\n [attr.role]=\"errorAction ? 'button' : null\"\n (click)=\"errorAction && handleImageClick($event, col, row)\"\n (keydown.enter)=\"errorAction && col.imageAction!(row)\">\n <tk-icon aria-hidden=\"true\" icon=\"triangle-exclamation\" styleIcon=\"regular\" />\n @if (label) {\n <span class=\"tk-table__sr-only\">{{ label }}</span>\n }\n </span>\n </ng-template>\n }\n @default {\n @let imageLoaded = isImageLoaded(col, row);\n <span class=\"tk-table__cell-img-frame\">\n @if (!imageLoaded) {\n <tk-skeleton class=\"tk-table__cell-img-skeleton tk-table__cell-img-skeleton--overlay\" height=\"100%\" />\n }\n <img\n class=\"tk-table__cell-img\"\n [class.tk-table__cell-img--clickable]=\"!!col.imageAction\"\n [class.tk-table__cell-img--pending]=\"!imageLoaded\"\n [src]=\"row[col.field!]\"\n [alt]=\"col.imageAlt ? col.imageAlt(row) : ''\"\n [style.width]=\"imageWidth\"\n [style.height]=\"imageHeight\"\n [attr.tabindex]=\"col.imageAction ? 0 : null\"\n [attr.role]=\"col.imageAction ? 'button' : null\"\n (click)=\"handleImageClick($event, col, row)\"\n (keydown.enter)=\"col.imageAction && col.imageAction(row)\"\n (load)=\"onImageLoad(col, row)\"\n (error)=\"onImageError($event, col, row)\"\n />\n </span>\n }\n }\n </ng-template>\n </td>\n }\n\n <!-- LINKS -->\n @if (col.type === 'links') {\n <td>\n <tk-link-group\n class=\"tk-table__cell-links\"\n [links]=\"col.links ? col.links(row) : []\"\n (click)=\"$event.stopPropagation()\"\n (keydown)=\"$event.stopPropagation()\" />\n </td>\n }\n }\n </tr>\n </ng-template>\n</p-table>\n\n@if (reorderableRows()) {\n<span class=\"tk-table__sr-only\" aria-live=\"polite\">{{ reorderAnnouncement() }}</span>\n}\n\n<!-- Filter Overlay rendered outside the table to avoid overflow clipping -->\n@if (activeFilterColumn()) {\n<div class=\"tk-table__filter-backdrop\"\n tabindex=\"-1\"\n (click)=\"closeFilterOverlay()\"\n (keydown.escape)=\"closeFilterOverlay()\"></div>\n<div\n class=\"tk-table__filter-overlay\"\n tabindex=\"-1\"\n [style.top.px]=\"filterOverlayPosition().top\"\n [style.left.px]=\"filterOverlayPosition().left\"\n (click)=\"$event.stopPropagation()\"\n (keydown.escape)=\"closeFilterOverlay()\">\n <div class=\"tk-table__filter-list\">\n @for (option of getUniqueColumnValues(activeFilterColumn()!); track option) {\n <button\n class=\"tk-table__filter-option\"\n [class.tk-table__filter-option--selected]=\"getActiveFilterValue(activeFilterColumn()!) === option\"\n type=\"button\"\n [attr.aria-pressed]=\"getActiveFilterValue(activeFilterColumn()!) === option\"\n (click)=\"selectFilterValue(activeFilterColumn()!, option)\">\n {{ option }}\n </button>\n }\n </div>\n @if (isColumnFiltered(activeFilterColumn()!)) {\n <div class=\"tk-table__filter-clear\">\n <button\n class=\"tk-table__filter-clear-btn\"\n type=\"button\"\n (click)=\"clearFilter(activeFilterColumn()!)\">\n Clear filter\n </button>\n </div>\n }\n</div>\n}", styles: [":host{display:block;min-width:0}:host ::ng-deep .p-datatable-column-sorted{background-color:var(--tk-primary-100, #b7b0d2)!important;color:var(--tk-primary-700, #10004f)!important}:host ::ng-deep .p-datatable-column-sorted svg{color:var(--tk-primary-700, #10004f)!important}:host ::ng-deep .p-datatable-sortable-column{font-size:var(--tk-font-size-sm, .875rem);color:var(--tk-surface-950, #191a1b);padding:.625rem}:host ::ng-deep .p-datatable-sortable-column svg{color:var(--tk-surface-500, #424243)}:host ::ng-deep .p-button-secondary{background-color:var(--tk-surface-0, #ffffff);border:1px solid var(--tk-surface-0, #ffffff)}:host ::ng-deep .p-datatable-tbody td{color:var(--tk-surface-950, #191a1b);font-size:var(--tk-font-size-sm, .875rem);padding:.625rem}:host ::ng-deep .tk-table__cell--truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}:host ::ng-deep .p-datatable-row-reorder-indicator-up,:host ::ng-deep .p-datatable-row-reorder-indicator-down{position:absolute;color:var(--tk-primary-500, #16006f);z-index:10}.tk-table__cell-icon-text{display:inline-flex;align-items:center;gap:var(--tk-spacing-gap-xs, .25rem)}.tk-table__cell-img-wrapper{display:inline-flex}.tk-table__cell-img{display:block;object-fit:cover}.tk-table__cell-img--clickable{cursor:pointer}.tk-table__cell-img--pending{opacity:0}.tk-table__cell-img-frame{position:relative;display:inline-flex}.tk-table__cell-img-skeleton--overlay{position:absolute;inset:0}.tk-table__cell-img-error{position:relative;display:inline-flex;align-items:center;justify-content:center;border-radius:var(--tk-borderRadius-xs, .25rem);background:var(--tk-color-feedback-danger-muted, #ffddd4);color:var(--tk-color-feedback-danger-strong, #cf2604)}.tk-table__cell-img-error--clickable{cursor:pointer}.tk-table__cell-links{max-width:100%}.tk-table__actions{display:flex;gap:var(--tk-spacing-gap-xs, .25rem)}.tk-table__header-content{display:flex;align-items:center;gap:.25rem;width:100%}.tk-table__header-label{white-space:nowrap}.tk-table__header--active{background-color:var(--tk-primary-100, #b7b0d2)!important}.tk-table__row-reorder-th,.tk-table__row-reorder-td{width:3rem!important;text-align:center;padding:.625rem .25rem!important}.tk-table__sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.tk-table__row-reorder-handle ::ng-deep .p-button:not(:disabled){cursor:grab}.tk-table__row-reorder-handle ::ng-deep .p-button:not(:disabled):active{cursor:grabbing}.tk-table__filter-trigger{display:inline-flex;align-items:center;justify-content:center;width:1.5rem;height:1.5rem;border:none;background:transparent;border-radius:var(--tk-border-radius-xs, 4px);cursor:pointer;color:var(--tk-surface-500, #8a8a8b);transition:background-color .2s,color .2s;padding:0;margin-left:auto}.tk-table__filter-trigger:hover{background-color:var(--tk-surface-200, #e4e4e4);color:var(--tk-surface-700, #424243)}.tk-table__filter-trigger--active{color:var(--tk-primary-700, #10004f);background-color:var(--tk-primary-50, #e8e6f1)}.tk-table__filter-trigger--active:hover{background-color:var(--tk-primary-100, #b7b0d2);color:var(--tk-primary-700, #10004f)}.tk-table__filter-backdrop{position:fixed;top:0;left:0;width:100%;height:100%;z-index:999;background:transparent}.tk-table__filter-overlay{position:fixed;z-index:1000;min-width:10rem;max-height:15rem;background-color:var(--tk-surface-0, #ffffff);border:1px solid var(--tk-surface-200, #e4e4e4);border-radius:var(--tk-border-radius-s, 8px);box-shadow:0 4px 16px #0000001f;overflow:hidden;display:flex;flex-direction:column;animation:tk-filter-fade-in .15s ease-out}.tk-table__filter-list{margin:0;padding:.25rem 0;overflow-y:auto;max-height:12rem;display:flex;flex-direction:column}.tk-table__filter-option{display:block;width:100%;padding:.5rem .75rem;font-size:.875rem;color:var(--tk-surface-950, #191a1b);cursor:pointer;transition:background-color .15s;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;border:none;background:transparent;text-align:left}.tk-table__filter-option:hover{background-color:var(--tk-surface-100, #f2f1f1)}.tk-table__filter-option--selected{background-color:var(--tk-primary-50, #e8e6f1);color:var(--tk-primary-700, #10004f);font-weight:600}.tk-table__filter-option--selected:hover{background-color:var(--tk-primary-100, #b7b0d2)}.tk-table__filter-clear{border-top:1px solid var(--tk-surface-200, #e4e4e4);padding:.375rem .75rem;display:flex;justify-content:center}.tk-table__filter-clear-btn{background:transparent;border:none;color:var(--tk-primary-500, #16006f);font-size:.8125rem;font-weight:600;cursor:pointer;padding:.25rem .5rem;border-radius:var(--tk-border-radius-xs, 4px);transition:background-color .15s}.tk-table__filter-clear-btn:hover{background-color:var(--tk-primary-50, #e8e6f1)}:host ::ng-deep .p-datatable-thead>tr>th{position:relative}@keyframes tk-filter-fade-in{0%{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:translateY(0)}}\n"] }]
|
|
783
|
+
}], ctorParameters: () => [], propDecorators: { data: [{ type: i0.Input, args: [{ isSignal: true, alias: "data", required: false }] }, { type: i0.Output, args: ["dataChange"] }], tableRef: [{ type: i0.ViewChild, args: ['tableRef', { isSignal: true }] }], columns: [{ type: i0.Input, args: [{ isSignal: true, alias: "columns", required: false }] }], reorderableRows: [{ type: i0.Input, args: [{ isSignal: true, alias: "reorderableRows", required: false }] }], reorderHandleLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "reorderHandleLabel", required: false }] }], reorderMovedLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "reorderMovedLabel", required: false }] }], imageLoadingLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "imageLoadingLabel", required: false }] }], rowReorder: [{ type: i0.Output, args: ["rowReorder"] }], selectionMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectionMode", required: false }] }], selection: [{ type: i0.Input, args: [{ isSignal: true, alias: "selection", required: false }] }, { type: i0.Output, args: ["selectionChange"] }], dataKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "dataKey", required: false }] }], hiddenColumns: [{ type: i0.Input, args: [{ isSignal: true, alias: "hiddenColumns", required: false }] }], minTableWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "minTableWidth", required: false }] }], columnFilters: [{ type: i0.Input, args: [{ isSignal: true, alias: "columnFilters", required: false }] }, { type: i0.Output, args: ["columnFiltersChange"] }], sortField: [{ type: i0.Input, args: [{ isSignal: true, alias: "sortField", required: false }] }, { type: i0.Output, args: ["sortFieldChange"] }], sortOrder: [{ type: i0.Input, args: [{ isSignal: true, alias: "sortOrder", required: false }] }, { type: i0.Output, args: ["sortOrderChange"] }] } });
|
|
561
784
|
|
|
562
785
|
/**
|
|
563
786
|
* Generated bundle index. Do not edit.
|