integra-ng 21.0.26 → 21.1.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/integra-ng.mjs +113 -232
- package/fesm2022/integra-ng.mjs.map +1 -1
- package/package.json +1 -1
- package/types/integra-ng.d.ts +141 -166
package/fesm2022/integra-ng.mjs
CHANGED
|
@@ -7537,32 +7537,19 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImpor
|
|
|
7537
7537
|
*
|
|
7538
7538
|
* @example
|
|
7539
7539
|
* ```html
|
|
7540
|
-
* <!--
|
|
7541
|
-
* <i-table
|
|
7542
|
-
* [data]="products"
|
|
7543
|
-
* [columns]="columns"
|
|
7544
|
-
* [sortable]="true"
|
|
7545
|
-
* [paginator]="true"
|
|
7546
|
-
* [rows]="10">
|
|
7547
|
-
* </i-table>
|
|
7540
|
+
* <!-- Flat table -->
|
|
7541
|
+
* <i-table [grid]="productGrid" [sortable]="true"></i-table>
|
|
7548
7542
|
*
|
|
7549
7543
|
* <!-- Table with selection -->
|
|
7550
7544
|
* <i-table
|
|
7551
|
-
* [
|
|
7552
|
-
* [columns]="columns"
|
|
7545
|
+
* [grid]="productGrid"
|
|
7553
7546
|
* selectionMode="multiple"
|
|
7554
7547
|
* [(selection)]="selectedProducts"
|
|
7555
7548
|
* (onSelectionChange)="onSelect($event)">
|
|
7556
7549
|
* </i-table>
|
|
7557
7550
|
*
|
|
7558
|
-
* <!--
|
|
7559
|
-
* <i-table
|
|
7560
|
-
* [data]="products"
|
|
7561
|
-
* [columns]="columns"
|
|
7562
|
-
* [showActions]="true"
|
|
7563
|
-
* [actions]="tableActions"
|
|
7564
|
-
* (onAction)="handleAction($event)">
|
|
7565
|
-
* </i-table>
|
|
7551
|
+
* <!-- Expandable detail (replaces grouped mode) -->
|
|
7552
|
+
* <i-table [grid]="categoryGrid" [sortable]="true"></i-table>
|
|
7566
7553
|
* ```
|
|
7567
7554
|
*
|
|
7568
7555
|
* @remarks
|
|
@@ -7571,25 +7558,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImpor
|
|
|
7571
7558
|
*/
|
|
7572
7559
|
class ITable {
|
|
7573
7560
|
el;
|
|
7574
|
-
// ===== DATA
|
|
7575
|
-
/**
|
|
7576
|
-
* Table data as a signal input
|
|
7577
|
-
*/
|
|
7578
|
-
data = input([], ...(ngDevMode ? [{ debugName: "data" }] : []));
|
|
7579
|
-
/**
|
|
7580
|
-
* Column definitions with field, header, sortable, filterable, width properties
|
|
7581
|
-
*/
|
|
7582
|
-
columns = input([], ...(ngDevMode ? [{ debugName: "columns" }] : []));
|
|
7561
|
+
// ===== DATA =====
|
|
7583
7562
|
/**
|
|
7584
|
-
*
|
|
7585
|
-
|
|
7586
|
-
|
|
7587
|
-
|
|
7588
|
-
* Column definitions for the outer group-level table header row.
|
|
7589
|
-
* Each group's `row` object is rendered using these columns.
|
|
7590
|
-
* When omitted, only a single label column is shown for the group row.
|
|
7563
|
+
* All table data in one object: columns, rows, optional per-row actions, and
|
|
7564
|
+
* an optional `details` spec for expandable sub-tables (replaces grouped mode).
|
|
7565
|
+
*
|
|
7566
|
+
* @see GridData
|
|
7591
7567
|
*/
|
|
7592
|
-
|
|
7568
|
+
grid = input({ columns: [], rows: [] }, ...(ngDevMode ? [{ debugName: "grid" }] : []));
|
|
7593
7569
|
/**
|
|
7594
7570
|
* Message displayed when table has no data
|
|
7595
7571
|
* @default 'No data available'
|
|
@@ -7677,19 +7653,8 @@ class ITable {
|
|
|
7677
7653
|
*/
|
|
7678
7654
|
onRowUnselect = new EventEmitter();
|
|
7679
7655
|
// ===== ROW ACTIONS =====
|
|
7680
|
-
|
|
7681
|
-
|
|
7682
|
-
* @default false
|
|
7683
|
-
*/
|
|
7684
|
-
showActions = false;
|
|
7685
|
-
/**
|
|
7686
|
-
* Action button definitions
|
|
7687
|
-
*/
|
|
7688
|
-
actions = [];
|
|
7689
|
-
/**
|
|
7690
|
-
* Event emitted when an action is clicked
|
|
7691
|
-
*/
|
|
7692
|
-
onAction = new EventEmitter();
|
|
7656
|
+
// Actions are embedded inside GridData.actions — each action has its own handler.
|
|
7657
|
+
// No separate @Input or @Output is needed.
|
|
7693
7658
|
// ===== VISUAL FEATURES =====
|
|
7694
7659
|
/**
|
|
7695
7660
|
* Show striped rows
|
|
@@ -7722,16 +7687,16 @@ class ITable {
|
|
|
7722
7687
|
*/
|
|
7723
7688
|
scrollable = false;
|
|
7724
7689
|
/**
|
|
7725
|
-
*
|
|
7726
|
-
|
|
7727
|
-
scrollHeight;
|
|
7728
|
-
/**
|
|
7729
|
-
* Alias Input for convenience — developer can set `height` or `scrollHeight`.
|
|
7690
|
+
* Container height (also controls virtual scroll viewport height).
|
|
7691
|
+
* @example '400px'
|
|
7730
7692
|
*/
|
|
7731
7693
|
height;
|
|
7732
|
-
// ===== VIRTUAL SCROLL =====
|
|
7733
7694
|
/**
|
|
7734
|
-
* Enable virtual
|
|
7695
|
+
* Enable CDK virtual scroll for large datasets.
|
|
7696
|
+
* Leave `false` (default) for small/medium tables — rows are rendered with
|
|
7697
|
+
* a regular `@for` loop inside a scrollable container.
|
|
7698
|
+
* Set to `true` only when the row count is large enough (≥ ~500 rows) to
|
|
7699
|
+
* benefit from virtual rendering.
|
|
7735
7700
|
* @default false
|
|
7736
7701
|
*/
|
|
7737
7702
|
virtualScroll = false;
|
|
@@ -7761,16 +7726,6 @@ class ITable {
|
|
|
7761
7726
|
* @default false
|
|
7762
7727
|
*/
|
|
7763
7728
|
resizableColumns = false;
|
|
7764
|
-
/**
|
|
7765
|
-
* Allow column reordering
|
|
7766
|
-
* @default false
|
|
7767
|
-
*/
|
|
7768
|
-
reorderableColumns = false;
|
|
7769
|
-
/**
|
|
7770
|
-
* Enable row expansion
|
|
7771
|
-
* @default false
|
|
7772
|
-
*/
|
|
7773
|
-
rowExpandable = false;
|
|
7774
7729
|
/**
|
|
7775
7730
|
* Event emitted when a row is expanded
|
|
7776
7731
|
*/
|
|
@@ -7824,11 +7779,6 @@ class ITable {
|
|
|
7824
7779
|
* @internal
|
|
7825
7780
|
*/
|
|
7826
7781
|
expandedRows = signal(new Set(), ...(ngDevMode ? [{ debugName: "expandedRows" }] : []));
|
|
7827
|
-
/**
|
|
7828
|
-
* Expanded groups (for grouped data mode)
|
|
7829
|
-
* @internal
|
|
7830
|
-
*/
|
|
7831
|
-
expandedGroups = signal(new Set(), ...(ngDevMode ? [{ debugName: "expandedGroups" }] : []));
|
|
7832
7782
|
/**
|
|
7833
7783
|
* Filter debounce timer
|
|
7834
7784
|
* @internal
|
|
@@ -7856,29 +7806,26 @@ class ITable {
|
|
|
7856
7806
|
columnWidths = signal({}, ...(ngDevMode ? [{ debugName: "columnWidths" }] : []));
|
|
7857
7807
|
constructor(el) {
|
|
7858
7808
|
this.el = el;
|
|
7859
|
-
effect(() => {
|
|
7860
|
-
const groups = this.groupedData();
|
|
7861
|
-
if (groups.length > 0) {
|
|
7862
|
-
const initialExpandedGroups = new Set();
|
|
7863
|
-
groups.forEach((group, index) => {
|
|
7864
|
-
if (group.expanded !== false) {
|
|
7865
|
-
initialExpandedGroups.add(group.label || index.toString());
|
|
7866
|
-
}
|
|
7867
|
-
});
|
|
7868
|
-
this.expandedGroups.set(initialExpandedGroups);
|
|
7869
|
-
}
|
|
7870
|
-
});
|
|
7871
7809
|
}
|
|
7810
|
+
// ===== DERIVED DATA =====
|
|
7811
|
+
/** Columns for the current table level. @internal */
|
|
7812
|
+
gridColumns = computed(() => this.grid().columns ?? [], ...(ngDevMode ? [{ debugName: "gridColumns" }] : []));
|
|
7813
|
+
/** Data rows for the current table level. @internal */
|
|
7814
|
+
gridRows = computed(() => this.grid().rows ?? [], ...(ngDevMode ? [{ debugName: "gridRows" }] : []));
|
|
7815
|
+
/** Per-row actions for the current table level. @internal */
|
|
7816
|
+
gridActions = computed(() => this.grid().actions ?? [], ...(ngDevMode ? [{ debugName: "gridActions" }] : []));
|
|
7817
|
+
/** Whether this table level has an expandable detail sub-table. @internal */
|
|
7818
|
+
hasDetails = computed(() => !!this.grid().details, ...(ngDevMode ? [{ debugName: "hasDetails" }] : []));
|
|
7872
7819
|
/**
|
|
7873
|
-
* Computed filtered and sorted data
|
|
7820
|
+
* Computed filtered and sorted data.
|
|
7874
7821
|
* @internal
|
|
7875
7822
|
*/
|
|
7876
7823
|
processedData = computed(() => {
|
|
7877
|
-
let result = [...
|
|
7824
|
+
let result = [...this.gridRows()];
|
|
7878
7825
|
// Apply global filter
|
|
7879
7826
|
const globalFilter = this.globalFilterValue();
|
|
7880
7827
|
if (globalFilter) {
|
|
7881
|
-
const cols = this.
|
|
7828
|
+
const cols = this.gridColumns();
|
|
7882
7829
|
result = result.filter((row) => cols.some((col) => {
|
|
7883
7830
|
const value = this.getCellValue(row, col.field);
|
|
7884
7831
|
return String(value)
|
|
@@ -8029,6 +7976,17 @@ class ITable {
|
|
|
8029
7976
|
}
|
|
8030
7977
|
return '';
|
|
8031
7978
|
}
|
|
7979
|
+
/**
|
|
7980
|
+
* Returns the combined CSS classes for an icon cell: the icon class itself,
|
|
7981
|
+
* the `i-severity-icon` marker (for scoped colour styles), and the severity
|
|
7982
|
+
* token (e.g. `success`, `danger`) needed by the sibling CSS rule.
|
|
7983
|
+
* @internal
|
|
7984
|
+
*/
|
|
7985
|
+
getIconClasses(row, column) {
|
|
7986
|
+
const icon = this.getCellIcon(row, column);
|
|
7987
|
+
const severity = this.getCellSeverity(row, column);
|
|
7988
|
+
return severity ? `${icon} i-severity-icon ${severity}` : icon;
|
|
7989
|
+
}
|
|
8032
7990
|
/**
|
|
8033
7991
|
* Checks if a column should render an icon
|
|
8034
7992
|
* @internal
|
|
@@ -8220,15 +8178,15 @@ class ITable {
|
|
|
8220
8178
|
}
|
|
8221
8179
|
// ===== ACTION METHODS =====
|
|
8222
8180
|
/**
|
|
8223
|
-
*
|
|
8181
|
+
* Dispatches a grid action by calling the action's own embedded handler.
|
|
8224
8182
|
* @internal
|
|
8225
8183
|
*/
|
|
8226
|
-
|
|
8184
|
+
triggerAction(action, row, event) {
|
|
8227
8185
|
event.stopPropagation();
|
|
8228
|
-
|
|
8186
|
+
action.handler(row);
|
|
8229
8187
|
}
|
|
8230
8188
|
/**
|
|
8231
|
-
* Checks if an action is disabled for a row
|
|
8189
|
+
* Checks if an action is disabled for a row.
|
|
8232
8190
|
* @internal
|
|
8233
8191
|
*/
|
|
8234
8192
|
isActionDisabled(action, row) {
|
|
@@ -8238,7 +8196,7 @@ class ITable {
|
|
|
8238
8196
|
return action.disabled ?? false;
|
|
8239
8197
|
}
|
|
8240
8198
|
/**
|
|
8241
|
-
* Checks if an action is visible for a row
|
|
8199
|
+
* Checks if an action is visible for a row.
|
|
8242
8200
|
* @internal
|
|
8243
8201
|
*/
|
|
8244
8202
|
isActionVisible(action, row) {
|
|
@@ -8250,7 +8208,7 @@ class ITable {
|
|
|
8250
8208
|
return action.visible;
|
|
8251
8209
|
}
|
|
8252
8210
|
/**
|
|
8253
|
-
* Gets the tooltip text for an action
|
|
8211
|
+
* Gets the tooltip text for an action.
|
|
8254
8212
|
* @internal
|
|
8255
8213
|
*/
|
|
8256
8214
|
getActionTooltip(action, row) {
|
|
@@ -8268,7 +8226,7 @@ class ITable {
|
|
|
8268
8226
|
*/
|
|
8269
8227
|
toggleRowExpansion(row, event) {
|
|
8270
8228
|
event.stopPropagation();
|
|
8271
|
-
if (!this.
|
|
8229
|
+
if (!this.hasDetails())
|
|
8272
8230
|
return;
|
|
8273
8231
|
const expanded = this.expandedRows();
|
|
8274
8232
|
const isExpanded = expanded.has(row);
|
|
@@ -8289,89 +8247,6 @@ class ITable {
|
|
|
8289
8247
|
isRowExpanded(row) {
|
|
8290
8248
|
return this.expandedRows().has(row);
|
|
8291
8249
|
}
|
|
8292
|
-
/**
|
|
8293
|
-
* Gets all rows across all groups (for grouped mode select-all)
|
|
8294
|
-
* @internal
|
|
8295
|
-
*/
|
|
8296
|
-
getAllGroupRows() {
|
|
8297
|
-
return this.groupedData().flatMap((g) => g.data || []);
|
|
8298
|
-
}
|
|
8299
|
-
/**
|
|
8300
|
-
* Checks if all rows across all groups are selected
|
|
8301
|
-
* @internal
|
|
8302
|
-
*/
|
|
8303
|
-
areAllGroupRowsSelected() {
|
|
8304
|
-
const all = this.getAllGroupRows();
|
|
8305
|
-
if (all.length === 0)
|
|
8306
|
-
return false;
|
|
8307
|
-
return all.every((d) => this.selection?.some((s) => this.compareObjects(s, d)));
|
|
8308
|
-
}
|
|
8309
|
-
/**
|
|
8310
|
-
* Checks if some (but not all) rows across all groups are selected
|
|
8311
|
-
* @internal
|
|
8312
|
-
*/
|
|
8313
|
-
areSomeGroupRowsSelected() {
|
|
8314
|
-
const all = this.getAllGroupRows();
|
|
8315
|
-
const count = all.filter((d) => this.selection?.some((s) => this.compareObjects(s, d))).length;
|
|
8316
|
-
return count > 0 && count < all.length;
|
|
8317
|
-
}
|
|
8318
|
-
/**
|
|
8319
|
-
* Toggles select-all for all groups
|
|
8320
|
-
* @internal
|
|
8321
|
-
*/
|
|
8322
|
-
toggleAllGroupSelection() {
|
|
8323
|
-
if (this.selectionMode !== 'multiple')
|
|
8324
|
-
return;
|
|
8325
|
-
const all = this.getAllGroupRows();
|
|
8326
|
-
const allSelected = this.areAllGroupRowsSelected();
|
|
8327
|
-
if (allSelected) {
|
|
8328
|
-
this.selection = this.selection.filter((s) => !all.some((d) => this.compareObjects(s, d)));
|
|
8329
|
-
}
|
|
8330
|
-
else {
|
|
8331
|
-
const newSelections = all.filter((d) => !this.selection.some((s) => this.compareObjects(s, d)));
|
|
8332
|
-
this.selection = [...this.selection, ...newSelections];
|
|
8333
|
-
}
|
|
8334
|
-
this.selectionChange.emit(this.selection);
|
|
8335
|
-
this.onSelectionChange.emit(this.selection);
|
|
8336
|
-
}
|
|
8337
|
-
// ===== GROUP EXPANSION METHODS =====
|
|
8338
|
-
/**
|
|
8339
|
-
* Toggles group expansion
|
|
8340
|
-
* @internal
|
|
8341
|
-
*/
|
|
8342
|
-
toggleGroupExpansion(groupLabel) {
|
|
8343
|
-
const expanded = this.expandedGroups();
|
|
8344
|
-
const isExpanded = expanded.has(groupLabel);
|
|
8345
|
-
const newExpanded = new Set(expanded);
|
|
8346
|
-
if (isExpanded) {
|
|
8347
|
-
newExpanded.delete(groupLabel);
|
|
8348
|
-
}
|
|
8349
|
-
else {
|
|
8350
|
-
newExpanded.add(groupLabel);
|
|
8351
|
-
}
|
|
8352
|
-
this.expandedGroups.set(newExpanded);
|
|
8353
|
-
}
|
|
8354
|
-
/**
|
|
8355
|
-
* Checks if a group is expanded
|
|
8356
|
-
* @internal
|
|
8357
|
-
*/
|
|
8358
|
-
isGroupExpanded(groupLabel) {
|
|
8359
|
-
return this.expandedGroups().has(groupLabel);
|
|
8360
|
-
}
|
|
8361
|
-
/**
|
|
8362
|
-
* Gets columns for a specific group
|
|
8363
|
-
* @internal
|
|
8364
|
-
*/
|
|
8365
|
-
getGroupColumns(group) {
|
|
8366
|
-
return group.columns || this.columns();
|
|
8367
|
-
}
|
|
8368
|
-
/**
|
|
8369
|
-
* Checks if table is in grouped mode
|
|
8370
|
-
* @internal
|
|
8371
|
-
*/
|
|
8372
|
-
isGroupedMode() {
|
|
8373
|
-
return this.groupedData().length > 0;
|
|
8374
|
-
}
|
|
8375
8250
|
// ===== DOWNLOAD METHODS =====
|
|
8376
8251
|
/**
|
|
8377
8252
|
* Handles download button click
|
|
@@ -8379,40 +8254,23 @@ class ITable {
|
|
|
8379
8254
|
*/
|
|
8380
8255
|
handleDownload() {
|
|
8381
8256
|
if (this.downloadMode === 'api') {
|
|
8382
|
-
// Emit event for API-based download
|
|
8383
8257
|
this.onDownload.emit({
|
|
8384
8258
|
format: this.downloadFormat,
|
|
8385
|
-
data: this.
|
|
8386
|
-
|
|
8387
|
-
: this.processedData(),
|
|
8388
|
-
columns: this.columns(),
|
|
8259
|
+
data: this.processedData(),
|
|
8260
|
+
columns: this.gridColumns(),
|
|
8389
8261
|
});
|
|
8390
8262
|
}
|
|
8391
8263
|
else {
|
|
8392
|
-
// Direct download
|
|
8393
8264
|
this.downloadData();
|
|
8394
8265
|
}
|
|
8395
8266
|
}
|
|
8396
|
-
/**
|
|
8397
|
-
* Gets flattened data from grouped data
|
|
8398
|
-
* @internal
|
|
8399
|
-
*/
|
|
8400
|
-
getFlattenedGroupedData() {
|
|
8401
|
-
const flattened = [];
|
|
8402
|
-
this.groupedData().forEach((group) => {
|
|
8403
|
-
flattened.push(...(group.data || []));
|
|
8404
|
-
});
|
|
8405
|
-
return flattened;
|
|
8406
|
-
}
|
|
8407
8267
|
/**
|
|
8408
8268
|
* Downloads table data directly (client-side)
|
|
8409
8269
|
* @internal
|
|
8410
8270
|
*/
|
|
8411
8271
|
downloadData() {
|
|
8412
|
-
const data = this.
|
|
8413
|
-
|
|
8414
|
-
: this.processedData();
|
|
8415
|
-
const columns = this.columns();
|
|
8272
|
+
const data = this.processedData();
|
|
8273
|
+
const columns = this.gridColumns();
|
|
8416
8274
|
const filename = this.downloadFilename || 'table-data';
|
|
8417
8275
|
switch (this.downloadFormat) {
|
|
8418
8276
|
case 'csv':
|
|
@@ -8559,17 +8417,21 @@ class ITable {
|
|
|
8559
8417
|
'i-table--small': this.size === 'small',
|
|
8560
8418
|
'i-table--medium': this.size === 'medium',
|
|
8561
8419
|
'i-table--large': this.size === 'large',
|
|
8562
|
-
'i-table--scrollable': this.scrollable || !!
|
|
8420
|
+
'i-table--scrollable': this.scrollable || !!this.height,
|
|
8563
8421
|
'i-table--loading': this.loading,
|
|
8564
8422
|
};
|
|
8565
8423
|
}
|
|
8566
8424
|
/**
|
|
8567
|
-
* Track by function for rows
|
|
8425
|
+
* Track by function for rows.
|
|
8426
|
+
* Must be an arrow property so that CDK virtual-scroll can call it as a
|
|
8427
|
+
* plain function reference without losing the component's `this` context.
|
|
8568
8428
|
* @internal
|
|
8569
8429
|
*/
|
|
8570
|
-
trackByRow(index, row) {
|
|
8571
|
-
|
|
8572
|
-
|
|
8430
|
+
trackByRow = (index, row) => {
|
|
8431
|
+
if (this.dataKey)
|
|
8432
|
+
return row[this.dataKey];
|
|
8433
|
+
return row?.id ?? index;
|
|
8434
|
+
};
|
|
8573
8435
|
/**
|
|
8574
8436
|
* Track by function for columns
|
|
8575
8437
|
* @internal
|
|
@@ -8577,16 +8439,55 @@ class ITable {
|
|
|
8577
8439
|
trackByColumn(index, column) {
|
|
8578
8440
|
return column.field;
|
|
8579
8441
|
}
|
|
8580
|
-
// =====
|
|
8442
|
+
// ===== COMPUTED LAYOUT HELPERS =====
|
|
8443
|
+
/**
|
|
8444
|
+
* Effective container height for the virtual scroll viewport.
|
|
8445
|
+
* Falls back to '400px' when no height is provided.
|
|
8446
|
+
* @internal
|
|
8447
|
+
*/
|
|
8448
|
+
effectiveHeight = computed(() => this.height || '400px', ...(ngDevMode ? [{ debugName: "effectiveHeight" }] : []));
|
|
8449
|
+
/**
|
|
8450
|
+
* Total column span used for empty-state and detail expansion cells.
|
|
8451
|
+
* @internal
|
|
8452
|
+
*/
|
|
8453
|
+
totalColspan = computed(() => {
|
|
8454
|
+
return (this.gridColumns().length +
|
|
8455
|
+
(this.selectionMode === 'multiple' ? 1 : 0) +
|
|
8456
|
+
(this.hasDetails() ? 2 : 0) + // expand column + detail-count column
|
|
8457
|
+
(this.gridActions().length > 0 ? 1 : 0));
|
|
8458
|
+
}, ...(ngDevMode ? [{ debugName: "totalColspan" }] : []));
|
|
8459
|
+
/**
|
|
8460
|
+
* Returns the number of detail rows for a given parent row.
|
|
8461
|
+
* Used to render the `(n)` count badge in the expand table.
|
|
8462
|
+
* @internal
|
|
8463
|
+
*/
|
|
8464
|
+
getDetailRowCount(row) {
|
|
8465
|
+
const details = this.grid().details;
|
|
8466
|
+
if (!details)
|
|
8467
|
+
return 0;
|
|
8468
|
+
return details.rows(row).length;
|
|
8469
|
+
}
|
|
8470
|
+
/**
|
|
8471
|
+
* Builds a `GridData` for the nested detail `<i-table>` of an expanded row.
|
|
8472
|
+
* @internal
|
|
8473
|
+
*/
|
|
8474
|
+
getDetailGrid(row) {
|
|
8475
|
+
const details = this.grid().details;
|
|
8476
|
+
if (!details)
|
|
8477
|
+
return { columns: [], rows: [] };
|
|
8478
|
+
return {
|
|
8479
|
+
columns: details.columns,
|
|
8480
|
+
rows: details.rows(row),
|
|
8481
|
+
actions: details.actions,
|
|
8482
|
+
};
|
|
8483
|
+
}
|
|
8581
8484
|
/**
|
|
8582
8485
|
* Scrolls to a specific index in the virtual scroll viewport
|
|
8583
8486
|
* @param index - The index to scroll to
|
|
8584
8487
|
* @param behavior - Scroll behavior ('auto' or 'smooth')
|
|
8585
8488
|
*/
|
|
8586
8489
|
scrollToIndex(index, behavior = 'auto') {
|
|
8587
|
-
|
|
8588
|
-
this.virtualScrollViewport.scrollToIndex(index, behavior);
|
|
8589
|
-
}
|
|
8490
|
+
this.virtualScrollViewport?.scrollToIndex(index, behavior);
|
|
8590
8491
|
}
|
|
8591
8492
|
/**
|
|
8592
8493
|
* Scrolls to a specific offset in the virtual scroll viewport
|
|
@@ -8594,36 +8495,28 @@ class ITable {
|
|
|
8594
8495
|
* @param behavior - Scroll behavior ('auto' or 'smooth')
|
|
8595
8496
|
*/
|
|
8596
8497
|
scrollToOffset(offset, behavior = 'auto') {
|
|
8597
|
-
|
|
8598
|
-
this.virtualScrollViewport.scrollToOffset(offset, behavior);
|
|
8599
|
-
}
|
|
8498
|
+
this.virtualScrollViewport?.scrollToOffset(offset, behavior);
|
|
8600
8499
|
}
|
|
8601
8500
|
/**
|
|
8602
8501
|
* Gets the total content size of the virtual scroll viewport
|
|
8603
8502
|
* @returns The total content size in pixels
|
|
8604
8503
|
*/
|
|
8605
8504
|
getVirtualScrollContentSize() {
|
|
8606
|
-
|
|
8607
|
-
return this.virtualScrollViewport.measureScrollOffset('bottom');
|
|
8608
|
-
}
|
|
8609
|
-
return 0;
|
|
8505
|
+
return this.virtualScrollViewport?.measureScrollOffset('bottom') ?? 0;
|
|
8610
8506
|
}
|
|
8611
8507
|
/**
|
|
8612
8508
|
* Gets the current scroll offset of the virtual scroll viewport
|
|
8613
8509
|
* @returns The current scroll offset in pixels
|
|
8614
8510
|
*/
|
|
8615
8511
|
getVirtualScrollOffset() {
|
|
8616
|
-
|
|
8617
|
-
return this.virtualScrollViewport.measureScrollOffset();
|
|
8618
|
-
}
|
|
8619
|
-
return 0;
|
|
8512
|
+
return this.virtualScrollViewport?.measureScrollOffset() ?? 0;
|
|
8620
8513
|
}
|
|
8621
8514
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: ITable, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component });
|
|
8622
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.3", type: ITable, isStandalone: true, selector: "i-table", inputs: { data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: false, transformFunction: null }, columns: { classPropertyName: "columns", publicName: "columns", isSignal: true, isRequired: false, transformFunction: null }, groupedData: { classPropertyName: "groupedData", publicName: "groupedData", isSignal: true, isRequired: false, transformFunction: null }, groupColumns: { classPropertyName: "groupColumns", publicName: "groupColumns", isSignal: true, isRequired: false, transformFunction: null }, emptyMessage: { classPropertyName: "emptyMessage", publicName: "emptyMessage", isSignal: false, isRequired: false, transformFunction: null }, sortable: { classPropertyName: "sortable", publicName: "sortable", isSignal: false, isRequired: false, transformFunction: null }, sortField: { classPropertyName: "sortField", publicName: "sortField", isSignal: false, isRequired: false, transformFunction: null }, sortOrder: { classPropertyName: "sortOrder", publicName: "sortOrder", isSignal: false, isRequired: false, transformFunction: null }, filterable: { classPropertyName: "filterable", publicName: "filterable", isSignal: false, isRequired: false, transformFunction: null }, globalFilter: { classPropertyName: "globalFilter", publicName: "globalFilter", isSignal: false, isRequired: false, transformFunction: null }, filterDelay: { classPropertyName: "filterDelay", publicName: "filterDelay", isSignal: false, isRequired: false, transformFunction: null }, selectionMode: { classPropertyName: "selectionMode", publicName: "selectionMode", isSignal: false, isRequired: false, transformFunction: null }, selection: { classPropertyName: "selection", publicName: "selection", isSignal: false, isRequired: false, transformFunction: null }, dataKey: { classPropertyName: "dataKey", publicName: "dataKey", isSignal: false, isRequired: false, transformFunction: null }, showActions: { classPropertyName: "showActions", publicName: "showActions", isSignal: false, isRequired: false, transformFunction: null }, actions: { classPropertyName: "actions", publicName: "actions", isSignal: false, isRequired: false, transformFunction: null }, striped: { classPropertyName: "striped", publicName: "striped", isSignal: false, isRequired: false, transformFunction: null }, hoverable: { classPropertyName: "hoverable", publicName: "hoverable", isSignal: false, isRequired: false, transformFunction: null }, bordered: { classPropertyName: "bordered", publicName: "bordered", isSignal: false, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: false, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: false, isRequired: false, transformFunction: null }, scrollable: { classPropertyName: "scrollable", publicName: "scrollable", isSignal: false, isRequired: false, transformFunction: null }, scrollHeight: { classPropertyName: "scrollHeight", publicName: "scrollHeight", isSignal: false, isRequired: false, transformFunction: null }, height: { classPropertyName: "height", publicName: "height", isSignal: false, isRequired: false, transformFunction: null }, virtualScroll: { classPropertyName: "virtualScroll", publicName: "virtualScroll", isSignal: false, isRequired: false, transformFunction: null }, virtualScrollItemSize: { classPropertyName: "virtualScrollItemSize", publicName: "virtualScrollItemSize", isSignal: false, isRequired: false, transformFunction: null }, virtualScrollMinBufferPx: { classPropertyName: "virtualScrollMinBufferPx", publicName: "virtualScrollMinBufferPx", isSignal: false, isRequired: false, transformFunction: null }, virtualScrollMaxBufferPx: { classPropertyName: "virtualScrollMaxBufferPx", publicName: "virtualScrollMaxBufferPx", isSignal: false, isRequired: false, transformFunction: null }, resizableColumns: { classPropertyName: "resizableColumns", publicName: "resizableColumns", isSignal: false, isRequired: false, transformFunction: null }, reorderableColumns: { classPropertyName: "reorderableColumns", publicName: "reorderableColumns", isSignal: false, isRequired: false, transformFunction: null }, rowExpandable: { classPropertyName: "rowExpandable", publicName: "rowExpandable", isSignal: false, isRequired: false, transformFunction: null }, downloadable: { classPropertyName: "downloadable", publicName: "downloadable", isSignal: false, isRequired: false, transformFunction: null }, downloadMode: { classPropertyName: "downloadMode", publicName: "downloadMode", isSignal: false, isRequired: false, transformFunction: null }, downloadFormat: { classPropertyName: "downloadFormat", publicName: "downloadFormat", isSignal: false, isRequired: false, transformFunction: null }, downloadFilename: { classPropertyName: "downloadFilename", publicName: "downloadFilename", isSignal: false, isRequired: false, transformFunction: null } }, outputs: { onSort: "onSort", onFilter: "onFilter", selectionChange: "selectionChange", onSelectionChange: "onSelectionChange", onRowSelect: "onRowSelect", onRowUnselect: "onRowUnselect", onAction: "onAction", onRowExpand: "onRowExpand", onRowCollapse: "onRowCollapse", onDownload: "onDownload" }, host: { listeners: { "document:mousemove": "onColumnResize($event)", "document:mouseup": "onColumnResizeEnd()" } }, viewQueries: [{ propertyName: "virtualScrollViewport", first: true, predicate: CdkVirtualScrollViewport, descendants: true }], ngImport: i0, template: "<div class=\"i-table-wrapper\" [ngClass]=\"getTableClasses()\">\n <!-- Table Header with ng-content, search, and download -->\n @if (globalFilter || downloadable) {\n <div class=\"i-table-header\">\n <div class=\"i-table-header-start\">\n <ng-content select=\"[header]\"></ng-content>\n </div>\n <div class=\"i-table-header-end\">\n @if (globalFilter) {\n <div class=\"i-table-global-filter\">\n <i-input-text\n [useFloatLabel]=\"false\"\n placeholder=\"Search...\"\n [ngModel]=\"globalFilterValue()\"\n (ngModelChange)=\"onGlobalFilterInput($event)\"\n [fluid]=\"false\"\n [icon]=\"'pi pi-search'\"\n ></i-input-text>\n </div>\n }\n @if (downloadable) {\n <div class=\"i-table-download\">\n <i-button\n severity=\"secondary\"\n [text]=\"true\"\n size=\"small\"\n icon=\"pi pi-download\"\n label=\"Download\"\n (clicked)=\"handleDownload()\"\n ></i-button>\n </div>\n }\n </div>\n </div>\n }\n\n <!-- Loading Overlay -->\n @if (loading) {\n <div class=\"i-table-loading-overlay\">\n <i class=\"pi pi-spin pi-spinner i-table-loading-icon\"></i>\n </div>\n }\n\n <!-- Scrollable Table Container -->\n <div\n class=\"i-table-container\"\n [class.i-table-container--scrollable]=\"scrollable || height || scrollHeight\"\n [class.i-table-container--virtual-scroll]=\"virtualScroll\"\n [style.height]=\"virtualScroll ? height || scrollHeight || '400px' : null\"\n [style.max-height]=\"!virtualScroll ? height || scrollHeight || null : null\"\n >\n <!-- Virtual Scroll Mode -->\n @if (virtualScroll) {\n <!-- Sticky Header Table (outside viewport) -->\n <div class=\"i-table-virtual-header\">\n <table class=\"i-table\">\n <thead>\n <!-- Column Filters Row -->\n @if (filterable) {\n <tr class=\"i-table-filter-row\">\n @if (selectionMode === \"multiple\") {\n <th class=\"i-table-selection-header\"></th>\n }\n @if (rowExpandable) {\n <th class=\"i-table-expand-header\"></th>\n }\n @for (\n column of columns();\n track trackByColumn($index, column)\n ) {\n @if (column.filterable !== false) {\n <th [style.width]=\"getColumnWidth(column)\">\n <input\n type=\"text\"\n class=\"i-table-column-filter\"\n placeholder=\"Filter...\"\n [ngModel]=\"columnFilters()[column.field] || ''\"\n (ngModelChange)=\"\n onColumnFilterInput(column.field, $event)\n \"\n />\n </th>\n } @else {\n <th [style.width]=\"getColumnWidth(column)\"></th>\n }\n }\n @if (showActions && actions.length > 0) {\n <th class=\"i-table-actions-header\"></th>\n }\n </tr>\n }\n\n <!-- Column Headers Row -->\n <tr>\n @if (selectionMode === \"multiple\") {\n <th class=\"i-table-selection-header\">\n <i-checkbox\n [checked]=\"areAllRowsSelected()\"\n [indeterminate]=\"areSomeRowsSelected()\"\n (onChange)=\"toggleAllSelection()\"\n ></i-checkbox>\n </th>\n }\n @if (rowExpandable) {\n <th class=\"i-table-expand-header\"></th>\n }\n @for (column of columns(); track trackByColumn($index, column)) {\n <th\n [style.width]=\"getColumnWidth(column)\"\n [style.text-align]=\"column.align || 'left'\"\n [class.i-table-sortable-column]=\"sortable && column.sortable\"\n [class.i-table-sorted]=\"sortField === column.field\"\n (click)=\"onSortColumn(column)\"\n >\n <div class=\"i-table-header-content\">\n <span class=\"i-table-header-text\">{{ column.header }}</span>\n @if (sortable && column.sortable) {\n <i\n [class]=\"getSortIcon(column)\"\n class=\"i-table-sort-icon\"\n ></i>\n }\n </div>\n @if (resizableColumns) {\n <span\n class=\"i-table-column-resizer\"\n (mousedown)=\"onColumnResizeStart($event, column)\"\n ></span>\n }\n </th>\n }\n @if (showActions && actions.length > 0) {\n <th class=\"i-table-actions-header\">Actions</th>\n }\n </tr>\n </thead>\n </table>\n </div>\n\n <!-- Virtual Scroll Viewport (body only) -->\n <cdk-virtual-scroll-viewport\n [itemSize]=\"virtualScrollItemSize\"\n [minBufferPx]=\"virtualScrollMinBufferPx\"\n [maxBufferPx]=\"virtualScrollMaxBufferPx\"\n class=\"i-table-virtual-viewport\"\n >\n <table class=\"i-table i-table-virtual-body\">\n <tbody>\n @if (processedData().length === 0) {\n <tr class=\"i-table-empty-row\">\n <td\n [attr.colspan]=\"\n columns().length +\n (selectionMode === 'multiple' ? 1 : 0) +\n (rowExpandable ? 1 : 0) +\n (showActions && actions.length > 0 ? 1 : 0)\n \"\n >\n <i-no-content />\n </td>\n </tr>\n }\n <!-- Virtual Scroll Rows -->\n <tr\n *cdkVirtualFor=\"\n let row of processedData();\n let rowIndex = index;\n trackBy: trackByRow\n \"\n [style.height.px]=\"virtualScrollItemSize\"\n [class.i-table-row-odd]=\"rowIndex % 2 !== 0\"\n [class.i-table-row-selected]=\"isRowSelected(row)\"\n (click)=\"toggleRowSelection(row)\"\n >\n @if (selectionMode === \"multiple\") {\n <td class=\"i-table-selection-cell\">\n <i-checkbox\n [checked]=\"isRowSelected(row)\"\n (onChange)=\"toggleRowSelection(row)\"\n (click)=\"$event.stopPropagation()\"\n ></i-checkbox>\n </td>\n }\n @if (rowExpandable) {\n <td class=\"i-table-expand-cell\">\n <i-button\n severity=\"secondary\"\n [text]=\"true\"\n size=\"xtra-small\"\n [icon]=\"\n isRowExpanded(row)\n ? 'pi pi-chevron-down'\n : 'pi pi-chevron-right'\n \"\n (clicked)=\"toggleRowExpansion(row, $event)\"\n ></i-button>\n </td>\n }\n @for (column of columns(); track trackByColumn($index, column)) {\n <td\n [style.text-align]=\"column.align || 'left'\"\n [style.width]=\"getColumnWidth(column)\"\n [class]=\"\n getCellSeverity(row, column)\n ? 'i-table-cell-' + getCellSeverity(row, column)\n : ''\n \"\n >\n @if (isIconColumn(column)) {\n <i\n [class]=\"getCellIcon(row, column)\"\n [class.i-severity-icon]=\"getCellSeverity(row, column)\"\n [style.font-size]=\"column.iconSize || '1rem'\"\n ></i>\n } @else if (isListColumn(column)) {\n <div class=\"i-table-list-cell\">\n @for (item of getCellListItems(row, column); track item) {\n <i-chip [label]=\"item\"></i-chip>\n }\n </div>\n } @else {\n <span\n [class.i-severity-text]=\"getCellSeverity(row, column)\"\n >\n {{\n formatCellValue(getCellValue(row, column.field), column)\n }}\n </span>\n }\n </td>\n }\n @if (showActions && actions.length > 0) {\n <td class=\"i-table-actions-cell\">\n <div class=\"i-table-actions\">\n @for (action of actions; track action.id) {\n <i-button\n [severity]=\"action.severity || 'secondary'\"\n [text]=\"true\"\n size=\"small\"\n [icon]=\"action.icon || ''\"\n [disabled]=\"isActionDisabled(action, row)\"\n [iTooltip]=\"getActionTooltip(action, row)\"\n [class.i-action-hidden]=\"!isActionVisible(action, row)\"\n (clicked)=\"onActionClick(action, row, $event)\"\n >\n @if (action.label) {\n {{ action.label }}\n }\n </i-button>\n }\n </div>\n </td>\n }\n </tr>\n </tbody>\n </table>\n </cdk-virtual-scroll-viewport>\n } @else if (isGroupedMode()) {\n <!-- Grouped Mode: single scrollable table \u2014 group summary rows expand to reveal nested tables -->\n <table class=\"i-table\">\n <thead>\n <!-- Outer filter row -->\n @if (filterable && groupColumns().length > 0) {\n <tr class=\"i-table-filter-row\">\n <th class=\"i-table-expand-header\"></th>\n @for (\n column of groupColumns();\n track trackByColumn($index, column)\n ) {\n @if (column.filterable !== false) {\n <th [style.width]=\"getColumnWidth(column)\">\n <input\n type=\"text\"\n class=\"i-table-column-filter\"\n placeholder=\"Filter...\"\n [ngModel]=\"columnFilters()[column.field] || ''\"\n (ngModelChange)=\"\n onColumnFilterInput(column.field, $event)\n \"\n />\n </th>\n } @else {\n <th [style.width]=\"getColumnWidth(column)\"></th>\n }\n }\n @if (showActions && actions.length > 0) {\n <th class=\"i-table-actions-header\"></th>\n }\n <th class=\"i-table-group-count-header\"></th>\n </tr>\n }\n\n <!-- Group column header row -->\n <tr>\n <th class=\"i-table-expand-header\"></th>\n @if (groupColumns().length === 0) {\n <th>Group</th>\n } @else {\n @for (\n column of groupColumns();\n track trackByColumn($index, column)\n ) {\n <th\n [style.width]=\"getColumnWidth(column)\"\n [style.text-align]=\"column.align || 'left'\"\n [class.i-table-sortable-column]=\"sortable && column.sortable\"\n [class.i-table-sorted]=\"sortField === column.field\"\n (click)=\"onSortColumn(column)\"\n >\n <div class=\"i-table-header-content\">\n <span class=\"i-table-header-text\">{{ column.header }}</span>\n @if (sortable && column.sortable) {\n <i\n [class]=\"getSortIcon(column)\"\n class=\"i-table-sort-icon\"\n ></i>\n }\n </div>\n @if (resizableColumns) {\n <span\n class=\"i-table-column-resizer\"\n (mousedown)=\"onColumnResizeStart($event, column)\"\n ></span>\n }\n </th>\n }\n }\n @if (showActions && actions.length > 0) {\n <th class=\"i-table-actions-header\">Actions</th>\n }\n <th class=\"i-table-group-count-header\"></th>\n </tr>\n </thead>\n\n <tbody>\n @if (groupedData().length === 0) {\n <tr class=\"i-table-empty-row\">\n <td\n [attr.colspan]=\"\n (groupColumns().length || 1) +\n 1 +\n 1 +\n (showActions && actions.length > 0 ? 1 : 0)\n \"\n >\n <i-no-content />\n </td>\n </tr>\n }\n @for (group of groupedData(); track $index) {\n <!-- Group summary row -->\n <tr\n class=\"i-table-group-summary-row\"\n [ngClass]=\"group.styleClass\"\n [class.i-table-group-expanded]=\"isGroupExpanded(group.label)\"\n (click)=\"toggleGroupExpansion(group.label)\"\n >\n <td class=\"i-table-expand-cell\">\n <i-button\n severity=\"secondary\"\n [text]=\"true\"\n size=\"xtra-small\"\n [icon]=\"\n isGroupExpanded(group.label)\n ? 'pi pi-chevron-down'\n : 'pi pi-chevron-right'\n \"\n (clicked)=\"\n toggleGroupExpansion(group.label); $event.stopPropagation()\n \"\n ></i-button>\n </td>\n @if (groupColumns().length === 0) {\n <!-- No groupColumns: show label + count in a single cell -->\n <td>\n <div class=\"i-table-group-header-content\">\n <span class=\"i-table-group-label\">{{ group.label }}</span>\n <span class=\"i-table-group-count\"\n >({{ group.data.length }})</span\n >\n </div>\n </td>\n } @else {\n @for (\n column of groupColumns();\n track trackByColumn($index, column)\n ) {\n <td\n [style.text-align]=\"column.align || 'left'\"\n [style.width]=\"getColumnWidth(column)\"\n [class]=\"\n getCellSeverity(group.row ?? {}, column)\n ? 'i-table-cell-' +\n getCellSeverity(group.row ?? {}, column)\n : ''\n \"\n >\n @if (isIconColumn(column)) {\n <i\n [class]=\"getCellIcon(group.row ?? {}, column)\"\n [class.i-severity-icon]=\"\n getCellSeverity(group.row ?? {}, column)\n \"\n [style.font-size]=\"column.iconSize || '1rem'\"\n ></i>\n } @else {\n <span\n [class.i-severity-text]=\"\n getCellSeverity(group.row ?? {}, column)\n \"\n >\n {{\n formatCellValue(\n getCellValue(group.row ?? {}, column.field),\n column\n )\n }}\n </span>\n }\n </td>\n }\n }\n @if (showActions && actions.length > 0) {\n <td\n class=\"i-table-actions-cell\"\n (click)=\"$event.stopPropagation()\"\n >\n <div class=\"i-table-actions\">\n @for (action of actions; track action.id) {\n <i-button\n [severity]=\"action.severity || 'secondary'\"\n [text]=\"true\"\n size=\"small\"\n [icon]=\"action.icon || ''\"\n [disabled]=\"isActionDisabled(action, group.row ?? {})\"\n [iTooltip]=\"getActionTooltip(action, group.row ?? {})\"\n [class.i-action-hidden]=\"\n !isActionVisible(action, group.row ?? {})\n \"\n (clicked)=\"\n onActionClick(action, group.row ?? {}, $event)\n \"\n >\n @if (action.label) {\n {{ action.label }}\n }\n </i-button>\n }\n </div>\n </td>\n }\n <td\n class=\"i-table-group-count-cell\"\n (click)=\"$event.stopPropagation()\"\n >\n <span class=\"i-table-group-count\"\n >({{ group.data.length }})</span\n >\n </td>\n </tr>\n\n <!-- Group detail row (visible when expanded) -->\n @if (isGroupExpanded(group.label)) {\n <tr class=\"i-table-group-detail-row\">\n <td\n [attr.colspan]=\"\n (groupColumns().length || 1) +\n 1 +\n 1 +\n (showActions && actions.length > 0 ? 1 : 0)\n \"\n class=\"i-table-group-detail-cell\"\n >\n <i-table\n [data]=\"group.data\"\n [columns]=\"getGroupColumns(group)\"\n [sortable]=\"sortable\"\n [filterable]=\"filterable\"\n [showActions]=\"showActions\"\n [actions]=\"actions\"\n [selectionMode]=\"selectionMode\"\n [selection]=\"selection\"\n [striped]=\"striped\"\n [hoverable]=\"hoverable\"\n [bordered]=\"bordered\"\n [size]=\"size\"\n [dataKey]=\"dataKey\"\n [rowExpandable]=\"rowExpandable\"\n [resizableColumns]=\"resizableColumns\"\n (onSort)=\"onSort.emit($event)\"\n (onFilter)=\"onFilter.emit($event)\"\n (onAction)=\"onAction.emit($event)\"\n (onSelectionChange)=\"onSelectionChange.emit($event)\"\n (selectionChange)=\"selectionChange.emit($event)\"\n (onRowSelect)=\"onRowSelect.emit($event)\"\n (onRowUnselect)=\"onRowUnselect.emit($event)\"\n (onRowExpand)=\"onRowExpand.emit($event)\"\n (onRowCollapse)=\"onRowCollapse.emit($event)\"\n ></i-table>\n </td>\n </tr>\n }\n }\n </tbody>\n </table>\n } @else {\n <!-- Non-Virtual Scroll Table -->\n <table class=\"i-table\">\n <!-- Table Header (sticky when scrollable) -->\n <thead>\n <!-- Column Filters Row -->\n @if (filterable) {\n <tr class=\"i-table-filter-row\">\n @if (selectionMode === \"multiple\") {\n <th class=\"i-table-selection-header\"></th>\n }\n @if (rowExpandable) {\n <th class=\"i-table-expand-header\"></th>\n }\n @for (column of columns(); track trackByColumn($index, column)) {\n @if (column.filterable !== false) {\n <th [style.width]=\"getColumnWidth(column)\">\n <input\n type=\"text\"\n class=\"i-table-column-filter\"\n placeholder=\"Filter...\"\n [ngModel]=\"columnFilters()[column.field] || ''\"\n (ngModelChange)=\"\n onColumnFilterInput(column.field, $event)\n \"\n />\n </th>\n } @else {\n <th [style.width]=\"getColumnWidth(column)\"></th>\n }\n }\n @if (showActions && actions.length > 0) {\n <th class=\"i-table-actions-header\"></th>\n }\n </tr>\n }\n\n <!-- Column Headers Row -->\n <tr>\n @if (selectionMode === \"multiple\") {\n <th class=\"i-table-selection-header\">\n <i-checkbox\n [checked]=\"areAllRowsSelected()\"\n [indeterminate]=\"areSomeRowsSelected()\"\n (onChange)=\"toggleAllSelection()\"\n ></i-checkbox>\n </th>\n }\n @if (rowExpandable) {\n <th class=\"i-table-expand-header\"></th>\n }\n @for (column of columns(); track trackByColumn($index, column)) {\n <th\n [style.width]=\"getColumnWidth(column)\"\n [style.text-align]=\"column.align || 'left'\"\n [class.i-table-sortable-column]=\"sortable && column.sortable\"\n [class.i-table-sorted]=\"sortField === column.field\"\n (click)=\"onSortColumn(column)\"\n >\n <div class=\"i-table-header-content\">\n <span class=\"i-table-header-text\">{{ column.header }}</span>\n @if (sortable && column.sortable) {\n <i\n [class]=\"getSortIcon(column)\"\n class=\"i-table-sort-icon\"\n ></i>\n }\n </div>\n @if (resizableColumns) {\n <span\n class=\"i-table-column-resizer\"\n (mousedown)=\"onColumnResizeStart($event, column)\"\n ></span>\n }\n </th>\n }\n @if (showActions && actions.length > 0) {\n <th class=\"i-table-actions-header\">Actions</th>\n }\n </tr>\n </thead>\n\n <!-- Table Body - Regular Mode -->\n <tbody>\n @if (processedData().length === 0) {\n <tr class=\"i-table-empty-row\">\n <td\n [attr.colspan]=\"\n columns().length +\n (selectionMode === 'multiple' ? 1 : 0) +\n (rowExpandable ? 1 : 0) +\n (showActions && actions.length > 0 ? 1 : 0)\n \"\n >\n <i-no-content />\n </td>\n </tr>\n } @else {\n @for (\n row of processedData();\n track trackByRow($index, row);\n let rowIndex = $index\n ) {\n <tr\n [class.i-table-row-odd]=\"$odd\"\n [class.i-table-row-selected]=\"isRowSelected(row)\"\n (click)=\"toggleRowSelection(row)\"\n >\n @if (selectionMode === \"multiple\") {\n <td class=\"i-table-selection-cell\">\n <i-checkbox\n [checked]=\"isRowSelected(row)\"\n (onChange)=\"toggleRowSelection(row)\"\n (click)=\"$event.stopPropagation()\"\n ></i-checkbox>\n </td>\n }\n @if (rowExpandable) {\n <td class=\"i-table-expand-cell\">\n <i-button\n severity=\"secondary\"\n [text]=\"true\"\n size=\"xtra-small\"\n [icon]=\"\n isRowExpanded(row)\n ? 'pi pi-chevron-down'\n : 'pi pi-chevron-right'\n \"\n (clicked)=\"toggleRowExpansion(row, $event)\"\n ></i-button>\n </td>\n }\n @for (\n column of columns();\n track trackByColumn($index, column)\n ) {\n <td\n [style.text-align]=\"column.align || 'left'\"\n [style.width]=\"getColumnWidth(column)\"\n [class]=\"\n getCellSeverity(row, column)\n ? 'i-table-cell-' + getCellSeverity(row, column)\n : ''\n \"\n >\n @if (isIconColumn(column)) {\n <i\n [class]=\"getCellIcon(row, column)\"\n [class.i-severity-icon]=\"getCellSeverity(row, column)\"\n [style.font-size]=\"column.iconSize || '1rem'\"\n ></i>\n } @else if (isListColumn(column)) {\n <div class=\"i-table-list-cell\">\n @for (\n item of getCellListItems(row, column);\n track item\n ) {\n <i-chip [label]=\"item\"></i-chip>\n }\n </div>\n } @else {\n <span\n [class.i-severity-text]=\"getCellSeverity(row, column)\"\n >\n {{\n formatCellValue(\n getCellValue(row, column.field),\n column\n )\n }}\n </span>\n }\n </td>\n }\n @if (showActions && actions.length > 0) {\n <td class=\"i-table-actions-cell\">\n <div class=\"i-table-actions\">\n @for (action of actions; track action.id) {\n <i-button\n [severity]=\"action.severity || 'secondary'\"\n [text]=\"true\"\n size=\"small\"\n [icon]=\"action.icon || ''\"\n [disabled]=\"isActionDisabled(action, row)\"\n [iTooltip]=\"getActionTooltip(action, row)\"\n [class.i-action-hidden]=\"\n !isActionVisible(action, row)\n \"\n (clicked)=\"onActionClick(action, row, $event)\"\n >\n @if (action.label) {\n {{ action.label }}\n }\n </i-button>\n }\n </div>\n </td>\n }\n </tr>\n <!-- Expanded Row Content -->\n @if (rowExpandable && isRowExpanded(row)) {\n <tr class=\"i-table-expanded-row\">\n <td\n [attr.colspan]=\"\n columns().length +\n (selectionMode === 'multiple' ? 1 : 0) +\n 1 +\n (showActions && actions.length > 0 ? 1 : 0)\n \"\n >\n <div class=\"i-table-expanded-content\">\n <pre>{{ row | json }}</pre>\n </div>\n </td>\n </tr>\n }\n }\n }\n </tbody>\n </table>\n }\n </div>\n</div>\n", styles: [".i-table-wrapper{color:var(--color-text-primary);background:var(--color-component-background)}.i-table-wrapper .i-table-header{background:var(--surface-section);border-bottom:1px solid var(--surface-border)}.i-table-wrapper .i-table-global-filter .i-input-text{background:var(--surface-ground)}.i-table-wrapper .i-table-loading-overlay{background:#ffffffb3}.i-table-wrapper .i-table-loading-overlay .i-table-loading-icon{color:var(--color-primary)}.i-table-wrapper table thead tr{background:var(--color-component-background)}.i-table-wrapper table thead tr th{color:var(--color-text-primary);border-bottom:1px solid var(--surface-border)}.i-table-wrapper table thead tr th.i-table-sortable-column{cursor:pointer}.i-table-wrapper table thead tr th.i-table-sortable-column:hover{background:var(--surface-hover)}.i-table-wrapper table thead tr th.i-table-sorted{background:var(--surface-hover);color:var(--color-primary)}.i-table-wrapper table thead tr th .i-table-sort-icon{color:var(--color-text-secondary)}.i-table-wrapper table thead tr th.i-table-sorted .i-table-sort-icon{color:var(--color-primary)}.i-table-wrapper table thead .i-table-filter-row th{background:var(--color-component-background)}.i-table-wrapper table thead .i-table-filter-row .i-table-column-filter{border:1px solid var(--surface-border);background:var(--surface-ground);color:var(--color-text-primary)}.i-table-wrapper table thead .i-table-filter-row .i-table-column-filter:focus{border-color:var(--color-primary);box-shadow:0 2px 10px #0003;outline:none}.i-table-wrapper table thead .i-table-filter-row .i-table-column-filter::placeholder{color:var(--color-text-tertiary)}.i-table-wrapper table tbody tr{background:var(--color-component-background);border-bottom:1px solid var(--surface-border)}.i-table-wrapper table tbody tr td{color:var(--color-text-primary)}.i-table-wrapper table tbody tr.i-table-row-odd{background:var(--color-component-background)}.i-table-wrapper table tbody tr.i-table-row-selected{background:var(--surface-hover);color:var(--color-primary)}.i-table-wrapper table tbody .i-table-expanded-row{background:var(--color-component-background)}.i-table-wrapper table tbody .i-table-expanded-row .i-table-expanded-content{background:var(--surface-ground);border:1px solid var(--surface-border)}.i-table-wrapper table tbody .i-table-empty-row td{background:var(--color-component-background)}.i-table-wrapper table tbody .i-table-group-header{background:var(--color-component-background);border-bottom:2px solid var(--surface-border)}.i-table-wrapper table tbody .i-table-group-header td{color:var(--color-text-primary)}.i-table-wrapper table tbody .i-table-group-header:hover{background:var(--surface-hover)}.i-table-wrapper table tbody .i-table-group-header .i-table-group-toggle-icon,.i-table-wrapper table tbody .i-table-group-header .i-table-group-count{color:var(--color-text-secondary)}.i-table-wrapper table tbody .i-table-group-columns-header{background:var(--color-component-background);border-bottom:1px solid var(--surface-border)}.i-table-wrapper table tbody .i-table-group-columns-header th{color:var(--color-text-primary);border-bottom:1px solid var(--surface-border)}.i-table-wrapper table tbody .i-table-group-row,.i-table-wrapper table tbody .i-table-group-row.i-table-row-odd{background:var(--color-component-background)}.i-table-wrapper table tbody .i-table-group-row.i-table-row-selected{background:var(--surface-hover);color:var(--color-primary)}.i-table-wrapper table tbody .i-table-group-summary-row{background:var(--surface-section);border-bottom:2px solid var(--surface-border)}.i-table-wrapper table tbody .i-table-group-summary-row td{color:var(--color-text-primary);font-weight:600}.i-table-wrapper table tbody .i-table-group-summary-row:hover{background:var(--surface-hover)}.i-table-wrapper table tbody .i-table-group-summary-row .i-table-group-count{color:var(--color-text-secondary)}.i-table-wrapper table tbody .i-table-group-detail-row,.i-table-wrapper table tbody .i-table-group-detail-row .i-table-group-detail-cell .i-table-wrapper{background:var(--surface-ground)}.i-table-wrapper table tbody .i-table-group-detail-row .i-table-group-detail-cell .i-table-wrapper table thead tr{background:var(--surface-section)}.i-table-wrapper.i-table--bordered table,.i-table-wrapper.i-table--bordered table th,.i-table-wrapper.i-table--bordered table td{border:1px solid var(--surface-border)}.i-table-wrapper.i-table--hoverable table tbody tr:not(.i-table-empty-row):not(.i-table-expanded-row):not(.i-table-group-header):not(.i-table-group-columns-header):not(.i-table-group-detail-row):hover{background:var(--surface-hover)}.i-table-wrapper.i-table--hoverable table tbody tr:not(.i-table-empty-row):not(.i-table-expanded-row):not(.i-table-group-header):not(.i-table-group-columns-header):not(.i-table-group-detail-row).i-table-row-selected:hover{background:var(--surface-hover)}.i-table-wrapper .i-table-column-resizer{background:var(--surface-border)}.i-table-wrapper .i-table-column-resizer:hover{background:var(--color-primary)}.i-table-wrapper{position:relative;display:block;border-radius:4px;overflow:visible}.i-table-wrapper.i-table--small table thead th{padding:8px 12px;font-size:13px}.i-table-wrapper.i-table--small table tbody td{padding:6px 12px;font-size:1em}.i-table-wrapper.i-table--small table .i-table-filter-row th{padding:4px 12px}.i-table-wrapper.i-table--large table thead th,.i-table-wrapper.i-table--large table tbody td{padding:16px 20px;font-size:16px}.i-table-wrapper.i-table--large table .i-table-filter-row th{padding:12px 20px}.i-table-wrapper.i-table--scrollable table{table-layout:fixed}.i-table-wrapper.i-table--loading{pointer-events:none;-webkit-user-select:none;user-select:none}.i-table-wrapper .i-table-header{display:flex;justify-content:space-between;align-items:center;padding:12px 16px;gap:16px}.i-table-wrapper .i-table-header .i-table-header-start{flex:0 1 auto;display:flex;align-items:center}.i-table-wrapper .i-table-header .i-table-header-end{flex:0 1 auto;display:flex;align-items:center;gap:12px;margin-left:auto}.i-table-wrapper .i-table-header .i-table-header-end .i-table-global-filter{width:250px}.i-table-wrapper .i-table-header .i-table-header-end .i-table-download{flex-shrink:0}.i-table-wrapper .i-table-loading-overlay{position:absolute;inset:0;z-index:10;display:flex;align-items:center;justify-content:center}.i-table-wrapper .i-table-loading-overlay .i-table-loading-icon{font-size:32px}.i-table-wrapper .i-table-container{overflow-x:auto}.i-table-wrapper .i-table-container::-webkit-scrollbar-track{background:transparent;border-radius:3px}.i-table-wrapper .i-table-container::-webkit-scrollbar-thumb{background:#0003;border-radius:3px;transition:background .2s ease}.i-table-wrapper .i-table-container::-webkit-scrollbar-thumb:hover{background:#00000059}.i-table-wrapper .i-table-container::-webkit-scrollbar-thumb:active{background:#00000080}.i-table-wrapper .i-table-container::-webkit-scrollbar-corner{background:transparent}.i-table-wrapper .i-table-container{scrollbar-width:thin;scrollbar-color:rgba(0,0,0,.2) transparent;scroll-behavior:smooth}.i-table-wrapper .i-table-container::-webkit-scrollbar-thumb{background:var(--color-text-secondary);opacity:.4}.i-table-wrapper .i-table-container::-webkit-scrollbar-thumb:hover{background:var(--color-text-primary);opacity:.6}.i-table-wrapper .i-table-container::-webkit-scrollbar-thumb:active{background:var(--color-primary);opacity:.7}.i-table-wrapper .i-table-container{scrollbar-color:var(--color-text-secondary) transparent}.i-table-wrapper .i-table-container::-webkit-scrollbar{width:6px;height:6px}.i-table-wrapper .i-table-container::-webkit-scrollbar-track{background:#0000000d;border-radius:3px;margin:2px 0}.i-table-wrapper .i-table-container::-webkit-scrollbar-thumb{border-radius:3px;min-height:20px;background:var(--color-text-secondary);opacity:.6}.i-table-wrapper .i-table-container::-webkit-scrollbar-thumb:hover{background:var(--color-text-primary);opacity:.8}.i-table-wrapper .i-table-container::-webkit-scrollbar-thumb:active{background:var(--color-primary);opacity:.9}.i-table-wrapper .i-table-container{scrollbar-width:thin;scrollbar-color:var(--color-text-secondary) rgba(0,0,0,.05)}.i-table-wrapper .i-table-container--scrollable{overflow-y:auto;scrollbar-gutter:stable}.i-table-wrapper .i-table-container--scrollable>table>thead{position:sticky;top:0;z-index:2}.i-table-wrapper .i-table-container--virtual-scroll{overflow:hidden;display:flex;flex-direction:column}.i-table-wrapper .i-table-container--virtual-scroll .i-table-virtual-header{flex-shrink:0;overflow:hidden;background:var(--color-surface-50)}.i-table-wrapper .i-table-container--virtual-scroll .i-table-virtual-header table{width:100%;border-collapse:collapse;table-layout:fixed}.i-table-wrapper .i-table-container--virtual-scroll .i-table-virtual-viewport{flex:1;min-height:0;width:100%}.i-table-wrapper .i-table-container--virtual-scroll .i-table-virtual-viewport .cdk-virtual-scroll-content-wrapper{width:100%}.i-table-wrapper .i-table-container--virtual-scroll .i-table-virtual-body{width:100%;border-collapse:collapse;table-layout:fixed}.i-table-wrapper .i-table-container--virtual-scroll table{display:table;width:100%;border-collapse:collapse}.i-table-wrapper .i-table-container--virtual-scroll tbody{display:table-row-group}.i-table-wrapper .i-table-container--virtual-scroll tr{display:table-row;box-sizing:border-box}.i-table-wrapper .i-table-container--virtual-scroll td,.i-table-wrapper .i-table-container--virtual-scroll th{display:table-cell}.i-table-wrapper table{width:100%;border-collapse:collapse;table-layout:auto}.i-table-wrapper table thead tr th{position:relative;padding:12px 16px;font-weight:600;text-align:left;white-space:nowrap;-webkit-user-select:none;user-select:none}.i-table-wrapper table thead tr th .i-table-header-content{display:flex;align-items:center;gap:8px}.i-table-wrapper table thead tr th .i-table-header-content .i-table-header-text{flex:1}.i-table-wrapper table thead tr th .i-table-sort-icon{font-size:.8em;opacity:.6;transition:opacity .15s ease,color .15s ease}.i-table-wrapper table thead tr th.i-table-sortable-column{transition:background-color .15s ease}.i-table-wrapper table thead tr th.i-table-sortable-column .i-table-sort-icon{opacity:.4}.i-table-wrapper table thead tr th.i-table-sortable-column:hover .i-table-sort-icon,.i-table-wrapper table thead tr th.i-table-sortable-column.i-table-sorted .i-table-sort-icon{opacity:1}.i-table-wrapper table thead tr th:hover .i-table-column-resizer{opacity:.5}.i-table-wrapper table thead tr th.i-table-actions-header{text-align:right}.i-table-wrapper table thead .i-table-filter-row th{padding:8px 16px}.i-table-wrapper table thead .i-table-filter-row th .i-table-column-filter{width:100%;padding:6px 10px;font-size:1em;border-radius:4px;transition:border-color .15s ease,box-shadow .15s ease}.i-table-wrapper table tbody{display:table-row-group}.i-table-wrapper table tbody tr{transition:background-color .15s ease}.i-table-wrapper table tbody tr td{padding:12px 16px;vertical-align:middle}.i-table-wrapper table tbody .i-table-empty-row td{padding:40px 16px;text-align:center}.i-table-wrapper table tbody .i-table-expanded-row td{padding:0}.i-table-wrapper table tbody .i-table-expanded-row td .i-table-expanded-content{padding:16px;margin:8px 16px;border-radius:4px}.i-table-wrapper table tbody .i-table-expanded-row td .i-table-expanded-content pre{margin:0;font-family:monospace;font-size:1em;white-space:pre-wrap;word-wrap:break-word}.i-table-wrapper table tbody .i-table-group-summary-row{cursor:pointer;-webkit-user-select:none;user-select:none;font-weight:600;transition:background-color .15s ease}.i-table-wrapper table tbody .i-table-group-summary-row td{padding:12px 16px}.i-table-wrapper table tbody .i-table-group-summary-row .i-table-group-header-content{display:flex;align-items:center;gap:8px}.i-table-wrapper table tbody .i-table-group-summary-row .i-table-group-header-content .i-table-group-label{flex:1;font-size:1.05em}.i-table-wrapper table tbody .i-table-group-summary-row .i-table-group-header-content .i-table-group-count{opacity:.7;font-size:.9em;font-weight:400}.i-table-wrapper table tbody .i-table-group-detail-row .i-table-group-detail-cell{padding:0;overflow:hidden}.i-table-wrapper table tbody .i-table-group-detail-row .i-table-group-detail-cell .i-table-wrapper{border-radius:0;border-top:none;overflow:hidden}.i-table-wrapper table tbody .i-table-group-count-header{width:60px;text-align:center;font-weight:400;opacity:.6;font-size:.85em}.i-table-wrapper table tbody .i-table-group-count-cell{width:60px;text-align:right;white-space:nowrap}.i-table-wrapper table tbody .i-table-group-count-cell .i-table-group-count{opacity:.7;font-size:.9em;font-weight:400}.i-table-wrapper table tbody .i-table-group-header td{padding:12px 16px;font-weight:600;cursor:pointer;-webkit-user-select:none;user-select:none;transition:background-color .15s ease}.i-table-wrapper table tbody .i-table-group-header td:hover{opacity:.8}.i-table-wrapper table tbody .i-table-group-header .i-table-group-header-content{display:flex;align-items:center;gap:8px}.i-table-wrapper table tbody .i-table-group-header .i-table-group-header-content .i-table-group-toggle-icon{font-size:.8em;transition:transform .15s ease}.i-table-wrapper table tbody .i-table-group-header .i-table-group-header-content .i-table-group-label{flex:1;font-size:1.1em}.i-table-wrapper table tbody .i-table-group-header .i-table-group-header-content .i-table-group-count{opacity:.7;font-size:.9em;font-weight:400}.i-table-wrapper table tbody .i-table-group-columns-header th{font-size:.95em;font-weight:600;padding:10px 16px}.i-table-wrapper table tbody .i-table-group-row td{padding-left:32px}.i-table-wrapper table tbody .i-table-group-row td:first-child{padding-left:16px}.i-table-wrapper .i-table-selection-header,.i-table-wrapper .i-table-selection-cell,.i-table-wrapper .i-table-expand-header,.i-table-wrapper .i-table-expand-cell{width:50px;text-align:center}.i-table-wrapper .i-table-actions-header,.i-table-wrapper .i-table-actions-cell{width:auto;white-space:nowrap;text-align:right}.i-table-wrapper .i-table-actions-header .i-table-actions,.i-table-wrapper .i-table-actions-cell .i-table-actions{display:flex;gap:4px;justify-content:flex-end}.i-table-wrapper .i-table-column-resizer{position:absolute;right:0;top:50%;transform:translateY(-50%);width:4px;height:60%;cursor:col-resize;opacity:0;transition:opacity .15s ease,background-color .15s ease}.i-table-wrapper .i-table-column-resizer:hover{opacity:1}.i-severity-icon.success,.i-table-cell-success .i-severity-icon,.i-severity-text.success,.i-table-cell-success .i-severity-text{color:var(--color-success)}.i-severity-icon.info,.i-table-cell-info .i-severity-icon,.i-severity-text.info,.i-table-cell-info .i-severity-text{color:var(--color-info)}.i-severity-icon.warning,.i-table-cell-warning .i-severity-icon,.i-severity-text.warning,.i-table-cell-warning .i-severity-text{color:var(--color-warning)}.i-severity-icon.danger,.i-table-cell-danger .i-severity-icon,.i-severity-text.danger,.i-table-cell-danger .i-severity-text{color:var(--color-danger)}.i-severity-icon.secondary,.i-table-cell-secondary .i-severity-icon,.i-severity-text.secondary,.i-table-cell-secondary .i-severity-text{color:var(--color-text-secondary)}.i-table-list-cell{display:flex;flex-direction:column;gap:4px;align-items:flex-start}.i-table-list-cell i-chip{display:block}.i-action-hidden{visibility:hidden;pointer-events:none}@media(max-width:768px){.i-table-wrapper .i-table-header{padding:8px 12px;flex-wrap:wrap}.i-table-wrapper .i-table-header .i-table-header-start{flex:1 1 100%;margin-bottom:8px}.i-table-wrapper .i-table-header .i-table-header-end{flex:1 1 100%;justify-content:flex-end}.i-table-wrapper .i-table-header .i-table-header-end .i-table-global-filter{flex:1;max-width:250px}}\n"], dependencies: [{ kind: "component", type: i0.forwardRef(() => ITable), selector: "i-table", inputs: ["data", "columns", "groupedData", "groupColumns", "emptyMessage", "sortable", "sortField", "sortOrder", "filterable", "globalFilter", "filterDelay", "selectionMode", "selection", "dataKey", "showActions", "actions", "striped", "hoverable", "bordered", "size", "loading", "scrollable", "scrollHeight", "height", "virtualScroll", "virtualScrollItemSize", "virtualScrollMinBufferPx", "virtualScrollMaxBufferPx", "resizableColumns", "reorderableColumns", "rowExpandable", "downloadable", "downloadMode", "downloadFormat", "downloadFilename"], outputs: ["onSort", "onFilter", "selectionChange", "onSelectionChange", "onRowSelect", "onRowUnselect", "onAction", "onRowExpand", "onRowCollapse", "onDownload"] }, { kind: "ngmodule", type: i0.forwardRef(() => CommonModule) }, { kind: "directive", type: i0.forwardRef(() => i1$1.NgClass), selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: i0.forwardRef(() => FormsModule) }, { kind: "directive", type: i0.forwardRef(() => i1.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: i0.forwardRef(() => i1.NgControlStatus), selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i0.forwardRef(() => i1.NgModel), selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i0.forwardRef(() => CdkVirtualScrollViewport), selector: "cdk-virtual-scroll-viewport", inputs: ["orientation", "appendOnly"], outputs: ["scrolledIndexChange"] }, { kind: "directive", type: i0.forwardRef(() => CdkVirtualForOf), selector: "[cdkVirtualFor][cdkVirtualForOf]", inputs: ["cdkVirtualForOf", "cdkVirtualForTrackBy", "cdkVirtualForTemplate", "cdkVirtualForTemplateCacheSize"] }, { kind: "directive", type: i0.forwardRef(() => CdkFixedSizeVirtualScroll), selector: "cdk-virtual-scroll-viewport[itemSize]", inputs: ["itemSize", "minBufferPx", "maxBufferPx"] }, { kind: "component", type: i0.forwardRef(() => IInputText), selector: "i-input-text", inputs: ["label", "type", "id", "fluid", "forceFloated", "hideText", "useFloatLabel", "placeholder", "externalInvalid", "externalErrorMessage", "backgroundStyle", "icon", "readonly", "disabled", "errorMessages"] }, { kind: "component", type: i0.forwardRef(() => IButton), selector: "i-button", inputs: ["severity", "size", "type", "disabled", "outlined", "raised", "text", "icon", "fluid", "loading"], outputs: ["clicked"] }, { kind: "component", type: i0.forwardRef(() => ICheckbox), selector: "i-checkbox", inputs: ["label", "id", "disabled", "readonly", "size", "indeterminate", "checked"], outputs: ["onChange"] }, { kind: "component", type: i0.forwardRef(() => IChip), selector: "i-chip", inputs: ["label", "icon", "image", "removable", "removeIcon", "styleClass", "disabled"], outputs: ["onRemove"] }, { kind: "component", type: i0.forwardRef(() => NoContentComponent), selector: "i-no-content", inputs: ["icon", "message"] }, { kind: "directive", type: i0.forwardRef(() => TooltipDirective), selector: "[iTooltip]", inputs: ["iTooltip", "tooltipPosition", "tooltipDelay"] }, { kind: "pipe", type: i0.forwardRef(() => i1$1.JsonPipe), name: "json" }] });
|
|
8515
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.3", type: ITable, isStandalone: true, selector: "i-table", inputs: { grid: { classPropertyName: "grid", publicName: "grid", isSignal: true, isRequired: false, transformFunction: null }, emptyMessage: { classPropertyName: "emptyMessage", publicName: "emptyMessage", isSignal: false, isRequired: false, transformFunction: null }, sortable: { classPropertyName: "sortable", publicName: "sortable", isSignal: false, isRequired: false, transformFunction: null }, sortField: { classPropertyName: "sortField", publicName: "sortField", isSignal: false, isRequired: false, transformFunction: null }, sortOrder: { classPropertyName: "sortOrder", publicName: "sortOrder", isSignal: false, isRequired: false, transformFunction: null }, filterable: { classPropertyName: "filterable", publicName: "filterable", isSignal: false, isRequired: false, transformFunction: null }, globalFilter: { classPropertyName: "globalFilter", publicName: "globalFilter", isSignal: false, isRequired: false, transformFunction: null }, filterDelay: { classPropertyName: "filterDelay", publicName: "filterDelay", isSignal: false, isRequired: false, transformFunction: null }, selectionMode: { classPropertyName: "selectionMode", publicName: "selectionMode", isSignal: false, isRequired: false, transformFunction: null }, selection: { classPropertyName: "selection", publicName: "selection", isSignal: false, isRequired: false, transformFunction: null }, dataKey: { classPropertyName: "dataKey", publicName: "dataKey", isSignal: false, isRequired: false, transformFunction: null }, striped: { classPropertyName: "striped", publicName: "striped", isSignal: false, isRequired: false, transformFunction: null }, hoverable: { classPropertyName: "hoverable", publicName: "hoverable", isSignal: false, isRequired: false, transformFunction: null }, bordered: { classPropertyName: "bordered", publicName: "bordered", isSignal: false, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: false, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: false, isRequired: false, transformFunction: null }, scrollable: { classPropertyName: "scrollable", publicName: "scrollable", isSignal: false, isRequired: false, transformFunction: null }, height: { classPropertyName: "height", publicName: "height", isSignal: false, isRequired: false, transformFunction: null }, virtualScroll: { classPropertyName: "virtualScroll", publicName: "virtualScroll", isSignal: false, isRequired: false, transformFunction: null }, virtualScrollItemSize: { classPropertyName: "virtualScrollItemSize", publicName: "virtualScrollItemSize", isSignal: false, isRequired: false, transformFunction: null }, virtualScrollMinBufferPx: { classPropertyName: "virtualScrollMinBufferPx", publicName: "virtualScrollMinBufferPx", isSignal: false, isRequired: false, transformFunction: null }, virtualScrollMaxBufferPx: { classPropertyName: "virtualScrollMaxBufferPx", publicName: "virtualScrollMaxBufferPx", isSignal: false, isRequired: false, transformFunction: null }, resizableColumns: { classPropertyName: "resizableColumns", publicName: "resizableColumns", isSignal: false, isRequired: false, transformFunction: null }, downloadable: { classPropertyName: "downloadable", publicName: "downloadable", isSignal: false, isRequired: false, transformFunction: null }, downloadMode: { classPropertyName: "downloadMode", publicName: "downloadMode", isSignal: false, isRequired: false, transformFunction: null }, downloadFormat: { classPropertyName: "downloadFormat", publicName: "downloadFormat", isSignal: false, isRequired: false, transformFunction: null }, downloadFilename: { classPropertyName: "downloadFilename", publicName: "downloadFilename", isSignal: false, isRequired: false, transformFunction: null } }, outputs: { onSort: "onSort", onFilter: "onFilter", selectionChange: "selectionChange", onSelectionChange: "onSelectionChange", onRowSelect: "onRowSelect", onRowUnselect: "onRowUnselect", onRowExpand: "onRowExpand", onRowCollapse: "onRowCollapse", onDownload: "onDownload" }, host: { listeners: { "document:mousemove": "onColumnResize($event)", "document:mouseup": "onColumnResizeEnd()" } }, viewQueries: [{ propertyName: "virtualScrollViewport", first: true, predicate: CdkVirtualScrollViewport, descendants: true }], ngImport: i0, template: "<div class=\"i-table-wrapper\" [ngClass]=\"getTableClasses()\">\n <!-- Table Header: global filter + download -->\n @if (globalFilter || downloadable) {\n <div class=\"i-table-header\">\n <div class=\"i-table-header-start\">\n <ng-content select=\"[header]\"></ng-content>\n </div>\n <div class=\"i-table-header-end\">\n @if (globalFilter) {\n <div class=\"i-table-global-filter\">\n <i-input-text\n [useFloatLabel]=\"false\"\n placeholder=\"Search...\"\n [ngModel]=\"globalFilterValue()\"\n (ngModelChange)=\"onGlobalFilterInput($event)\"\n [fluid]=\"false\"\n [icon]=\"'pi pi-search'\"\n ></i-input-text>\n </div>\n }\n @if (downloadable) {\n <div class=\"i-table-download\">\n <i-button\n severity=\"secondary\"\n [text]=\"true\"\n size=\"small\"\n icon=\"pi pi-download\"\n label=\"Download\"\n (clicked)=\"handleDownload()\"\n ></i-button>\n </div>\n }\n </div>\n </div>\n }\n\n <!-- Loading Overlay -->\n @if (loading) {\n <div class=\"i-table-loading-overlay\">\n <i class=\"pi pi-spin pi-spinner i-table-loading-icon\"></i>\n </div>\n }\n\n <!-- ================================================================\n PATH A \u2014 Detail-expandable table\n Uses a standard scrollable container so that nested <i-table>\n components can expand inline below their parent rows.\n ================================================================ -->\n @if (hasDetails()) {\n <div\n class=\"i-table-container i-table-container--scrollable\"\n [style.max-height]=\"effectiveHeight()\"\n >\n <table class=\"i-table\">\n <thead>\n <!-- Column Filter Row -->\n @if (filterable) {\n <tr class=\"i-table-filter-row\">\n @if (selectionMode === \"multiple\") {\n <th class=\"i-table-selection-header\"></th>\n }\n <th class=\"i-table-expand-header\"></th>\n @for (\n column of gridColumns();\n track trackByColumn($index, column)\n ) {\n @if (column.filterable !== false) {\n <th [style.width]=\"getColumnWidth(column)\">\n <input\n type=\"text\"\n class=\"i-table-column-filter\"\n placeholder=\"Filter...\"\n [ngModel]=\"columnFilters()[column.field] || ''\"\n (ngModelChange)=\"\n onColumnFilterInput(column.field, $event)\n \"\n />\n </th>\n } @else {\n <th [style.width]=\"getColumnWidth(column)\"></th>\n }\n }\n <th class=\"i-table-detail-count-header\"></th>\n @if (gridActions().length > 0) {\n <th class=\"i-table-actions-header\"></th>\n }\n </tr>\n }\n\n <!-- Column Headers -->\n <tr>\n @if (selectionMode === \"multiple\") {\n <th class=\"i-table-selection-header\">\n <i-checkbox\n [checked]=\"areAllRowsSelected()\"\n [indeterminate]=\"areSomeRowsSelected()\"\n (onChange)=\"toggleAllSelection()\"\n ></i-checkbox>\n </th>\n }\n <th class=\"i-table-expand-header\"></th>\n @for (\n column of gridColumns();\n track trackByColumn($index, column)\n ) {\n <th\n [style.width]=\"getColumnWidth(column)\"\n [style.text-align]=\"column.align || 'left'\"\n [class.i-table-sortable-column]=\"sortable && column.sortable\"\n [class.i-table-sorted]=\"sortField === column.field\"\n (click)=\"onSortColumn(column)\"\n >\n <div class=\"i-table-header-content\">\n <span class=\"i-table-header-text\">{{ column.header }}</span>\n @if (sortable && column.sortable) {\n <i\n [class]=\"getSortIcon(column)\"\n class=\"i-table-sort-icon\"\n ></i>\n }\n </div>\n @if (resizableColumns) {\n <span\n class=\"i-table-column-resizer\"\n (mousedown)=\"onColumnResizeStart($event, column)\"\n ></span>\n }\n </th>\n }\n <th class=\"i-table-detail-count-header\"></th>\n @if (gridActions().length > 0) {\n <th class=\"i-table-actions-header\">Actions</th>\n }\n </tr>\n </thead>\n\n <tbody>\n @if (processedData().length === 0) {\n <tr class=\"i-table-empty-row\">\n <td [attr.colspan]=\"totalColspan()\">\n <i-no-content />\n </td>\n </tr>\n }\n @for (row of processedData(); track trackByRow($index, row)) {\n <!-- Parent row -->\n <tr\n [class.i-table-row-odd]=\"$odd\"\n [class.i-table-row-selected]=\"isRowSelected(row)\"\n (click)=\"toggleRowSelection(row)\"\n >\n @if (selectionMode === \"multiple\") {\n <td class=\"i-table-selection-cell\">\n <i-checkbox\n [checked]=\"isRowSelected(row)\"\n (onChange)=\"toggleRowSelection(row)\"\n (click)=\"$event.stopPropagation()\"\n ></i-checkbox>\n </td>\n }\n <td class=\"i-table-expand-cell\">\n <i-button\n severity=\"secondary\"\n [text]=\"true\"\n size=\"xtra-small\"\n [icon]=\"\n isRowExpanded(row)\n ? 'pi pi-chevron-down'\n : 'pi pi-chevron-right'\n \"\n (clicked)=\"toggleRowExpansion(row, $event)\"\n ></i-button>\n </td>\n @for (\n column of gridColumns();\n track trackByColumn($index, column)\n ) {\n <td\n [style.text-align]=\"column.align || 'left'\"\n [style.width]=\"getColumnWidth(column)\"\n [class]=\"\n getCellSeverity(row, column)\n ? 'i-table-cell-' + getCellSeverity(row, column)\n : ''\n \"\n >\n @if (isIconColumn(column)) {\n <i\n [class]=\"getCellIcon(row, column)\"\n [class.i-severity-icon]=\"getCellSeverity(row, column)\"\n [style.font-size]=\"column.iconSize || '1rem'\"\n ></i>\n } @else if (isListColumn(column)) {\n <div class=\"i-table-list-cell\">\n @for (item of getCellListItems(row, column); track item) {\n <i-chip [label]=\"item\"></i-chip>\n }\n </div>\n } @else {\n <span\n [class.i-severity-text]=\"getCellSeverity(row, column)\"\n >\n {{\n formatCellValue(getCellValue(row, column.field), column)\n }}\n </span>\n }\n </td>\n }\n <td class=\"i-table-detail-count-cell\">\n ({{ getDetailRowCount(row) }})\n </td>\n @if (gridActions().length > 0) {\n <td class=\"i-table-actions-cell\">\n <div class=\"i-table-actions\">\n @for (action of gridActions(); track action.id) {\n <i-button\n [severity]=\"action.severity || 'secondary'\"\n [text]=\"true\"\n size=\"small\"\n [icon]=\"action.icon || ''\"\n [disabled]=\"isActionDisabled(action, row)\"\n [iTooltip]=\"getActionTooltip(action, row)\"\n [class.i-action-hidden]=\"!isActionVisible(action, row)\"\n (clicked)=\"triggerAction(action, row, $event)\"\n >\n @if (action.label) {\n {{ action.label }}\n }\n </i-button>\n }\n </div>\n </td>\n }\n </tr>\n\n <!-- Detail expansion row -->\n @if (isRowExpanded(row)) {\n <tr class=\"i-table-expanded-row\">\n <td\n [attr.colspan]=\"totalColspan()\"\n class=\"i-table-expanded-cell\"\n >\n <div class=\"i-table-expanded-content\">\n <i-table\n [grid]=\"getDetailGrid(row)\"\n [sortable]=\"sortable\"\n [filterable]=\"filterable\"\n [selectionMode]=\"selectionMode\"\n [selection]=\"selection\"\n [striped]=\"striped\"\n [hoverable]=\"hoverable\"\n [bordered]=\"bordered\"\n [size]=\"size\"\n [dataKey]=\"dataKey\"\n [resizableColumns]=\"resizableColumns\"\n (onSort)=\"onSort.emit($event)\"\n (onFilter)=\"onFilter.emit($event)\"\n (onSelectionChange)=\"onSelectionChange.emit($event)\"\n (selectionChange)=\"selectionChange.emit($event)\"\n (onRowSelect)=\"onRowSelect.emit($event)\"\n (onRowUnselect)=\"onRowUnselect.emit($event)\"\n ></i-table>\n </div>\n </td>\n </tr>\n }\n }\n </tbody>\n </table>\n </div>\n } @else if (virtualScroll) {\n <!-- ================================================================\n PATH B \u2014 CDK Virtual Scroll (div-based rows)\n Use only for large row counts (\u2265 ~500 rows). Uses flex <div> rows\n so CDK's wrapper <div> does not end up inside <tbody> (invalid HTML).\n ================================================================ -->\n <div\n class=\"i-table-container i-table-container--scrollable i-table-container--virtual-scroll\"\n [style.height]=\"effectiveHeight()\"\n >\n <!-- Sticky header \u2014 flex rows that mirror the virtual body rows -->\n <div class=\"i-table-virtual-header\">\n @if (filterable) {\n <div class=\"i-table-virtual-row i-table-filter-row\">\n @if (selectionMode === \"multiple\") {\n <div class=\"i-table-virtual-cell i-table-selection-header\"></div>\n }\n @for (\n column of gridColumns();\n track trackByColumn($index, column)\n ) {\n @if (column.filterable !== false) {\n <div\n class=\"i-table-virtual-cell\"\n [style.width]=\"\n getColumnWidth(column) !== 'auto'\n ? getColumnWidth(column)\n : null\n \"\n [style.flex]=\"getColumnWidth(column) === 'auto' ? '1' : null\"\n >\n <input\n type=\"text\"\n class=\"i-table-column-filter\"\n placeholder=\"Filter...\"\n [ngModel]=\"columnFilters()[column.field] || ''\"\n (ngModelChange)=\"onColumnFilterInput(column.field, $event)\"\n />\n </div>\n } @else {\n <div\n class=\"i-table-virtual-cell\"\n [style.width]=\"\n getColumnWidth(column) !== 'auto'\n ? getColumnWidth(column)\n : null\n \"\n [style.flex]=\"getColumnWidth(column) === 'auto' ? '1' : null\"\n ></div>\n }\n }\n @if (gridActions().length > 0) {\n <div class=\"i-table-virtual-cell i-table-actions-header\"></div>\n }\n </div>\n }\n <div class=\"i-table-virtual-row i-table-header-row\">\n @if (selectionMode === \"multiple\") {\n <div class=\"i-table-virtual-cell i-table-selection-header\">\n <i-checkbox\n [checked]=\"areAllRowsSelected()\"\n [indeterminate]=\"areSomeRowsSelected()\"\n (onChange)=\"toggleAllSelection()\"\n ></i-checkbox>\n </div>\n }\n @for (column of gridColumns(); track trackByColumn($index, column)) {\n <div\n class=\"i-table-virtual-cell i-table-header-cell\"\n [style.width]=\"\n getColumnWidth(column) !== 'auto'\n ? getColumnWidth(column)\n : null\n \"\n [style.flex]=\"getColumnWidth(column) === 'auto' ? '1' : null\"\n [style.text-align]=\"column.align || 'left'\"\n [class.i-table-sortable-column]=\"sortable && column.sortable\"\n [class.i-table-sorted]=\"sortField === column.field\"\n (click)=\"onSortColumn(column)\"\n >\n <div class=\"i-table-header-content\">\n <span class=\"i-table-header-text\">{{ column.header }}</span>\n @if (sortable && column.sortable) {\n <i\n [class]=\"getSortIcon(column)\"\n class=\"i-table-sort-icon\"\n ></i>\n }\n </div>\n </div>\n }\n @if (gridActions().length > 0) {\n <div class=\"i-table-virtual-cell i-table-actions-header\">\n Actions\n </div>\n }\n </div>\n </div>\n\n <!-- Virtual Scroll Viewport \u2014 *cdkVirtualFor on <div>, not <tr> -->\n <cdk-virtual-scroll-viewport\n [itemSize]=\"virtualScrollItemSize\"\n [minBufferPx]=\"virtualScrollMinBufferPx\"\n [maxBufferPx]=\"virtualScrollMaxBufferPx\"\n class=\"i-table-virtual-viewport\"\n >\n @if (processedData().length === 0) {\n <div class=\"i-table-virtual-row i-table-empty-row\">\n <div\n class=\"i-table-virtual-cell\"\n style=\"flex: 1; text-align: center; padding: 40px 16px\"\n >\n <i-no-content />\n </div>\n </div>\n }\n <div\n *cdkVirtualFor=\"\n let row of processedData();\n let rowIndex = index;\n trackBy: trackByRow\n \"\n class=\"i-table-virtual-row\"\n [style.height.px]=\"virtualScrollItemSize\"\n [class.i-table-row-odd]=\"rowIndex % 2 !== 0\"\n [class.i-table-row-selected]=\"isRowSelected(row)\"\n (click)=\"toggleRowSelection(row)\"\n >\n @if (selectionMode === \"multiple\") {\n <div class=\"i-table-virtual-cell i-table-selection-cell\">\n <i-checkbox\n [checked]=\"isRowSelected(row)\"\n (onChange)=\"toggleRowSelection(row)\"\n (click)=\"$event.stopPropagation()\"\n ></i-checkbox>\n </div>\n }\n @for (column of gridColumns(); track trackByColumn($index, column)) {\n <div\n class=\"i-table-virtual-cell\"\n [style.width]=\"\n getColumnWidth(column) !== 'auto'\n ? getColumnWidth(column)\n : null\n \"\n [style.flex]=\"getColumnWidth(column) === 'auto' ? '1' : null\"\n [style.text-align]=\"column.align || 'left'\"\n [ngClass]=\"\n getCellSeverity(row, column)\n ? 'i-table-cell-' + getCellSeverity(row, column)\n : ''\n \"\n >\n @if (isIconColumn(column)) {\n <i\n [class]=\"getIconClasses(row, column)\"\n [style.font-size]=\"column.iconSize || '1rem'\"\n ></i>\n } @else if (isListColumn(column)) {\n <div class=\"i-table-list-cell\">\n @for (item of getCellListItems(row, column); track item) {\n <i-chip [label]=\"item\"></i-chip>\n }\n </div>\n } @else {\n <span [class.i-severity-text]=\"getCellSeverity(row, column)\">\n {{ formatCellValue(getCellValue(row, column.field), column) }}\n </span>\n }\n </div>\n }\n @if (gridActions().length > 0) {\n <div class=\"i-table-virtual-cell i-table-actions-cell\">\n <div class=\"i-table-actions\">\n @for (action of gridActions(); track action.id) {\n <i-button\n [severity]=\"action.severity || 'secondary'\"\n [text]=\"true\"\n size=\"small\"\n [icon]=\"action.icon || ''\"\n [disabled]=\"isActionDisabled(action, row)\"\n [iTooltip]=\"getActionTooltip(action, row)\"\n [class.i-action-hidden]=\"!isActionVisible(action, row)\"\n (clicked)=\"triggerAction(action, row, $event)\"\n >\n @if (action.label) {\n {{ action.label }}\n }\n </i-button>\n }\n </div>\n </div>\n }\n </div>\n </cdk-virtual-scroll-viewport>\n </div>\n } @else {\n <!-- ================================================================\n PATH C \u2014 Regular scrollable table\n Default for small/medium datasets and nested detail tables.\n Uses a plain overflow container with a @for loop \u2014 no CDK needed.\n ================================================================ -->\n <div\n class=\"i-table-container i-table-container--scrollable\"\n [style.max-height]=\"effectiveHeight()\"\n >\n <table class=\"i-table\">\n <thead>\n <!-- Column Filter Row -->\n @if (filterable) {\n <tr class=\"i-table-filter-row\">\n @if (selectionMode === \"multiple\") {\n <th class=\"i-table-selection-header\"></th>\n }\n @for (\n column of gridColumns();\n track trackByColumn($index, column)\n ) {\n @if (column.filterable !== false) {\n <th [style.width]=\"getColumnWidth(column)\">\n <input\n type=\"text\"\n class=\"i-table-column-filter\"\n placeholder=\"Filter...\"\n [ngModel]=\"columnFilters()[column.field] || ''\"\n (ngModelChange)=\"\n onColumnFilterInput(column.field, $event)\n \"\n />\n </th>\n } @else {\n <th [style.width]=\"getColumnWidth(column)\"></th>\n }\n }\n @if (gridActions().length > 0) {\n <th class=\"i-table-actions-header\"></th>\n }\n </tr>\n }\n\n <!-- Column Headers -->\n <tr>\n @if (selectionMode === \"multiple\") {\n <th class=\"i-table-selection-header\">\n <i-checkbox\n [checked]=\"areAllRowsSelected()\"\n [indeterminate]=\"areSomeRowsSelected()\"\n (onChange)=\"toggleAllSelection()\"\n ></i-checkbox>\n </th>\n }\n @for (\n column of gridColumns();\n track trackByColumn($index, column)\n ) {\n <th\n [style.width]=\"getColumnWidth(column)\"\n [style.text-align]=\"column.align || 'left'\"\n [class.i-table-sortable-column]=\"sortable && column.sortable\"\n [class.i-table-sorted]=\"sortField === column.field\"\n (click)=\"onSortColumn(column)\"\n >\n <div class=\"i-table-header-content\">\n <span class=\"i-table-header-text\">{{ column.header }}</span>\n @if (sortable && column.sortable) {\n <i\n [class]=\"getSortIcon(column)\"\n class=\"i-table-sort-icon\"\n ></i>\n }\n </div>\n @if (resizableColumns) {\n <span\n class=\"i-table-column-resizer\"\n (mousedown)=\"onColumnResizeStart($event, column)\"\n ></span>\n }\n </th>\n }\n @if (gridActions().length > 0) {\n <th class=\"i-table-actions-header\">Actions</th>\n }\n </tr>\n </thead>\n\n <tbody>\n @if (processedData().length === 0) {\n <tr class=\"i-table-empty-row\">\n <td [attr.colspan]=\"totalColspan()\">\n <i-no-content />\n </td>\n </tr>\n }\n @for (row of processedData(); track trackByRow($index, row)) {\n <tr\n [class.i-table-row-odd]=\"$odd\"\n [class.i-table-row-selected]=\"isRowSelected(row)\"\n (click)=\"toggleRowSelection(row)\"\n >\n @if (selectionMode === \"multiple\") {\n <td class=\"i-table-selection-cell\">\n <i-checkbox\n [checked]=\"isRowSelected(row)\"\n (onChange)=\"toggleRowSelection(row)\"\n (click)=\"$event.stopPropagation()\"\n ></i-checkbox>\n </td>\n }\n @for (\n column of gridColumns();\n track trackByColumn($index, column)\n ) {\n <td\n [style.text-align]=\"column.align || 'left'\"\n [style.width]=\"getColumnWidth(column)\"\n [class]=\"\n getCellSeverity(row, column)\n ? 'i-table-cell-' + getCellSeverity(row, column)\n : ''\n \"\n >\n @if (isIconColumn(column)) {\n <i\n [class]=\"getIconClasses(row, column)\"\n [style.font-size]=\"column.iconSize || '1rem'\"\n ></i>\n } @else if (isListColumn(column)) {\n <div class=\"i-table-list-cell\">\n @for (item of getCellListItems(row, column); track item) {\n <i-chip [label]=\"item\"></i-chip>\n }\n </div>\n } @else {\n <span\n [class.i-severity-text]=\"getCellSeverity(row, column)\"\n >\n {{\n formatCellValue(getCellValue(row, column.field), column)\n }}\n </span>\n }\n </td>\n }\n @if (gridActions().length > 0) {\n <td class=\"i-table-actions-cell\">\n <div class=\"i-table-actions\">\n @for (action of gridActions(); track action.id) {\n <i-button\n [severity]=\"action.severity || 'secondary'\"\n [text]=\"true\"\n size=\"small\"\n [icon]=\"action.icon || ''\"\n [disabled]=\"isActionDisabled(action, row)\"\n [iTooltip]=\"getActionTooltip(action, row)\"\n [class.i-action-hidden]=\"!isActionVisible(action, row)\"\n (clicked)=\"triggerAction(action, row, $event)\"\n >\n @if (action.label) {\n {{ action.label }}\n }\n </i-button>\n }\n </div>\n </td>\n }\n </tr>\n }\n </tbody>\n </table>\n </div>\n }\n</div>\n", styles: [".i-table-wrapper{color:var(--color-text-primary);background:var(--color-component-background)}.i-table-wrapper .i-table-header{background:var(--surface-section);border-bottom:1px solid var(--surface-border)}.i-table-wrapper .i-table-global-filter .i-input-text{background:var(--surface-ground)}.i-table-wrapper .i-table-loading-overlay{background:#ffffffb3}.i-table-wrapper .i-table-loading-overlay .i-table-loading-icon{color:var(--color-primary)}.i-table-wrapper table thead tr{background:var(--color-component-background)}.i-table-wrapper table thead tr th{color:var(--color-text-primary);border-bottom:1px solid var(--surface-border)}.i-table-wrapper table thead tr th.i-table-sortable-column{cursor:pointer}.i-table-wrapper table thead tr th.i-table-sortable-column:hover{background:var(--surface-hover)}.i-table-wrapper table thead tr th.i-table-sorted{background:var(--surface-hover);color:var(--color-primary)}.i-table-wrapper table thead tr th .i-table-sort-icon{color:var(--color-text-secondary)}.i-table-wrapper table thead tr th.i-table-sorted .i-table-sort-icon{color:var(--color-primary)}.i-table-wrapper table thead .i-table-filter-row th{background:var(--color-component-background)}.i-table-wrapper table thead .i-table-filter-row .i-table-column-filter{border:1px solid var(--surface-border);background:var(--surface-ground);color:var(--color-text-primary)}.i-table-wrapper table thead .i-table-filter-row .i-table-column-filter:focus{border-color:var(--color-primary);box-shadow:0 2px 10px #0003;outline:none}.i-table-wrapper table thead .i-table-filter-row .i-table-column-filter::placeholder{color:var(--color-text-tertiary)}.i-table-wrapper table tbody tr{background:var(--color-component-background);border-bottom:1px solid var(--surface-border)}.i-table-wrapper table tbody tr td{color:var(--color-text-primary)}.i-table-wrapper table tbody tr.i-table-row-odd{background:var(--color-component-background)}.i-table-wrapper table tbody tr.i-table-row-selected{background:var(--surface-hover);color:var(--color-primary)}.i-table-wrapper table tbody .i-table-expanded-row{background:var(--color-component-background)}.i-table-wrapper table tbody .i-table-expanded-row .i-table-expanded-content{background:transparent}.i-table-wrapper table tbody .i-table-empty-row td{background:var(--color-component-background)}.i-table-wrapper table tbody .i-table-group-header{background:var(--color-component-background);border-bottom:2px solid var(--surface-border)}.i-table-wrapper table tbody .i-table-group-header td{color:var(--color-text-primary)}.i-table-wrapper table tbody .i-table-group-header:hover{background:var(--surface-hover)}.i-table-wrapper table tbody .i-table-group-header .i-table-group-toggle-icon,.i-table-wrapper table tbody .i-table-group-header .i-table-group-count{color:var(--color-text-secondary)}.i-table-wrapper table tbody .i-table-group-columns-header{background:var(--color-component-background);border-bottom:1px solid var(--surface-border)}.i-table-wrapper table tbody .i-table-group-columns-header th{color:var(--color-text-primary);border-bottom:1px solid var(--surface-border)}.i-table-wrapper table tbody .i-table-group-row,.i-table-wrapper table tbody .i-table-group-row.i-table-row-odd{background:var(--color-component-background)}.i-table-wrapper table tbody .i-table-group-row.i-table-row-selected{background:var(--surface-hover);color:var(--color-primary)}.i-table-wrapper table tbody .i-table-group-summary-row{background:var(--surface-section);border-bottom:2px solid var(--surface-border)}.i-table-wrapper table tbody .i-table-group-summary-row td{color:var(--color-text-primary);font-weight:600}.i-table-wrapper table tbody .i-table-group-summary-row:hover{background:var(--surface-hover)}.i-table-wrapper table tbody .i-table-group-summary-row .i-table-group-count{color:var(--color-text-secondary)}.i-table-wrapper table tbody .i-table-group-detail-row,.i-table-wrapper table tbody .i-table-group-detail-row .i-table-group-detail-cell .i-table-wrapper{background:var(--surface-ground)}.i-table-wrapper table tbody .i-table-group-detail-row .i-table-group-detail-cell .i-table-wrapper table thead tr{background:var(--surface-section)}.i-table-wrapper.i-table--bordered table,.i-table-wrapper.i-table--bordered table th,.i-table-wrapper.i-table--bordered table td{border:1px solid var(--surface-border)}.i-table-wrapper.i-table--hoverable table tbody tr:not(.i-table-empty-row):not(.i-table-expanded-row):not(.i-table-group-header):not(.i-table-group-columns-header):not(.i-table-group-detail-row):hover{background:var(--surface-hover)}.i-table-wrapper.i-table--hoverable table tbody tr:not(.i-table-empty-row):not(.i-table-expanded-row):not(.i-table-group-header):not(.i-table-group-columns-header):not(.i-table-group-detail-row).i-table-row-selected:hover{background:var(--surface-hover)}.i-table-wrapper .i-table-column-resizer{background:var(--surface-border)}.i-table-wrapper .i-table-column-resizer:hover{background:var(--color-primary)}.i-table-wrapper .i-table-container--virtual-scroll .i-table-virtual-header{background:var(--color-component-background);border-bottom:1px solid var(--surface-border)}.i-table-wrapper .i-table-container--virtual-scroll .i-table-virtual-header .i-table-virtual-cell{color:var(--color-text-primary)}.i-table-wrapper .i-table-container--virtual-scroll .i-table-virtual-header .i-table-header-cell .i-table-sort-icon{color:var(--color-text-secondary)}.i-table-wrapper .i-table-container--virtual-scroll .i-table-virtual-header .i-table-header-cell.i-table-sortable-column:hover{background:var(--surface-hover)}.i-table-wrapper .i-table-container--virtual-scroll .i-table-virtual-header .i-table-header-cell.i-table-sorted{background:var(--surface-hover);color:var(--color-primary)}.i-table-wrapper .i-table-container--virtual-scroll .i-table-virtual-header .i-table-header-cell.i-table-sorted .i-table-sort-icon{color:var(--color-primary)}.i-table-wrapper .i-table-container--virtual-scroll .i-table-virtual-header .i-table-filter-row .i-table-column-filter{border:1px solid var(--surface-border);background:var(--surface-ground);color:var(--color-text-primary)}.i-table-wrapper .i-table-container--virtual-scroll .i-table-virtual-header .i-table-filter-row .i-table-column-filter:focus{border-color:var(--color-primary);outline:none}.i-table-wrapper .i-table-container--virtual-scroll .i-table-virtual-header .i-table-filter-row .i-table-column-filter::placeholder{color:var(--color-text-tertiary)}.i-table-wrapper .i-table-container--virtual-scroll .i-table-virtual-viewport .i-table-virtual-row{background:var(--color-component-background);border-bottom:1px solid var(--surface-border);color:var(--color-text-primary);transition:background-color .15s ease}.i-table-wrapper .i-table-container--virtual-scroll .i-table-virtual-viewport .i-table-virtual-row.i-table-row-odd{background:var(--color-component-background)}.i-table-wrapper .i-table-container--virtual-scroll .i-table-virtual-viewport .i-table-virtual-row.i-table-row-selected{background:var(--surface-hover);color:var(--color-primary)}.i-table-wrapper.i-table--nested{background:transparent}.i-table-wrapper.i-table--nested table thead tr{background:var(--surface-section)}.i-table-wrapper{position:relative;display:block;border-radius:4px;overflow:visible}.i-table-wrapper.i-table--small table thead th{padding:8px 12px;font-size:13px}.i-table-wrapper.i-table--small table tbody td{padding:6px 12px;font-size:1em}.i-table-wrapper.i-table--small table .i-table-filter-row th{padding:4px 12px}.i-table-wrapper.i-table--large table thead th,.i-table-wrapper.i-table--large table tbody td{padding:16px 20px;font-size:16px}.i-table-wrapper.i-table--large table .i-table-filter-row th{padding:12px 20px}.i-table-wrapper.i-table--scrollable table{table-layout:fixed}.i-table-wrapper.i-table--loading{pointer-events:none;-webkit-user-select:none;user-select:none}.i-table-wrapper .i-table-header{display:flex;justify-content:space-between;align-items:center;padding:12px 16px;gap:16px}.i-table-wrapper .i-table-header .i-table-header-start{flex:0 1 auto;display:flex;align-items:center}.i-table-wrapper .i-table-header .i-table-header-end{flex:0 1 auto;display:flex;align-items:center;gap:12px;margin-left:auto}.i-table-wrapper .i-table-header .i-table-header-end .i-table-global-filter{width:250px}.i-table-wrapper .i-table-header .i-table-header-end .i-table-download{flex-shrink:0}.i-table-wrapper .i-table-loading-overlay{position:absolute;inset:0;z-index:10;display:flex;align-items:center;justify-content:center}.i-table-wrapper .i-table-loading-overlay .i-table-loading-icon{font-size:32px}.i-table-wrapper .i-table-container{overflow-x:auto}.i-table-wrapper .i-table-container::-webkit-scrollbar-track{background:transparent;border-radius:3px}.i-table-wrapper .i-table-container::-webkit-scrollbar-thumb{background:#0003;border-radius:3px;transition:background .2s ease}.i-table-wrapper .i-table-container::-webkit-scrollbar-thumb:hover{background:#00000059}.i-table-wrapper .i-table-container::-webkit-scrollbar-thumb:active{background:#00000080}.i-table-wrapper .i-table-container::-webkit-scrollbar-corner{background:transparent}.i-table-wrapper .i-table-container{scrollbar-width:thin;scrollbar-color:rgba(0,0,0,.2) transparent;scroll-behavior:smooth}.i-table-wrapper .i-table-container::-webkit-scrollbar-thumb{background:var(--color-text-secondary);opacity:.4}.i-table-wrapper .i-table-container::-webkit-scrollbar-thumb:hover{background:var(--color-text-primary);opacity:.6}.i-table-wrapper .i-table-container::-webkit-scrollbar-thumb:active{background:var(--color-primary);opacity:.7}.i-table-wrapper .i-table-container{scrollbar-color:var(--color-text-secondary) transparent}.i-table-wrapper .i-table-container::-webkit-scrollbar{width:6px;height:6px}.i-table-wrapper .i-table-container::-webkit-scrollbar-track{background:#0000000d;border-radius:3px;margin:2px 0}.i-table-wrapper .i-table-container::-webkit-scrollbar-thumb{border-radius:3px;min-height:20px;background:var(--color-text-secondary);opacity:.6}.i-table-wrapper .i-table-container::-webkit-scrollbar-thumb:hover{background:var(--color-text-primary);opacity:.8}.i-table-wrapper .i-table-container::-webkit-scrollbar-thumb:active{background:var(--color-primary);opacity:.9}.i-table-wrapper .i-table-container{scrollbar-width:thin;scrollbar-color:var(--color-text-secondary) rgba(0,0,0,.05)}.i-table-wrapper .i-table-container--scrollable{overflow-y:auto;scrollbar-gutter:stable}.i-table-wrapper .i-table-container--scrollable>table>thead{position:sticky;top:0;z-index:2}.i-table-wrapper .i-table-container--virtual-scroll{overflow:hidden;display:flex;flex-direction:column}.i-table-wrapper .i-table-container--virtual-scroll .i-table-virtual-header{flex-shrink:0;overflow:hidden}.i-table-wrapper .i-table-container--virtual-scroll .i-table-virtual-header .i-table-sort-icon{font-size:.8em;opacity:.6;transition:opacity .15s ease,color .15s ease}.i-table-wrapper .i-table-container--virtual-scroll .i-table-virtual-header .i-table-header-cell.i-table-sortable-column{cursor:pointer}.i-table-wrapper .i-table-container--virtual-scroll .i-table-virtual-header .i-table-header-cell.i-table-sortable-column .i-table-sort-icon{opacity:.4}.i-table-wrapper .i-table-container--virtual-scroll .i-table-virtual-header .i-table-header-cell.i-table-sortable-column:hover .i-table-sort-icon,.i-table-wrapper .i-table-container--virtual-scroll .i-table-virtual-header .i-table-header-cell.i-table-sortable-column.i-table-sorted .i-table-sort-icon{opacity:1}.i-table-wrapper .i-table-container--virtual-scroll .i-table-virtual-header .i-table-filter-row .i-table-virtual-cell{padding:8px 16px}.i-table-wrapper .i-table-container--virtual-scroll .i-table-virtual-header .i-table-filter-row .i-table-virtual-cell .i-table-column-filter{width:100%;padding:6px 10px;font-size:1em;border-radius:4px;transition:border-color .15s ease,box-shadow .15s ease}.i-table-wrapper .i-table-container--virtual-scroll .i-table-virtual-viewport{flex:1;min-height:0;width:100%;overflow-y:auto}.i-table-wrapper .i-table-container--virtual-scroll .i-table-virtual-viewport::-webkit-scrollbar-track{background:transparent;border-radius:3px}.i-table-wrapper .i-table-container--virtual-scroll .i-table-virtual-viewport::-webkit-scrollbar-thumb{background:#0003;border-radius:3px;transition:background .2s ease}.i-table-wrapper .i-table-container--virtual-scroll .i-table-virtual-viewport::-webkit-scrollbar-thumb:hover{background:#00000059}.i-table-wrapper .i-table-container--virtual-scroll .i-table-virtual-viewport::-webkit-scrollbar-thumb:active{background:#00000080}.i-table-wrapper .i-table-container--virtual-scroll .i-table-virtual-viewport::-webkit-scrollbar-corner{background:transparent}.i-table-wrapper .i-table-container--virtual-scroll .i-table-virtual-viewport{scrollbar-width:thin;scrollbar-color:rgba(0,0,0,.2) transparent;scroll-behavior:smooth}.i-table-wrapper .i-table-container--virtual-scroll .i-table-virtual-viewport::-webkit-scrollbar-thumb{background:var(--color-text-secondary);opacity:.4}.i-table-wrapper .i-table-container--virtual-scroll .i-table-virtual-viewport::-webkit-scrollbar-thumb:hover{background:var(--color-text-primary);opacity:.6}.i-table-wrapper .i-table-container--virtual-scroll .i-table-virtual-viewport::-webkit-scrollbar-thumb:active{background:var(--color-primary);opacity:.7}.i-table-wrapper .i-table-container--virtual-scroll .i-table-virtual-viewport{scrollbar-color:var(--color-text-secondary) transparent}.i-table-wrapper .i-table-container--virtual-scroll .i-table-virtual-viewport::-webkit-scrollbar{width:6px;height:6px}.i-table-wrapper .i-table-container--virtual-scroll .i-table-virtual-viewport::-webkit-scrollbar-track{background:#0000000d;border-radius:3px;margin:2px 0}.i-table-wrapper .i-table-container--virtual-scroll .i-table-virtual-viewport::-webkit-scrollbar-thumb{border-radius:3px;min-height:20px;background:var(--color-text-secondary);opacity:.6}.i-table-wrapper .i-table-container--virtual-scroll .i-table-virtual-viewport::-webkit-scrollbar-thumb:hover{background:var(--color-text-primary);opacity:.8}.i-table-wrapper .i-table-container--virtual-scroll .i-table-virtual-viewport::-webkit-scrollbar-thumb:active{background:var(--color-primary);opacity:.9}.i-table-wrapper .i-table-container--virtual-scroll .i-table-virtual-viewport{scrollbar-width:thin;scrollbar-color:var(--color-text-secondary) rgba(0,0,0,.05)}.i-table-wrapper .i-table-container--virtual-scroll .i-table-virtual-viewport .cdk-virtual-scroll-content-wrapper{width:100%}.i-table-wrapper .i-table-container--virtual-scroll .i-table-virtual-row{display:flex;align-items:center;width:100%;box-sizing:border-box}.i-table-wrapper .i-table-container--virtual-scroll .i-table-virtual-cell{padding:12px 16px;box-sizing:border-box;flex-shrink:0;overflow:hidden;display:flex;align-items:center}.i-table-wrapper .i-table-container--virtual-scroll .i-table-virtual-cell.i-table-header-cell{-webkit-user-select:none;user-select:none;font-weight:600;white-space:nowrap}.i-table-wrapper .i-table-container--virtual-scroll .i-table-virtual-cell.i-table-header-cell .i-table-header-content{display:flex;align-items:center;gap:8px}.i-table-wrapper .i-table-container--virtual-scroll .i-table-virtual-cell.i-table-header-cell .i-table-header-content .i-table-header-text{flex:1}.i-table-wrapper .i-table-container--virtual-scroll .i-table-virtual-cell.i-table-selection-header,.i-table-wrapper .i-table-container--virtual-scroll .i-table-virtual-cell.i-table-selection-cell{width:50px;flex:0 0 50px;justify-content:center}.i-table-wrapper .i-table-container--virtual-scroll .i-table-virtual-cell.i-table-actions-header,.i-table-wrapper .i-table-container--virtual-scroll .i-table-virtual-cell.i-table-actions-cell{flex:0 0 auto;justify-content:flex-end}.i-table-wrapper .i-table-container--virtual-scroll .i-table-virtual-cell.i-table-actions-header .i-table-actions,.i-table-wrapper .i-table-container--virtual-scroll .i-table-virtual-cell.i-table-actions-cell .i-table-actions{display:flex;gap:4px;justify-content:flex-end}.i-table-wrapper table{width:100%;border-collapse:collapse;table-layout:auto}.i-table-wrapper table thead tr th{position:relative;padding:12px 16px;font-weight:600;text-align:left;white-space:nowrap;-webkit-user-select:none;user-select:none}.i-table-wrapper table thead tr th .i-table-header-content{display:flex;align-items:center;gap:8px}.i-table-wrapper table thead tr th .i-table-header-content .i-table-header-text{flex:1}.i-table-wrapper table thead tr th .i-table-sort-icon{font-size:.8em;opacity:.6;transition:opacity .15s ease,color .15s ease}.i-table-wrapper table thead tr th.i-table-sortable-column{transition:background-color .15s ease}.i-table-wrapper table thead tr th.i-table-sortable-column .i-table-sort-icon{opacity:.4}.i-table-wrapper table thead tr th.i-table-sortable-column:hover .i-table-sort-icon,.i-table-wrapper table thead tr th.i-table-sortable-column.i-table-sorted .i-table-sort-icon{opacity:1}.i-table-wrapper table thead tr th:hover .i-table-column-resizer{opacity:.5}.i-table-wrapper table thead tr th.i-table-actions-header{text-align:right}.i-table-wrapper table thead .i-table-filter-row th{padding:8px 16px}.i-table-wrapper table thead .i-table-filter-row th .i-table-column-filter{width:100%;padding:6px 10px;font-size:1em;border-radius:4px;transition:border-color .15s ease,box-shadow .15s ease}.i-table-wrapper table tbody{display:table-row-group}.i-table-wrapper table tbody tr{transition:background-color .15s ease}.i-table-wrapper table tbody tr td{padding:12px 16px;vertical-align:middle}.i-table-wrapper table tbody .i-table-empty-row td{padding:40px 16px;text-align:center}.i-table-wrapper table tbody .i-table-expanded-row td .i-table-expanded-content{padding:0;margin:2px 0 24px;border-radius:4px}.i-table-wrapper table tbody .i-table-expanded-row td .i-table-expanded-content pre{margin:0;font-family:monospace;font-size:1em;white-space:pre-wrap;word-wrap:break-word}.i-table-wrapper table tbody .i-table-group-summary-row{cursor:pointer;-webkit-user-select:none;user-select:none;font-weight:600;transition:background-color .15s ease}.i-table-wrapper table tbody .i-table-group-summary-row td{padding:12px 16px}.i-table-wrapper table tbody .i-table-group-summary-row .i-table-group-header-content{display:flex;align-items:center;gap:8px}.i-table-wrapper table tbody .i-table-group-summary-row .i-table-group-header-content .i-table-group-label{flex:1;font-size:1.05em}.i-table-wrapper table tbody .i-table-group-summary-row .i-table-group-header-content .i-table-group-count{opacity:.7;font-size:.9em;font-weight:400}.i-table-wrapper table tbody .i-table-group-detail-row .i-table-group-detail-cell{padding:0;overflow:hidden}.i-table-wrapper table tbody .i-table-group-detail-row .i-table-group-detail-cell .i-table-wrapper{border-radius:0;border-top:none;overflow:hidden}.i-table-wrapper table tbody .i-table-group-count-header{width:60px;text-align:center;font-weight:400;opacity:.6;font-size:.85em}.i-table-wrapper table tbody .i-table-group-count-cell{width:60px;text-align:right;white-space:nowrap}.i-table-wrapper table tbody .i-table-group-count-cell .i-table-group-count{opacity:.7;font-size:.9em;font-weight:400}.i-table-wrapper table tbody .i-table-group-header td{padding:12px 16px;font-weight:600;cursor:pointer;-webkit-user-select:none;user-select:none;transition:background-color .15s ease}.i-table-wrapper table tbody .i-table-group-header td:hover{opacity:.8}.i-table-wrapper table tbody .i-table-group-header .i-table-group-header-content{display:flex;align-items:center;gap:8px}.i-table-wrapper table tbody .i-table-group-header .i-table-group-header-content .i-table-group-toggle-icon{font-size:.8em;transition:transform .15s ease}.i-table-wrapper table tbody .i-table-group-header .i-table-group-header-content .i-table-group-label{flex:1;font-size:1.1em}.i-table-wrapper table tbody .i-table-group-header .i-table-group-header-content .i-table-group-count{opacity:.7;font-size:.9em;font-weight:400}.i-table-wrapper table tbody .i-table-group-columns-header th{font-size:.95em;font-weight:600;padding:10px 16px}.i-table-wrapper table tbody .i-table-group-row td{padding-left:32px}.i-table-wrapper table tbody .i-table-group-row td:first-child{padding-left:16px}.i-table-wrapper .i-table-selection-header,.i-table-wrapper .i-table-selection-cell,.i-table-wrapper .i-table-expand-header,.i-table-wrapper .i-table-expand-cell{width:50px;text-align:center}.i-table-wrapper .i-table-detail-count-header{width:36px;padding:0}.i-table-wrapper .i-table-detail-count-cell{width:36px;padding:0 4px 0 0;text-align:right;white-space:nowrap;font-size:.78em;opacity:.5;font-weight:400}.i-table-wrapper .i-table-actions-header,.i-table-wrapper .i-table-actions-cell{width:auto;white-space:nowrap;text-align:right}.i-table-wrapper .i-table-actions-header .i-table-actions,.i-table-wrapper .i-table-actions-cell .i-table-actions{display:flex;gap:4px;justify-content:flex-end}.i-table-wrapper .i-table-column-resizer{position:absolute;right:0;top:50%;transform:translateY(-50%);width:4px;height:60%;cursor:col-resize;opacity:0;transition:opacity .15s ease,background-color .15s ease}.i-table-wrapper .i-table-column-resizer:hover{opacity:1}.i-severity-icon.success,.i-table-cell-success .i-severity-icon,.i-severity-text.success,.i-table-cell-success .i-severity-text{color:var(--color-success)}.i-severity-icon.info,.i-table-cell-info .i-severity-icon,.i-severity-text.info,.i-table-cell-info .i-severity-text{color:var(--color-info)}.i-severity-icon.warning,.i-table-cell-warning .i-severity-icon,.i-severity-text.warning,.i-table-cell-warning .i-severity-text{color:var(--color-warning)}.i-severity-icon.danger,.i-table-cell-danger .i-severity-icon,.i-severity-text.danger,.i-table-cell-danger .i-severity-text{color:var(--color-danger)}.i-severity-icon.secondary,.i-table-cell-secondary .i-severity-icon,.i-severity-text.secondary,.i-table-cell-secondary .i-severity-text{color:var(--color-text-secondary)}.i-table-list-cell{display:flex;flex-direction:column;gap:4px;align-items:flex-start}.i-table-list-cell i-chip{display:block}.i-action-hidden{visibility:hidden;pointer-events:none}@media(max-width:768px){.i-table-wrapper .i-table-header{padding:8px 12px;flex-wrap:wrap}.i-table-wrapper .i-table-header .i-table-header-start{flex:1 1 100%;margin-bottom:8px}.i-table-wrapper .i-table-header .i-table-header-end{flex:1 1 100%;justify-content:flex-end}.i-table-wrapper .i-table-header .i-table-header-end .i-table-global-filter{flex:1;max-width:250px}}\n"], dependencies: [{ kind: "component", type: i0.forwardRef(() => ITable), selector: "i-table", inputs: ["grid", "emptyMessage", "sortable", "sortField", "sortOrder", "filterable", "globalFilter", "filterDelay", "selectionMode", "selection", "dataKey", "striped", "hoverable", "bordered", "size", "loading", "scrollable", "height", "virtualScroll", "virtualScrollItemSize", "virtualScrollMinBufferPx", "virtualScrollMaxBufferPx", "resizableColumns", "downloadable", "downloadMode", "downloadFormat", "downloadFilename"], outputs: ["onSort", "onFilter", "selectionChange", "onSelectionChange", "onRowSelect", "onRowUnselect", "onRowExpand", "onRowCollapse", "onDownload"] }, { kind: "ngmodule", type: i0.forwardRef(() => CommonModule) }, { kind: "directive", type: i0.forwardRef(() => i1$1.NgClass), selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: i0.forwardRef(() => FormsModule) }, { kind: "directive", type: i0.forwardRef(() => i1.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: i0.forwardRef(() => i1.NgControlStatus), selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i0.forwardRef(() => i1.NgModel), selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i0.forwardRef(() => CdkVirtualScrollViewport), selector: "cdk-virtual-scroll-viewport", inputs: ["orientation", "appendOnly"], outputs: ["scrolledIndexChange"] }, { kind: "directive", type: i0.forwardRef(() => CdkVirtualForOf), selector: "[cdkVirtualFor][cdkVirtualForOf]", inputs: ["cdkVirtualForOf", "cdkVirtualForTrackBy", "cdkVirtualForTemplate", "cdkVirtualForTemplateCacheSize"] }, { kind: "directive", type: i0.forwardRef(() => CdkFixedSizeVirtualScroll), selector: "cdk-virtual-scroll-viewport[itemSize]", inputs: ["itemSize", "minBufferPx", "maxBufferPx"] }, { kind: "component", type: i0.forwardRef(() => IInputText), selector: "i-input-text", inputs: ["label", "type", "id", "fluid", "forceFloated", "hideText", "useFloatLabel", "placeholder", "externalInvalid", "externalErrorMessage", "backgroundStyle", "icon", "readonly", "disabled", "errorMessages"] }, { kind: "component", type: i0.forwardRef(() => IButton), selector: "i-button", inputs: ["severity", "size", "type", "disabled", "outlined", "raised", "text", "icon", "fluid", "loading"], outputs: ["clicked"] }, { kind: "component", type: i0.forwardRef(() => ICheckbox), selector: "i-checkbox", inputs: ["label", "id", "disabled", "readonly", "size", "indeterminate", "checked"], outputs: ["onChange"] }, { kind: "component", type: i0.forwardRef(() => IChip), selector: "i-chip", inputs: ["label", "icon", "image", "removable", "removeIcon", "styleClass", "disabled"], outputs: ["onRemove"] }, { kind: "component", type: i0.forwardRef(() => NoContentComponent), selector: "i-no-content", inputs: ["icon", "message"] }, { kind: "directive", type: i0.forwardRef(() => TooltipDirective), selector: "[iTooltip]", inputs: ["iTooltip", "tooltipPosition", "tooltipDelay"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
8623
8516
|
}
|
|
8624
8517
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: ITable, decorators: [{
|
|
8625
8518
|
type: Component,
|
|
8626
|
-
args: [{ selector: 'i-table', standalone: true, imports: [
|
|
8519
|
+
args: [{ selector: 'i-table', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [
|
|
8627
8520
|
CommonModule,
|
|
8628
8521
|
FormsModule,
|
|
8629
8522
|
CdkVirtualScrollViewport,
|
|
@@ -8636,8 +8529,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImpor
|
|
|
8636
8529
|
NoContentComponent,
|
|
8637
8530
|
TooltipDirective,
|
|
8638
8531
|
forwardRef(() => ITable),
|
|
8639
|
-
], template: "<div class=\"i-table-wrapper\" [ngClass]=\"getTableClasses()\">\n <!-- Table Header with ng-content, search, and download -->\n @if (globalFilter || downloadable) {\n <div class=\"i-table-header\">\n <div class=\"i-table-header-start\">\n <ng-content select=\"[header]\"></ng-content>\n </div>\n <div class=\"i-table-header-end\">\n @if (globalFilter) {\n <div class=\"i-table-global-filter\">\n <i-input-text\n [useFloatLabel]=\"false\"\n placeholder=\"Search...\"\n [ngModel]=\"globalFilterValue()\"\n (ngModelChange)=\"onGlobalFilterInput($event)\"\n [fluid]=\"false\"\n [icon]=\"'pi pi-search'\"\n ></i-input-text>\n </div>\n }\n @if (downloadable) {\n <div class=\"i-table-download\">\n <i-button\n severity=\"secondary\"\n [text]=\"true\"\n size=\"small\"\n icon=\"pi pi-download\"\n label=\"Download\"\n (clicked)=\"handleDownload()\"\n ></i-button>\n </div>\n }\n </div>\n </div>\n }\n\n <!-- Loading Overlay -->\n @if (loading) {\n <div class=\"i-table-loading-overlay\">\n <i class=\"pi pi-spin pi-spinner i-table-loading-icon\"></i>\n </div>\n }\n\n <!-- Scrollable Table Container -->\n <div\n class=\"i-table-container\"\n [class.i-table-container--scrollable]=\"scrollable || height || scrollHeight\"\n [class.i-table-container--virtual-scroll]=\"virtualScroll\"\n [style.height]=\"virtualScroll ? height || scrollHeight || '400px' : null\"\n [style.max-height]=\"!virtualScroll ? height || scrollHeight || null : null\"\n >\n <!-- Virtual Scroll Mode -->\n @if (virtualScroll) {\n <!-- Sticky Header Table (outside viewport) -->\n <div class=\"i-table-virtual-header\">\n <table class=\"i-table\">\n <thead>\n <!-- Column Filters Row -->\n @if (filterable) {\n <tr class=\"i-table-filter-row\">\n @if (selectionMode === \"multiple\") {\n <th class=\"i-table-selection-header\"></th>\n }\n @if (rowExpandable) {\n <th class=\"i-table-expand-header\"></th>\n }\n @for (\n column of columns();\n track trackByColumn($index, column)\n ) {\n @if (column.filterable !== false) {\n <th [style.width]=\"getColumnWidth(column)\">\n <input\n type=\"text\"\n class=\"i-table-column-filter\"\n placeholder=\"Filter...\"\n [ngModel]=\"columnFilters()[column.field] || ''\"\n (ngModelChange)=\"\n onColumnFilterInput(column.field, $event)\n \"\n />\n </th>\n } @else {\n <th [style.width]=\"getColumnWidth(column)\"></th>\n }\n }\n @if (showActions && actions.length > 0) {\n <th class=\"i-table-actions-header\"></th>\n }\n </tr>\n }\n\n <!-- Column Headers Row -->\n <tr>\n @if (selectionMode === \"multiple\") {\n <th class=\"i-table-selection-header\">\n <i-checkbox\n [checked]=\"areAllRowsSelected()\"\n [indeterminate]=\"areSomeRowsSelected()\"\n (onChange)=\"toggleAllSelection()\"\n ></i-checkbox>\n </th>\n }\n @if (rowExpandable) {\n <th class=\"i-table-expand-header\"></th>\n }\n @for (column of columns(); track trackByColumn($index, column)) {\n <th\n [style.width]=\"getColumnWidth(column)\"\n [style.text-align]=\"column.align || 'left'\"\n [class.i-table-sortable-column]=\"sortable && column.sortable\"\n [class.i-table-sorted]=\"sortField === column.field\"\n (click)=\"onSortColumn(column)\"\n >\n <div class=\"i-table-header-content\">\n <span class=\"i-table-header-text\">{{ column.header }}</span>\n @if (sortable && column.sortable) {\n <i\n [class]=\"getSortIcon(column)\"\n class=\"i-table-sort-icon\"\n ></i>\n }\n </div>\n @if (resizableColumns) {\n <span\n class=\"i-table-column-resizer\"\n (mousedown)=\"onColumnResizeStart($event, column)\"\n ></span>\n }\n </th>\n }\n @if (showActions && actions.length > 0) {\n <th class=\"i-table-actions-header\">Actions</th>\n }\n </tr>\n </thead>\n </table>\n </div>\n\n <!-- Virtual Scroll Viewport (body only) -->\n <cdk-virtual-scroll-viewport\n [itemSize]=\"virtualScrollItemSize\"\n [minBufferPx]=\"virtualScrollMinBufferPx\"\n [maxBufferPx]=\"virtualScrollMaxBufferPx\"\n class=\"i-table-virtual-viewport\"\n >\n <table class=\"i-table i-table-virtual-body\">\n <tbody>\n @if (processedData().length === 0) {\n <tr class=\"i-table-empty-row\">\n <td\n [attr.colspan]=\"\n columns().length +\n (selectionMode === 'multiple' ? 1 : 0) +\n (rowExpandable ? 1 : 0) +\n (showActions && actions.length > 0 ? 1 : 0)\n \"\n >\n <i-no-content />\n </td>\n </tr>\n }\n <!-- Virtual Scroll Rows -->\n <tr\n *cdkVirtualFor=\"\n let row of processedData();\n let rowIndex = index;\n trackBy: trackByRow\n \"\n [style.height.px]=\"virtualScrollItemSize\"\n [class.i-table-row-odd]=\"rowIndex % 2 !== 0\"\n [class.i-table-row-selected]=\"isRowSelected(row)\"\n (click)=\"toggleRowSelection(row)\"\n >\n @if (selectionMode === \"multiple\") {\n <td class=\"i-table-selection-cell\">\n <i-checkbox\n [checked]=\"isRowSelected(row)\"\n (onChange)=\"toggleRowSelection(row)\"\n (click)=\"$event.stopPropagation()\"\n ></i-checkbox>\n </td>\n }\n @if (rowExpandable) {\n <td class=\"i-table-expand-cell\">\n <i-button\n severity=\"secondary\"\n [text]=\"true\"\n size=\"xtra-small\"\n [icon]=\"\n isRowExpanded(row)\n ? 'pi pi-chevron-down'\n : 'pi pi-chevron-right'\n \"\n (clicked)=\"toggleRowExpansion(row, $event)\"\n ></i-button>\n </td>\n }\n @for (column of columns(); track trackByColumn($index, column)) {\n <td\n [style.text-align]=\"column.align || 'left'\"\n [style.width]=\"getColumnWidth(column)\"\n [class]=\"\n getCellSeverity(row, column)\n ? 'i-table-cell-' + getCellSeverity(row, column)\n : ''\n \"\n >\n @if (isIconColumn(column)) {\n <i\n [class]=\"getCellIcon(row, column)\"\n [class.i-severity-icon]=\"getCellSeverity(row, column)\"\n [style.font-size]=\"column.iconSize || '1rem'\"\n ></i>\n } @else if (isListColumn(column)) {\n <div class=\"i-table-list-cell\">\n @for (item of getCellListItems(row, column); track item) {\n <i-chip [label]=\"item\"></i-chip>\n }\n </div>\n } @else {\n <span\n [class.i-severity-text]=\"getCellSeverity(row, column)\"\n >\n {{\n formatCellValue(getCellValue(row, column.field), column)\n }}\n </span>\n }\n </td>\n }\n @if (showActions && actions.length > 0) {\n <td class=\"i-table-actions-cell\">\n <div class=\"i-table-actions\">\n @for (action of actions; track action.id) {\n <i-button\n [severity]=\"action.severity || 'secondary'\"\n [text]=\"true\"\n size=\"small\"\n [icon]=\"action.icon || ''\"\n [disabled]=\"isActionDisabled(action, row)\"\n [iTooltip]=\"getActionTooltip(action, row)\"\n [class.i-action-hidden]=\"!isActionVisible(action, row)\"\n (clicked)=\"onActionClick(action, row, $event)\"\n >\n @if (action.label) {\n {{ action.label }}\n }\n </i-button>\n }\n </div>\n </td>\n }\n </tr>\n </tbody>\n </table>\n </cdk-virtual-scroll-viewport>\n } @else if (isGroupedMode()) {\n <!-- Grouped Mode: single scrollable table \u2014 group summary rows expand to reveal nested tables -->\n <table class=\"i-table\">\n <thead>\n <!-- Outer filter row -->\n @if (filterable && groupColumns().length > 0) {\n <tr class=\"i-table-filter-row\">\n <th class=\"i-table-expand-header\"></th>\n @for (\n column of groupColumns();\n track trackByColumn($index, column)\n ) {\n @if (column.filterable !== false) {\n <th [style.width]=\"getColumnWidth(column)\">\n <input\n type=\"text\"\n class=\"i-table-column-filter\"\n placeholder=\"Filter...\"\n [ngModel]=\"columnFilters()[column.field] || ''\"\n (ngModelChange)=\"\n onColumnFilterInput(column.field, $event)\n \"\n />\n </th>\n } @else {\n <th [style.width]=\"getColumnWidth(column)\"></th>\n }\n }\n @if (showActions && actions.length > 0) {\n <th class=\"i-table-actions-header\"></th>\n }\n <th class=\"i-table-group-count-header\"></th>\n </tr>\n }\n\n <!-- Group column header row -->\n <tr>\n <th class=\"i-table-expand-header\"></th>\n @if (groupColumns().length === 0) {\n <th>Group</th>\n } @else {\n @for (\n column of groupColumns();\n track trackByColumn($index, column)\n ) {\n <th\n [style.width]=\"getColumnWidth(column)\"\n [style.text-align]=\"column.align || 'left'\"\n [class.i-table-sortable-column]=\"sortable && column.sortable\"\n [class.i-table-sorted]=\"sortField === column.field\"\n (click)=\"onSortColumn(column)\"\n >\n <div class=\"i-table-header-content\">\n <span class=\"i-table-header-text\">{{ column.header }}</span>\n @if (sortable && column.sortable) {\n <i\n [class]=\"getSortIcon(column)\"\n class=\"i-table-sort-icon\"\n ></i>\n }\n </div>\n @if (resizableColumns) {\n <span\n class=\"i-table-column-resizer\"\n (mousedown)=\"onColumnResizeStart($event, column)\"\n ></span>\n }\n </th>\n }\n }\n @if (showActions && actions.length > 0) {\n <th class=\"i-table-actions-header\">Actions</th>\n }\n <th class=\"i-table-group-count-header\"></th>\n </tr>\n </thead>\n\n <tbody>\n @if (groupedData().length === 0) {\n <tr class=\"i-table-empty-row\">\n <td\n [attr.colspan]=\"\n (groupColumns().length || 1) +\n 1 +\n 1 +\n (showActions && actions.length > 0 ? 1 : 0)\n \"\n >\n <i-no-content />\n </td>\n </tr>\n }\n @for (group of groupedData(); track $index) {\n <!-- Group summary row -->\n <tr\n class=\"i-table-group-summary-row\"\n [ngClass]=\"group.styleClass\"\n [class.i-table-group-expanded]=\"isGroupExpanded(group.label)\"\n (click)=\"toggleGroupExpansion(group.label)\"\n >\n <td class=\"i-table-expand-cell\">\n <i-button\n severity=\"secondary\"\n [text]=\"true\"\n size=\"xtra-small\"\n [icon]=\"\n isGroupExpanded(group.label)\n ? 'pi pi-chevron-down'\n : 'pi pi-chevron-right'\n \"\n (clicked)=\"\n toggleGroupExpansion(group.label); $event.stopPropagation()\n \"\n ></i-button>\n </td>\n @if (groupColumns().length === 0) {\n <!-- No groupColumns: show label + count in a single cell -->\n <td>\n <div class=\"i-table-group-header-content\">\n <span class=\"i-table-group-label\">{{ group.label }}</span>\n <span class=\"i-table-group-count\"\n >({{ group.data.length }})</span\n >\n </div>\n </td>\n } @else {\n @for (\n column of groupColumns();\n track trackByColumn($index, column)\n ) {\n <td\n [style.text-align]=\"column.align || 'left'\"\n [style.width]=\"getColumnWidth(column)\"\n [class]=\"\n getCellSeverity(group.row ?? {}, column)\n ? 'i-table-cell-' +\n getCellSeverity(group.row ?? {}, column)\n : ''\n \"\n >\n @if (isIconColumn(column)) {\n <i\n [class]=\"getCellIcon(group.row ?? {}, column)\"\n [class.i-severity-icon]=\"\n getCellSeverity(group.row ?? {}, column)\n \"\n [style.font-size]=\"column.iconSize || '1rem'\"\n ></i>\n } @else {\n <span\n [class.i-severity-text]=\"\n getCellSeverity(group.row ?? {}, column)\n \"\n >\n {{\n formatCellValue(\n getCellValue(group.row ?? {}, column.field),\n column\n )\n }}\n </span>\n }\n </td>\n }\n }\n @if (showActions && actions.length > 0) {\n <td\n class=\"i-table-actions-cell\"\n (click)=\"$event.stopPropagation()\"\n >\n <div class=\"i-table-actions\">\n @for (action of actions; track action.id) {\n <i-button\n [severity]=\"action.severity || 'secondary'\"\n [text]=\"true\"\n size=\"small\"\n [icon]=\"action.icon || ''\"\n [disabled]=\"isActionDisabled(action, group.row ?? {})\"\n [iTooltip]=\"getActionTooltip(action, group.row ?? {})\"\n [class.i-action-hidden]=\"\n !isActionVisible(action, group.row ?? {})\n \"\n (clicked)=\"\n onActionClick(action, group.row ?? {}, $event)\n \"\n >\n @if (action.label) {\n {{ action.label }}\n }\n </i-button>\n }\n </div>\n </td>\n }\n <td\n class=\"i-table-group-count-cell\"\n (click)=\"$event.stopPropagation()\"\n >\n <span class=\"i-table-group-count\"\n >({{ group.data.length }})</span\n >\n </td>\n </tr>\n\n <!-- Group detail row (visible when expanded) -->\n @if (isGroupExpanded(group.label)) {\n <tr class=\"i-table-group-detail-row\">\n <td\n [attr.colspan]=\"\n (groupColumns().length || 1) +\n 1 +\n 1 +\n (showActions && actions.length > 0 ? 1 : 0)\n \"\n class=\"i-table-group-detail-cell\"\n >\n <i-table\n [data]=\"group.data\"\n [columns]=\"getGroupColumns(group)\"\n [sortable]=\"sortable\"\n [filterable]=\"filterable\"\n [showActions]=\"showActions\"\n [actions]=\"actions\"\n [selectionMode]=\"selectionMode\"\n [selection]=\"selection\"\n [striped]=\"striped\"\n [hoverable]=\"hoverable\"\n [bordered]=\"bordered\"\n [size]=\"size\"\n [dataKey]=\"dataKey\"\n [rowExpandable]=\"rowExpandable\"\n [resizableColumns]=\"resizableColumns\"\n (onSort)=\"onSort.emit($event)\"\n (onFilter)=\"onFilter.emit($event)\"\n (onAction)=\"onAction.emit($event)\"\n (onSelectionChange)=\"onSelectionChange.emit($event)\"\n (selectionChange)=\"selectionChange.emit($event)\"\n (onRowSelect)=\"onRowSelect.emit($event)\"\n (onRowUnselect)=\"onRowUnselect.emit($event)\"\n (onRowExpand)=\"onRowExpand.emit($event)\"\n (onRowCollapse)=\"onRowCollapse.emit($event)\"\n ></i-table>\n </td>\n </tr>\n }\n }\n </tbody>\n </table>\n } @else {\n <!-- Non-Virtual Scroll Table -->\n <table class=\"i-table\">\n <!-- Table Header (sticky when scrollable) -->\n <thead>\n <!-- Column Filters Row -->\n @if (filterable) {\n <tr class=\"i-table-filter-row\">\n @if (selectionMode === \"multiple\") {\n <th class=\"i-table-selection-header\"></th>\n }\n @if (rowExpandable) {\n <th class=\"i-table-expand-header\"></th>\n }\n @for (column of columns(); track trackByColumn($index, column)) {\n @if (column.filterable !== false) {\n <th [style.width]=\"getColumnWidth(column)\">\n <input\n type=\"text\"\n class=\"i-table-column-filter\"\n placeholder=\"Filter...\"\n [ngModel]=\"columnFilters()[column.field] || ''\"\n (ngModelChange)=\"\n onColumnFilterInput(column.field, $event)\n \"\n />\n </th>\n } @else {\n <th [style.width]=\"getColumnWidth(column)\"></th>\n }\n }\n @if (showActions && actions.length > 0) {\n <th class=\"i-table-actions-header\"></th>\n }\n </tr>\n }\n\n <!-- Column Headers Row -->\n <tr>\n @if (selectionMode === \"multiple\") {\n <th class=\"i-table-selection-header\">\n <i-checkbox\n [checked]=\"areAllRowsSelected()\"\n [indeterminate]=\"areSomeRowsSelected()\"\n (onChange)=\"toggleAllSelection()\"\n ></i-checkbox>\n </th>\n }\n @if (rowExpandable) {\n <th class=\"i-table-expand-header\"></th>\n }\n @for (column of columns(); track trackByColumn($index, column)) {\n <th\n [style.width]=\"getColumnWidth(column)\"\n [style.text-align]=\"column.align || 'left'\"\n [class.i-table-sortable-column]=\"sortable && column.sortable\"\n [class.i-table-sorted]=\"sortField === column.field\"\n (click)=\"onSortColumn(column)\"\n >\n <div class=\"i-table-header-content\">\n <span class=\"i-table-header-text\">{{ column.header }}</span>\n @if (sortable && column.sortable) {\n <i\n [class]=\"getSortIcon(column)\"\n class=\"i-table-sort-icon\"\n ></i>\n }\n </div>\n @if (resizableColumns) {\n <span\n class=\"i-table-column-resizer\"\n (mousedown)=\"onColumnResizeStart($event, column)\"\n ></span>\n }\n </th>\n }\n @if (showActions && actions.length > 0) {\n <th class=\"i-table-actions-header\">Actions</th>\n }\n </tr>\n </thead>\n\n <!-- Table Body - Regular Mode -->\n <tbody>\n @if (processedData().length === 0) {\n <tr class=\"i-table-empty-row\">\n <td\n [attr.colspan]=\"\n columns().length +\n (selectionMode === 'multiple' ? 1 : 0) +\n (rowExpandable ? 1 : 0) +\n (showActions && actions.length > 0 ? 1 : 0)\n \"\n >\n <i-no-content />\n </td>\n </tr>\n } @else {\n @for (\n row of processedData();\n track trackByRow($index, row);\n let rowIndex = $index\n ) {\n <tr\n [class.i-table-row-odd]=\"$odd\"\n [class.i-table-row-selected]=\"isRowSelected(row)\"\n (click)=\"toggleRowSelection(row)\"\n >\n @if (selectionMode === \"multiple\") {\n <td class=\"i-table-selection-cell\">\n <i-checkbox\n [checked]=\"isRowSelected(row)\"\n (onChange)=\"toggleRowSelection(row)\"\n (click)=\"$event.stopPropagation()\"\n ></i-checkbox>\n </td>\n }\n @if (rowExpandable) {\n <td class=\"i-table-expand-cell\">\n <i-button\n severity=\"secondary\"\n [text]=\"true\"\n size=\"xtra-small\"\n [icon]=\"\n isRowExpanded(row)\n ? 'pi pi-chevron-down'\n : 'pi pi-chevron-right'\n \"\n (clicked)=\"toggleRowExpansion(row, $event)\"\n ></i-button>\n </td>\n }\n @for (\n column of columns();\n track trackByColumn($index, column)\n ) {\n <td\n [style.text-align]=\"column.align || 'left'\"\n [style.width]=\"getColumnWidth(column)\"\n [class]=\"\n getCellSeverity(row, column)\n ? 'i-table-cell-' + getCellSeverity(row, column)\n : ''\n \"\n >\n @if (isIconColumn(column)) {\n <i\n [class]=\"getCellIcon(row, column)\"\n [class.i-severity-icon]=\"getCellSeverity(row, column)\"\n [style.font-size]=\"column.iconSize || '1rem'\"\n ></i>\n } @else if (isListColumn(column)) {\n <div class=\"i-table-list-cell\">\n @for (\n item of getCellListItems(row, column);\n track item\n ) {\n <i-chip [label]=\"item\"></i-chip>\n }\n </div>\n } @else {\n <span\n [class.i-severity-text]=\"getCellSeverity(row, column)\"\n >\n {{\n formatCellValue(\n getCellValue(row, column.field),\n column\n )\n }}\n </span>\n }\n </td>\n }\n @if (showActions && actions.length > 0) {\n <td class=\"i-table-actions-cell\">\n <div class=\"i-table-actions\">\n @for (action of actions; track action.id) {\n <i-button\n [severity]=\"action.severity || 'secondary'\"\n [text]=\"true\"\n size=\"small\"\n [icon]=\"action.icon || ''\"\n [disabled]=\"isActionDisabled(action, row)\"\n [iTooltip]=\"getActionTooltip(action, row)\"\n [class.i-action-hidden]=\"\n !isActionVisible(action, row)\n \"\n (clicked)=\"onActionClick(action, row, $event)\"\n >\n @if (action.label) {\n {{ action.label }}\n }\n </i-button>\n }\n </div>\n </td>\n }\n </tr>\n <!-- Expanded Row Content -->\n @if (rowExpandable && isRowExpanded(row)) {\n <tr class=\"i-table-expanded-row\">\n <td\n [attr.colspan]=\"\n columns().length +\n (selectionMode === 'multiple' ? 1 : 0) +\n 1 +\n (showActions && actions.length > 0 ? 1 : 0)\n \"\n >\n <div class=\"i-table-expanded-content\">\n <pre>{{ row | json }}</pre>\n </div>\n </td>\n </tr>\n }\n }\n }\n </tbody>\n </table>\n }\n </div>\n</div>\n", styles: [".i-table-wrapper{color:var(--color-text-primary);background:var(--color-component-background)}.i-table-wrapper .i-table-header{background:var(--surface-section);border-bottom:1px solid var(--surface-border)}.i-table-wrapper .i-table-global-filter .i-input-text{background:var(--surface-ground)}.i-table-wrapper .i-table-loading-overlay{background:#ffffffb3}.i-table-wrapper .i-table-loading-overlay .i-table-loading-icon{color:var(--color-primary)}.i-table-wrapper table thead tr{background:var(--color-component-background)}.i-table-wrapper table thead tr th{color:var(--color-text-primary);border-bottom:1px solid var(--surface-border)}.i-table-wrapper table thead tr th.i-table-sortable-column{cursor:pointer}.i-table-wrapper table thead tr th.i-table-sortable-column:hover{background:var(--surface-hover)}.i-table-wrapper table thead tr th.i-table-sorted{background:var(--surface-hover);color:var(--color-primary)}.i-table-wrapper table thead tr th .i-table-sort-icon{color:var(--color-text-secondary)}.i-table-wrapper table thead tr th.i-table-sorted .i-table-sort-icon{color:var(--color-primary)}.i-table-wrapper table thead .i-table-filter-row th{background:var(--color-component-background)}.i-table-wrapper table thead .i-table-filter-row .i-table-column-filter{border:1px solid var(--surface-border);background:var(--surface-ground);color:var(--color-text-primary)}.i-table-wrapper table thead .i-table-filter-row .i-table-column-filter:focus{border-color:var(--color-primary);box-shadow:0 2px 10px #0003;outline:none}.i-table-wrapper table thead .i-table-filter-row .i-table-column-filter::placeholder{color:var(--color-text-tertiary)}.i-table-wrapper table tbody tr{background:var(--color-component-background);border-bottom:1px solid var(--surface-border)}.i-table-wrapper table tbody tr td{color:var(--color-text-primary)}.i-table-wrapper table tbody tr.i-table-row-odd{background:var(--color-component-background)}.i-table-wrapper table tbody tr.i-table-row-selected{background:var(--surface-hover);color:var(--color-primary)}.i-table-wrapper table tbody .i-table-expanded-row{background:var(--color-component-background)}.i-table-wrapper table tbody .i-table-expanded-row .i-table-expanded-content{background:var(--surface-ground);border:1px solid var(--surface-border)}.i-table-wrapper table tbody .i-table-empty-row td{background:var(--color-component-background)}.i-table-wrapper table tbody .i-table-group-header{background:var(--color-component-background);border-bottom:2px solid var(--surface-border)}.i-table-wrapper table tbody .i-table-group-header td{color:var(--color-text-primary)}.i-table-wrapper table tbody .i-table-group-header:hover{background:var(--surface-hover)}.i-table-wrapper table tbody .i-table-group-header .i-table-group-toggle-icon,.i-table-wrapper table tbody .i-table-group-header .i-table-group-count{color:var(--color-text-secondary)}.i-table-wrapper table tbody .i-table-group-columns-header{background:var(--color-component-background);border-bottom:1px solid var(--surface-border)}.i-table-wrapper table tbody .i-table-group-columns-header th{color:var(--color-text-primary);border-bottom:1px solid var(--surface-border)}.i-table-wrapper table tbody .i-table-group-row,.i-table-wrapper table tbody .i-table-group-row.i-table-row-odd{background:var(--color-component-background)}.i-table-wrapper table tbody .i-table-group-row.i-table-row-selected{background:var(--surface-hover);color:var(--color-primary)}.i-table-wrapper table tbody .i-table-group-summary-row{background:var(--surface-section);border-bottom:2px solid var(--surface-border)}.i-table-wrapper table tbody .i-table-group-summary-row td{color:var(--color-text-primary);font-weight:600}.i-table-wrapper table tbody .i-table-group-summary-row:hover{background:var(--surface-hover)}.i-table-wrapper table tbody .i-table-group-summary-row .i-table-group-count{color:var(--color-text-secondary)}.i-table-wrapper table tbody .i-table-group-detail-row,.i-table-wrapper table tbody .i-table-group-detail-row .i-table-group-detail-cell .i-table-wrapper{background:var(--surface-ground)}.i-table-wrapper table tbody .i-table-group-detail-row .i-table-group-detail-cell .i-table-wrapper table thead tr{background:var(--surface-section)}.i-table-wrapper.i-table--bordered table,.i-table-wrapper.i-table--bordered table th,.i-table-wrapper.i-table--bordered table td{border:1px solid var(--surface-border)}.i-table-wrapper.i-table--hoverable table tbody tr:not(.i-table-empty-row):not(.i-table-expanded-row):not(.i-table-group-header):not(.i-table-group-columns-header):not(.i-table-group-detail-row):hover{background:var(--surface-hover)}.i-table-wrapper.i-table--hoverable table tbody tr:not(.i-table-empty-row):not(.i-table-expanded-row):not(.i-table-group-header):not(.i-table-group-columns-header):not(.i-table-group-detail-row).i-table-row-selected:hover{background:var(--surface-hover)}.i-table-wrapper .i-table-column-resizer{background:var(--surface-border)}.i-table-wrapper .i-table-column-resizer:hover{background:var(--color-primary)}.i-table-wrapper{position:relative;display:block;border-radius:4px;overflow:visible}.i-table-wrapper.i-table--small table thead th{padding:8px 12px;font-size:13px}.i-table-wrapper.i-table--small table tbody td{padding:6px 12px;font-size:1em}.i-table-wrapper.i-table--small table .i-table-filter-row th{padding:4px 12px}.i-table-wrapper.i-table--large table thead th,.i-table-wrapper.i-table--large table tbody td{padding:16px 20px;font-size:16px}.i-table-wrapper.i-table--large table .i-table-filter-row th{padding:12px 20px}.i-table-wrapper.i-table--scrollable table{table-layout:fixed}.i-table-wrapper.i-table--loading{pointer-events:none;-webkit-user-select:none;user-select:none}.i-table-wrapper .i-table-header{display:flex;justify-content:space-between;align-items:center;padding:12px 16px;gap:16px}.i-table-wrapper .i-table-header .i-table-header-start{flex:0 1 auto;display:flex;align-items:center}.i-table-wrapper .i-table-header .i-table-header-end{flex:0 1 auto;display:flex;align-items:center;gap:12px;margin-left:auto}.i-table-wrapper .i-table-header .i-table-header-end .i-table-global-filter{width:250px}.i-table-wrapper .i-table-header .i-table-header-end .i-table-download{flex-shrink:0}.i-table-wrapper .i-table-loading-overlay{position:absolute;inset:0;z-index:10;display:flex;align-items:center;justify-content:center}.i-table-wrapper .i-table-loading-overlay .i-table-loading-icon{font-size:32px}.i-table-wrapper .i-table-container{overflow-x:auto}.i-table-wrapper .i-table-container::-webkit-scrollbar-track{background:transparent;border-radius:3px}.i-table-wrapper .i-table-container::-webkit-scrollbar-thumb{background:#0003;border-radius:3px;transition:background .2s ease}.i-table-wrapper .i-table-container::-webkit-scrollbar-thumb:hover{background:#00000059}.i-table-wrapper .i-table-container::-webkit-scrollbar-thumb:active{background:#00000080}.i-table-wrapper .i-table-container::-webkit-scrollbar-corner{background:transparent}.i-table-wrapper .i-table-container{scrollbar-width:thin;scrollbar-color:rgba(0,0,0,.2) transparent;scroll-behavior:smooth}.i-table-wrapper .i-table-container::-webkit-scrollbar-thumb{background:var(--color-text-secondary);opacity:.4}.i-table-wrapper .i-table-container::-webkit-scrollbar-thumb:hover{background:var(--color-text-primary);opacity:.6}.i-table-wrapper .i-table-container::-webkit-scrollbar-thumb:active{background:var(--color-primary);opacity:.7}.i-table-wrapper .i-table-container{scrollbar-color:var(--color-text-secondary) transparent}.i-table-wrapper .i-table-container::-webkit-scrollbar{width:6px;height:6px}.i-table-wrapper .i-table-container::-webkit-scrollbar-track{background:#0000000d;border-radius:3px;margin:2px 0}.i-table-wrapper .i-table-container::-webkit-scrollbar-thumb{border-radius:3px;min-height:20px;background:var(--color-text-secondary);opacity:.6}.i-table-wrapper .i-table-container::-webkit-scrollbar-thumb:hover{background:var(--color-text-primary);opacity:.8}.i-table-wrapper .i-table-container::-webkit-scrollbar-thumb:active{background:var(--color-primary);opacity:.9}.i-table-wrapper .i-table-container{scrollbar-width:thin;scrollbar-color:var(--color-text-secondary) rgba(0,0,0,.05)}.i-table-wrapper .i-table-container--scrollable{overflow-y:auto;scrollbar-gutter:stable}.i-table-wrapper .i-table-container--scrollable>table>thead{position:sticky;top:0;z-index:2}.i-table-wrapper .i-table-container--virtual-scroll{overflow:hidden;display:flex;flex-direction:column}.i-table-wrapper .i-table-container--virtual-scroll .i-table-virtual-header{flex-shrink:0;overflow:hidden;background:var(--color-surface-50)}.i-table-wrapper .i-table-container--virtual-scroll .i-table-virtual-header table{width:100%;border-collapse:collapse;table-layout:fixed}.i-table-wrapper .i-table-container--virtual-scroll .i-table-virtual-viewport{flex:1;min-height:0;width:100%}.i-table-wrapper .i-table-container--virtual-scroll .i-table-virtual-viewport .cdk-virtual-scroll-content-wrapper{width:100%}.i-table-wrapper .i-table-container--virtual-scroll .i-table-virtual-body{width:100%;border-collapse:collapse;table-layout:fixed}.i-table-wrapper .i-table-container--virtual-scroll table{display:table;width:100%;border-collapse:collapse}.i-table-wrapper .i-table-container--virtual-scroll tbody{display:table-row-group}.i-table-wrapper .i-table-container--virtual-scroll tr{display:table-row;box-sizing:border-box}.i-table-wrapper .i-table-container--virtual-scroll td,.i-table-wrapper .i-table-container--virtual-scroll th{display:table-cell}.i-table-wrapper table{width:100%;border-collapse:collapse;table-layout:auto}.i-table-wrapper table thead tr th{position:relative;padding:12px 16px;font-weight:600;text-align:left;white-space:nowrap;-webkit-user-select:none;user-select:none}.i-table-wrapper table thead tr th .i-table-header-content{display:flex;align-items:center;gap:8px}.i-table-wrapper table thead tr th .i-table-header-content .i-table-header-text{flex:1}.i-table-wrapper table thead tr th .i-table-sort-icon{font-size:.8em;opacity:.6;transition:opacity .15s ease,color .15s ease}.i-table-wrapper table thead tr th.i-table-sortable-column{transition:background-color .15s ease}.i-table-wrapper table thead tr th.i-table-sortable-column .i-table-sort-icon{opacity:.4}.i-table-wrapper table thead tr th.i-table-sortable-column:hover .i-table-sort-icon,.i-table-wrapper table thead tr th.i-table-sortable-column.i-table-sorted .i-table-sort-icon{opacity:1}.i-table-wrapper table thead tr th:hover .i-table-column-resizer{opacity:.5}.i-table-wrapper table thead tr th.i-table-actions-header{text-align:right}.i-table-wrapper table thead .i-table-filter-row th{padding:8px 16px}.i-table-wrapper table thead .i-table-filter-row th .i-table-column-filter{width:100%;padding:6px 10px;font-size:1em;border-radius:4px;transition:border-color .15s ease,box-shadow .15s ease}.i-table-wrapper table tbody{display:table-row-group}.i-table-wrapper table tbody tr{transition:background-color .15s ease}.i-table-wrapper table tbody tr td{padding:12px 16px;vertical-align:middle}.i-table-wrapper table tbody .i-table-empty-row td{padding:40px 16px;text-align:center}.i-table-wrapper table tbody .i-table-expanded-row td{padding:0}.i-table-wrapper table tbody .i-table-expanded-row td .i-table-expanded-content{padding:16px;margin:8px 16px;border-radius:4px}.i-table-wrapper table tbody .i-table-expanded-row td .i-table-expanded-content pre{margin:0;font-family:monospace;font-size:1em;white-space:pre-wrap;word-wrap:break-word}.i-table-wrapper table tbody .i-table-group-summary-row{cursor:pointer;-webkit-user-select:none;user-select:none;font-weight:600;transition:background-color .15s ease}.i-table-wrapper table tbody .i-table-group-summary-row td{padding:12px 16px}.i-table-wrapper table tbody .i-table-group-summary-row .i-table-group-header-content{display:flex;align-items:center;gap:8px}.i-table-wrapper table tbody .i-table-group-summary-row .i-table-group-header-content .i-table-group-label{flex:1;font-size:1.05em}.i-table-wrapper table tbody .i-table-group-summary-row .i-table-group-header-content .i-table-group-count{opacity:.7;font-size:.9em;font-weight:400}.i-table-wrapper table tbody .i-table-group-detail-row .i-table-group-detail-cell{padding:0;overflow:hidden}.i-table-wrapper table tbody .i-table-group-detail-row .i-table-group-detail-cell .i-table-wrapper{border-radius:0;border-top:none;overflow:hidden}.i-table-wrapper table tbody .i-table-group-count-header{width:60px;text-align:center;font-weight:400;opacity:.6;font-size:.85em}.i-table-wrapper table tbody .i-table-group-count-cell{width:60px;text-align:right;white-space:nowrap}.i-table-wrapper table tbody .i-table-group-count-cell .i-table-group-count{opacity:.7;font-size:.9em;font-weight:400}.i-table-wrapper table tbody .i-table-group-header td{padding:12px 16px;font-weight:600;cursor:pointer;-webkit-user-select:none;user-select:none;transition:background-color .15s ease}.i-table-wrapper table tbody .i-table-group-header td:hover{opacity:.8}.i-table-wrapper table tbody .i-table-group-header .i-table-group-header-content{display:flex;align-items:center;gap:8px}.i-table-wrapper table tbody .i-table-group-header .i-table-group-header-content .i-table-group-toggle-icon{font-size:.8em;transition:transform .15s ease}.i-table-wrapper table tbody .i-table-group-header .i-table-group-header-content .i-table-group-label{flex:1;font-size:1.1em}.i-table-wrapper table tbody .i-table-group-header .i-table-group-header-content .i-table-group-count{opacity:.7;font-size:.9em;font-weight:400}.i-table-wrapper table tbody .i-table-group-columns-header th{font-size:.95em;font-weight:600;padding:10px 16px}.i-table-wrapper table tbody .i-table-group-row td{padding-left:32px}.i-table-wrapper table tbody .i-table-group-row td:first-child{padding-left:16px}.i-table-wrapper .i-table-selection-header,.i-table-wrapper .i-table-selection-cell,.i-table-wrapper .i-table-expand-header,.i-table-wrapper .i-table-expand-cell{width:50px;text-align:center}.i-table-wrapper .i-table-actions-header,.i-table-wrapper .i-table-actions-cell{width:auto;white-space:nowrap;text-align:right}.i-table-wrapper .i-table-actions-header .i-table-actions,.i-table-wrapper .i-table-actions-cell .i-table-actions{display:flex;gap:4px;justify-content:flex-end}.i-table-wrapper .i-table-column-resizer{position:absolute;right:0;top:50%;transform:translateY(-50%);width:4px;height:60%;cursor:col-resize;opacity:0;transition:opacity .15s ease,background-color .15s ease}.i-table-wrapper .i-table-column-resizer:hover{opacity:1}.i-severity-icon.success,.i-table-cell-success .i-severity-icon,.i-severity-text.success,.i-table-cell-success .i-severity-text{color:var(--color-success)}.i-severity-icon.info,.i-table-cell-info .i-severity-icon,.i-severity-text.info,.i-table-cell-info .i-severity-text{color:var(--color-info)}.i-severity-icon.warning,.i-table-cell-warning .i-severity-icon,.i-severity-text.warning,.i-table-cell-warning .i-severity-text{color:var(--color-warning)}.i-severity-icon.danger,.i-table-cell-danger .i-severity-icon,.i-severity-text.danger,.i-table-cell-danger .i-severity-text{color:var(--color-danger)}.i-severity-icon.secondary,.i-table-cell-secondary .i-severity-icon,.i-severity-text.secondary,.i-table-cell-secondary .i-severity-text{color:var(--color-text-secondary)}.i-table-list-cell{display:flex;flex-direction:column;gap:4px;align-items:flex-start}.i-table-list-cell i-chip{display:block}.i-action-hidden{visibility:hidden;pointer-events:none}@media(max-width:768px){.i-table-wrapper .i-table-header{padding:8px 12px;flex-wrap:wrap}.i-table-wrapper .i-table-header .i-table-header-start{flex:1 1 100%;margin-bottom:8px}.i-table-wrapper .i-table-header .i-table-header-end{flex:1 1 100%;justify-content:flex-end}.i-table-wrapper .i-table-header .i-table-header-end .i-table-global-filter{flex:1;max-width:250px}}\n"] }]
|
|
8640
|
-
}], ctorParameters: () => [{ type: i0.ElementRef }], propDecorators: {
|
|
8532
|
+
], template: "<div class=\"i-table-wrapper\" [ngClass]=\"getTableClasses()\">\n <!-- Table Header: global filter + download -->\n @if (globalFilter || downloadable) {\n <div class=\"i-table-header\">\n <div class=\"i-table-header-start\">\n <ng-content select=\"[header]\"></ng-content>\n </div>\n <div class=\"i-table-header-end\">\n @if (globalFilter) {\n <div class=\"i-table-global-filter\">\n <i-input-text\n [useFloatLabel]=\"false\"\n placeholder=\"Search...\"\n [ngModel]=\"globalFilterValue()\"\n (ngModelChange)=\"onGlobalFilterInput($event)\"\n [fluid]=\"false\"\n [icon]=\"'pi pi-search'\"\n ></i-input-text>\n </div>\n }\n @if (downloadable) {\n <div class=\"i-table-download\">\n <i-button\n severity=\"secondary\"\n [text]=\"true\"\n size=\"small\"\n icon=\"pi pi-download\"\n label=\"Download\"\n (clicked)=\"handleDownload()\"\n ></i-button>\n </div>\n }\n </div>\n </div>\n }\n\n <!-- Loading Overlay -->\n @if (loading) {\n <div class=\"i-table-loading-overlay\">\n <i class=\"pi pi-spin pi-spinner i-table-loading-icon\"></i>\n </div>\n }\n\n <!-- ================================================================\n PATH A \u2014 Detail-expandable table\n Uses a standard scrollable container so that nested <i-table>\n components can expand inline below their parent rows.\n ================================================================ -->\n @if (hasDetails()) {\n <div\n class=\"i-table-container i-table-container--scrollable\"\n [style.max-height]=\"effectiveHeight()\"\n >\n <table class=\"i-table\">\n <thead>\n <!-- Column Filter Row -->\n @if (filterable) {\n <tr class=\"i-table-filter-row\">\n @if (selectionMode === \"multiple\") {\n <th class=\"i-table-selection-header\"></th>\n }\n <th class=\"i-table-expand-header\"></th>\n @for (\n column of gridColumns();\n track trackByColumn($index, column)\n ) {\n @if (column.filterable !== false) {\n <th [style.width]=\"getColumnWidth(column)\">\n <input\n type=\"text\"\n class=\"i-table-column-filter\"\n placeholder=\"Filter...\"\n [ngModel]=\"columnFilters()[column.field] || ''\"\n (ngModelChange)=\"\n onColumnFilterInput(column.field, $event)\n \"\n />\n </th>\n } @else {\n <th [style.width]=\"getColumnWidth(column)\"></th>\n }\n }\n <th class=\"i-table-detail-count-header\"></th>\n @if (gridActions().length > 0) {\n <th class=\"i-table-actions-header\"></th>\n }\n </tr>\n }\n\n <!-- Column Headers -->\n <tr>\n @if (selectionMode === \"multiple\") {\n <th class=\"i-table-selection-header\">\n <i-checkbox\n [checked]=\"areAllRowsSelected()\"\n [indeterminate]=\"areSomeRowsSelected()\"\n (onChange)=\"toggleAllSelection()\"\n ></i-checkbox>\n </th>\n }\n <th class=\"i-table-expand-header\"></th>\n @for (\n column of gridColumns();\n track trackByColumn($index, column)\n ) {\n <th\n [style.width]=\"getColumnWidth(column)\"\n [style.text-align]=\"column.align || 'left'\"\n [class.i-table-sortable-column]=\"sortable && column.sortable\"\n [class.i-table-sorted]=\"sortField === column.field\"\n (click)=\"onSortColumn(column)\"\n >\n <div class=\"i-table-header-content\">\n <span class=\"i-table-header-text\">{{ column.header }}</span>\n @if (sortable && column.sortable) {\n <i\n [class]=\"getSortIcon(column)\"\n class=\"i-table-sort-icon\"\n ></i>\n }\n </div>\n @if (resizableColumns) {\n <span\n class=\"i-table-column-resizer\"\n (mousedown)=\"onColumnResizeStart($event, column)\"\n ></span>\n }\n </th>\n }\n <th class=\"i-table-detail-count-header\"></th>\n @if (gridActions().length > 0) {\n <th class=\"i-table-actions-header\">Actions</th>\n }\n </tr>\n </thead>\n\n <tbody>\n @if (processedData().length === 0) {\n <tr class=\"i-table-empty-row\">\n <td [attr.colspan]=\"totalColspan()\">\n <i-no-content />\n </td>\n </tr>\n }\n @for (row of processedData(); track trackByRow($index, row)) {\n <!-- Parent row -->\n <tr\n [class.i-table-row-odd]=\"$odd\"\n [class.i-table-row-selected]=\"isRowSelected(row)\"\n (click)=\"toggleRowSelection(row)\"\n >\n @if (selectionMode === \"multiple\") {\n <td class=\"i-table-selection-cell\">\n <i-checkbox\n [checked]=\"isRowSelected(row)\"\n (onChange)=\"toggleRowSelection(row)\"\n (click)=\"$event.stopPropagation()\"\n ></i-checkbox>\n </td>\n }\n <td class=\"i-table-expand-cell\">\n <i-button\n severity=\"secondary\"\n [text]=\"true\"\n size=\"xtra-small\"\n [icon]=\"\n isRowExpanded(row)\n ? 'pi pi-chevron-down'\n : 'pi pi-chevron-right'\n \"\n (clicked)=\"toggleRowExpansion(row, $event)\"\n ></i-button>\n </td>\n @for (\n column of gridColumns();\n track trackByColumn($index, column)\n ) {\n <td\n [style.text-align]=\"column.align || 'left'\"\n [style.width]=\"getColumnWidth(column)\"\n [class]=\"\n getCellSeverity(row, column)\n ? 'i-table-cell-' + getCellSeverity(row, column)\n : ''\n \"\n >\n @if (isIconColumn(column)) {\n <i\n [class]=\"getCellIcon(row, column)\"\n [class.i-severity-icon]=\"getCellSeverity(row, column)\"\n [style.font-size]=\"column.iconSize || '1rem'\"\n ></i>\n } @else if (isListColumn(column)) {\n <div class=\"i-table-list-cell\">\n @for (item of getCellListItems(row, column); track item) {\n <i-chip [label]=\"item\"></i-chip>\n }\n </div>\n } @else {\n <span\n [class.i-severity-text]=\"getCellSeverity(row, column)\"\n >\n {{\n formatCellValue(getCellValue(row, column.field), column)\n }}\n </span>\n }\n </td>\n }\n <td class=\"i-table-detail-count-cell\">\n ({{ getDetailRowCount(row) }})\n </td>\n @if (gridActions().length > 0) {\n <td class=\"i-table-actions-cell\">\n <div class=\"i-table-actions\">\n @for (action of gridActions(); track action.id) {\n <i-button\n [severity]=\"action.severity || 'secondary'\"\n [text]=\"true\"\n size=\"small\"\n [icon]=\"action.icon || ''\"\n [disabled]=\"isActionDisabled(action, row)\"\n [iTooltip]=\"getActionTooltip(action, row)\"\n [class.i-action-hidden]=\"!isActionVisible(action, row)\"\n (clicked)=\"triggerAction(action, row, $event)\"\n >\n @if (action.label) {\n {{ action.label }}\n }\n </i-button>\n }\n </div>\n </td>\n }\n </tr>\n\n <!-- Detail expansion row -->\n @if (isRowExpanded(row)) {\n <tr class=\"i-table-expanded-row\">\n <td\n [attr.colspan]=\"totalColspan()\"\n class=\"i-table-expanded-cell\"\n >\n <div class=\"i-table-expanded-content\">\n <i-table\n [grid]=\"getDetailGrid(row)\"\n [sortable]=\"sortable\"\n [filterable]=\"filterable\"\n [selectionMode]=\"selectionMode\"\n [selection]=\"selection\"\n [striped]=\"striped\"\n [hoverable]=\"hoverable\"\n [bordered]=\"bordered\"\n [size]=\"size\"\n [dataKey]=\"dataKey\"\n [resizableColumns]=\"resizableColumns\"\n (onSort)=\"onSort.emit($event)\"\n (onFilter)=\"onFilter.emit($event)\"\n (onSelectionChange)=\"onSelectionChange.emit($event)\"\n (selectionChange)=\"selectionChange.emit($event)\"\n (onRowSelect)=\"onRowSelect.emit($event)\"\n (onRowUnselect)=\"onRowUnselect.emit($event)\"\n ></i-table>\n </div>\n </td>\n </tr>\n }\n }\n </tbody>\n </table>\n </div>\n } @else if (virtualScroll) {\n <!-- ================================================================\n PATH B \u2014 CDK Virtual Scroll (div-based rows)\n Use only for large row counts (\u2265 ~500 rows). Uses flex <div> rows\n so CDK's wrapper <div> does not end up inside <tbody> (invalid HTML).\n ================================================================ -->\n <div\n class=\"i-table-container i-table-container--scrollable i-table-container--virtual-scroll\"\n [style.height]=\"effectiveHeight()\"\n >\n <!-- Sticky header \u2014 flex rows that mirror the virtual body rows -->\n <div class=\"i-table-virtual-header\">\n @if (filterable) {\n <div class=\"i-table-virtual-row i-table-filter-row\">\n @if (selectionMode === \"multiple\") {\n <div class=\"i-table-virtual-cell i-table-selection-header\"></div>\n }\n @for (\n column of gridColumns();\n track trackByColumn($index, column)\n ) {\n @if (column.filterable !== false) {\n <div\n class=\"i-table-virtual-cell\"\n [style.width]=\"\n getColumnWidth(column) !== 'auto'\n ? getColumnWidth(column)\n : null\n \"\n [style.flex]=\"getColumnWidth(column) === 'auto' ? '1' : null\"\n >\n <input\n type=\"text\"\n class=\"i-table-column-filter\"\n placeholder=\"Filter...\"\n [ngModel]=\"columnFilters()[column.field] || ''\"\n (ngModelChange)=\"onColumnFilterInput(column.field, $event)\"\n />\n </div>\n } @else {\n <div\n class=\"i-table-virtual-cell\"\n [style.width]=\"\n getColumnWidth(column) !== 'auto'\n ? getColumnWidth(column)\n : null\n \"\n [style.flex]=\"getColumnWidth(column) === 'auto' ? '1' : null\"\n ></div>\n }\n }\n @if (gridActions().length > 0) {\n <div class=\"i-table-virtual-cell i-table-actions-header\"></div>\n }\n </div>\n }\n <div class=\"i-table-virtual-row i-table-header-row\">\n @if (selectionMode === \"multiple\") {\n <div class=\"i-table-virtual-cell i-table-selection-header\">\n <i-checkbox\n [checked]=\"areAllRowsSelected()\"\n [indeterminate]=\"areSomeRowsSelected()\"\n (onChange)=\"toggleAllSelection()\"\n ></i-checkbox>\n </div>\n }\n @for (column of gridColumns(); track trackByColumn($index, column)) {\n <div\n class=\"i-table-virtual-cell i-table-header-cell\"\n [style.width]=\"\n getColumnWidth(column) !== 'auto'\n ? getColumnWidth(column)\n : null\n \"\n [style.flex]=\"getColumnWidth(column) === 'auto' ? '1' : null\"\n [style.text-align]=\"column.align || 'left'\"\n [class.i-table-sortable-column]=\"sortable && column.sortable\"\n [class.i-table-sorted]=\"sortField === column.field\"\n (click)=\"onSortColumn(column)\"\n >\n <div class=\"i-table-header-content\">\n <span class=\"i-table-header-text\">{{ column.header }}</span>\n @if (sortable && column.sortable) {\n <i\n [class]=\"getSortIcon(column)\"\n class=\"i-table-sort-icon\"\n ></i>\n }\n </div>\n </div>\n }\n @if (gridActions().length > 0) {\n <div class=\"i-table-virtual-cell i-table-actions-header\">\n Actions\n </div>\n }\n </div>\n </div>\n\n <!-- Virtual Scroll Viewport \u2014 *cdkVirtualFor on <div>, not <tr> -->\n <cdk-virtual-scroll-viewport\n [itemSize]=\"virtualScrollItemSize\"\n [minBufferPx]=\"virtualScrollMinBufferPx\"\n [maxBufferPx]=\"virtualScrollMaxBufferPx\"\n class=\"i-table-virtual-viewport\"\n >\n @if (processedData().length === 0) {\n <div class=\"i-table-virtual-row i-table-empty-row\">\n <div\n class=\"i-table-virtual-cell\"\n style=\"flex: 1; text-align: center; padding: 40px 16px\"\n >\n <i-no-content />\n </div>\n </div>\n }\n <div\n *cdkVirtualFor=\"\n let row of processedData();\n let rowIndex = index;\n trackBy: trackByRow\n \"\n class=\"i-table-virtual-row\"\n [style.height.px]=\"virtualScrollItemSize\"\n [class.i-table-row-odd]=\"rowIndex % 2 !== 0\"\n [class.i-table-row-selected]=\"isRowSelected(row)\"\n (click)=\"toggleRowSelection(row)\"\n >\n @if (selectionMode === \"multiple\") {\n <div class=\"i-table-virtual-cell i-table-selection-cell\">\n <i-checkbox\n [checked]=\"isRowSelected(row)\"\n (onChange)=\"toggleRowSelection(row)\"\n (click)=\"$event.stopPropagation()\"\n ></i-checkbox>\n </div>\n }\n @for (column of gridColumns(); track trackByColumn($index, column)) {\n <div\n class=\"i-table-virtual-cell\"\n [style.width]=\"\n getColumnWidth(column) !== 'auto'\n ? getColumnWidth(column)\n : null\n \"\n [style.flex]=\"getColumnWidth(column) === 'auto' ? '1' : null\"\n [style.text-align]=\"column.align || 'left'\"\n [ngClass]=\"\n getCellSeverity(row, column)\n ? 'i-table-cell-' + getCellSeverity(row, column)\n : ''\n \"\n >\n @if (isIconColumn(column)) {\n <i\n [class]=\"getIconClasses(row, column)\"\n [style.font-size]=\"column.iconSize || '1rem'\"\n ></i>\n } @else if (isListColumn(column)) {\n <div class=\"i-table-list-cell\">\n @for (item of getCellListItems(row, column); track item) {\n <i-chip [label]=\"item\"></i-chip>\n }\n </div>\n } @else {\n <span [class.i-severity-text]=\"getCellSeverity(row, column)\">\n {{ formatCellValue(getCellValue(row, column.field), column) }}\n </span>\n }\n </div>\n }\n @if (gridActions().length > 0) {\n <div class=\"i-table-virtual-cell i-table-actions-cell\">\n <div class=\"i-table-actions\">\n @for (action of gridActions(); track action.id) {\n <i-button\n [severity]=\"action.severity || 'secondary'\"\n [text]=\"true\"\n size=\"small\"\n [icon]=\"action.icon || ''\"\n [disabled]=\"isActionDisabled(action, row)\"\n [iTooltip]=\"getActionTooltip(action, row)\"\n [class.i-action-hidden]=\"!isActionVisible(action, row)\"\n (clicked)=\"triggerAction(action, row, $event)\"\n >\n @if (action.label) {\n {{ action.label }}\n }\n </i-button>\n }\n </div>\n </div>\n }\n </div>\n </cdk-virtual-scroll-viewport>\n </div>\n } @else {\n <!-- ================================================================\n PATH C \u2014 Regular scrollable table\n Default for small/medium datasets and nested detail tables.\n Uses a plain overflow container with a @for loop \u2014 no CDK needed.\n ================================================================ -->\n <div\n class=\"i-table-container i-table-container--scrollable\"\n [style.max-height]=\"effectiveHeight()\"\n >\n <table class=\"i-table\">\n <thead>\n <!-- Column Filter Row -->\n @if (filterable) {\n <tr class=\"i-table-filter-row\">\n @if (selectionMode === \"multiple\") {\n <th class=\"i-table-selection-header\"></th>\n }\n @for (\n column of gridColumns();\n track trackByColumn($index, column)\n ) {\n @if (column.filterable !== false) {\n <th [style.width]=\"getColumnWidth(column)\">\n <input\n type=\"text\"\n class=\"i-table-column-filter\"\n placeholder=\"Filter...\"\n [ngModel]=\"columnFilters()[column.field] || ''\"\n (ngModelChange)=\"\n onColumnFilterInput(column.field, $event)\n \"\n />\n </th>\n } @else {\n <th [style.width]=\"getColumnWidth(column)\"></th>\n }\n }\n @if (gridActions().length > 0) {\n <th class=\"i-table-actions-header\"></th>\n }\n </tr>\n }\n\n <!-- Column Headers -->\n <tr>\n @if (selectionMode === \"multiple\") {\n <th class=\"i-table-selection-header\">\n <i-checkbox\n [checked]=\"areAllRowsSelected()\"\n [indeterminate]=\"areSomeRowsSelected()\"\n (onChange)=\"toggleAllSelection()\"\n ></i-checkbox>\n </th>\n }\n @for (\n column of gridColumns();\n track trackByColumn($index, column)\n ) {\n <th\n [style.width]=\"getColumnWidth(column)\"\n [style.text-align]=\"column.align || 'left'\"\n [class.i-table-sortable-column]=\"sortable && column.sortable\"\n [class.i-table-sorted]=\"sortField === column.field\"\n (click)=\"onSortColumn(column)\"\n >\n <div class=\"i-table-header-content\">\n <span class=\"i-table-header-text\">{{ column.header }}</span>\n @if (sortable && column.sortable) {\n <i\n [class]=\"getSortIcon(column)\"\n class=\"i-table-sort-icon\"\n ></i>\n }\n </div>\n @if (resizableColumns) {\n <span\n class=\"i-table-column-resizer\"\n (mousedown)=\"onColumnResizeStart($event, column)\"\n ></span>\n }\n </th>\n }\n @if (gridActions().length > 0) {\n <th class=\"i-table-actions-header\">Actions</th>\n }\n </tr>\n </thead>\n\n <tbody>\n @if (processedData().length === 0) {\n <tr class=\"i-table-empty-row\">\n <td [attr.colspan]=\"totalColspan()\">\n <i-no-content />\n </td>\n </tr>\n }\n @for (row of processedData(); track trackByRow($index, row)) {\n <tr\n [class.i-table-row-odd]=\"$odd\"\n [class.i-table-row-selected]=\"isRowSelected(row)\"\n (click)=\"toggleRowSelection(row)\"\n >\n @if (selectionMode === \"multiple\") {\n <td class=\"i-table-selection-cell\">\n <i-checkbox\n [checked]=\"isRowSelected(row)\"\n (onChange)=\"toggleRowSelection(row)\"\n (click)=\"$event.stopPropagation()\"\n ></i-checkbox>\n </td>\n }\n @for (\n column of gridColumns();\n track trackByColumn($index, column)\n ) {\n <td\n [style.text-align]=\"column.align || 'left'\"\n [style.width]=\"getColumnWidth(column)\"\n [class]=\"\n getCellSeverity(row, column)\n ? 'i-table-cell-' + getCellSeverity(row, column)\n : ''\n \"\n >\n @if (isIconColumn(column)) {\n <i\n [class]=\"getIconClasses(row, column)\"\n [style.font-size]=\"column.iconSize || '1rem'\"\n ></i>\n } @else if (isListColumn(column)) {\n <div class=\"i-table-list-cell\">\n @for (item of getCellListItems(row, column); track item) {\n <i-chip [label]=\"item\"></i-chip>\n }\n </div>\n } @else {\n <span\n [class.i-severity-text]=\"getCellSeverity(row, column)\"\n >\n {{\n formatCellValue(getCellValue(row, column.field), column)\n }}\n </span>\n }\n </td>\n }\n @if (gridActions().length > 0) {\n <td class=\"i-table-actions-cell\">\n <div class=\"i-table-actions\">\n @for (action of gridActions(); track action.id) {\n <i-button\n [severity]=\"action.severity || 'secondary'\"\n [text]=\"true\"\n size=\"small\"\n [icon]=\"action.icon || ''\"\n [disabled]=\"isActionDisabled(action, row)\"\n [iTooltip]=\"getActionTooltip(action, row)\"\n [class.i-action-hidden]=\"!isActionVisible(action, row)\"\n (clicked)=\"triggerAction(action, row, $event)\"\n >\n @if (action.label) {\n {{ action.label }}\n }\n </i-button>\n }\n </div>\n </td>\n }\n </tr>\n }\n </tbody>\n </table>\n </div>\n }\n</div>\n", styles: [".i-table-wrapper{color:var(--color-text-primary);background:var(--color-component-background)}.i-table-wrapper .i-table-header{background:var(--surface-section);border-bottom:1px solid var(--surface-border)}.i-table-wrapper .i-table-global-filter .i-input-text{background:var(--surface-ground)}.i-table-wrapper .i-table-loading-overlay{background:#ffffffb3}.i-table-wrapper .i-table-loading-overlay .i-table-loading-icon{color:var(--color-primary)}.i-table-wrapper table thead tr{background:var(--color-component-background)}.i-table-wrapper table thead tr th{color:var(--color-text-primary);border-bottom:1px solid var(--surface-border)}.i-table-wrapper table thead tr th.i-table-sortable-column{cursor:pointer}.i-table-wrapper table thead tr th.i-table-sortable-column:hover{background:var(--surface-hover)}.i-table-wrapper table thead tr th.i-table-sorted{background:var(--surface-hover);color:var(--color-primary)}.i-table-wrapper table thead tr th .i-table-sort-icon{color:var(--color-text-secondary)}.i-table-wrapper table thead tr th.i-table-sorted .i-table-sort-icon{color:var(--color-primary)}.i-table-wrapper table thead .i-table-filter-row th{background:var(--color-component-background)}.i-table-wrapper table thead .i-table-filter-row .i-table-column-filter{border:1px solid var(--surface-border);background:var(--surface-ground);color:var(--color-text-primary)}.i-table-wrapper table thead .i-table-filter-row .i-table-column-filter:focus{border-color:var(--color-primary);box-shadow:0 2px 10px #0003;outline:none}.i-table-wrapper table thead .i-table-filter-row .i-table-column-filter::placeholder{color:var(--color-text-tertiary)}.i-table-wrapper table tbody tr{background:var(--color-component-background);border-bottom:1px solid var(--surface-border)}.i-table-wrapper table tbody tr td{color:var(--color-text-primary)}.i-table-wrapper table tbody tr.i-table-row-odd{background:var(--color-component-background)}.i-table-wrapper table tbody tr.i-table-row-selected{background:var(--surface-hover);color:var(--color-primary)}.i-table-wrapper table tbody .i-table-expanded-row{background:var(--color-component-background)}.i-table-wrapper table tbody .i-table-expanded-row .i-table-expanded-content{background:transparent}.i-table-wrapper table tbody .i-table-empty-row td{background:var(--color-component-background)}.i-table-wrapper table tbody .i-table-group-header{background:var(--color-component-background);border-bottom:2px solid var(--surface-border)}.i-table-wrapper table tbody .i-table-group-header td{color:var(--color-text-primary)}.i-table-wrapper table tbody .i-table-group-header:hover{background:var(--surface-hover)}.i-table-wrapper table tbody .i-table-group-header .i-table-group-toggle-icon,.i-table-wrapper table tbody .i-table-group-header .i-table-group-count{color:var(--color-text-secondary)}.i-table-wrapper table tbody .i-table-group-columns-header{background:var(--color-component-background);border-bottom:1px solid var(--surface-border)}.i-table-wrapper table tbody .i-table-group-columns-header th{color:var(--color-text-primary);border-bottom:1px solid var(--surface-border)}.i-table-wrapper table tbody .i-table-group-row,.i-table-wrapper table tbody .i-table-group-row.i-table-row-odd{background:var(--color-component-background)}.i-table-wrapper table tbody .i-table-group-row.i-table-row-selected{background:var(--surface-hover);color:var(--color-primary)}.i-table-wrapper table tbody .i-table-group-summary-row{background:var(--surface-section);border-bottom:2px solid var(--surface-border)}.i-table-wrapper table tbody .i-table-group-summary-row td{color:var(--color-text-primary);font-weight:600}.i-table-wrapper table tbody .i-table-group-summary-row:hover{background:var(--surface-hover)}.i-table-wrapper table tbody .i-table-group-summary-row .i-table-group-count{color:var(--color-text-secondary)}.i-table-wrapper table tbody .i-table-group-detail-row,.i-table-wrapper table tbody .i-table-group-detail-row .i-table-group-detail-cell .i-table-wrapper{background:var(--surface-ground)}.i-table-wrapper table tbody .i-table-group-detail-row .i-table-group-detail-cell .i-table-wrapper table thead tr{background:var(--surface-section)}.i-table-wrapper.i-table--bordered table,.i-table-wrapper.i-table--bordered table th,.i-table-wrapper.i-table--bordered table td{border:1px solid var(--surface-border)}.i-table-wrapper.i-table--hoverable table tbody tr:not(.i-table-empty-row):not(.i-table-expanded-row):not(.i-table-group-header):not(.i-table-group-columns-header):not(.i-table-group-detail-row):hover{background:var(--surface-hover)}.i-table-wrapper.i-table--hoverable table tbody tr:not(.i-table-empty-row):not(.i-table-expanded-row):not(.i-table-group-header):not(.i-table-group-columns-header):not(.i-table-group-detail-row).i-table-row-selected:hover{background:var(--surface-hover)}.i-table-wrapper .i-table-column-resizer{background:var(--surface-border)}.i-table-wrapper .i-table-column-resizer:hover{background:var(--color-primary)}.i-table-wrapper .i-table-container--virtual-scroll .i-table-virtual-header{background:var(--color-component-background);border-bottom:1px solid var(--surface-border)}.i-table-wrapper .i-table-container--virtual-scroll .i-table-virtual-header .i-table-virtual-cell{color:var(--color-text-primary)}.i-table-wrapper .i-table-container--virtual-scroll .i-table-virtual-header .i-table-header-cell .i-table-sort-icon{color:var(--color-text-secondary)}.i-table-wrapper .i-table-container--virtual-scroll .i-table-virtual-header .i-table-header-cell.i-table-sortable-column:hover{background:var(--surface-hover)}.i-table-wrapper .i-table-container--virtual-scroll .i-table-virtual-header .i-table-header-cell.i-table-sorted{background:var(--surface-hover);color:var(--color-primary)}.i-table-wrapper .i-table-container--virtual-scroll .i-table-virtual-header .i-table-header-cell.i-table-sorted .i-table-sort-icon{color:var(--color-primary)}.i-table-wrapper .i-table-container--virtual-scroll .i-table-virtual-header .i-table-filter-row .i-table-column-filter{border:1px solid var(--surface-border);background:var(--surface-ground);color:var(--color-text-primary)}.i-table-wrapper .i-table-container--virtual-scroll .i-table-virtual-header .i-table-filter-row .i-table-column-filter:focus{border-color:var(--color-primary);outline:none}.i-table-wrapper .i-table-container--virtual-scroll .i-table-virtual-header .i-table-filter-row .i-table-column-filter::placeholder{color:var(--color-text-tertiary)}.i-table-wrapper .i-table-container--virtual-scroll .i-table-virtual-viewport .i-table-virtual-row{background:var(--color-component-background);border-bottom:1px solid var(--surface-border);color:var(--color-text-primary);transition:background-color .15s ease}.i-table-wrapper .i-table-container--virtual-scroll .i-table-virtual-viewport .i-table-virtual-row.i-table-row-odd{background:var(--color-component-background)}.i-table-wrapper .i-table-container--virtual-scroll .i-table-virtual-viewport .i-table-virtual-row.i-table-row-selected{background:var(--surface-hover);color:var(--color-primary)}.i-table-wrapper.i-table--nested{background:transparent}.i-table-wrapper.i-table--nested table thead tr{background:var(--surface-section)}.i-table-wrapper{position:relative;display:block;border-radius:4px;overflow:visible}.i-table-wrapper.i-table--small table thead th{padding:8px 12px;font-size:13px}.i-table-wrapper.i-table--small table tbody td{padding:6px 12px;font-size:1em}.i-table-wrapper.i-table--small table .i-table-filter-row th{padding:4px 12px}.i-table-wrapper.i-table--large table thead th,.i-table-wrapper.i-table--large table tbody td{padding:16px 20px;font-size:16px}.i-table-wrapper.i-table--large table .i-table-filter-row th{padding:12px 20px}.i-table-wrapper.i-table--scrollable table{table-layout:fixed}.i-table-wrapper.i-table--loading{pointer-events:none;-webkit-user-select:none;user-select:none}.i-table-wrapper .i-table-header{display:flex;justify-content:space-between;align-items:center;padding:12px 16px;gap:16px}.i-table-wrapper .i-table-header .i-table-header-start{flex:0 1 auto;display:flex;align-items:center}.i-table-wrapper .i-table-header .i-table-header-end{flex:0 1 auto;display:flex;align-items:center;gap:12px;margin-left:auto}.i-table-wrapper .i-table-header .i-table-header-end .i-table-global-filter{width:250px}.i-table-wrapper .i-table-header .i-table-header-end .i-table-download{flex-shrink:0}.i-table-wrapper .i-table-loading-overlay{position:absolute;inset:0;z-index:10;display:flex;align-items:center;justify-content:center}.i-table-wrapper .i-table-loading-overlay .i-table-loading-icon{font-size:32px}.i-table-wrapper .i-table-container{overflow-x:auto}.i-table-wrapper .i-table-container::-webkit-scrollbar-track{background:transparent;border-radius:3px}.i-table-wrapper .i-table-container::-webkit-scrollbar-thumb{background:#0003;border-radius:3px;transition:background .2s ease}.i-table-wrapper .i-table-container::-webkit-scrollbar-thumb:hover{background:#00000059}.i-table-wrapper .i-table-container::-webkit-scrollbar-thumb:active{background:#00000080}.i-table-wrapper .i-table-container::-webkit-scrollbar-corner{background:transparent}.i-table-wrapper .i-table-container{scrollbar-width:thin;scrollbar-color:rgba(0,0,0,.2) transparent;scroll-behavior:smooth}.i-table-wrapper .i-table-container::-webkit-scrollbar-thumb{background:var(--color-text-secondary);opacity:.4}.i-table-wrapper .i-table-container::-webkit-scrollbar-thumb:hover{background:var(--color-text-primary);opacity:.6}.i-table-wrapper .i-table-container::-webkit-scrollbar-thumb:active{background:var(--color-primary);opacity:.7}.i-table-wrapper .i-table-container{scrollbar-color:var(--color-text-secondary) transparent}.i-table-wrapper .i-table-container::-webkit-scrollbar{width:6px;height:6px}.i-table-wrapper .i-table-container::-webkit-scrollbar-track{background:#0000000d;border-radius:3px;margin:2px 0}.i-table-wrapper .i-table-container::-webkit-scrollbar-thumb{border-radius:3px;min-height:20px;background:var(--color-text-secondary);opacity:.6}.i-table-wrapper .i-table-container::-webkit-scrollbar-thumb:hover{background:var(--color-text-primary);opacity:.8}.i-table-wrapper .i-table-container::-webkit-scrollbar-thumb:active{background:var(--color-primary);opacity:.9}.i-table-wrapper .i-table-container{scrollbar-width:thin;scrollbar-color:var(--color-text-secondary) rgba(0,0,0,.05)}.i-table-wrapper .i-table-container--scrollable{overflow-y:auto;scrollbar-gutter:stable}.i-table-wrapper .i-table-container--scrollable>table>thead{position:sticky;top:0;z-index:2}.i-table-wrapper .i-table-container--virtual-scroll{overflow:hidden;display:flex;flex-direction:column}.i-table-wrapper .i-table-container--virtual-scroll .i-table-virtual-header{flex-shrink:0;overflow:hidden}.i-table-wrapper .i-table-container--virtual-scroll .i-table-virtual-header .i-table-sort-icon{font-size:.8em;opacity:.6;transition:opacity .15s ease,color .15s ease}.i-table-wrapper .i-table-container--virtual-scroll .i-table-virtual-header .i-table-header-cell.i-table-sortable-column{cursor:pointer}.i-table-wrapper .i-table-container--virtual-scroll .i-table-virtual-header .i-table-header-cell.i-table-sortable-column .i-table-sort-icon{opacity:.4}.i-table-wrapper .i-table-container--virtual-scroll .i-table-virtual-header .i-table-header-cell.i-table-sortable-column:hover .i-table-sort-icon,.i-table-wrapper .i-table-container--virtual-scroll .i-table-virtual-header .i-table-header-cell.i-table-sortable-column.i-table-sorted .i-table-sort-icon{opacity:1}.i-table-wrapper .i-table-container--virtual-scroll .i-table-virtual-header .i-table-filter-row .i-table-virtual-cell{padding:8px 16px}.i-table-wrapper .i-table-container--virtual-scroll .i-table-virtual-header .i-table-filter-row .i-table-virtual-cell .i-table-column-filter{width:100%;padding:6px 10px;font-size:1em;border-radius:4px;transition:border-color .15s ease,box-shadow .15s ease}.i-table-wrapper .i-table-container--virtual-scroll .i-table-virtual-viewport{flex:1;min-height:0;width:100%;overflow-y:auto}.i-table-wrapper .i-table-container--virtual-scroll .i-table-virtual-viewport::-webkit-scrollbar-track{background:transparent;border-radius:3px}.i-table-wrapper .i-table-container--virtual-scroll .i-table-virtual-viewport::-webkit-scrollbar-thumb{background:#0003;border-radius:3px;transition:background .2s ease}.i-table-wrapper .i-table-container--virtual-scroll .i-table-virtual-viewport::-webkit-scrollbar-thumb:hover{background:#00000059}.i-table-wrapper .i-table-container--virtual-scroll .i-table-virtual-viewport::-webkit-scrollbar-thumb:active{background:#00000080}.i-table-wrapper .i-table-container--virtual-scroll .i-table-virtual-viewport::-webkit-scrollbar-corner{background:transparent}.i-table-wrapper .i-table-container--virtual-scroll .i-table-virtual-viewport{scrollbar-width:thin;scrollbar-color:rgba(0,0,0,.2) transparent;scroll-behavior:smooth}.i-table-wrapper .i-table-container--virtual-scroll .i-table-virtual-viewport::-webkit-scrollbar-thumb{background:var(--color-text-secondary);opacity:.4}.i-table-wrapper .i-table-container--virtual-scroll .i-table-virtual-viewport::-webkit-scrollbar-thumb:hover{background:var(--color-text-primary);opacity:.6}.i-table-wrapper .i-table-container--virtual-scroll .i-table-virtual-viewport::-webkit-scrollbar-thumb:active{background:var(--color-primary);opacity:.7}.i-table-wrapper .i-table-container--virtual-scroll .i-table-virtual-viewport{scrollbar-color:var(--color-text-secondary) transparent}.i-table-wrapper .i-table-container--virtual-scroll .i-table-virtual-viewport::-webkit-scrollbar{width:6px;height:6px}.i-table-wrapper .i-table-container--virtual-scroll .i-table-virtual-viewport::-webkit-scrollbar-track{background:#0000000d;border-radius:3px;margin:2px 0}.i-table-wrapper .i-table-container--virtual-scroll .i-table-virtual-viewport::-webkit-scrollbar-thumb{border-radius:3px;min-height:20px;background:var(--color-text-secondary);opacity:.6}.i-table-wrapper .i-table-container--virtual-scroll .i-table-virtual-viewport::-webkit-scrollbar-thumb:hover{background:var(--color-text-primary);opacity:.8}.i-table-wrapper .i-table-container--virtual-scroll .i-table-virtual-viewport::-webkit-scrollbar-thumb:active{background:var(--color-primary);opacity:.9}.i-table-wrapper .i-table-container--virtual-scroll .i-table-virtual-viewport{scrollbar-width:thin;scrollbar-color:var(--color-text-secondary) rgba(0,0,0,.05)}.i-table-wrapper .i-table-container--virtual-scroll .i-table-virtual-viewport .cdk-virtual-scroll-content-wrapper{width:100%}.i-table-wrapper .i-table-container--virtual-scroll .i-table-virtual-row{display:flex;align-items:center;width:100%;box-sizing:border-box}.i-table-wrapper .i-table-container--virtual-scroll .i-table-virtual-cell{padding:12px 16px;box-sizing:border-box;flex-shrink:0;overflow:hidden;display:flex;align-items:center}.i-table-wrapper .i-table-container--virtual-scroll .i-table-virtual-cell.i-table-header-cell{-webkit-user-select:none;user-select:none;font-weight:600;white-space:nowrap}.i-table-wrapper .i-table-container--virtual-scroll .i-table-virtual-cell.i-table-header-cell .i-table-header-content{display:flex;align-items:center;gap:8px}.i-table-wrapper .i-table-container--virtual-scroll .i-table-virtual-cell.i-table-header-cell .i-table-header-content .i-table-header-text{flex:1}.i-table-wrapper .i-table-container--virtual-scroll .i-table-virtual-cell.i-table-selection-header,.i-table-wrapper .i-table-container--virtual-scroll .i-table-virtual-cell.i-table-selection-cell{width:50px;flex:0 0 50px;justify-content:center}.i-table-wrapper .i-table-container--virtual-scroll .i-table-virtual-cell.i-table-actions-header,.i-table-wrapper .i-table-container--virtual-scroll .i-table-virtual-cell.i-table-actions-cell{flex:0 0 auto;justify-content:flex-end}.i-table-wrapper .i-table-container--virtual-scroll .i-table-virtual-cell.i-table-actions-header .i-table-actions,.i-table-wrapper .i-table-container--virtual-scroll .i-table-virtual-cell.i-table-actions-cell .i-table-actions{display:flex;gap:4px;justify-content:flex-end}.i-table-wrapper table{width:100%;border-collapse:collapse;table-layout:auto}.i-table-wrapper table thead tr th{position:relative;padding:12px 16px;font-weight:600;text-align:left;white-space:nowrap;-webkit-user-select:none;user-select:none}.i-table-wrapper table thead tr th .i-table-header-content{display:flex;align-items:center;gap:8px}.i-table-wrapper table thead tr th .i-table-header-content .i-table-header-text{flex:1}.i-table-wrapper table thead tr th .i-table-sort-icon{font-size:.8em;opacity:.6;transition:opacity .15s ease,color .15s ease}.i-table-wrapper table thead tr th.i-table-sortable-column{transition:background-color .15s ease}.i-table-wrapper table thead tr th.i-table-sortable-column .i-table-sort-icon{opacity:.4}.i-table-wrapper table thead tr th.i-table-sortable-column:hover .i-table-sort-icon,.i-table-wrapper table thead tr th.i-table-sortable-column.i-table-sorted .i-table-sort-icon{opacity:1}.i-table-wrapper table thead tr th:hover .i-table-column-resizer{opacity:.5}.i-table-wrapper table thead tr th.i-table-actions-header{text-align:right}.i-table-wrapper table thead .i-table-filter-row th{padding:8px 16px}.i-table-wrapper table thead .i-table-filter-row th .i-table-column-filter{width:100%;padding:6px 10px;font-size:1em;border-radius:4px;transition:border-color .15s ease,box-shadow .15s ease}.i-table-wrapper table tbody{display:table-row-group}.i-table-wrapper table tbody tr{transition:background-color .15s ease}.i-table-wrapper table tbody tr td{padding:12px 16px;vertical-align:middle}.i-table-wrapper table tbody .i-table-empty-row td{padding:40px 16px;text-align:center}.i-table-wrapper table tbody .i-table-expanded-row td .i-table-expanded-content{padding:0;margin:2px 0 24px;border-radius:4px}.i-table-wrapper table tbody .i-table-expanded-row td .i-table-expanded-content pre{margin:0;font-family:monospace;font-size:1em;white-space:pre-wrap;word-wrap:break-word}.i-table-wrapper table tbody .i-table-group-summary-row{cursor:pointer;-webkit-user-select:none;user-select:none;font-weight:600;transition:background-color .15s ease}.i-table-wrapper table tbody .i-table-group-summary-row td{padding:12px 16px}.i-table-wrapper table tbody .i-table-group-summary-row .i-table-group-header-content{display:flex;align-items:center;gap:8px}.i-table-wrapper table tbody .i-table-group-summary-row .i-table-group-header-content .i-table-group-label{flex:1;font-size:1.05em}.i-table-wrapper table tbody .i-table-group-summary-row .i-table-group-header-content .i-table-group-count{opacity:.7;font-size:.9em;font-weight:400}.i-table-wrapper table tbody .i-table-group-detail-row .i-table-group-detail-cell{padding:0;overflow:hidden}.i-table-wrapper table tbody .i-table-group-detail-row .i-table-group-detail-cell .i-table-wrapper{border-radius:0;border-top:none;overflow:hidden}.i-table-wrapper table tbody .i-table-group-count-header{width:60px;text-align:center;font-weight:400;opacity:.6;font-size:.85em}.i-table-wrapper table tbody .i-table-group-count-cell{width:60px;text-align:right;white-space:nowrap}.i-table-wrapper table tbody .i-table-group-count-cell .i-table-group-count{opacity:.7;font-size:.9em;font-weight:400}.i-table-wrapper table tbody .i-table-group-header td{padding:12px 16px;font-weight:600;cursor:pointer;-webkit-user-select:none;user-select:none;transition:background-color .15s ease}.i-table-wrapper table tbody .i-table-group-header td:hover{opacity:.8}.i-table-wrapper table tbody .i-table-group-header .i-table-group-header-content{display:flex;align-items:center;gap:8px}.i-table-wrapper table tbody .i-table-group-header .i-table-group-header-content .i-table-group-toggle-icon{font-size:.8em;transition:transform .15s ease}.i-table-wrapper table tbody .i-table-group-header .i-table-group-header-content .i-table-group-label{flex:1;font-size:1.1em}.i-table-wrapper table tbody .i-table-group-header .i-table-group-header-content .i-table-group-count{opacity:.7;font-size:.9em;font-weight:400}.i-table-wrapper table tbody .i-table-group-columns-header th{font-size:.95em;font-weight:600;padding:10px 16px}.i-table-wrapper table tbody .i-table-group-row td{padding-left:32px}.i-table-wrapper table tbody .i-table-group-row td:first-child{padding-left:16px}.i-table-wrapper .i-table-selection-header,.i-table-wrapper .i-table-selection-cell,.i-table-wrapper .i-table-expand-header,.i-table-wrapper .i-table-expand-cell{width:50px;text-align:center}.i-table-wrapper .i-table-detail-count-header{width:36px;padding:0}.i-table-wrapper .i-table-detail-count-cell{width:36px;padding:0 4px 0 0;text-align:right;white-space:nowrap;font-size:.78em;opacity:.5;font-weight:400}.i-table-wrapper .i-table-actions-header,.i-table-wrapper .i-table-actions-cell{width:auto;white-space:nowrap;text-align:right}.i-table-wrapper .i-table-actions-header .i-table-actions,.i-table-wrapper .i-table-actions-cell .i-table-actions{display:flex;gap:4px;justify-content:flex-end}.i-table-wrapper .i-table-column-resizer{position:absolute;right:0;top:50%;transform:translateY(-50%);width:4px;height:60%;cursor:col-resize;opacity:0;transition:opacity .15s ease,background-color .15s ease}.i-table-wrapper .i-table-column-resizer:hover{opacity:1}.i-severity-icon.success,.i-table-cell-success .i-severity-icon,.i-severity-text.success,.i-table-cell-success .i-severity-text{color:var(--color-success)}.i-severity-icon.info,.i-table-cell-info .i-severity-icon,.i-severity-text.info,.i-table-cell-info .i-severity-text{color:var(--color-info)}.i-severity-icon.warning,.i-table-cell-warning .i-severity-icon,.i-severity-text.warning,.i-table-cell-warning .i-severity-text{color:var(--color-warning)}.i-severity-icon.danger,.i-table-cell-danger .i-severity-icon,.i-severity-text.danger,.i-table-cell-danger .i-severity-text{color:var(--color-danger)}.i-severity-icon.secondary,.i-table-cell-secondary .i-severity-icon,.i-severity-text.secondary,.i-table-cell-secondary .i-severity-text{color:var(--color-text-secondary)}.i-table-list-cell{display:flex;flex-direction:column;gap:4px;align-items:flex-start}.i-table-list-cell i-chip{display:block}.i-action-hidden{visibility:hidden;pointer-events:none}@media(max-width:768px){.i-table-wrapper .i-table-header{padding:8px 12px;flex-wrap:wrap}.i-table-wrapper .i-table-header .i-table-header-start{flex:1 1 100%;margin-bottom:8px}.i-table-wrapper .i-table-header .i-table-header-end{flex:1 1 100%;justify-content:flex-end}.i-table-wrapper .i-table-header .i-table-header-end .i-table-global-filter{flex:1;max-width:250px}}\n"] }]
|
|
8533
|
+
}], ctorParameters: () => [{ type: i0.ElementRef }], propDecorators: { grid: [{ type: i0.Input, args: [{ isSignal: true, alias: "grid", required: false }] }], emptyMessage: [{
|
|
8641
8534
|
type: Input
|
|
8642
8535
|
}], sortable: [{
|
|
8643
8536
|
type: Input
|
|
@@ -8669,12 +8562,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImpor
|
|
|
8669
8562
|
type: Output
|
|
8670
8563
|
}], onRowUnselect: [{
|
|
8671
8564
|
type: Output
|
|
8672
|
-
}], showActions: [{
|
|
8673
|
-
type: Input
|
|
8674
|
-
}], actions: [{
|
|
8675
|
-
type: Input
|
|
8676
|
-
}], onAction: [{
|
|
8677
|
-
type: Output
|
|
8678
8565
|
}], striped: [{
|
|
8679
8566
|
type: Input
|
|
8680
8567
|
}], hoverable: [{
|
|
@@ -8687,8 +8574,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImpor
|
|
|
8687
8574
|
type: Input
|
|
8688
8575
|
}], scrollable: [{
|
|
8689
8576
|
type: Input
|
|
8690
|
-
}], scrollHeight: [{
|
|
8691
|
-
type: Input
|
|
8692
8577
|
}], height: [{
|
|
8693
8578
|
type: Input
|
|
8694
8579
|
}], virtualScroll: [{
|
|
@@ -8704,10 +8589,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImpor
|
|
|
8704
8589
|
args: [CdkVirtualScrollViewport]
|
|
8705
8590
|
}], resizableColumns: [{
|
|
8706
8591
|
type: Input
|
|
8707
|
-
}], reorderableColumns: [{
|
|
8708
|
-
type: Input
|
|
8709
|
-
}], rowExpandable: [{
|
|
8710
|
-
type: Input
|
|
8711
8592
|
}], onRowExpand: [{
|
|
8712
8593
|
type: Output
|
|
8713
8594
|
}], onRowCollapse: [{
|