eru-grid 0.0.22-d → 0.0.22-e
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/eru-grid.mjs +88 -385
- package/fesm2022/eru-grid.mjs.map +1 -1
- package/index.d.ts +1 -29
- package/package.json +1 -1
package/fesm2022/eru-grid.mjs
CHANGED
|
@@ -406,7 +406,6 @@ class PivotTransformService {
|
|
|
406
406
|
return Array.from(values).sort();
|
|
407
407
|
});
|
|
408
408
|
// Generate subtotals for EACH level of column dimensions separately
|
|
409
|
-
// This creates subtotals for Priority, Rating, etc. individually
|
|
410
409
|
for (let dimIndex = 0; dimIndex < subtotalDimensions.length; dimIndex++) {
|
|
411
410
|
const currentDimension = subtotalDimensions[dimIndex];
|
|
412
411
|
const currentDimensionValues = dimensionValues[dimIndex];
|
|
@@ -633,7 +632,7 @@ class PivotTransformService {
|
|
|
633
632
|
}
|
|
634
633
|
// Generate nested column headers with collapsible support
|
|
635
634
|
this.buildNestedHeaders(dimensionValues, aggregations, headerRows, 0, columnDimensions, maxDepth, gridConfiguration);
|
|
636
|
-
// Insert column subtotal headers at the correct positions within each
|
|
635
|
+
// Insert column subtotal headers at the correct positions within each dimension group
|
|
637
636
|
if (enableColumnSubtotals) {
|
|
638
637
|
this.insertColumnSubtotalHeaders(headerRows, columnDimensions, aggregations, gridConfiguration, sourceData);
|
|
639
638
|
}
|
|
@@ -680,7 +679,7 @@ class PivotTransformService {
|
|
|
680
679
|
const groupKey = this.generateColumnGroupKey(dimension, currentLevel);
|
|
681
680
|
const isExpanded = this.isColumnGroupExpanded(groupKey);
|
|
682
681
|
const column = gridConfiguration?.fields.find((col) => col.name === dimension);
|
|
683
|
-
// Add the
|
|
682
|
+
// Add the dimension-level header
|
|
684
683
|
headerRows[currentLevel].push({
|
|
685
684
|
name: dimension,
|
|
686
685
|
label: value,
|
|
@@ -1253,25 +1252,31 @@ class PivotTransformService {
|
|
|
1253
1252
|
const subtotalColumnName = `_${dimensionPath.join('_')}_subtotal_${aggregation.name}`;
|
|
1254
1253
|
let measureTotal = 0;
|
|
1255
1254
|
const matchedColumns = [];
|
|
1256
|
-
// Find all columns that match this dimension
|
|
1255
|
+
// Find all pivot-combination columns that match this dimension path
|
|
1256
|
+
// and sum their values. Pivot keys are produced by createPivotRows as
|
|
1257
|
+
// "<dim1>|<dim2>|...|<dimN>|<aggregationName>" (pipe-separated), and
|
|
1258
|
+
// must not be confused with subtotal/grand-total keys which are
|
|
1259
|
+
// prefixed with an underscore (e.g. "_2025-2026_subtotal_kpi").
|
|
1260
|
+
const aggregationSuffix = `|${aggregation.name}`;
|
|
1257
1261
|
Object.keys(row).forEach(key => {
|
|
1258
|
-
if (key.
|
|
1259
|
-
//
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
if (isMatch) {
|
|
1271
|
-
measureTotal += row[key];
|
|
1272
|
-
matchedColumns.push(key);
|
|
1262
|
+
if (key.startsWith('_'))
|
|
1263
|
+
return; // skip synthetic subtotal/grand-total columns
|
|
1264
|
+
if (!key.endsWith(aggregationSuffix) || typeof row[key] !== 'number')
|
|
1265
|
+
return;
|
|
1266
|
+
const columnKey = key.slice(0, -aggregationSuffix.length);
|
|
1267
|
+
const columnParts = columnKey.split('|');
|
|
1268
|
+
// Check this column matches the dimension path up to `level`
|
|
1269
|
+
let isMatch = true;
|
|
1270
|
+
for (let i = 0; i <= level; i++) {
|
|
1271
|
+
if (columnParts[i] !== dimensionPath[i]) {
|
|
1272
|
+
isMatch = false;
|
|
1273
|
+
break;
|
|
1273
1274
|
}
|
|
1274
1275
|
}
|
|
1276
|
+
if (isMatch) {
|
|
1277
|
+
measureTotal += row[key];
|
|
1278
|
+
matchedColumns.push(key);
|
|
1279
|
+
}
|
|
1275
1280
|
});
|
|
1276
1281
|
newRow[subtotalColumnName] = measureTotal;
|
|
1277
1282
|
}
|
|
@@ -1311,276 +1316,86 @@ class PivotTransformService {
|
|
|
1311
1316
|
const relevantDimensions = dimensionValues.slice(0, targetLevel + 1);
|
|
1312
1317
|
return this.generateCombinations(relevantDimensions);
|
|
1313
1318
|
}
|
|
1314
|
-
/**
|
|
1315
|
-
* Generate columns with properly positioned subtotal columns
|
|
1316
|
-
*/
|
|
1317
|
-
generateColumnsWithInterleavedSubtotals(dimensionValues, aggregations, columnDimensions, gridConfiguration, startingColumnIndex = 0) {
|
|
1318
|
-
const columns = [];
|
|
1319
|
-
let columnIndex = startingColumnIndex;
|
|
1320
|
-
const subtotalPositionColumn = gridConfiguration?.config?.subtotalPositionColumn ?? 'after';
|
|
1321
|
-
// Generate all pivot combinations in proper order
|
|
1322
|
-
const allCombinations = this.generateCombinations(dimensionValues);
|
|
1323
|
-
// Group by first level (Priority: Low, Medium, Urgent)
|
|
1324
|
-
const priorityGroups = new Map();
|
|
1325
|
-
allCombinations.forEach(combination => {
|
|
1326
|
-
const priority = combination[0];
|
|
1327
|
-
if (!priorityGroups.has(priority)) {
|
|
1328
|
-
priorityGroups.set(priority, []);
|
|
1329
|
-
}
|
|
1330
|
-
priorityGroups.get(priority).push(combination);
|
|
1331
|
-
});
|
|
1332
|
-
// Process each priority group
|
|
1333
|
-
Array.from(priorityGroups.keys()).sort().forEach(priority => {
|
|
1334
|
-
const priorityCombinations = priorityGroups.get(priority);
|
|
1335
|
-
// If we have multiple dimension levels, group by second level within this priority
|
|
1336
|
-
if (columnDimensions.length > 2) {
|
|
1337
|
-
const ratingGroups = new Map();
|
|
1338
|
-
priorityCombinations.forEach(combination => {
|
|
1339
|
-
if (combination.length >= 2) {
|
|
1340
|
-
const rating = combination[1];
|
|
1341
|
-
const ratingKey = `${priority}|${rating}`;
|
|
1342
|
-
if (!ratingGroups.has(ratingKey)) {
|
|
1343
|
-
ratingGroups.set(ratingKey, []);
|
|
1344
|
-
}
|
|
1345
|
-
ratingGroups.get(ratingKey).push(combination);
|
|
1346
|
-
}
|
|
1347
|
-
});
|
|
1348
|
-
// Process each rating group within this priority
|
|
1349
|
-
Array.from(ratingGroups.keys()).sort().forEach(ratingKey => {
|
|
1350
|
-
const ratingCombinations = ratingGroups.get(ratingKey);
|
|
1351
|
-
// Add all columns for this rating group
|
|
1352
|
-
ratingCombinations.forEach(combination => {
|
|
1353
|
-
aggregations.forEach(aggregation => {
|
|
1354
|
-
const aggregationColumn = gridConfiguration?.fields.find((col) => col.name === aggregation.name);
|
|
1355
|
-
const columnKey = combination.join('|');
|
|
1356
|
-
const columnName = `${columnKey}_${aggregation.name}`;
|
|
1357
|
-
const columnLabel = aggregations.length > 1
|
|
1358
|
-
? `${combination.join(' - ')} (${aggregation.label})`
|
|
1359
|
-
: combination.join(' - ');
|
|
1360
|
-
columns.push({
|
|
1361
|
-
name: columnName,
|
|
1362
|
-
label: columnLabel,
|
|
1363
|
-
datatype: this.getAggregationDataType(aggregation.aggregationFunction),
|
|
1364
|
-
field_size: aggregation.field_size || aggregationColumn?.field_size || 120,
|
|
1365
|
-
grid_index: columnIndex++,
|
|
1366
|
-
isLeaf: true,
|
|
1367
|
-
level: dimensionValues.length + (aggregations.length > 1 ? 1 : 0),
|
|
1368
|
-
parentPath: combination,
|
|
1369
|
-
rowspan: 1,
|
|
1370
|
-
colspan: 1,
|
|
1371
|
-
aggregationFunction: aggregation.aggregationFunction,
|
|
1372
|
-
enableDrilldown: aggregation.enableDrilldown || false
|
|
1373
|
-
});
|
|
1374
|
-
});
|
|
1375
|
-
});
|
|
1376
|
-
// Add rating subtotal after this rating group
|
|
1377
|
-
if (subtotalPositionColumn === 'after') {
|
|
1378
|
-
const ratingParts = ratingKey.split('|');
|
|
1379
|
-
aggregations.forEach(aggregation => {
|
|
1380
|
-
if (aggregation.showSubtotals) {
|
|
1381
|
-
const aggregationColumn = gridConfiguration?.fields.find((col) => col.name === aggregation.name);
|
|
1382
|
-
const subtotalColumnName = `_${ratingParts.join('_')}_subtotal_${aggregation.name}`;
|
|
1383
|
-
const subtotalLabel = `${ratingParts.join('+')} Subtotal - ${aggregation.label || aggregation.name}`;
|
|
1384
|
-
columns.push({
|
|
1385
|
-
name: subtotalColumnName,
|
|
1386
|
-
label: subtotalLabel,
|
|
1387
|
-
datatype: this.getAggregationDataType(aggregation.aggregationFunction),
|
|
1388
|
-
field_size: aggregation.field_size || aggregationColumn?.field_size || 120,
|
|
1389
|
-
grid_index: columnIndex++,
|
|
1390
|
-
isLeaf: true,
|
|
1391
|
-
level: dimensionValues.length + (aggregations.length > 1 ? 1 : 0),
|
|
1392
|
-
parentPath: ratingParts,
|
|
1393
|
-
rowspan: 1,
|
|
1394
|
-
colspan: 1,
|
|
1395
|
-
aggregationFunction: aggregation.aggregationFunction,
|
|
1396
|
-
enableDrilldown: aggregation.enableDrilldown || false
|
|
1397
|
-
});
|
|
1398
|
-
}
|
|
1399
|
-
});
|
|
1400
|
-
}
|
|
1401
|
-
});
|
|
1402
|
-
}
|
|
1403
|
-
else {
|
|
1404
|
-
// For 2 dimensions, just add all columns for this priority
|
|
1405
|
-
priorityCombinations.forEach(combination => {
|
|
1406
|
-
aggregations.forEach(aggregation => {
|
|
1407
|
-
const aggregationColumn = gridConfiguration?.fields.find((col) => col.name === aggregation.name);
|
|
1408
|
-
const columnKey = combination.join('|');
|
|
1409
|
-
const columnName = `${columnKey}_${aggregation.name}`;
|
|
1410
|
-
const columnLabel = aggregations.length > 1
|
|
1411
|
-
? `${combination.join(' - ')} (${aggregation.label})`
|
|
1412
|
-
: combination.join(' - ');
|
|
1413
|
-
columns.push({
|
|
1414
|
-
name: columnName,
|
|
1415
|
-
label: columnLabel,
|
|
1416
|
-
datatype: this.getAggregationDataType(aggregation.aggregationFunction),
|
|
1417
|
-
field_size: aggregation.field_size || aggregationColumn?.field_size || 120,
|
|
1418
|
-
grid_index: columnIndex++,
|
|
1419
|
-
isLeaf: true,
|
|
1420
|
-
level: dimensionValues.length + (aggregations.length > 1 ? 1 : 0),
|
|
1421
|
-
parentPath: combination,
|
|
1422
|
-
rowspan: 1,
|
|
1423
|
-
colspan: 1,
|
|
1424
|
-
aggregationFunction: aggregation.aggregationFunction,
|
|
1425
|
-
enableDrilldown: aggregation.enableDrilldown || false
|
|
1426
|
-
});
|
|
1427
|
-
});
|
|
1428
|
-
});
|
|
1429
|
-
}
|
|
1430
|
-
// Add priority subtotal after all rating groups for this priority
|
|
1431
|
-
if (subtotalPositionColumn === 'after') {
|
|
1432
|
-
aggregations.forEach(aggregation => {
|
|
1433
|
-
if (aggregation.showSubtotals) {
|
|
1434
|
-
const aggregationColumn = gridConfiguration?.fields.find((col) => col.name === aggregation.name);
|
|
1435
|
-
const subtotalColumnName = `_${priority}_subtotal_${aggregation.name}`;
|
|
1436
|
-
const subtotalLabel = `${priority} Subtotal - ${aggregation.label || aggregation.name}`;
|
|
1437
|
-
columns.push({
|
|
1438
|
-
name: subtotalColumnName,
|
|
1439
|
-
label: subtotalLabel,
|
|
1440
|
-
datatype: this.getAggregationDataType(aggregation.aggregationFunction),
|
|
1441
|
-
field_size: aggregation.field_size || aggregationColumn?.field_size || 120,
|
|
1442
|
-
grid_index: columnIndex++,
|
|
1443
|
-
isLeaf: true,
|
|
1444
|
-
level: dimensionValues.length + (aggregations.length > 1 ? 1 : 0),
|
|
1445
|
-
parentPath: [priority],
|
|
1446
|
-
rowspan: 1,
|
|
1447
|
-
colspan: 1,
|
|
1448
|
-
aggregationFunction: aggregation.aggregationFunction,
|
|
1449
|
-
enableDrilldown: aggregation.enableDrilldown || false
|
|
1450
|
-
});
|
|
1451
|
-
}
|
|
1452
|
-
});
|
|
1453
|
-
}
|
|
1454
|
-
});
|
|
1455
|
-
// Add column grand totals if positioned after
|
|
1456
|
-
const enableColumnGrandTotal = gridConfiguration?.config?.enableColumnGrandTotal ?? false;
|
|
1457
|
-
const grandTotalPositionColumn = gridConfiguration?.config?.grandTotalPositionColumn ?? 'after';
|
|
1458
|
-
if (enableColumnGrandTotal && grandTotalPositionColumn === 'after') {
|
|
1459
|
-
aggregations.forEach(aggregation => {
|
|
1460
|
-
const aggregationColumn = gridConfiguration?.fields.find((col) => col.name === aggregation.name);
|
|
1461
|
-
columns.push({
|
|
1462
|
-
name: `_${aggregation.aggregationFunction}_column_grand_total_${aggregation.name}`,
|
|
1463
|
-
label: `${this.toTitleCase(aggregation.aggregationFunction)} of ${aggregation.label || aggregation.name}`,
|
|
1464
|
-
datatype: this.getAggregationDataType(aggregation.aggregationFunction),
|
|
1465
|
-
field_size: aggregation.field_size || aggregationColumn?.field_size || 120,
|
|
1466
|
-
grid_index: columnIndex++,
|
|
1467
|
-
isLeaf: true,
|
|
1468
|
-
level: 0,
|
|
1469
|
-
rowspan: dimensionValues.length + (aggregations.length > 1 ? 1 : 0),
|
|
1470
|
-
colspan: 1,
|
|
1471
|
-
aggregationFunction: aggregation.aggregationFunction,
|
|
1472
|
-
enableDrilldown: aggregation.enableDrilldown || false
|
|
1473
|
-
});
|
|
1474
|
-
});
|
|
1475
|
-
}
|
|
1476
|
-
return columns;
|
|
1477
|
-
}
|
|
1478
|
-
/**
|
|
1479
|
-
* Group combinations by dimension levels for subtotal insertion
|
|
1480
|
-
*/
|
|
1481
|
-
groupCombinationsByDimensions(allCombinations, maxLevel) {
|
|
1482
|
-
const groupedByLevel = [];
|
|
1483
|
-
// For each level (0 to maxLevel-1)
|
|
1484
|
-
for (let level = 0; level < maxLevel; level++) {
|
|
1485
|
-
const levelGroups = [];
|
|
1486
|
-
const groupMap = new Map();
|
|
1487
|
-
// Group combinations by prefix at this level
|
|
1488
|
-
allCombinations.forEach(combination => {
|
|
1489
|
-
if (combination.length > level) {
|
|
1490
|
-
const prefix = combination.slice(0, level + 1);
|
|
1491
|
-
const prefixKey = prefix.join('|');
|
|
1492
|
-
if (!groupMap.has(prefixKey)) {
|
|
1493
|
-
groupMap.set(prefixKey, []);
|
|
1494
|
-
}
|
|
1495
|
-
groupMap.get(prefixKey).push(combination);
|
|
1496
|
-
}
|
|
1497
|
-
});
|
|
1498
|
-
// Convert map to array format
|
|
1499
|
-
groupMap.forEach((combinations, prefixKey) => {
|
|
1500
|
-
const prefix = prefixKey.split('|');
|
|
1501
|
-
levelGroups.push({ prefix, combinations });
|
|
1502
|
-
});
|
|
1503
|
-
groupedByLevel.push(levelGroups);
|
|
1504
|
-
}
|
|
1505
|
-
return groupedByLevel;
|
|
1506
|
-
}
|
|
1507
1319
|
/**
|
|
1508
1320
|
* Add interleaved subtotals within column groups
|
|
1509
1321
|
*/
|
|
1510
1322
|
addInterleavedSubtotals(pivotColumns, dimensionValues, aggregations, columnDimensions, gridConfiguration, startingIndex = 0, subtotalPosition = 'after') {
|
|
1511
1323
|
const result = [];
|
|
1512
1324
|
let columnIndex = startingIndex;
|
|
1513
|
-
//
|
|
1514
|
-
const
|
|
1515
|
-
// Group columns by Priority (first dimension)
|
|
1325
|
+
// Group pivot columns by the first column-dimension value
|
|
1326
|
+
const firstLevelGroups = new Map();
|
|
1516
1327
|
pivotColumns.forEach(column => {
|
|
1517
|
-
const columnKey = column.name.split('_')[0]; //
|
|
1328
|
+
const columnKey = column.name.split('_')[0]; // Part before aggregation
|
|
1518
1329
|
const parts = columnKey.split('|');
|
|
1519
|
-
const
|
|
1520
|
-
if (!
|
|
1521
|
-
|
|
1330
|
+
const firstLevelValue = parts[0];
|
|
1331
|
+
if (!firstLevelGroups.has(firstLevelValue)) {
|
|
1332
|
+
firstLevelGroups.set(firstLevelValue, []);
|
|
1522
1333
|
}
|
|
1523
|
-
|
|
1334
|
+
firstLevelGroups.get(firstLevelValue).push(column);
|
|
1524
1335
|
});
|
|
1525
|
-
//
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
|
|
1336
|
+
// Subtotals only apply to dimensions that have a deeper dimension beneath
|
|
1337
|
+
// them — the leaf dimension never gets its own subtotal column.
|
|
1338
|
+
const firstLevelHasDeeperDimension = columnDimensions.length > 1;
|
|
1339
|
+
const secondLevelHasDeeperDimension = columnDimensions.length > 2;
|
|
1340
|
+
// Process each first-level group
|
|
1341
|
+
Array.from(firstLevelGroups.keys()).sort().forEach(firstLevelValue => {
|
|
1342
|
+
const firstLevelColumns = firstLevelGroups.get(firstLevelValue);
|
|
1343
|
+
// First-level subtotal before its columns
|
|
1344
|
+
if (subtotalPosition === 'before' && firstLevelHasDeeperDimension) {
|
|
1530
1345
|
aggregations.forEach(aggregation => {
|
|
1531
1346
|
if (aggregation.showSubtotals) {
|
|
1532
|
-
const subtotalColumn = this.createSubtotalColumn([
|
|
1347
|
+
const subtotalColumn = this.createSubtotalColumn([firstLevelValue], 0, aggregation, gridConfiguration, columnIndex++);
|
|
1533
1348
|
result.push(subtotalColumn);
|
|
1534
1349
|
}
|
|
1535
1350
|
});
|
|
1536
1351
|
}
|
|
1537
|
-
// Group
|
|
1538
|
-
const
|
|
1539
|
-
|
|
1352
|
+
// Group this first-level bucket by the second column-dimension value
|
|
1353
|
+
const secondLevelGroups = new Map();
|
|
1354
|
+
firstLevelColumns.forEach(column => {
|
|
1540
1355
|
const columnKey = column.name.split('_')[0];
|
|
1541
1356
|
const parts = columnKey.split('|');
|
|
1542
1357
|
if (parts.length >= 2) {
|
|
1543
|
-
const
|
|
1544
|
-
const
|
|
1545
|
-
if (!
|
|
1546
|
-
|
|
1358
|
+
const secondLevelValue = parts[1];
|
|
1359
|
+
const secondLevelKey = `${firstLevelValue}|${secondLevelValue}`;
|
|
1360
|
+
if (!secondLevelGroups.has(secondLevelKey)) {
|
|
1361
|
+
secondLevelGroups.set(secondLevelKey, []);
|
|
1547
1362
|
}
|
|
1548
|
-
|
|
1363
|
+
secondLevelGroups.get(secondLevelKey).push(column);
|
|
1549
1364
|
}
|
|
1550
1365
|
});
|
|
1551
|
-
// Process each
|
|
1552
|
-
Array.from(
|
|
1553
|
-
const
|
|
1554
|
-
const
|
|
1555
|
-
//
|
|
1556
|
-
if (subtotalPosition === 'before') {
|
|
1366
|
+
// Process each second-level group within this first-level bucket
|
|
1367
|
+
Array.from(secondLevelGroups.keys()).sort().forEach(secondLevelKey => {
|
|
1368
|
+
const secondLevelColumns = secondLevelGroups.get(secondLevelKey);
|
|
1369
|
+
const secondLevelParts = secondLevelKey.split('|');
|
|
1370
|
+
// Second-level subtotal before its columns
|
|
1371
|
+
if (subtotalPosition === 'before' && secondLevelHasDeeperDimension) {
|
|
1557
1372
|
aggregations.forEach(aggregation => {
|
|
1558
1373
|
if (aggregation.showSubtotals) {
|
|
1559
|
-
const subtotalColumn = this.createSubtotalColumn(
|
|
1374
|
+
const subtotalColumn = this.createSubtotalColumn(secondLevelParts, 1, aggregation, gridConfiguration, columnIndex++);
|
|
1560
1375
|
result.push(subtotalColumn);
|
|
1561
1376
|
}
|
|
1562
1377
|
});
|
|
1563
1378
|
}
|
|
1564
|
-
// Add the actual columns for this
|
|
1565
|
-
|
|
1379
|
+
// Add the actual leaf columns for this second-level group
|
|
1380
|
+
secondLevelColumns.forEach(col => {
|
|
1566
1381
|
col.grid_index = columnIndex++;
|
|
1567
1382
|
result.push(col);
|
|
1568
1383
|
});
|
|
1569
|
-
//
|
|
1570
|
-
if (subtotalPosition === 'after') {
|
|
1384
|
+
// Second-level subtotal after its columns
|
|
1385
|
+
if (subtotalPosition === 'after' && secondLevelHasDeeperDimension) {
|
|
1571
1386
|
aggregations.forEach(aggregation => {
|
|
1572
1387
|
if (aggregation.showSubtotals) {
|
|
1573
|
-
const subtotalColumn = this.createSubtotalColumn(
|
|
1388
|
+
const subtotalColumn = this.createSubtotalColumn(secondLevelParts, 1, aggregation, gridConfiguration, columnIndex++);
|
|
1574
1389
|
result.push(subtotalColumn);
|
|
1575
1390
|
}
|
|
1576
1391
|
});
|
|
1577
1392
|
}
|
|
1578
1393
|
});
|
|
1579
|
-
//
|
|
1580
|
-
if (subtotalPosition === 'after') {
|
|
1394
|
+
// First-level subtotal after its columns
|
|
1395
|
+
if (subtotalPosition === 'after' && firstLevelHasDeeperDimension) {
|
|
1581
1396
|
aggregations.forEach(aggregation => {
|
|
1582
1397
|
if (aggregation.showSubtotals) {
|
|
1583
|
-
const subtotalColumn = this.createSubtotalColumn([
|
|
1398
|
+
const subtotalColumn = this.createSubtotalColumn([firstLevelValue], 0, aggregation, gridConfiguration, columnIndex++);
|
|
1584
1399
|
result.push(subtotalColumn);
|
|
1585
1400
|
}
|
|
1586
1401
|
});
|
|
@@ -1588,38 +1403,6 @@ class PivotTransformService {
|
|
|
1588
1403
|
});
|
|
1589
1404
|
return result;
|
|
1590
1405
|
}
|
|
1591
|
-
/**
|
|
1592
|
-
* Group pivot columns by dimension prefixes for subtotal insertion
|
|
1593
|
-
*/
|
|
1594
|
-
groupPivotColumnsByDimensions(pivotColumns, maxLevel) {
|
|
1595
|
-
const groupedByLevel = [];
|
|
1596
|
-
// For each level that should have subtotals
|
|
1597
|
-
for (let level = 0; level < maxLevel; level++) {
|
|
1598
|
-
const levelGroups = [];
|
|
1599
|
-
const groupMap = new Map();
|
|
1600
|
-
// Group columns by their dimension prefix at this level
|
|
1601
|
-
pivotColumns.forEach(column => {
|
|
1602
|
-
const columnKey = column.name.split('_')[0]; // Get part before aggregation
|
|
1603
|
-
const parts = columnKey.split('|');
|
|
1604
|
-
if (parts.length > level) {
|
|
1605
|
-
const prefix = parts.slice(0, level + 1);
|
|
1606
|
-
const prefixKey = prefix.join('|');
|
|
1607
|
-
if (!groupMap.has(prefixKey)) {
|
|
1608
|
-
groupMap.set(prefixKey, []);
|
|
1609
|
-
}
|
|
1610
|
-
groupMap.get(prefixKey).push(column);
|
|
1611
|
-
}
|
|
1612
|
-
});
|
|
1613
|
-
// Convert map to array format and sort
|
|
1614
|
-
Array.from(groupMap.keys()).sort().forEach(prefixKey => {
|
|
1615
|
-
const prefix = prefixKey.split('|');
|
|
1616
|
-
const columns = groupMap.get(prefixKey);
|
|
1617
|
-
levelGroups.push({ prefix, columns });
|
|
1618
|
-
});
|
|
1619
|
-
groupedByLevel.push(levelGroups);
|
|
1620
|
-
}
|
|
1621
|
-
return groupedByLevel;
|
|
1622
|
-
}
|
|
1623
1406
|
/**
|
|
1624
1407
|
* Create a subtotal column for a specific dimension prefix
|
|
1625
1408
|
*/
|
|
@@ -2066,7 +1849,7 @@ class PivotTransformService {
|
|
|
2066
1849
|
return rowspanInfo;
|
|
2067
1850
|
}
|
|
2068
1851
|
/**
|
|
2069
|
-
* Insert column subtotal headers at the correct positions within each
|
|
1852
|
+
* Insert column subtotal headers at the correct positions within each dimension group
|
|
2070
1853
|
*/
|
|
2071
1854
|
insertColumnSubtotalHeaders(headerRows, columnDimensions, aggregations, gridConfiguration, sourceData) {
|
|
2072
1855
|
const enableColumnSubtotals = gridConfiguration?.config?.enableColumnSubtotals ?? false;
|
|
@@ -2118,8 +1901,7 @@ class PivotTransformService {
|
|
|
2118
1901
|
isSubtotal: true,
|
|
2119
1902
|
dataType: aggregation.datatype || 'textbox'
|
|
2120
1903
|
};
|
|
2121
|
-
//
|
|
2122
|
-
// Priority subtotals go to Rating row (level 1), Rating subtotals go to Status row (level 2)
|
|
1904
|
+
// Place the subtotal one row below the dimension it aggregates
|
|
2123
1905
|
const targetRow = Math.min(level + 1, headerRows.length - 1);
|
|
2124
1906
|
headerRows[targetRow].push(subtotalHeader);
|
|
2125
1907
|
}
|
|
@@ -2151,56 +1933,46 @@ class PivotTransformService {
|
|
|
2151
1933
|
reorderHeadersByHierarchy(pivotHeaders, subtotalHeaders, rowIndex, columnDimensions, subtotalPositionColumn, sourceData) {
|
|
2152
1934
|
const reordered = [];
|
|
2153
1935
|
if (rowIndex === 0) {
|
|
2154
|
-
//
|
|
1936
|
+
// First dimension level — headers stand on their own
|
|
2155
1937
|
reordered.push(...pivotHeaders);
|
|
2156
1938
|
}
|
|
2157
1939
|
else if (rowIndex === 1) {
|
|
2158
|
-
//
|
|
2159
|
-
// Add parentGroupKey to regular headers based on their position
|
|
1940
|
+
// Second dimension level — interleave its headers with first-level subtotals
|
|
2160
1941
|
this.addParentGroupKeysToHeaders(pivotHeaders, rowIndex, sourceData, columnDimensions);
|
|
2161
|
-
|
|
2162
|
-
const
|
|
2163
|
-
const prioritySubtotals = this.groupSubtotalsByParentKey(subtotalHeaders);
|
|
2164
|
-
// Process each first dimension group in correct order (dynamically extracted)
|
|
1942
|
+
const secondLevelGroups = this.groupHeadersByParentKey(pivotHeaders);
|
|
1943
|
+
const firstLevelSubtotals = this.groupSubtotalsByParentKey(subtotalHeaders);
|
|
2165
1944
|
const firstDimensionValues = this.extractDimensionValues(sourceData, columnDimensions[0]);
|
|
2166
1945
|
firstDimensionValues.forEach(firstDimensionValue => {
|
|
2167
|
-
const
|
|
2168
|
-
const subtotals =
|
|
2169
|
-
// Add rating headers for this priority
|
|
1946
|
+
const secondLevelHeaders = secondLevelGroups[firstDimensionValue] || [];
|
|
1947
|
+
const subtotals = firstLevelSubtotals[firstDimensionValue] || [];
|
|
2170
1948
|
if (subtotalPositionColumn === 'before') {
|
|
2171
|
-
// Add subtotals first, then rating headers
|
|
2172
1949
|
reordered.push(...subtotals);
|
|
2173
|
-
reordered.push(...
|
|
1950
|
+
reordered.push(...secondLevelHeaders);
|
|
2174
1951
|
}
|
|
2175
1952
|
else {
|
|
2176
|
-
|
|
2177
|
-
reordered.push(...ratingHeaders);
|
|
1953
|
+
reordered.push(...secondLevelHeaders);
|
|
2178
1954
|
reordered.push(...subtotals);
|
|
2179
1955
|
}
|
|
2180
1956
|
});
|
|
2181
1957
|
}
|
|
2182
1958
|
else if (rowIndex === 2) {
|
|
2183
|
-
//
|
|
1959
|
+
// Third dimension level — interleave its headers with second-level subtotals
|
|
2184
1960
|
this.addParentGroupKeysToHeaders(pivotHeaders, rowIndex, sourceData, columnDimensions);
|
|
2185
|
-
const
|
|
2186
|
-
const
|
|
2187
|
-
console.log(`DEBUG: Status groups with parentKey: ${Object.keys(statusGroups).length}, Rating subtotals: ${Object.keys(ratingSubtotals).length}`);
|
|
2188
|
-
// Process each dimension combination dynamically
|
|
1961
|
+
const thirdLevelGroups = this.groupHeadersByParentKey(pivotHeaders);
|
|
1962
|
+
const secondLevelSubtotals = this.groupSubtotalsByParentKey(subtotalHeaders);
|
|
2189
1963
|
const firstDimensionValues = this.extractDimensionValues(sourceData, columnDimensions[0]);
|
|
2190
1964
|
const secondDimensionValues = this.extractDimensionValues(sourceData, columnDimensions[1]);
|
|
2191
1965
|
firstDimensionValues.forEach(firstDimensionValue => {
|
|
2192
1966
|
secondDimensionValues.forEach(secondDimensionValue => {
|
|
2193
1967
|
const groupKey = `${firstDimensionValue}+${secondDimensionValue}`;
|
|
2194
|
-
const
|
|
2195
|
-
const subtotals =
|
|
1968
|
+
const thirdLevelHeaders = thirdLevelGroups[groupKey] || [];
|
|
1969
|
+
const subtotals = secondLevelSubtotals[groupKey] || [];
|
|
2196
1970
|
if (subtotalPositionColumn === 'before') {
|
|
2197
|
-
// Add subtotals first, then status headers
|
|
2198
1971
|
reordered.push(...subtotals);
|
|
2199
|
-
reordered.push(...
|
|
1972
|
+
reordered.push(...thirdLevelHeaders);
|
|
2200
1973
|
}
|
|
2201
1974
|
else {
|
|
2202
|
-
|
|
2203
|
-
reordered.push(...statusHeaders);
|
|
1975
|
+
reordered.push(...thirdLevelHeaders);
|
|
2204
1976
|
reordered.push(...subtotals);
|
|
2205
1977
|
}
|
|
2206
1978
|
});
|
|
@@ -2225,78 +1997,6 @@ class PivotTransformService {
|
|
|
2225
1997
|
extractAllDimensionValues(sourceData, columnDimensions) {
|
|
2226
1998
|
return columnDimensions.map(dimension => this.extractDimensionValues(sourceData, dimension));
|
|
2227
1999
|
}
|
|
2228
|
-
/**
|
|
2229
|
-
* Group rating headers by their priority parent - GENERIC VERSION
|
|
2230
|
-
*/
|
|
2231
|
-
groupRatingHeadersByPriority(headers, sourceData, columnDimensions) {
|
|
2232
|
-
const groups = {};
|
|
2233
|
-
if (columnDimensions.length >= 2) {
|
|
2234
|
-
const firstDimensionValues = this.extractDimensionValues(sourceData, columnDimensions[0]);
|
|
2235
|
-
const secondDimensionCount = this.extractDimensionValues(sourceData, columnDimensions[1]).length;
|
|
2236
|
-
headers.forEach(header => {
|
|
2237
|
-
const headerIndex = headers.indexOf(header);
|
|
2238
|
-
const firstDimensionIndex = Math.floor(headerIndex / secondDimensionCount);
|
|
2239
|
-
const firstDimensionValue = firstDimensionValues[firstDimensionIndex] || firstDimensionValues[0] || '';
|
|
2240
|
-
if (!groups[firstDimensionValue])
|
|
2241
|
-
groups[firstDimensionValue] = [];
|
|
2242
|
-
groups[firstDimensionValue].push(header);
|
|
2243
|
-
});
|
|
2244
|
-
}
|
|
2245
|
-
return groups;
|
|
2246
|
-
}
|
|
2247
|
-
/**
|
|
2248
|
-
* Group subtotals by their priority
|
|
2249
|
-
*/
|
|
2250
|
-
groupSubtotalsByPriority(subtotals) {
|
|
2251
|
-
const groups = {};
|
|
2252
|
-
subtotals.forEach(subtotal => {
|
|
2253
|
-
if (subtotal.label && subtotal.label.includes('Subtotal')) {
|
|
2254
|
-
const priority = subtotal.label.split(' ')[0]; // Extract "Low", "Medium", "Urgent"
|
|
2255
|
-
if (!groups[priority])
|
|
2256
|
-
groups[priority] = [];
|
|
2257
|
-
groups[priority].push(subtotal);
|
|
2258
|
-
}
|
|
2259
|
-
});
|
|
2260
|
-
return groups;
|
|
2261
|
-
}
|
|
2262
|
-
/**
|
|
2263
|
-
* Group status headers by their rating parent (combination) - GENERIC VERSION
|
|
2264
|
-
*/
|
|
2265
|
-
groupStatusHeadersByRating(headers, sourceData, columnDimensions) {
|
|
2266
|
-
const groups = {};
|
|
2267
|
-
if (columnDimensions.length >= 3) {
|
|
2268
|
-
const firstDimensionValues = this.extractDimensionValues(sourceData, columnDimensions[0]);
|
|
2269
|
-
const secondDimensionValues = this.extractDimensionValues(sourceData, columnDimensions[1]);
|
|
2270
|
-
const thirdDimensionCount = this.extractDimensionValues(sourceData, columnDimensions[2]).length;
|
|
2271
|
-
headers.forEach(header => {
|
|
2272
|
-
const headerIndex = headers.indexOf(header);
|
|
2273
|
-
const secondDimensionIndex = Math.floor(headerIndex / thirdDimensionCount);
|
|
2274
|
-
const firstDimensionIndex = Math.floor(secondDimensionIndex / secondDimensionValues.length);
|
|
2275
|
-
const firstDimensionValue = firstDimensionValues[firstDimensionIndex] || firstDimensionValues[0] || '';
|
|
2276
|
-
const secondDimensionValue = secondDimensionValues[secondDimensionIndex % secondDimensionValues.length] || secondDimensionValues[0] || '';
|
|
2277
|
-
const groupKey = `${firstDimensionValue}+${secondDimensionValue}`;
|
|
2278
|
-
if (!groups[groupKey])
|
|
2279
|
-
groups[groupKey] = [];
|
|
2280
|
-
groups[groupKey].push(header);
|
|
2281
|
-
});
|
|
2282
|
-
}
|
|
2283
|
-
return groups;
|
|
2284
|
-
}
|
|
2285
|
-
/**
|
|
2286
|
-
* Group subtotals by their rating (Priority+Rating combination)
|
|
2287
|
-
*/
|
|
2288
|
-
groupSubtotalsByRating(subtotals) {
|
|
2289
|
-
const groups = {};
|
|
2290
|
-
subtotals.forEach(subtotal => {
|
|
2291
|
-
if (subtotal.label && subtotal.label.includes('+') && subtotal.label.includes('Subtotal')) {
|
|
2292
|
-
const parts = subtotal.label.split(' ')[0]; // Extract "Low+0", "Medium+1", etc.
|
|
2293
|
-
if (!groups[parts])
|
|
2294
|
-
groups[parts] = [];
|
|
2295
|
-
groups[parts].push(subtotal);
|
|
2296
|
-
}
|
|
2297
|
-
});
|
|
2298
|
-
return groups;
|
|
2299
|
-
}
|
|
2300
2000
|
/**
|
|
2301
2001
|
* Add parent group keys to headers based on their position and row level - GENERIC VERSION
|
|
2302
2002
|
*/
|
|
@@ -2307,7 +2007,7 @@ class PivotTransformService {
|
|
|
2307
2007
|
// Extract all dimension values dynamically
|
|
2308
2008
|
const dimensionValues = this.extractAllDimensionValues(sourceData, columnDimensions);
|
|
2309
2009
|
if (rowIndex === 1) {
|
|
2310
|
-
// Second
|
|
2010
|
+
// Second dimension level — assign parent first-dimension group keys
|
|
2311
2011
|
const firstDimensionValues = dimensionValues[0] || [];
|
|
2312
2012
|
if (dimensionValues.length >= 2) {
|
|
2313
2013
|
const secondDimensionCount = dimensionValues[1].length;
|
|
@@ -5805,7 +5505,10 @@ class EruGridComponent {
|
|
|
5805
5505
|
return;
|
|
5806
5506
|
const headerShell = container.querySelector('.header-shell');
|
|
5807
5507
|
const gtShell = container.querySelector('.gt-shell');
|
|
5808
|
-
|
|
5508
|
+
let viewport = container.querySelector('.pivot-viewport');
|
|
5509
|
+
if (!viewport) {
|
|
5510
|
+
viewport = container.querySelector('.table-viewport');
|
|
5511
|
+
}
|
|
5809
5512
|
if (headerShell && viewport) {
|
|
5810
5513
|
// Calculate scrollbar width by comparing viewport dimensions
|
|
5811
5514
|
let scrollbarWidth = viewport.offsetWidth - viewport.clientWidth;
|
|
@@ -5844,7 +5547,7 @@ class EruGridComponent {
|
|
|
5844
5547
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: EruGridComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
|
|
5845
5548
|
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.3", type: EruGridComponent, isStandalone: true, selector: "eru-grid", inputs: { gridConfig: "gridConfig" }, providers: [EruGridStore, EruGridService,
|
|
5846
5549
|
...MATERIAL_PROVIDERS
|
|
5847
|
-
], viewQueries: [{ propertyName: "viewport", first: true, predicate: CdkVirtualScrollViewport, descendants: true }, { propertyName: "rowContainer", first: true, predicate: ["rowContainer"], descendants: true }, { propertyName: "headerScroller", first: true, predicate: ["headerScroller"], descendants: true, read: ElementRef }, { propertyName: "gtScroller", first: true, predicate: ["gtScroller"], descendants: true, read: ElementRef }, { propertyName: "vp", first: true, predicate: ["vp"], descendants: true }], ngImport: i0, template: "<!-- <div style=\"background: #f0f0f0; font-size: 12px; border-bottom: 1px solid #ccc;\">\n currentPivotScrollIndex {{currentPivotScrollIndex()}} | \n firstDataRowIndex {{firstDataRowIndex()}} | \n firstTr {{firstTr}} |\n maxDepth {{maxDepth()}}\n</div> -->\n<div class=\"incremental-row-container eru-grid\" #rowContainer [class.pivot-mode]=\"gridStore.isPivotMode()\"\n [class.table-mode]=\"!gridStore.isPivotMode()\">\n\n <!-- Pivot Mode Template -->\n @if (gridStore.isPivotMode()) {\n <ng-container>\n <div class=\"pivot-container\" style=\"display: flex; flex-direction: column; height: 100%;\"\n [style]=\"'--table-min-height: ' + getInitialMinHeightPx() + 'px; --table-total-width: ' + getInitialTotalWidth() + 'px'\">\n <!-- Debug info for first visible row -->\n\n\n <div class=\"pivot-single-table\"\n style=\"height: 100%; width: 100%; overflow: hidden; display: flex; flex-direction: column;\">\n @if (freezeHeader()) {\n <div #headerScroller class=\"header-shell\">\n <table class=\"eru-grid-table pivot-table\"\n [style]=\"'width: auto; min-width: 100%; --table-total-width: ' + getInitialTotalWidth() + 'px'\"\n [class.show-column-lines]=\"showColumnLines()\" [class.show-row-lines]=\"showRowLines()\">\n <!-- Column Groups for consistent width -->\n <ng-container *ngTemplateOutlet=\"pivotColGroup\"></ng-container>\n\n <ng-container *ngTemplateOutlet=\"pivotTableHead\"></ng-container>\n @if(grandTotalPosition() === 'before' && freezeGrandTotal()) {\n <ng-container *ngTemplateOutlet=\"pivotGrandTotal\"></ng-container>\n }\n </table>\n </div>\n }\n <!-- Virtual Scrolled Table Body -->\n <div>\n <cdk-virtual-scroll-viewport #vp [itemSize]=\"50\" class=\"viewport pivot-viewport\"\n [class.apply-cdk-width]=\"applyCdkWidth()\" (scrolledIndexChange)=\"onPivotScroll($event)\"\n (scroll)=\"onBodyScroll($event)\" style=\"overflow: auto;\">\n <table class=\"eru-grid-table pivot-table\"\n [style]=\"'width: auto; min-width: 100%; --table-total-width: ' + getInitialTotalWidth() + 'px'\"\n [class.show-column-lines]=\"showColumnLines()\" [class.show-row-lines]=\"showRowLines()\">\n <!-- Column Groups for consistent width -->\n <ng-container *ngTemplateOutlet=\"pivotColGroup\"></ng-container>\n\n @if (!freezeHeader()) {\n <ng-container *ngTemplateOutlet=\"pivotTableHead\"></ng-container>\n }\n <!-- Table Body with Virtual Scrolling -->\n <tbody class=\"pivot-tbody\">\n\n <tr *cdkVirtualFor=\"let pivotRow of gridStore.pivotDisplayData(); \n trackBy: trackByPivotRowFn; \n let i = index\" class=\"pivot-row\" [class.subtotal-row]=\"pivotRow._isSubtotal\"\n [class.grand-total-row]=\"pivotRow._isGrandTotal\"\n [class.subtotal-bold]=\"pivotRow._isSubtotal && subTotalStyle() === 'bold'\"\n [class.subtotal-italic]=\"pivotRow._isSubtotal && subTotalStyle() === 'italic'\"\n [class.subtotal-highlighted]=\"pivotRow._isSubtotal && subTotalStyle() === 'highlighted'\"\n [class.grand-total-bold]=\"pivotRow._isGrandTotal && grandTotalStyle() === 'bold'\"\n [class.grand-total-italic]=\"pivotRow._isGrandTotal && grandTotalStyle() === 'italic'\"\n [class.grand-total-highlighted]=\"pivotRow._isGrandTotal && grandTotalStyle() === 'highlighted'\"\n [style.height.px]=\"50\" [attr.data-pivot-row]=\"i\">\n @if ((!pivotRow._isGrandTotal && freezeGrandTotal() ) || (!freezeGrandTotal() )) {\n @for (column of getLeafColumns(); track trackByColumnFn($index, column); let colIndex = $index) {\n @if (!shouldSkipCell(i, column.name)) {\n <td [attr.rowspan]=\"getEffectiveRowspan(i, column.name)\" [style.width.px]=\"column.field_size\"\n [style.minWidth.px]=\"column.field_size\" class=\"pivot-cell\"\n [class.row-dimension-cell]=\"isRowDimensionColumn(column.name)\"\n [class.column-dimension-cell]=\"!isRowDimensionColumn(column.name)\"\n [class.aggregated-value]=\"!isRowDimensionColumn(column.name) && column.datatype === 'number'\"\n [class.rowspan-cell]=\"getEffectiveRowspan(i, column.name) || 1 > 1\"\n [class.sticky-column]=\"isStickyColumn(column.name, colIndex)\"\n [style.position]=\"isStickyColumn(column.name, colIndex) ? 'sticky' : 'static'\"\n [style.left.px]=\"getStickyColumnLeft(column.name, colIndex)\"\n [style.z-index]=\"isStickyColumn(column.name, colIndex) ? 99 : 1\" [style.height.px]=\"50\"\n [attr.xx]=\"i\">\n <div class=\"cell-content pivot-cell-content\">\n <data-cell [class.aggregation]=\"!!column.aggregationFunction\" [fieldSize]=\"column.field_size\"\n [columnDatatype]=\"column.datatype\" [columnName]=\"column.name\"\n [value]=\"getEffectiveCellValue(i,column.name, pivotRow)\" [column]=\"column\"\n [drillable]=\"column.enableDrilldown || false\" [mode]=\"mode()\" [isEditable]=\"isEditable()\"\n [id]=\"'pivot_' + i + '_' + column.name\" [eruGridStore]=\"gridStore\">\n </data-cell>\n </div>\n </td>\n }\n }\n } @else {\n <td [style.height.px]=\"50\" [attr.colspan]=\"getLeafColumns().length\"> </td>\n }\n </tr>\n </tbody>\n </table>\n </cdk-virtual-scroll-viewport>\n\n </div>\n @if (freezeGrandTotal() && grandTotalPosition() === 'after') {\n <div #gtScroller class=\"header-shell gt-shell\" [class.adjust-bottom]=\"!applyCdkWidth()\"\n [class.adjust-bottom-vs]=\"adjustScrollWidth()\">\n <table class=\"eru-grid-table pivot-table\"\n [style]=\"'width: auto; min-width: 100%; --table-total-width: ' + getInitialTotalWidth() + 'px'\"\n [class.show-column-lines]=\"showColumnLines()\" [class.show-row-lines]=\"showRowLines()\">\n <ng-container *ngTemplateOutlet=\"pivotColGroup\"></ng-container>\n\n <ng-container *ngTemplateOutlet=\"pivotGrandTotal\"></ng-container>\n\n </table>\n </div>\n }\n\n\n </div>\n </div>\n </ng-container>\n } @else {\n\n <!-- Table Mode Template -->\n <ng-container>\n <cdk-virtual-scroll-viewport [itemSize]=\"30\" class=\"viewport table-viewport\"\n (scrolledIndexChange)=\"onScroll($event)\"\n [style]=\"'--table-min-height: ' + getInitialMinHeightPx() + 'px; --table-total-width: ' + getInitialTotalWidth() + 'px'\">\n <div class=\"table-wrapper\">\n\n <table class=\"eru-grid-table\" [class.show-column-lines]=\"showColumnLines()\"\n [class.show-row-lines]=\"showRowLines()\">\n <thead>\n <tr>\n @if(gridStore.configuration().config.allowSelection) {\n <th class=\"checkbox-column\"></th>\n }\n @if(shouldShowActionColumn('before')) {\n <th class=\"action-column column-header table-column-header\"\n style=\"width: 40px; min-width: 40px; max-width: 40px;\">\n Action\n </th>\n }\n <th *ngFor=\"let column of columns(); trackBy: trackByColumnFn\" [style.width.px]=\"column.field_size\"\n [resizeColumn]=\"gridStore.isFeatureEnabled('columnResizable')\" [style.minWidth.px]=\"column.field_size\"\n class=\"column-header table-column-header\">\n {{column.label}}\n </th>\n @if(shouldShowActionColumn('after')) {\n <th class=\"action-column column-header table-column-header\"\n style=\"width: 40px; min-width: 40px; max-width: 40px;\">\n Action\n </th>\n }\n </tr>\n </thead>\n <tbody *ngIf=\"columns() as columnsList\">\n <ng-container *cdkVirtualFor=\"let groupItem of groupedRows();\n trackBy: trackByGroupItemFn;\n let i = index;\n let first=first\">\n <tr *ngIf=\"groupItem.type === 'header' && groups().length > 1\" class=\"group-header\"\n (click)=\"toggleGroupExpansion(groupItem.group?.id || '')\">\n\n <td class=\"checkbox-column\" style=\"border: none;\">\n {{ groupItem.group?.isExpanded ? '\u25BC' : '\u25B6' }}\n </td>\n\n <td [attr.colspan]=\"2\" style=\"border: none;\">\n <span class=\"group-title\">\n {{ groupItem.group?.title }}\n </span>\n <span class=\"group-row-count\">\n ({{ groupItem.group?.currentLoadedRows || 0 }}/{{ groupItem.group?.totalRowCount || 0 }})\n </span>\n </td>\n </tr>\n <tr *ngIf=\"groupItem.type === 'table-header' && groups().length > 1\" style=\"background:#fafafa\">\n @if(gridStore.configuration().config.allowSelection) {\n <th class=\"checkbox-column\" style=\"text-align: center;\">\n <input type=\"checkbox\" [checked]=\"isGroupSelected(groupItem.group?.id || '')\"\n (click)=\"$event.stopPropagation()\"\n (change)=\"toggleGroupSelection($event, groupItem.group?.id || '')\">\n </th>\n }\n @if(shouldShowActionColumn('before')) {\n <td class=\"action-column\"\n style=\"width: 40px; min-width: 40px; max-width: 40px; text-align: center; cursor: pointer;\">\n @if (gridActions().length > 0) {\n <mat-icon [matMenuTriggerFor]=\"actionMenu\"\n [matMenuTriggerData]=\"{row: groupItem.row}\">more_horiz</mat-icon>\n } @else {\n <mat-icon (click)=\"onActionClick($event, groupItem.row)\">more_horiz</mat-icon>\n }\n </td>\n }\n <th *ngFor=\"let column of columns(); trackBy: trackByColumnFn;let i =index\" style=\"text-align: center;\"\n [style.width.px]=\"column.field_size\" [style.minWidth.px]=\"column.field_size\" [resizeColumn]=\"true\"\n [columnConfig]=\"column\" [columnDraggable]=\"i\" class=\"column-header\">\n <div class=\"column-drag-handle\"></div>\n {{column.label}} {{column.symbol}}\n </th>\n @if(shouldShowActionColumn('after')) {\n <td class=\"action-column\"\n style=\"width: 40px; min-width: 40px; max-width: 40px; text-align: center; cursor: pointer;\">\n @if (gridActions().length > 0) {\n <mat-icon [matMenuTriggerFor]=\"actionMenu\"\n [matMenuTriggerData]=\"{row: groupItem.row}\">more_horiz</mat-icon>\n } @else {\n <mat-icon (click)=\"onActionClick($event, groupItem.row)\">more_horiz</mat-icon>\n }\n </td>\n }\n </tr>\n <tr *ngIf=\"groupItem.type === 'row' && groupItem.group?.isExpanded\" class=\"row-item\"\n [attr.data-row-id]=\"groupItem.row?.entity_id\" [style.height.px]=\"30\" [style.minHeight.px]=\"30\"\n [style.maxHeight.px]=\"30\">\n @if(gridStore.configuration().config.allowSelection) {\n <td class=\"checkbox-column\" style=\"text-align: center;\">\n <input type=\"checkbox\" [checked]=\"isRowSelected(groupItem.row?.entity_id)\"\n (change)=\"toggleRowSelection($event, groupItem.row)\">\n </td>\n }\n @if(shouldShowActionColumn('before')) {\n <td class=\"action-column\"\n style=\"width: 40px; min-width: 40px; max-width: 40px; text-align: center; cursor: pointer;\">\n @if (gridActions().length > 0) {\n <mat-icon [matMenuTriggerFor]=\"actionMenu\"\n [matMenuTriggerData]=\"{row: groupItem.row}\">more_horiz</mat-icon>\n } @else {\n <mat-icon (click)=\"onActionClick($event, groupItem.row)\">more_horiz</mat-icon>\n }\n </td>\n }\n <td #cell *ngFor=\"let column of columns(); trackBy: trackByColumnFn\"\n [style.width.px]=\"column.field_size\" [style.minWidth.px]=\"column.field_size\" class=\"data-cell\"\n [style.height.px]=\"30\" [style.minHeight.px]=\"30\" [style.maxHeight.px]=\"30\"\n [matTooltipClass]=\"'error-message'\" [matTooltip]=\"datacell.error()?'Error: ' + datacell.error():''\"\n matTooltipPosition=\"below\">\n <div class=\"cell-content\">\n <data-cell #datacell [td]=cell [fieldSize]=\"column.field_size\" [columnDatatype]=\"column.datatype\"\n [columnName]=\"column.name\" [value]=\"groupItem.row?.[column.name] || ''\" [column]=\"column\"\n [mode]=\"mode()\" [isEditable]=\"isEditable()\" [drillable]=\"column.enableDrilldown || false\"\n [id]=\"i + '_' + column.name\" [eruGridStore]=\"gridStore\"></data-cell>\n </div>\n </td>\n @if(shouldShowActionColumn('after')) {\n <td class=\"action-column\"\n style=\"width: 40px; min-width: 40px; max-width: 40px; text-align: center; cursor: pointer;\">\n @if (gridActions().length > 0) {\n <mat-icon [matMenuTriggerFor]=\"actionMenu\"\n [matMenuTriggerData]=\"{row: groupItem.row}\">more_horiz</mat-icon>\n } @else {\n <mat-icon (click)=\"onActionClick($event, groupItem.row)\">more_horiz</mat-icon>\n }\n </td>\n }\n </tr>\n\n <tr *ngIf=\"groupItem.type === 'ghost-loading' && groupItem.group?.isExpanded\" class=\"ghost-loading-row\"\n [style.height.px]=\"30\" [style.minHeight.px]=\"30\" [style.maxHeight.px]=\"30\">\n @if(gridStore.configuration().config.allowSelection) {\n <th class=\"checkbox-column\"></th>\n }\n @if(shouldShowActionColumn('before')) {\n <td class=\"action-column ghost-cell-container\" style=\"width: 40px; min-width: 40px; max-width: 40px;\">\n <div class=\"ghost-cell\"></div>\n </td>\n }\n <td *ngFor=\"let column of columns(); trackBy: trackByColumnFn\" [style.width.px]=\"column.field_size\"\n [style.minWidth.px]=\"column.field_size\" class=\"ghost-cell-container\">\n <div class=\"ghost-cell\"></div>\n </td>\n @if(shouldShowActionColumn('after')) {\n <td class=\"action-column ghost-cell-container\" style=\"width: 40px; min-width: 40px; max-width: 40px;\">\n <div class=\"ghost-cell\"></div>\n </td>\n }\n </tr>\n\n <tr *ngIf=\"groupItem.type === 'row-place-holder'\" class=\"group-separator\">\n <td [attr.colspan]=\"groupSeperatorColSpan()\" class=\"separator-cell\"></td>\n </tr>\n </ng-container>\n </tbody>\n </table>\n </div>\n </cdk-virtual-scroll-viewport>\n </ng-container>\n }\n</div>\n\n<!-- Pivot Table Header Template -->\n<ng-template #pivotTableHead>\n <thead>\n @if (hasNestedHeaders()) {\n <ng-container>\n @for (headerRow of getHeaderRows(); track headerRow; let rowIndex = $index) {\n <tr class=\"pivot-header pivot-header-container\" [class.pivot-header-level]=\"'level-' + rowIndex\">\n @for (header of headerRow; track trackByHeaderFn($index, header); let colIndex = $index) {\n <th [attr.colspan]=\"header.colspan\" [attr.rowspan]=\"header.rowspan\"\n [resizeColumn]=\"gridStore.isFeatureEnabled('columnResizable') && header.level === 0\"\n class=\"column-header pivot-column-header nested-header\"\n [class.row-dimension-header]=\"isRowDimensionHeader(header)\"\n [class.column-dimension-header]=\"!isRowDimensionHeader(header)\" [class.expanded]=\"header.isExpanded\"\n [class.collapsed]=\"!header.isExpanded\" [class.sticky-column]=\"isStickyColumn(header.name, colIndex)\"\n [style.position]=\"isStickyColumn(header.name, colIndex) ? 'sticky' : 'static'\"\n [style.left.px]=\"getStickyColumnLeft(header.name, colIndex)\"\n [style.z-index]=\"isStickyColumn(header.name, colIndex) ? 100 : 1\"\n style=\"min-height: 40px; height: auto; padding: 8px 6px;\">\n <div class=\"header-content\">\n\n <data-cell [fieldSize]=\"header.field_size\" [columnDatatype]=\"header.dataType\" [columnName]=\"header.name\"\n [value]=\"header.label\" [column]=\"header\" [frozenGrandTotalCell]=\"true\"\n [drillable]=\"header.enableDrilldown || false\" [mode]=\"mode()\" [isEditable]=\"isEditable()\"\n [id]=\"'pivot_' + $index + '_' + header.name\" [eruGridStore]=\"gridStore\">\n </data-cell>\n <!-- <span class=\"header-label header-wrap-text\">{{header.label}}</span> -->\n <!-- <button *ngIf=\"!isRowDimensionHeader(header)\" \n class=\"collapse-toggle-btn\"\n [title]=\"header.isExpanded ? 'Collapse group' : 'Expand group'\"\n (click)=\"toggleColumnGroup(header.groupKey)\"\n type=\"button\">\n <span class=\"collapse-icon\">+</span>\n </button> -->\n </div>\n </th>\n }\n </tr>\n }\n </ng-container>\n } @else {\n <!-- Simple header fallback -->\n <ng-container>\n <tr class=\"pivot-header\" [class.freeze-header-enabled]=\"freezeHeader()\">\n @for (column of getLeafColumns(); track trackByColumnFn($index, column); let colIndex = $index) {\n <th [style.width.px]=\"column.field_size\" [style.minWidth.px]=\"column.field_size\"\n [resizeColumn]=\"gridStore.isFeatureEnabled('columnResizable')\" [columnConfig]=\"column\"\n class=\"column-header pivot-column-header\" [class.sticky-column]=\"isStickyColumn(column.name, colIndex)\"\n [style.position]=\"isStickyColumn(column.name, colIndex) ? 'sticky' : 'static'\"\n [style.left.px]=\"getStickyColumnLeft(column.name, colIndex)\"\n [style.z-index]=\"isStickyColumn(column.name, colIndex) ? 100 : 1\"\n style=\"min-height: 40px;height: auto;padding: 8px 6px;position: relative;left: 0px;z-index: 1\">\n {{column.label}}\n </th>\n }\n </tr>\n </ng-container>\n }\n\n </thead>\n</ng-template>\n\n<!-- Column Group Template for consistent column widths -->\n<ng-template #pivotColGroup>\n <colgroup>\n @for (column of getLeafColumns(); track trackByColumnFn($index, column)) {\n <col\n [style]=\"'width: ' + column.field_size + 'px !important; min-width: ' + column.field_size + 'px !important; max-width: ' + column.field_size + 'px !important; --col-width: ' + column.field_size + 'px'\">\n }\n </colgroup>\n</ng-template>\n\n<ng-template #pivotGrandTotal>\n <tbody class=\"pivot-tbody\">\n @for (pivotRow of gridStore.pivotGrandTotalData(); track trackByPivotRowFn($index, pivotRow); let i = $index) {\n <tr class=\"pivot-row grand-total-row\"\n [class.grand-total-bold]=\"pivotRow._isGrandTotal && grandTotalStyle() === 'bold'\"\n [class.grand-total-italic]=\"pivotRow._isGrandTotal && grandTotalStyle() === 'italic'\"\n [class.grand-total-highlighted]=\"pivotRow._isGrandTotal && grandTotalStyle() === 'highlighted'\"\n [style.height.px]=\"50\" [attr.data-pivot-row]=\"i\">\n <!-- <td colspan=\"20\">{{pivotRow | json}}</td> -->\n @for (column of getLeafColumns(); track trackByColumnFn($index, column); let colIndex = $index) {\n <td [attr.rowspan]=\"getEffectiveRowspan(i, column.name)\" [style.width.px]=\"column.field_size\"\n [style.minWidth.px]=\"column.field_size\" class=\"pivot-cell\"\n [class.row-dimension-cell]=\"isRowDimensionColumn(column.name)\"\n [class.column-dimension-cell]=\"!isRowDimensionColumn(column.name)\"\n [class.aggregated-value]=\"!isRowDimensionColumn(column.name) && column.datatype === 'number'\"\n [class.rowspan-cell]=\"getEffectiveRowspan(i, column.name) || 1 > 1\"\n [class.sticky-column]=\"isStickyColumn(column.name, colIndex)\"\n [style.position]=\"isStickyColumn(column.name, colIndex) ? 'sticky' : 'static'\"\n [style.left.px]=\"getStickyColumnLeft(column.name, colIndex)\"\n [style.z-index]=\"isStickyColumn(column.name, colIndex) ? 99 : 1\" [style.height.px]=\"50\" [attr.xx]=\"i\">\n <div class=\"cell-content pivot-cell-content\">\n <data-cell [fieldSize]=\"column.field_size\" [columnDatatype]=\"column.datatype\" [columnName]=\"column.name\"\n [value]=\"getEffectiveCellValue(i,column.name, pivotRow)\" [column]=\"column\" [frozenGrandTotalCell]=\"true\"\n [drillable]=\"column.enableDrilldown || false\" [mode]=\"mode()\" [isEditable]=\"isEditable()\"\n [id]=\"'pivot_' + i + '_' + column.name\" [eruGridStore]=\"gridStore\">\n </data-cell>\n </div>\n </td>\n }\n </tr>\n }\n </tbody>\n</ng-template>\n\n<mat-menu #actionMenu=\"matMenu\">\n <ng-template matMenuContent let-row=\"row\">\n @for (item of gridActions(); track item.action) {\n <button mat-menu-item (click)=\"onActionClick($event, row, item)\">\n @if (item.icon) {\n <mat-icon class=\"action-icon\" fontIcon=\"{{item.icon}}\"></mat-icon>\n }\n <span>{{item.menu}}</span>\n </button>\n }\n </ng-template>\n</mat-menu>", styles: ["@charset \"UTF-8\";:host{display:block;width:100%;height:100%;font-family:var(--grid-font-family);--grid-primary: #6750a4;--grid-on-primary: #ffffff;--grid-surface: #fef7ff;--grid-surface-variant: #e7e0ec;--grid-surface-container: #f3edf7;--grid-surface-container-high: #ede7f0;--grid-on-surface: #1d1b20;--grid-on-surface-variant: #49454f;--grid-outline: #79757f;--grid-outline-variant: #cac4d0;--grid-error: #ba1a1a;--grid-error-container: #ffdad6;--grid-font-family: \"Poppins\", \"Roboto\", -apple-system, BlinkMacSystemFont, \"Segoe UI\", sans-serif;--grid-font-size-body: 12px;--grid-font-size-caption: 12px !important;--grid-line-height-body: 1;--grid-aggregation-text-align: right;--grid-number-text-align: right;--grid-spacing-xxs: 2px;--grid-spacing-xs: 4px;--grid-spacing-sm: 8px;--grid-spacing-md: 16px;--grid-spacing-lg: 24px;--grid-border-radius: 4px;--grid-elevation-1: 0px 1px 2px 0px rgba(0, 0, 0, .3), 0px 1px 3px 1px rgba(0, 0, 0, .15);--grid-elevation-2: 0px 1px 2px 0px rgba(0, 0, 0, .3), 0px 2px 6px 2px rgba(0, 0, 0, .15)}.incremental-row-container{padding:10px;width:100%;height:100%;min-height:var(--table-min-height, 400px);max-height:none;overflow:auto;position:relative;background-color:var(--grid-surface);border-radius:var(--grid-border-radius);box-shadow:var(--grid-elevation-1);font-family:var(--grid-font-family)}.viewport{overflow-x:auto;overflow-y:auto;background-color:var(--grid-surface);scrollbar-gutter:stable}.viewport.apply-cdk-width{width:calc(var(--table-total-width) + 10px)!important}.table-viewport{background-color:var(--grid-surface);height:auto;min-height:var(--table-min-height, 300px);max-height:80vh;overflow-x:auto;overflow-y:auto}.pivot-viewport{min-height:var(--table-min-height, 300px);overflow-x:auto;overflow-y:auto;background-color:var(--grid-surface)}.pivot-viewport .cdk-virtual-scroll-content-wrapper{width:auto;height:auto}.table-wrapper{min-width:100%;overflow-x:visible}.incremental-row-container .eru-grid-table,.eru-grid-table{width:100%!important;border-collapse:separate;border-spacing:0;table-layout:fixed!important;background-color:var(--grid-surface);color:var(--grid-on-surface);font-size:var(--grid-font-size-body);line-height:var(--grid-line-height-body)}.eru-grid-table th,.eru-grid-table td{text-align:left;overflow:hidden!important;text-overflow:ellipsis!important;white-space:nowrap!important;background-color:var(--grid-surface);color:var(--grid-on-surface);min-width:0;max-width:100%!important;box-sizing:border-box;position:relative}.eru-grid-table th:hover,.eru-grid-table td:hover{background-color:var(--grid-surface-variant)}.eru-grid-table thead{background-color:var(--grid-surface-container);transform:translateZ(0);will-change:transform;backface-visibility:hidden}.eru-grid-table thead.freeze-header-enabled{box-shadow:0 2px 4px #0000001a;border-bottom:2px solid var(--grid-outline)}.eru-grid-table thead th{background-color:var(--grid-surface-container);color:var(--grid-on-surface);font-weight:500;font-size:var(--grid-font-size-caption)}.checkbox-column{width:50px;min-width:50px;max-width:50px;text-align:center;background-color:var(--grid-surface-container)}.checkbox-column input[type=checkbox]{width:16px;height:16px;cursor:pointer;accent-color:var(--grid-primary);border-radius:var(--grid-border-radius)}.checkbox-column input[type=checkbox]:focus{outline:2px solid var(--grid-primary);outline-offset:2px}.group-header{background-color:var(--grid-surface-container);color:var(--grid-on-surface);font-size:var(--grid-font-size-caption);font-weight:500;border-bottom:1px solid var(--grid-outline);cursor:pointer;transition:background-color .2s ease}.group-header:hover{background-color:var(--grid-surface-container-high)}.group-header .group-title{font-weight:600;color:var(--grid-primary)}.group-header .group-row-count{color:var(--grid-on-surface-variant);font-size:var(--grid-font-size-caption);margin-left:var(--grid-spacing-sm)}.row-item{border:1px solid var(--grid-outline);background-color:var(--grid-surface);transition:background-color .2s ease,box-shadow .2s ease}.row-item:hover{background-color:var(--grid-surface-variant);box-shadow:var(--grid-elevation-1)}.table-column-header{padding:12px 8px}.column-header{font-weight:500;text-align:center!important;font-size:var(--grid-font-size-caption, 12px);position:relative;-webkit-user-select:none;user-select:none;background-color:var(--grid-surface-container);color:var(--grid-on-surface)}.column-header:hover{background-color:var(--grid-surface-container-high)}.column-drag-handle{position:absolute;left:0;top:0;bottom:0;width:12px;cursor:grab;opacity:0;transition:opacity .2s ease,background-color .2s ease;z-index:2;display:flex;align-items:center;justify-content:center;border-right:1px solid transparent}.column-drag-handle:after{content:\"\\22ee\\22ee\";font-size:14px;color:var(--grid-on-surface-variant);transform:rotate(90deg)}.column-drag-handle:hover{background-color:var(--grid-surface-container-high);border-right-color:var(--grid-outline)}.column-header:hover .column-drag-handle{opacity:1}.column-drag-handle:active{cursor:grabbing}.dragging{opacity:1;background-color:var(--grid-surface-container);box-shadow:var(--grid-elevation-2)}.drag-over{background-color:var(--grid-surface-container);border-color:var(--grid-primary)}.data-cell{background-color:var(--grid-surface);color:var(--grid-on-surface);font-size:var(--grid-font-size-body)}.cell-content{align-items:center}.cell-content .mdc-text-field{padding:0px var(--grid-spacing-xxs)!important}.cell-display-text{align-items:center;padding:0px var(--grid-spacing-xs)}.ghost-loading-row{background-color:transparent}.ghost-cell-container{padding:var(--grid-spacing-sm)}.ghost-cell{height:20px;width:100%;background-color:var(--grid-surface-container);animation:pulse 1.5s ease-in-out infinite;border-radius:var(--grid-border-radius)}@keyframes pulse{0%,to{opacity:1}50%{opacity:.5}}.resizing{cursor:col-resize;-webkit-user-select:none;user-select:none}.column-resizer{position:absolute;right:0;top:0;bottom:0;width:4px;cursor:col-resize;background-color:transparent;transition:background-color .2s ease}.column-resizer:hover{background-color:var(--grid-primary)}.group-separator{height:var(--grid-spacing-sm);background-color:var(--grid-surface-variant)}.group-separator .separator-cell{background-color:var(--grid-surface-variant);border:none;height:var(--grid-spacing-sm)}.error-state{background-color:var(--grid-error-container);color:var(--grid-error);border-color:var(--grid-error)}.error-message{background-color:var(--grid-error);color:#fff;padding:var(--grid-spacing-sm);border-radius:var(--grid-border-radius);font-size:var(--grid-font-size-caption)}.incremental-row-container .eru-grid-table tbody,.incremental-row-container .eru-grid-table{position:relative}.incremental-row-container .eru-grid-table.show-column-lines{border-right:var(--grid-outline-width, 1px) solid var(--grid-outline, #e0e0e0)!important;border-top:var(--grid-outline-width, 1px) solid var(--grid-outline, #e0e0e0)!important;border-bottom:var(--grid-outline-width, 1px) solid var(--grid-outline, #e0e0e0)!important}.incremental-row-container .eru-grid-table:not(.show-column-lines){border:var(--grid-outline-width, 1px) solid var(--grid-outline, #e0e0e0)!important}.incremental-row-container .eru-grid-table thead:after{content:\"\";position:absolute;bottom:0;left:0;right:0;height:calc(var(--grid-outline-width, 1px) * 2);background-color:var(--grid-outline, #e0e0e0);pointer-events:none;z-index:10}.incremental-row-container .eru-grid-table.show-column-lines thead th{border-left:var(--grid-outline-width, 1px) solid var(--grid-outline, #e0e0e0)!important;border-bottom:var(--grid-outline-width, 1px) solid var(--grid-outline, #e0e0e0)!important}.incremental-row-container .eru-grid-table.show-column-lines tbody td{border-left:var(--grid-outline-width, 1px) solid var(--grid-outline, #e0e0e0)!important}.incremental-row-container .eru-grid-table.show-row-lines thead th{border-left:var(--grid-outline-width, 1px) solid var(--grid-outline, #e0e0e0)!important;border-bottom:var(--grid-outline-width, 1px) solid var(--grid-outline, #e0e0e0)!important}.incremental-row-container .eru-grid-table.show-row-lines tbody td{border-bottom:var(--grid-outline-width, 1px) solid var(--grid-outline, #e0e0e0)!important}@media (max-width: 768px){.incremental-row-container{height:600px}.eru-grid-table th,.eru-grid-table td{font-size:var(--grid-font-size-caption)}.checkbox-column{width:40px;min-width:40px;max-width:40px}}@media (prefers-contrast: high){.eru-grid-table th,.eru-grid-table td{border-width:2px}.row-item:hover{border-width:2px;border-color:var(--grid-primary)}}@media (prefers-reduced-motion: reduce){.row-item,.column-drag-handle,.ghost-cell{transition:none;animation:none}}.pivot-table .nested-header{text-align:center;font-weight:600;background:var(--grid-surface-container)}.pivot-table .nested-header.row-dimension-header{background:var(--grid-surface-container);font-weight:600}.pivot-table .pivot-header-leafcols{padding:0;margin:0;height:0}.pivot-table .pivot-header-level.level-0 .nested-header{font-size:14px;padding:12px 8px}.pivot-table .pivot-header-level.level-1 .nested-header{font-size:13px;padding:10px 6px}.pivot-table .pivot-header-level.level-2 .nested-header{font-size:12px;padding:8px 4px}.pivot-table .nested-header:hover{background:var(--grid-surface-variant);color:var(--grid-primary);transition:all .2s ease}.pivot-table .pivot-cell.aggregated-value{font-weight:500;font-family:Roboto Mono,monospace}.pivot-table .pivot-cell-content{display:flex;justify-content:center;align-items:center;min-height:38px}.pivot-table .rowspan-cell{vertical-align:middle}.pivot-table .rowspan-cell .pivot-cell-content{height:100%}.pivot-mode .incremental-row-container{display:flex;flex-direction:column;height:auto;max-height:85vh;overflow:auto}.pivot-mode .h-shell{position:relative;width:calc(100% - var(--scrollbar-width, 17px))!important;top:0;z-index:1;overflow-x:hidden;overflow-y:hidden;scrollbar-width:none;-ms-overflow-style:none}.pivot-mode .h-shell::-webkit-scrollbar{display:none}.pivot-mode .gt-shell{position:relative;bottom:50px;flex-shrink:0;overflow-x:hidden;overflow-y:hidden;scrollbar-width:none;-ms-overflow-style:none}.pivot-mode .gt-shell::-webkit-scrollbar{display:none}.pivot-mode .gt-shell table{border-bottom:var(--grid-outline-width, 1px) solid var(--grid-outline, #e0e0e0)!important}.pivot-mode .gt-shell.adjust-bottom-vs{bottom:66px!important}.pivot-mode .gt-shell.adjust-bottom:not(.adjust-bottom-vs){bottom:calc(66px - var(--scrollbar-width, 17px))!important}.pivot-mode .header-shell{flex-shrink:0;width:100%;box-sizing:border-box;padding-right:var(--scrollbar-width, 17px);overflow-x:auto;overflow-y:hidden;scrollbar-width:none;-ms-overflow-style:none}.pivot-mode .header-shell::-webkit-scrollbar{display:none}.pivot-mode .header-shell.apply-cdk-width{width:calc(var(--table-total-width) + 10px)!important}.pivot-mode .header-shell .eru-grid-table{margin-bottom:0;width:100%;table-layout:fixed}.pivot-mode .header-shell .eru-grid-table thead{background:var(--grid-surface-container)}.pivot-mode .header-shell .eru-grid-table thead th{background:var(--grid-surface-container);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;width:var(--col-width)!important;min-width:var(--col-width)!important;max-width:var(--col-width)!important}.pivot-mode .header-shell .eru-grid-table thead th.sticky-column{position:sticky;background:var(--grid-surface-container);z-index:111}.pivot-mode .header-shell .eru-grid-table tbody td{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;width:var(--col-width)!important;min-width:var(--col-width)!important;max-width:var(--col-width)!important}.pivot-mode .pivot-container{display:flex;flex-direction:column;height:100%;width:100%;overflow:hidden}.pivot-mode .pivot-table{width:auto!important;min-width:100%!important;table-layout:fixed!important;width:100%!important}.pivot-mode .pivot-table colgroup col{width:var(--col-width)!important;min-width:var(--col-width)!important;max-width:var(--col-width)!important;flex:none!important;flex-shrink:0!important;flex-grow:0!important}.pivot-mode .pivot-table td,.pivot-mode .pivot-table th{box-sizing:border-box!important;flex:none!important;flex-shrink:0!important;flex-grow:0!important;word-wrap:break-word!important;word-break:break-all!important}.pivot-mode .pivot-table *{max-width:var(--col-width)!important;box-sizing:border-box!important}.pivot-mode .pivot-table colgroup{width:100%!important}.pivot-mode .pivot-table colgroup col{width:var(--col-width)!important;min-width:var(--col-width)!important;max-width:var(--col-width)!important;flex-basis:var(--col-width)!important;flex:0 0 var(--col-width)!important}.pivot-mode .pivot-table table{width:100%!important;table-layout:fixed!important;border-collapse:collapse!important;border-spacing:0!important}.pivot-mode .pivot-table[style*=--table-total-width]{width:var(--table-total-width)!important;min-width:var(--table-total-width)!important;max-width:var(--table-total-width)!important}.pivot-mode .pivot-table colgroup col{width:var(--col-width)!important;min-width:var(--col-width)!important;max-width:var(--col-width)!important;flex:0 0 var(--col-width)!important;flex-basis:var(--col-width)!important;flex-grow:0!important;flex-shrink:0!important;overflow:hidden!important}.pivot-mode .pivot-table tbody td,.pivot-mode .pivot-table thead th{width:var(--col-width)!important;min-width:var(--col-width)!important;max-width:var(--col-width)!important;overflow:hidden!important;text-overflow:ellipsis!important;white-space:nowrap!important}.pivot-mode .pivot-table .cell-content,.pivot-mode .pivot-table data-cell{width:100%!important;max-width:100%!important;overflow:hidden!important;text-overflow:ellipsis!important;white-space:nowrap!important;display:block!important}.pivot-mode .pivot-table table{width:var(--table-total-width)!important;min-width:var(--table-total-width)!important;max-width:var(--table-total-width)!important;table-layout:fixed!important;border-collapse:collapse!important;border-spacing:0!important;word-wrap:break-word!important;word-break:break-all!important}.pivot-mode .pivot-tbody tr.pivot-row{min-height:50px!important;height:50px!important}.pivot-mode .pivot-tbody tr.pivot-row:hover{background-color:var(--grid-surface-variant)}.pivot-mode .pivot-tbody tr.pivot-row:nth-child(2n){background-color:#00000005}.pivot-mode .pivot-tbody tr.pivot-row td{min-height:50px!important;height:50px!important;vertical-align:middle;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;width:var(--col-width)!important;min-width:var(--col-width)!important;max-width:var(--col-width)!important}.pivot-mode .pivot-tbody tr.pivot-row td .cell-content{min-height:48px;display:flex;align-items:center;justify-content:center}.pivot-mode .pivot-tbody tr.pivot-row td .cell-content data-cell{width:100%;min-height:46px;display:flex;align-items:center;justify-content:center;overflow:hidden;flex-shrink:0}.pivot-mode .pivot-cell{vertical-align:middle;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;width:var(--col-width)!important;min-width:var(--col-width)!important;max-width:var(--col-width)!important}.pivot-mode .pivot-cell.aggregated-value{font-weight:500;font-family:Roboto Mono,monospace}.pivot-mode .pivot-cell .cell-content{display:flex;justify-content:center;align-items:center;min-height:40px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;flex-shrink:0}.pivot-mode .pivot-table .subtotal-row{background-color:var(--grid-surface-container)!important;font-weight:600}.pivot-mode .pivot-table .subtotal-row td{background-color:var(--grid-surface-container);color:var(--grid-on-surface-variant)}.pivot-mode .pivot-table .subtotal-row td:first-child{color:var(--grid-primary)}.pivot-mode .pivot-table .subtotal-row td.aggregated-value{font-weight:500;color:var(--grid-primary)}.pivot-mode .pivot-table .subtotal-row:hover{background-color:var(--grid-surface-container-high)!important}.pivot-mode .pivot-table .subtotal-row:hover td{background-color:var(--grid-surface-container-high)}.pivot-mode .pivot-table .subtotal-bold td{font-weight:600!important;font-style:normal!important}.pivot-mode .pivot-table .subtotal-bold td.aggregated-value{font-weight:600!important}.pivot-mode .pivot-table .subtotal-italic td{font-style:italic!important}.pivot-mode .pivot-table .subtotal-italic td:first-child{font-weight:600!important}.pivot-mode .pivot-table .subtotal-italic td.aggregated-value{font-style:italic!important;font-weight:500!important}.pivot-mode .pivot-table .subtotal-highlighted{background-color:var(--grid-surface-variant)!important}.pivot-mode .pivot-table .subtotal-highlighted td{background-color:var(--grid-surface-variant)!important;font-weight:700!important;font-style:normal!important;color:var(--grid-primary)!important}.pivot-mode .pivot-table .subtotal-highlighted td.aggregated-value{font-weight:500!important;color:var(--grid-primary)!important}.pivot-mode .pivot-table .subtotal-highlighted:hover,.pivot-mode .pivot-table .subtotal-highlighted:hover td{background-color:var(--grid-surface-container-high)!important}.pivot-mode .pivot-table .grand-total-row{background-color:var(--grid-surface-container-high)!important;font-weight:700;font-size:var(--grid-font-size-body)}.pivot-mode .pivot-table .grand-total-row td{background-color:var(--grid-surface-container-high)!important;color:var(--grid-on-surface)}.pivot-mode .pivot-table .grand-total-row td:first-child{font-style:normal;font-weight:800;color:var(--grid-primary)}.pivot-mode .pivot-table .grand-total-row td.aggregated-value{font-weight:500;color:var(--grid-primary);font-family:Roboto Mono,monospace}.pivot-mode .pivot-table .grand-total-row:hover,.pivot-mode .pivot-table .grand-total-row:hover td{background-color:var(--grid-surface-container-high)!important}.pivot-mode .pivot-table .grand-total-bold td{font-weight:700!important;font-style:normal!important}.pivot-mode .pivot-table .grand-total-bold td.aggregated-value{font-weight:700!important}.pivot-mode .pivot-table .grand-total-italic td,.pivot-mode .pivot-table .grand-total-italic td.aggregated-value{font-style:italic!important;font-weight:500!important}.pivot-mode .pivot-table .grand-total-highlighted{background-color:var(--grid-primary)!important;box-shadow:var(--grid-elevation-2)!important}.pivot-mode .pivot-table .grand-total-highlighted td{background-color:var(--grid-primary)!important;color:var(--grid-on-primary)!important;font-weight:500!important;font-style:normal!important}.pivot-mode .pivot-table .grand-total-highlighted td.aggregated-value{color:var(--grid-on-primary)!important;font-weight:500!important}.pivot-mode .pivot-table .grand-total-highlighted:hover,.pivot-mode .pivot-table .grand-total-highlighted:hover td{background-color:var(--grid-primary)!important}.pivot-mode .pivot-table .collapsible-header{position:relative}.pivot-mode .pivot-table .collapsible-header .header-content{display:flex;align-items:center;justify-content:space-between;gap:var(--grid-spacing-xs);padding:var(--grid-spacing-xs) var(--grid-spacing-sm)}.pivot-mode .pivot-table .collapsible-header .header-label{flex:1;font-weight:600}.pivot-mode .pivot-table .collapsible-header .collapse-toggle-btn{background:none;border:none;cursor:pointer;padding:var(--grid-spacing-xxs);margin:0;display:flex;align-items:center;justify-content:center;width:20px;height:20px;border-radius:var(--grid-border-radius);color:var(--grid-on-surface-variant);transition:all .2s ease;font-size:12px;font-weight:600}.pivot-mode .pivot-table .collapsible-header .collapse-toggle-btn:hover{background-color:var(--grid-surface-container);color:var(--grid-primary);transform:scale(1.1)}.pivot-mode .pivot-table .collapsible-header .collapse-toggle-btn:focus{outline:2px solid var(--grid-primary);outline-offset:1px}.pivot-mode .pivot-table .collapsible-header .collapse-toggle-btn .collapse-icon{display:block;line-height:1;font-family:monospace;font-size:14px}.pivot-mode .pivot-table .collapsible-header.expanded .collapse-toggle-btn .collapse-icon{color:var(--grid-primary)}.pivot-mode .pivot-table .collapsible-header.collapsed{background-color:var(--grid-surface-variant)}.pivot-mode .pivot-table .collapsible-header.collapsed .header-label{font-style:italic;color:var(--grid-on-surface-variant)}.pivot-mode .pivot-table .collapsible-header.collapsed .collapse-toggle-btn .collapse-icon{color:var(--grid-outline)}.pivot-mode .pivot-table .collapsible-header:hover{background-color:var(--grid-surface-container)}.pivot-mode .pivot-table .collapsible-header:hover .header-label{color:var(--grid-on-surface)}.pivot-mode .pivot-table .pivot-single-table{display:flex;flex-direction:column;height:100%;width:100%;overflow:hidden;min-height:var(--table-min-height)!important}.pivot-mode .pivot-table .pivot-single-table .pivot-header-container{flex-shrink:0;background:var(--grid-surface)!important;overflow-x:auto;overflow-y:hidden;min-height:100px!important;height:auto!important}.pivot-mode .pivot-table .pivot-single-table .pivot-header-container .pivot-table{width:auto;min-width:100%;height:auto!important;min-height:100px!important}.pivot-mode .pivot-table .pivot-single-table .pivot-header-container .pivot-table th{background:var(--grid-surface-container)!important;padding:8px 6px!important;white-space:nowrap;min-width:50px;min-height:40px!important;height:auto!important;position:relative;visibility:visible!important;color:var(--grid-on-surface)!important}.pivot-mode .pivot-table .pivot-single-table .pivot-header-container .pivot-table th.sticky-column{position:sticky!important;background:var(--grid-surface-container)!important;border-right:2px solid var(--grid-primary)!important;box-shadow:2px 0 4px #0000001a;z-index:101!important}.pivot-mode .pivot-table .pivot-single-table .pivot-data-container{flex:1;overflow:auto;min-height:300px!important;height:auto!important}.pivot-mode .pivot-table .pivot-single-table .pivot-data-container .pivot-viewport{height:100%!important;width:100%!important;overflow-x:auto!important;overflow-y:auto!important}.pivot-mode .pivot-table .pivot-single-table .pivot-data-container .pivot-table,.pivot-mode .pivot-table .pivot-single-table .pivot-data-container .pivot-data-table{width:auto;min-width:100%;height:auto!important}.pivot-mode .pivot-table .pivot-single-table .pivot-data-container .pivot-table td,.pivot-mode .pivot-table .pivot-single-table .pivot-data-container .pivot-data-table td{padding:8px 6px!important;white-space:nowrap;min-width:50px;min-height:32px!important;height:auto!important;background:var(--grid-surface)!important;color:var(--grid-on-surface)!important;visibility:visible!important}.pivot-mode .pivot-table .pivot-single-table .pivot-data-container .pivot-table td.sticky-column,.pivot-mode .pivot-table .pivot-single-table .pivot-data-container .pivot-data-table td.sticky-column{position:sticky!important;background:var(--grid-surface-container)!important;border-right:2px solid var(--grid-primary)!important;box-shadow:2px 0 4px #0000001a;z-index:100!important}.pivot-mode .pivot-table .pivot-single-table .pivot-data-container .pivot-table tbody tr,.pivot-mode .pivot-table .pivot-single-table .pivot-data-container .pivot-data-table tbody tr{height:auto!important;min-height:50px!important}.pivot-mode .pivot-table .pivot-single-table .pivot-data-container .pivot-table tbody tr.pivot-row,.pivot-mode .pivot-table .pivot-single-table .pivot-data-container .pivot-data-table tbody tr.pivot-row{visibility:visible!important;display:table-row!important}.pivot-mode .pivot-table .collapsed-column-group{background-color:var(--grid-surface-container);border-left:3px solid var(--grid-primary)}.pivot-mode .pivot-table .collapsed-column-group:hover{background-color:var(--grid-surface-container-high)}.pivot-row.subtotal-row{background-color:var(--grid-surface-variant);font-weight:500}.pivot-row.subtotal-row.subtotal-bold{font-weight:500}.pivot-row.subtotal-row.subtotal-italic{font-style:italic}.pivot-row.subtotal-row.subtotal-highlighted{background-color:var(--grid-primary);color:var(--grid-on-primary)}.pivot-row.grand-total-row{background-color:var(--grid-surface-container);font-weight:600}.pivot-row.grand-total-row.grand-total-bold{font-weight:800}.pivot-row.grand-total-row.grand-total-italic{font-style:italic}.pivot-row.grand-total-row.grand-total-highlighted{background-color:var(--grid-primary);color:var(--grid-on-primary)}.pivot-row.first-visible-row{background-color:#6750a41a!important;position:relative}.pivot-row.first-visible-row:before{content:\"\\1f441\\fe0f First Visible\";position:absolute;top:-20px;left:0;background:var(--grid-primary);color:var(--grid-on-primary);padding:2px 6px;font-size:10px;border-radius:2px;z-index:1000}.header-wrap-text{white-space:pre-wrap;word-break:auto-phrase}.action-column{width:40px;min-width:40px;max-width:40px;text-align:center;background-color:var(--grid-surface-container)}.action-column mat-icon{font-family:Material Icons!important;font-size:20px;width:20px;height:20px;line-height:20px;color:var(--grid-on-surface-variant);cursor:pointer}.action-column mat-icon:hover{color:var(--grid-primary)}.mat-mdc-menu-item{min-height:0px!important}.mat-mdc-menu-content{padding:0!important}.action-icon{font-family:Material Icons!important;font-size:20px!important;width:20px!important;height:20px!important;line-height:20px!important;text-transform:none!important;font-weight:400!important;font-style:normal!important;display:inline-flex!important;align-items:center;justify-content:center;margin-right:12px;color:var(--grid-on-surface-variant);cursor:pointer}.action-icon:hover{color:var(--grid-primary)}\n"], dependencies: [{ kind: "component", type: DataCellComponent, selector: "data-cell", inputs: ["eruGridStore", "fieldSize", "columnDatatype", "columnName", "column", "value", "id", "frozenGrandTotalCell", "td", "drillable", "mode", "isEditable"], outputs: ["tdChange"] }, { kind: "ngmodule", type: ScrollingModule }, { kind: "directive", type: i1$2.ɵɵCdkFixedSizeVirtualScroll, selector: "cdk-virtual-scroll-viewport[itemSize]", inputs: ["itemSize", "minBufferPx", "maxBufferPx"] }, { kind: "directive", type: i1$2.ɵɵCdkVirtualForOf, selector: "[cdkVirtualFor][cdkVirtualForOf]", inputs: ["cdkVirtualForOf", "cdkVirtualForTrackBy", "cdkVirtualForTemplate", "cdkVirtualForTemplateCacheSize"] }, { kind: "component", type: i1$2.ɵɵCdkVirtualScrollViewport, selector: "cdk-virtual-scroll-viewport", inputs: ["orientation", "appendOnly"], outputs: ["scrolledIndexChange"] }, { kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2$1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: i1.MatCommonModule }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i4$1.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "directive", type: ResizeColumnDirective, selector: "[resizeColumn]", inputs: ["resizeColumn", "index", "columnConfig", "gridConfig"] }, { kind: "directive", type: ColumnDragDirective, selector: "[columnDraggable]", inputs: ["columnDraggable"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i5$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatMenuModule }, { kind: "component", type: i6$1.MatMenu, selector: "mat-menu", inputs: ["backdropClass", "aria-label", "aria-labelledby", "aria-describedby", "xPosition", "yPosition", "overlapTrigger", "hasBackdrop", "class", "classList"], outputs: ["closed", "close"], exportAs: ["matMenu"] }, { kind: "component", type: i6$1.MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i6$1.MatMenuContent, selector: "ng-template[matMenuContent]" }, { kind: "directive", type: i6$1.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
5550
|
+
], viewQueries: [{ propertyName: "viewport", first: true, predicate: CdkVirtualScrollViewport, descendants: true }, { propertyName: "rowContainer", first: true, predicate: ["rowContainer"], descendants: true }, { propertyName: "headerScroller", first: true, predicate: ["headerScroller"], descendants: true, read: ElementRef }, { propertyName: "gtScroller", first: true, predicate: ["gtScroller"], descendants: true, read: ElementRef }, { propertyName: "vp", first: true, predicate: ["vp"], descendants: true }], ngImport: i0, template: "<!-- <div style=\"background: #f0f0f0; font-size: 12px; border-bottom: 1px solid #ccc;\">\n currentPivotScrollIndex {{currentPivotScrollIndex()}} | \n firstDataRowIndex {{firstDataRowIndex()}} | \n firstTr {{firstTr}} |\n maxDepth {{maxDepth()}}\n</div> -->\n<div class=\"incremental-row-container eru-grid\" #rowContainer [class.pivot-mode]=\"gridStore.isPivotMode()\"\n [class.table-mode]=\"!gridStore.isPivotMode()\">\n\n <!-- Pivot Mode Template -->\n @if (gridStore.isPivotMode()) {\n <ng-container>\n <div class=\"pivot-container\" style=\"display: flex; flex-direction: column; height: 100%;\"\n [style]=\"'--table-min-height: ' + getInitialMinHeightPx() + 'px; --table-total-width: ' + getInitialTotalWidth() + 'px'\">\n <!-- Debug info for first visible row -->\n\n\n <div class=\"pivot-single-table\"\n style=\"height: 100%; width: 100%; overflow: hidden; display: flex; flex-direction: column;\">\n @if (freezeHeader()) {\n <div #headerScroller class=\"header-shell\">\n <table class=\"eru-grid-table pivot-table\"\n [style]=\"'width: auto; min-width: 100%; --table-total-width: ' + getInitialTotalWidth() + 'px'\"\n [class.show-column-lines]=\"showColumnLines()\" [class.show-row-lines]=\"showRowLines()\">\n <!-- Column Groups for consistent width -->\n <ng-container *ngTemplateOutlet=\"pivotColGroup\"></ng-container>\n\n <ng-container *ngTemplateOutlet=\"pivotTableHead\"></ng-container>\n @if(grandTotalPosition() === 'before' && freezeGrandTotal()) {\n <ng-container *ngTemplateOutlet=\"pivotGrandTotal\"></ng-container>\n }\n </table>\n </div>\n }\n <!-- Virtual Scrolled Table Body -->\n <div>\n <cdk-virtual-scroll-viewport #vp [itemSize]=\"50\" class=\"viewport pivot-viewport\"\n [class.apply-cdk-width]=\"applyCdkWidth()\" (scrolledIndexChange)=\"onPivotScroll($event)\"\n (scroll)=\"onBodyScroll($event)\" style=\"overflow: auto;\">\n <table class=\"eru-grid-table pivot-table\"\n [style]=\"'width: auto; min-width: 100%; --table-total-width: ' + getInitialTotalWidth() + 'px'\"\n [class.show-column-lines]=\"showColumnLines()\" [class.show-row-lines]=\"showRowLines()\">\n <!-- Column Groups for consistent width -->\n <ng-container *ngTemplateOutlet=\"pivotColGroup\"></ng-container>\n\n @if (!freezeHeader()) {\n <ng-container *ngTemplateOutlet=\"pivotTableHead\"></ng-container>\n }\n <!-- Table Body with Virtual Scrolling -->\n <tbody class=\"pivot-tbody\">\n\n <tr *cdkVirtualFor=\"let pivotRow of gridStore.pivotDisplayData(); \n trackBy: trackByPivotRowFn; \n let i = index\" class=\"pivot-row\" [class.subtotal-row]=\"pivotRow._isSubtotal\"\n [class.grand-total-row]=\"pivotRow._isGrandTotal\"\n [class.subtotal-bold]=\"pivotRow._isSubtotal && subTotalStyle() === 'bold'\"\n [class.subtotal-italic]=\"pivotRow._isSubtotal && subTotalStyle() === 'italic'\"\n [class.subtotal-highlighted]=\"pivotRow._isSubtotal && subTotalStyle() === 'highlighted'\"\n [class.grand-total-bold]=\"pivotRow._isGrandTotal && grandTotalStyle() === 'bold'\"\n [class.grand-total-italic]=\"pivotRow._isGrandTotal && grandTotalStyle() === 'italic'\"\n [class.grand-total-highlighted]=\"pivotRow._isGrandTotal && grandTotalStyle() === 'highlighted'\"\n [style.height.px]=\"50\" [attr.data-pivot-row]=\"i\">\n @if ((!pivotRow._isGrandTotal && freezeGrandTotal() ) || (!freezeGrandTotal() )) {\n @for (column of getLeafColumns(); track trackByColumnFn($index, column); let colIndex = $index) {\n @if (!shouldSkipCell(i, column.name)) {\n <td [attr.rowspan]=\"getEffectiveRowspan(i, column.name)\" [style.width.px]=\"column.field_size\"\n [style.minWidth.px]=\"column.field_size\" class=\"pivot-cell\"\n [class.row-dimension-cell]=\"isRowDimensionColumn(column.name)\"\n [class.column-dimension-cell]=\"!isRowDimensionColumn(column.name)\"\n [class.aggregated-value]=\"!isRowDimensionColumn(column.name) && column.datatype === 'number'\"\n [class.rowspan-cell]=\"getEffectiveRowspan(i, column.name) || 1 > 1\"\n [class.sticky-column]=\"isStickyColumn(column.name, colIndex)\"\n [style.position]=\"isStickyColumn(column.name, colIndex) ? 'sticky' : 'static'\"\n [style.left.px]=\"getStickyColumnLeft(column.name, colIndex)\"\n [style.z-index]=\"isStickyColumn(column.name, colIndex) ? 99 : 1\" [style.height.px]=\"50\"\n [attr.xx]=\"i\">\n <div class=\"cell-content pivot-cell-content\">\n <data-cell [class.aggregation]=\"!!column.aggregationFunction\" [fieldSize]=\"column.field_size\"\n [columnDatatype]=\"column.datatype\" [columnName]=\"column.name\"\n [value]=\"getEffectiveCellValue(i,column.name, pivotRow)\" [column]=\"column\"\n [drillable]=\"column.enableDrilldown || false\" [mode]=\"mode()\" [isEditable]=\"isEditable()\"\n [id]=\"'pivot_' + i + '_' + column.name\" [eruGridStore]=\"gridStore\">\n </data-cell>\n </div>\n </td>\n }\n }\n } @else {\n <td [style.height.px]=\"50\" [attr.colspan]=\"getLeafColumns().length\"> </td>\n }\n </tr>\n </tbody>\n </table>\n </cdk-virtual-scroll-viewport>\n\n </div>\n @if (freezeGrandTotal() && grandTotalPosition() === 'after') {\n <div #gtScroller class=\"header-shell gt-shell\" [class.adjust-bottom]=\"!applyCdkWidth()\"\n [class.adjust-bottom-vs]=\"adjustScrollWidth()\">\n <table class=\"eru-grid-table pivot-table\"\n [style]=\"'width: auto; min-width: 100%; --table-total-width: ' + getInitialTotalWidth() + 'px'\"\n [class.show-column-lines]=\"showColumnLines()\" [class.show-row-lines]=\"showRowLines()\">\n <ng-container *ngTemplateOutlet=\"pivotColGroup\"></ng-container>\n\n <ng-container *ngTemplateOutlet=\"pivotGrandTotal\"></ng-container>\n\n </table>\n </div>\n }\n\n\n </div>\n </div>\n </ng-container>\n } @else {\n\n <!-- Table Mode Template -->\n <ng-container>\n @if (freezeHeader()) {\n <div #headerScroller class=\"header-shell\">\n <table class=\"eru-grid-table\" [class.show-column-lines]=\"showColumnLines()\"\n [class.show-row-lines]=\"showRowLines()\">\n <ng-container *ngTemplateOutlet=\"tableHeaderTpl\"></ng-container>\n </table>\n </div>\n }\n <cdk-virtual-scroll-viewport [itemSize]=\"30\" class=\"viewport table-viewport\"\n (scrolledIndexChange)=\"onScroll($event)\"\n (scroll)=\"onBodyScroll($event)\"\n [style]=\"'--table-min-height: ' + getInitialMinHeightPx() + 'px; --table-total-width: ' + getInitialTotalWidth() + 'px'\">\n <div class=\"table-wrapper\">\n\n <table class=\"eru-grid-table\" [class.show-column-lines]=\"showColumnLines()\"\n [class.show-row-lines]=\"showRowLines()\">\n @if (!freezeHeader()) {\n <ng-container *ngTemplateOutlet=\"tableHeaderTpl\"></ng-container>\n }\n <tbody *ngIf=\"columns() as columnsList\">\n <ng-container *cdkVirtualFor=\"let groupItem of groupedRows();\n trackBy: trackByGroupItemFn;\n let i = index;\n let first=first\">\n <tr *ngIf=\"groupItem.type === 'header' && groups().length > 1\" class=\"group-header\"\n (click)=\"toggleGroupExpansion(groupItem.group?.id || '')\">\n\n <td class=\"checkbox-column\" style=\"border: none;\">\n {{ groupItem.group?.isExpanded ? '\u25BC' : '\u25B6' }}\n </td>\n\n <td [attr.colspan]=\"2\" style=\"border: none;\">\n <span class=\"group-title\">\n {{ groupItem.group?.title }}\n </span>\n <span class=\"group-row-count\">\n ({{ groupItem.group?.currentLoadedRows || 0 }}/{{ groupItem.group?.totalRowCount || 0 }})\n </span>\n </td>\n </tr>\n <tr *ngIf=\"groupItem.type === 'table-header' && groups().length > 1\" style=\"background:#fafafa\">\n @if(gridStore.configuration().config.allowSelection) {\n <th class=\"checkbox-column\" style=\"text-align: center;\">\n <input type=\"checkbox\" [checked]=\"isGroupSelected(groupItem.group?.id || '')\"\n (click)=\"$event.stopPropagation()\"\n (change)=\"toggleGroupSelection($event, groupItem.group?.id || '')\">\n </th>\n }\n @if(shouldShowActionColumn('before')) {\n <td class=\"action-column\"\n style=\"width: 40px; min-width: 40px; max-width: 40px; text-align: center; cursor: pointer;\">\n @if (gridActions().length > 0) {\n <mat-icon [matMenuTriggerFor]=\"actionMenu\"\n [matMenuTriggerData]=\"{row: groupItem.row}\">more_horiz</mat-icon>\n } @else {\n <mat-icon (click)=\"onActionClick($event, groupItem.row)\">more_horiz</mat-icon>\n }\n </td>\n }\n <th *ngFor=\"let column of columns(); trackBy: trackByColumnFn;let i =index\" style=\"text-align: center;\"\n [style.width.px]=\"column.field_size\" [style.minWidth.px]=\"column.field_size\" [resizeColumn]=\"true\"\n [columnConfig]=\"column\" [columnDraggable]=\"i\" class=\"column-header\">\n <div class=\"column-drag-handle\"></div>\n {{column.label}} {{column.symbol}}\n </th>\n @if(shouldShowActionColumn('after')) {\n <td class=\"action-column\"\n style=\"width: 40px; min-width: 40px; max-width: 40px; text-align: center; cursor: pointer;\">\n @if (gridActions().length > 0) {\n <mat-icon [matMenuTriggerFor]=\"actionMenu\"\n [matMenuTriggerData]=\"{row: groupItem.row}\">more_horiz</mat-icon>\n } @else {\n <mat-icon (click)=\"onActionClick($event, groupItem.row)\">more_horiz</mat-icon>\n }\n </td>\n }\n </tr>\n <tr *ngIf=\"groupItem.type === 'row' && groupItem.group?.isExpanded\" class=\"row-item\"\n [attr.data-row-id]=\"groupItem.row?.entity_id\" [style.height.px]=\"30\" [style.minHeight.px]=\"30\"\n [style.maxHeight.px]=\"30\">\n @if(gridStore.configuration().config.allowSelection) {\n <td class=\"checkbox-column\" style=\"text-align: center;\">\n <input type=\"checkbox\" [checked]=\"isRowSelected(groupItem.row?.entity_id)\"\n (change)=\"toggleRowSelection($event, groupItem.row)\">\n </td>\n }\n @if(shouldShowActionColumn('before')) {\n <td class=\"action-column\"\n style=\"width: 40px; min-width: 40px; max-width: 40px; text-align: center; cursor: pointer;\">\n @if (gridActions().length > 0) {\n <mat-icon [matMenuTriggerFor]=\"actionMenu\"\n [matMenuTriggerData]=\"{row: groupItem.row}\">more_horiz</mat-icon>\n } @else {\n <mat-icon (click)=\"onActionClick($event, groupItem.row)\">more_horiz</mat-icon>\n }\n </td>\n }\n <td #cell *ngFor=\"let column of columns(); trackBy: trackByColumnFn\"\n [style.width.px]=\"column.field_size\" [style.minWidth.px]=\"column.field_size\" class=\"data-cell\"\n [style.height.px]=\"30\" [style.minHeight.px]=\"30\" [style.maxHeight.px]=\"30\"\n [matTooltipClass]=\"'error-message'\" [matTooltip]=\"datacell.error()?'Error: ' + datacell.error():''\"\n matTooltipPosition=\"below\">\n <div class=\"cell-content\">\n <data-cell #datacell [td]=cell [fieldSize]=\"column.field_size\" [columnDatatype]=\"column.datatype\"\n [columnName]=\"column.name\" [value]=\"groupItem.row?.[column.name] || ''\" [column]=\"column\"\n [mode]=\"mode()\" [isEditable]=\"isEditable()\" [drillable]=\"column.enableDrilldown || false\"\n [id]=\"i + '_' + column.name\" [eruGridStore]=\"gridStore\"></data-cell>\n </div>\n </td>\n @if(shouldShowActionColumn('after')) {\n <td class=\"action-column\"\n style=\"width: 40px; min-width: 40px; max-width: 40px; text-align: center; cursor: pointer;\">\n @if (gridActions().length > 0) {\n <mat-icon [matMenuTriggerFor]=\"actionMenu\"\n [matMenuTriggerData]=\"{row: groupItem.row}\">more_horiz</mat-icon>\n } @else {\n <mat-icon (click)=\"onActionClick($event, groupItem.row)\">more_horiz</mat-icon>\n }\n </td>\n }\n </tr>\n\n <tr *ngIf=\"groupItem.type === 'ghost-loading' && groupItem.group?.isExpanded\" class=\"ghost-loading-row\"\n [style.height.px]=\"30\" [style.minHeight.px]=\"30\" [style.maxHeight.px]=\"30\">\n @if(gridStore.configuration().config.allowSelection) {\n <th class=\"checkbox-column\"></th>\n }\n @if(shouldShowActionColumn('before')) {\n <td class=\"action-column ghost-cell-container\" style=\"width: 40px; min-width: 40px; max-width: 40px;\">\n <div class=\"ghost-cell\"></div>\n </td>\n }\n <td *ngFor=\"let column of columns(); trackBy: trackByColumnFn\" [style.width.px]=\"column.field_size\"\n [style.minWidth.px]=\"column.field_size\" class=\"ghost-cell-container\">\n <div class=\"ghost-cell\"></div>\n </td>\n @if(shouldShowActionColumn('after')) {\n <td class=\"action-column ghost-cell-container\" style=\"width: 40px; min-width: 40px; max-width: 40px;\">\n <div class=\"ghost-cell\"></div>\n </td>\n }\n </tr>\n\n <tr *ngIf=\"groupItem.type === 'row-place-holder'\" class=\"group-separator\">\n <td [attr.colspan]=\"groupSeperatorColSpan()\" class=\"separator-cell\"></td>\n </tr>\n </ng-container>\n </tbody>\n </table>\n </div>\n </cdk-virtual-scroll-viewport>\n </ng-container>\n }\n</div>\n\n<!-- Pivot Table Header Template -->\n<ng-template #pivotTableHead>\n <thead>\n @if (hasNestedHeaders()) {\n <ng-container>\n @for (headerRow of getHeaderRows(); track headerRow; let rowIndex = $index) {\n <tr class=\"pivot-header pivot-header-container\" [class.pivot-header-level]=\"'level-' + rowIndex\">\n @for (header of headerRow; track trackByHeaderFn($index, header); let colIndex = $index) {\n <th [attr.colspan]=\"header.colspan\" [attr.rowspan]=\"header.rowspan\"\n [resizeColumn]=\"gridStore.isFeatureEnabled('columnResizable') && header.level === 0\"\n class=\"column-header pivot-column-header nested-header\"\n [class.row-dimension-header]=\"isRowDimensionHeader(header)\"\n [class.column-dimension-header]=\"!isRowDimensionHeader(header)\" [class.expanded]=\"header.isExpanded\"\n [class.collapsed]=\"!header.isExpanded\" [class.sticky-column]=\"isStickyColumn(header.name, colIndex)\"\n [style.position]=\"isStickyColumn(header.name, colIndex) ? 'sticky' : 'static'\"\n [style.left.px]=\"getStickyColumnLeft(header.name, colIndex)\"\n [style.z-index]=\"isStickyColumn(header.name, colIndex) ? 100 : 1\"\n style=\"min-height: 40px; height: auto; padding: 8px 6px;\">\n <div class=\"header-content\">\n\n <data-cell [fieldSize]=\"header.field_size\" [columnDatatype]=\"header.dataType\" [columnName]=\"header.name\"\n [value]=\"header.label\" [column]=\"header\" [frozenGrandTotalCell]=\"true\"\n [drillable]=\"header.enableDrilldown || false\" [mode]=\"mode()\" [isEditable]=\"isEditable()\"\n [id]=\"'pivot_' + $index + '_' + header.name\" [eruGridStore]=\"gridStore\">\n </data-cell>\n <!-- <span class=\"header-label header-wrap-text\">{{header.label}}</span> -->\n <!-- <button *ngIf=\"!isRowDimensionHeader(header)\" \n class=\"collapse-toggle-btn\"\n [title]=\"header.isExpanded ? 'Collapse group' : 'Expand group'\"\n (click)=\"toggleColumnGroup(header.groupKey)\"\n type=\"button\">\n <span class=\"collapse-icon\">+</span>\n </button> -->\n </div>\n </th>\n }\n </tr>\n }\n </ng-container>\n } @else {\n <!-- Simple header fallback -->\n <ng-container>\n <tr class=\"pivot-header\" [class.freeze-header-enabled]=\"freezeHeader()\">\n @for (column of getLeafColumns(); track trackByColumnFn($index, column); let colIndex = $index) {\n <th [style.width.px]=\"column.field_size\" [style.minWidth.px]=\"column.field_size\"\n [resizeColumn]=\"gridStore.isFeatureEnabled('columnResizable')\" [columnConfig]=\"column\"\n class=\"column-header pivot-column-header\" [class.sticky-column]=\"isStickyColumn(column.name, colIndex)\"\n [style.position]=\"isStickyColumn(column.name, colIndex) ? 'sticky' : 'static'\"\n [style.left.px]=\"getStickyColumnLeft(column.name, colIndex)\"\n [style.z-index]=\"isStickyColumn(column.name, colIndex) ? 100 : 1\"\n style=\"min-height: 40px;height: auto;padding: 8px 6px;position: relative;left: 0px;z-index: 1\">\n {{column.label}}\n </th>\n }\n </tr>\n </ng-container>\n }\n\n </thead>\n</ng-template>\n\n<!-- Column Group Template for consistent column widths -->\n<ng-template #pivotColGroup>\n <colgroup>\n @for (column of getLeafColumns(); track trackByColumnFn($index, column)) {\n <col\n [style]=\"'width: ' + column.field_size + 'px !important; min-width: ' + column.field_size + 'px !important; max-width: ' + column.field_size + 'px !important; --col-width: ' + column.field_size + 'px'\">\n }\n </colgroup>\n</ng-template>\n\n<ng-template #pivotGrandTotal>\n <tbody class=\"pivot-tbody\">\n @for (pivotRow of gridStore.pivotGrandTotalData(); track trackByPivotRowFn($index, pivotRow); let i = $index) {\n <tr class=\"pivot-row grand-total-row\"\n [class.grand-total-bold]=\"pivotRow._isGrandTotal && grandTotalStyle() === 'bold'\"\n [class.grand-total-italic]=\"pivotRow._isGrandTotal && grandTotalStyle() === 'italic'\"\n [class.grand-total-highlighted]=\"pivotRow._isGrandTotal && grandTotalStyle() === 'highlighted'\"\n [style.height.px]=\"50\" [attr.data-pivot-row]=\"i\">\n <!-- <td colspan=\"20\">{{pivotRow | json}}</td> -->\n @for (column of getLeafColumns(); track trackByColumnFn($index, column); let colIndex = $index) {\n <td [attr.rowspan]=\"getEffectiveRowspan(i, column.name)\" [style.width.px]=\"column.field_size\"\n [style.minWidth.px]=\"column.field_size\" class=\"pivot-cell\"\n [class.row-dimension-cell]=\"isRowDimensionColumn(column.name)\"\n [class.column-dimension-cell]=\"!isRowDimensionColumn(column.name)\"\n [class.aggregated-value]=\"!isRowDimensionColumn(column.name) && column.datatype === 'number'\"\n [class.rowspan-cell]=\"getEffectiveRowspan(i, column.name) || 1 > 1\"\n [class.sticky-column]=\"isStickyColumn(column.name, colIndex)\"\n [style.position]=\"isStickyColumn(column.name, colIndex) ? 'sticky' : 'static'\"\n [style.left.px]=\"getStickyColumnLeft(column.name, colIndex)\"\n [style.z-index]=\"isStickyColumn(column.name, colIndex) ? 99 : 1\" [style.height.px]=\"50\" [attr.xx]=\"i\">\n <div class=\"cell-content pivot-cell-content\">\n <data-cell [fieldSize]=\"column.field_size\" [columnDatatype]=\"column.datatype\" [columnName]=\"column.name\"\n [value]=\"getEffectiveCellValue(i,column.name, pivotRow)\" [column]=\"column\" [frozenGrandTotalCell]=\"true\"\n [drillable]=\"column.enableDrilldown || false\" [mode]=\"mode()\" [isEditable]=\"isEditable()\"\n [id]=\"'pivot_' + i + '_' + column.name\" [eruGridStore]=\"gridStore\">\n </data-cell>\n </div>\n </td>\n }\n </tr>\n }\n </tbody>\n</ng-template>\n\n<!-- Table Mode Header Template -->\n<ng-template #tableHeaderTpl>\n <thead>\n <tr>\n @if(gridStore.configuration().config.allowSelection) {\n <th class=\"checkbox-column\"></th>\n }\n @if(shouldShowActionColumn('before')) {\n <th class=\"action-column column-header table-column-header\"\n style=\"width: 40px; min-width: 40px; max-width: 40px;\">\n Action\n </th>\n }\n <th *ngFor=\"let column of columns(); trackBy: trackByColumnFn\" [style.width.px]=\"column.field_size\"\n [resizeColumn]=\"gridStore.isFeatureEnabled('columnResizable')\" [style.minWidth.px]=\"column.field_size\"\n class=\"column-header table-column-header\">\n {{column.label}}\n </th>\n @if(shouldShowActionColumn('after')) {\n <th class=\"action-column column-header table-column-header\"\n style=\"width: 40px; min-width: 40px; max-width: 40px;\">\n Action\n </th>\n }\n </tr>\n </thead>\n</ng-template>\n\n<mat-menu #actionMenu=\"matMenu\">\n <ng-template matMenuContent let-row=\"row\">\n @for (item of gridActions(); track item.action) {\n <button mat-menu-item (click)=\"onActionClick($event, row, item)\">\n @if (item.icon) {\n <mat-icon class=\"action-icon\" fontIcon=\"{{item.icon}}\"></mat-icon>\n }\n <span>{{item.menu}}</span>\n </button>\n }\n </ng-template>\n</mat-menu>", styles: ["@charset \"UTF-8\";:host{display:block;width:100%;height:100%;font-family:var(--grid-font-family);--grid-primary: #6750a4;--grid-on-primary: #ffffff;--grid-surface: #fef7ff;--grid-surface-variant: #e7e0ec;--grid-surface-container: #f3edf7;--grid-surface-container-high: #ede7f0;--grid-on-surface: #1d1b20;--grid-on-surface-variant: #49454f;--grid-outline: #79757f;--grid-outline-variant: #cac4d0;--grid-error: #ba1a1a;--grid-error-container: #ffdad6;--grid-font-family: \"Poppins\", \"Roboto\", -apple-system, BlinkMacSystemFont, \"Segoe UI\", sans-serif;--grid-font-size-body: 12px;--grid-font-size-caption: 12px !important;--grid-line-height-body: 1;--grid-aggregation-text-align: right;--grid-number-text-align: right;--grid-spacing-xxs: 2px;--grid-spacing-xs: 4px;--grid-spacing-sm: 8px;--grid-spacing-md: 16px;--grid-spacing-lg: 24px;--grid-border-radius: 4px;--grid-elevation-1: 0px 1px 2px 0px rgba(0, 0, 0, .3), 0px 1px 3px 1px rgba(0, 0, 0, .15);--grid-elevation-2: 0px 1px 2px 0px rgba(0, 0, 0, .3), 0px 2px 6px 2px rgba(0, 0, 0, .15)}.incremental-row-container{padding:10px;width:100%;height:100%;min-height:var(--table-min-height, 400px);max-height:none;overflow:auto;position:relative;background-color:var(--grid-surface);border-radius:var(--grid-border-radius);box-shadow:var(--grid-elevation-1);font-family:var(--grid-font-family)}.viewport{overflow-x:auto;overflow-y:auto;background-color:var(--grid-surface);scrollbar-gutter:stable}.viewport.apply-cdk-width{width:calc(var(--table-total-width) + 10px)!important}.table-viewport{background-color:var(--grid-surface);height:auto;min-height:var(--table-min-height, 300px);max-height:80vh;overflow-x:auto;overflow-y:auto}.pivot-viewport{min-height:var(--table-min-height, 300px);overflow-x:auto;overflow-y:auto;background-color:var(--grid-surface)}.pivot-viewport .cdk-virtual-scroll-content-wrapper{width:auto;height:auto}.table-wrapper{min-width:100%;overflow-x:visible}.incremental-row-container .eru-grid-table,.eru-grid-table{width:100%!important;border-collapse:separate;border-spacing:0;table-layout:fixed!important;background-color:var(--grid-surface);color:var(--grid-on-surface);font-size:var(--grid-font-size-body);line-height:var(--grid-line-height-body)}.eru-grid-table th,.eru-grid-table td{text-align:left;overflow:hidden!important;text-overflow:ellipsis!important;white-space:nowrap!important;background-color:var(--grid-surface);color:var(--grid-on-surface);min-width:0;max-width:100%!important;box-sizing:border-box;position:relative}.eru-grid-table th:hover,.eru-grid-table td:hover{background-color:var(--grid-surface-variant)}.eru-grid-table thead{background-color:var(--grid-surface-container);transform:translateZ(0);will-change:transform;backface-visibility:hidden}.eru-grid-table thead.freeze-header-enabled{box-shadow:0 2px 4px #0000001a;border-bottom:2px solid var(--grid-outline)}.eru-grid-table thead th{background-color:var(--grid-surface-container);color:var(--grid-on-surface);font-weight:500;font-size:var(--grid-font-size-caption)}.checkbox-column{width:50px;min-width:50px;max-width:50px;text-align:center;background-color:var(--grid-surface-container)}.checkbox-column input[type=checkbox]{width:16px;height:16px;cursor:pointer;accent-color:var(--grid-primary);border-radius:var(--grid-border-radius)}.checkbox-column input[type=checkbox]:focus{outline:2px solid var(--grid-primary);outline-offset:2px}.group-header{background-color:var(--grid-surface-container);color:var(--grid-on-surface);font-size:var(--grid-font-size-caption);font-weight:500;border-bottom:1px solid var(--grid-outline);cursor:pointer;transition:background-color .2s ease}.group-header:hover{background-color:var(--grid-surface-container-high)}.group-header .group-title{font-weight:600;color:var(--grid-primary)}.group-header .group-row-count{color:var(--grid-on-surface-variant);font-size:var(--grid-font-size-caption);margin-left:var(--grid-spacing-sm)}.row-item{border:1px solid var(--grid-outline);background-color:var(--grid-surface);transition:background-color .2s ease,box-shadow .2s ease}.row-item:hover{background-color:var(--grid-surface-variant);box-shadow:var(--grid-elevation-1)}.table-column-header{padding:12px 8px}.column-header{font-weight:500;text-align:center!important;font-size:var(--grid-font-size-caption, 12px);position:relative;-webkit-user-select:none;user-select:none;background-color:var(--grid-surface-container);color:var(--grid-on-surface)}.column-header:hover{background-color:var(--grid-surface-container-high)}.column-drag-handle{position:absolute;left:0;top:0;bottom:0;width:12px;cursor:grab;opacity:0;transition:opacity .2s ease,background-color .2s ease;z-index:2;display:flex;align-items:center;justify-content:center;border-right:1px solid transparent}.column-drag-handle:after{content:\"\\22ee\\22ee\";font-size:14px;color:var(--grid-on-surface-variant);transform:rotate(90deg)}.column-drag-handle:hover{background-color:var(--grid-surface-container-high);border-right-color:var(--grid-outline)}.column-header:hover .column-drag-handle{opacity:1}.column-drag-handle:active{cursor:grabbing}.dragging{opacity:1;background-color:var(--grid-surface-container);box-shadow:var(--grid-elevation-2)}.drag-over{background-color:var(--grid-surface-container);border-color:var(--grid-primary)}.data-cell{background-color:var(--grid-surface);color:var(--grid-on-surface);font-size:var(--grid-font-size-body)}.cell-content{align-items:center}.cell-content .mdc-text-field{padding:0px var(--grid-spacing-xxs)!important}.cell-display-text{align-items:center;padding:0px var(--grid-spacing-xs)}.ghost-loading-row{background-color:transparent}.ghost-cell-container{padding:var(--grid-spacing-sm)}.ghost-cell{height:20px;width:100%;background-color:var(--grid-surface-container);animation:pulse 1.5s ease-in-out infinite;border-radius:var(--grid-border-radius)}@keyframes pulse{0%,to{opacity:1}50%{opacity:.5}}.resizing{cursor:col-resize;-webkit-user-select:none;user-select:none}.column-resizer{position:absolute;right:0;top:0;bottom:0;width:4px;cursor:col-resize;background-color:transparent;transition:background-color .2s ease}.column-resizer:hover{background-color:var(--grid-primary)}.group-separator{height:var(--grid-spacing-sm);background-color:var(--grid-surface-variant)}.group-separator .separator-cell{background-color:var(--grid-surface-variant);border:none;height:var(--grid-spacing-sm)}.error-state{background-color:var(--grid-error-container);color:var(--grid-error);border-color:var(--grid-error)}.error-message{background-color:var(--grid-error);color:#fff;padding:var(--grid-spacing-sm);border-radius:var(--grid-border-radius);font-size:var(--grid-font-size-caption)}.incremental-row-container .eru-grid-table tbody,.incremental-row-container .eru-grid-table{position:relative}.incremental-row-container .eru-grid-table.show-column-lines{border-right:var(--grid-outline-width, 1px) solid var(--grid-outline, #e0e0e0)!important;border-top:var(--grid-outline-width, 1px) solid var(--grid-outline, #e0e0e0)!important;border-bottom:var(--grid-outline-width, 1px) solid var(--grid-outline, #e0e0e0)!important}.incremental-row-container .eru-grid-table:not(.show-column-lines){border:var(--grid-outline-width, 1px) solid var(--grid-outline, #e0e0e0)!important}.incremental-row-container .eru-grid-table thead:after{content:\"\";position:absolute;bottom:0;left:0;right:0;height:calc(var(--grid-outline-width, 1px) * 2);background-color:var(--grid-outline, #e0e0e0);pointer-events:none;z-index:10}.incremental-row-container .eru-grid-table.show-column-lines thead th{border-left:var(--grid-outline-width, 1px) solid var(--grid-outline, #e0e0e0)!important;border-bottom:var(--grid-outline-width, 1px) solid var(--grid-outline, #e0e0e0)!important}.incremental-row-container .eru-grid-table.show-column-lines tbody td{border-left:var(--grid-outline-width, 1px) solid var(--grid-outline, #e0e0e0)!important}.incremental-row-container .eru-grid-table.show-row-lines thead th{border-left:var(--grid-outline-width, 1px) solid var(--grid-outline, #e0e0e0)!important;border-bottom:var(--grid-outline-width, 1px) solid var(--grid-outline, #e0e0e0)!important}.incremental-row-container .eru-grid-table.show-row-lines tbody td{border-bottom:var(--grid-outline-width, 1px) solid var(--grid-outline, #e0e0e0)!important}@media (max-width: 768px){.incremental-row-container{height:600px}.eru-grid-table th,.eru-grid-table td{font-size:var(--grid-font-size-caption)}.checkbox-column{width:40px;min-width:40px;max-width:40px}}@media (prefers-contrast: high){.eru-grid-table th,.eru-grid-table td{border-width:2px}.row-item:hover{border-width:2px;border-color:var(--grid-primary)}}@media (prefers-reduced-motion: reduce){.row-item,.column-drag-handle,.ghost-cell{transition:none;animation:none}}.pivot-table .nested-header{text-align:center;font-weight:600;background:var(--grid-surface-container)}.pivot-table .nested-header.row-dimension-header{background:var(--grid-surface-container);font-weight:600}.pivot-table .pivot-header-leafcols{padding:0;margin:0;height:0}.pivot-table .pivot-header-level.level-0 .nested-header{font-size:14px;padding:12px 8px}.pivot-table .pivot-header-level.level-1 .nested-header{font-size:13px;padding:10px 6px}.pivot-table .pivot-header-level.level-2 .nested-header{font-size:12px;padding:8px 4px}.pivot-table .nested-header:hover{background:var(--grid-surface-variant);color:var(--grid-primary);transition:all .2s ease}.pivot-table .pivot-cell.aggregated-value{font-weight:500;font-family:Roboto Mono,monospace}.pivot-table .pivot-cell-content{display:flex;justify-content:center;align-items:center;min-height:38px}.pivot-table .rowspan-cell{vertical-align:middle}.pivot-table .rowspan-cell .pivot-cell-content{height:100%}.pivot-mode .incremental-row-container{display:flex;flex-direction:column;height:auto;max-height:85vh;overflow:auto}.pivot-mode .h-shell{position:relative;width:calc(100% - var(--scrollbar-width, 17px))!important;top:0;z-index:1;overflow-x:hidden;overflow-y:hidden;scrollbar-width:none;-ms-overflow-style:none}.pivot-mode .h-shell::-webkit-scrollbar{display:none}.pivot-mode .gt-shell{position:relative;bottom:50px;flex-shrink:0;overflow-x:hidden;overflow-y:hidden;scrollbar-width:none;-ms-overflow-style:none}.pivot-mode .gt-shell::-webkit-scrollbar{display:none}.pivot-mode .gt-shell table{border-bottom:var(--grid-outline-width, 1px) solid var(--grid-outline, #e0e0e0)!important}.pivot-mode .gt-shell.adjust-bottom-vs{bottom:66px!important}.pivot-mode .gt-shell.adjust-bottom:not(.adjust-bottom-vs){bottom:calc(66px - var(--scrollbar-width, 17px))!important}.pivot-mode .header-shell{flex-shrink:0;width:100%;box-sizing:border-box;padding-right:var(--scrollbar-width, 17px);overflow-x:auto;overflow-y:hidden;scrollbar-width:none;-ms-overflow-style:none}.pivot-mode .header-shell::-webkit-scrollbar{display:none}.pivot-mode .header-shell.apply-cdk-width{width:calc(var(--table-total-width) + 10px)!important}.pivot-mode .header-shell .eru-grid-table{margin-bottom:0;width:100%;table-layout:fixed}.pivot-mode .header-shell .eru-grid-table thead{background:var(--grid-surface-container)}.pivot-mode .header-shell .eru-grid-table thead th{background:var(--grid-surface-container);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;width:var(--col-width)!important;min-width:var(--col-width)!important;max-width:var(--col-width)!important}.pivot-mode .header-shell .eru-grid-table thead th.sticky-column{position:sticky;background:var(--grid-surface-container);z-index:111}.pivot-mode .header-shell .eru-grid-table tbody td{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;width:var(--col-width)!important;min-width:var(--col-width)!important;max-width:var(--col-width)!important}.pivot-mode .pivot-container{display:flex;flex-direction:column;height:100%;width:100%;overflow:hidden}.pivot-mode .pivot-table{width:auto!important;min-width:100%!important;table-layout:fixed!important;width:100%!important}.pivot-mode .pivot-table colgroup col{width:var(--col-width)!important;min-width:var(--col-width)!important;max-width:var(--col-width)!important;flex:none!important;flex-shrink:0!important;flex-grow:0!important}.pivot-mode .pivot-table td,.pivot-mode .pivot-table th{box-sizing:border-box!important;flex:none!important;flex-shrink:0!important;flex-grow:0!important;word-wrap:break-word!important;word-break:break-all!important}.pivot-mode .pivot-table *{max-width:var(--col-width)!important;box-sizing:border-box!important}.pivot-mode .pivot-table colgroup{width:100%!important}.pivot-mode .pivot-table colgroup col{width:var(--col-width)!important;min-width:var(--col-width)!important;max-width:var(--col-width)!important;flex-basis:var(--col-width)!important;flex:0 0 var(--col-width)!important}.pivot-mode .pivot-table table{width:100%!important;table-layout:fixed!important;border-collapse:collapse!important;border-spacing:0!important}.pivot-mode .pivot-table[style*=--table-total-width]{width:var(--table-total-width)!important;min-width:var(--table-total-width)!important;max-width:var(--table-total-width)!important}.pivot-mode .pivot-table colgroup col{width:var(--col-width)!important;min-width:var(--col-width)!important;max-width:var(--col-width)!important;flex:0 0 var(--col-width)!important;flex-basis:var(--col-width)!important;flex-grow:0!important;flex-shrink:0!important;overflow:hidden!important}.pivot-mode .pivot-table tbody td,.pivot-mode .pivot-table thead th{width:var(--col-width)!important;min-width:var(--col-width)!important;max-width:var(--col-width)!important;overflow:hidden!important;text-overflow:ellipsis!important;white-space:nowrap!important}.pivot-mode .pivot-table .cell-content,.pivot-mode .pivot-table data-cell{width:100%!important;max-width:100%!important;overflow:hidden!important;text-overflow:ellipsis!important;white-space:nowrap!important;display:block!important}.pivot-mode .pivot-table table{width:var(--table-total-width)!important;min-width:var(--table-total-width)!important;max-width:var(--table-total-width)!important;table-layout:fixed!important;border-collapse:collapse!important;border-spacing:0!important;word-wrap:break-word!important;word-break:break-all!important}.pivot-mode .pivot-tbody tr.pivot-row{min-height:50px!important;height:50px!important}.pivot-mode .pivot-tbody tr.pivot-row:hover{background-color:var(--grid-surface-variant)}.pivot-mode .pivot-tbody tr.pivot-row:nth-child(2n){background-color:#00000005}.pivot-mode .pivot-tbody tr.pivot-row td{min-height:50px!important;height:50px!important;vertical-align:middle;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;width:var(--col-width)!important;min-width:var(--col-width)!important;max-width:var(--col-width)!important}.pivot-mode .pivot-tbody tr.pivot-row td .cell-content{min-height:48px;display:flex;align-items:center;justify-content:center}.pivot-mode .pivot-tbody tr.pivot-row td .cell-content data-cell{width:100%;min-height:46px;display:flex;align-items:center;justify-content:center;overflow:hidden;flex-shrink:0}.pivot-mode .pivot-cell{vertical-align:middle;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;width:var(--col-width)!important;min-width:var(--col-width)!important;max-width:var(--col-width)!important}.pivot-mode .pivot-cell.aggregated-value{font-weight:500;font-family:Roboto Mono,monospace}.pivot-mode .pivot-cell .cell-content{display:flex;justify-content:center;align-items:center;min-height:40px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;flex-shrink:0}.pivot-mode .pivot-table .subtotal-row{background-color:var(--grid-surface-container)!important;font-weight:600}.pivot-mode .pivot-table .subtotal-row td{background-color:var(--grid-surface-container);color:var(--grid-on-surface-variant)}.pivot-mode .pivot-table .subtotal-row td:first-child{color:var(--grid-primary)}.pivot-mode .pivot-table .subtotal-row td.aggregated-value{font-weight:500;color:var(--grid-primary)}.pivot-mode .pivot-table .subtotal-row:hover{background-color:var(--grid-surface-container-high)!important}.pivot-mode .pivot-table .subtotal-row:hover td{background-color:var(--grid-surface-container-high)}.pivot-mode .pivot-table .subtotal-bold td{font-weight:600!important;font-style:normal!important}.pivot-mode .pivot-table .subtotal-bold td.aggregated-value{font-weight:600!important}.pivot-mode .pivot-table .subtotal-italic td{font-style:italic!important}.pivot-mode .pivot-table .subtotal-italic td:first-child{font-weight:600!important}.pivot-mode .pivot-table .subtotal-italic td.aggregated-value{font-style:italic!important;font-weight:500!important}.pivot-mode .pivot-table .subtotal-highlighted{background-color:var(--grid-surface-variant)!important}.pivot-mode .pivot-table .subtotal-highlighted td{background-color:var(--grid-surface-variant)!important;font-weight:700!important;font-style:normal!important;color:var(--grid-primary)!important}.pivot-mode .pivot-table .subtotal-highlighted td.aggregated-value{font-weight:500!important;color:var(--grid-primary)!important}.pivot-mode .pivot-table .subtotal-highlighted:hover,.pivot-mode .pivot-table .subtotal-highlighted:hover td{background-color:var(--grid-surface-container-high)!important}.pivot-mode .pivot-table .grand-total-row{background-color:var(--grid-surface-container-high)!important;font-weight:700;font-size:var(--grid-font-size-body)}.pivot-mode .pivot-table .grand-total-row td{background-color:var(--grid-surface-container-high)!important;color:var(--grid-on-surface)}.pivot-mode .pivot-table .grand-total-row td:first-child{font-style:normal;font-weight:800;color:var(--grid-primary)}.pivot-mode .pivot-table .grand-total-row td.aggregated-value{font-weight:500;color:var(--grid-primary);font-family:Roboto Mono,monospace}.pivot-mode .pivot-table .grand-total-row:hover,.pivot-mode .pivot-table .grand-total-row:hover td{background-color:var(--grid-surface-container-high)!important}.pivot-mode .pivot-table .grand-total-bold td{font-weight:700!important;font-style:normal!important}.pivot-mode .pivot-table .grand-total-bold td.aggregated-value{font-weight:700!important}.pivot-mode .pivot-table .grand-total-italic td,.pivot-mode .pivot-table .grand-total-italic td.aggregated-value{font-style:italic!important;font-weight:500!important}.pivot-mode .pivot-table .grand-total-highlighted{background-color:var(--grid-primary)!important;box-shadow:var(--grid-elevation-2)!important}.pivot-mode .pivot-table .grand-total-highlighted td{background-color:var(--grid-primary)!important;color:var(--grid-on-primary)!important;font-weight:500!important;font-style:normal!important}.pivot-mode .pivot-table .grand-total-highlighted td.aggregated-value{color:var(--grid-on-primary)!important;font-weight:500!important}.pivot-mode .pivot-table .grand-total-highlighted:hover,.pivot-mode .pivot-table .grand-total-highlighted:hover td{background-color:var(--grid-primary)!important}.pivot-mode .pivot-table .collapsible-header{position:relative}.pivot-mode .pivot-table .collapsible-header .header-content{display:flex;align-items:center;justify-content:space-between;gap:var(--grid-spacing-xs);padding:var(--grid-spacing-xs) var(--grid-spacing-sm)}.pivot-mode .pivot-table .collapsible-header .header-label{flex:1;font-weight:600}.pivot-mode .pivot-table .collapsible-header .collapse-toggle-btn{background:none;border:none;cursor:pointer;padding:var(--grid-spacing-xxs);margin:0;display:flex;align-items:center;justify-content:center;width:20px;height:20px;border-radius:var(--grid-border-radius);color:var(--grid-on-surface-variant);transition:all .2s ease;font-size:12px;font-weight:600}.pivot-mode .pivot-table .collapsible-header .collapse-toggle-btn:hover{background-color:var(--grid-surface-container);color:var(--grid-primary);transform:scale(1.1)}.pivot-mode .pivot-table .collapsible-header .collapse-toggle-btn:focus{outline:2px solid var(--grid-primary);outline-offset:1px}.pivot-mode .pivot-table .collapsible-header .collapse-toggle-btn .collapse-icon{display:block;line-height:1;font-family:monospace;font-size:14px}.pivot-mode .pivot-table .collapsible-header.expanded .collapse-toggle-btn .collapse-icon{color:var(--grid-primary)}.pivot-mode .pivot-table .collapsible-header.collapsed{background-color:var(--grid-surface-variant)}.pivot-mode .pivot-table .collapsible-header.collapsed .header-label{font-style:italic;color:var(--grid-on-surface-variant)}.pivot-mode .pivot-table .collapsible-header.collapsed .collapse-toggle-btn .collapse-icon{color:var(--grid-outline)}.pivot-mode .pivot-table .collapsible-header:hover{background-color:var(--grid-surface-container)}.pivot-mode .pivot-table .collapsible-header:hover .header-label{color:var(--grid-on-surface)}.pivot-mode .pivot-table .pivot-single-table{display:flex;flex-direction:column;height:100%;width:100%;overflow:hidden;min-height:var(--table-min-height)!important}.pivot-mode .pivot-table .pivot-single-table .pivot-header-container{flex-shrink:0;background:var(--grid-surface)!important;overflow-x:auto;overflow-y:hidden;min-height:100px!important;height:auto!important}.pivot-mode .pivot-table .pivot-single-table .pivot-header-container .pivot-table{width:auto;min-width:100%;height:auto!important;min-height:100px!important}.pivot-mode .pivot-table .pivot-single-table .pivot-header-container .pivot-table th{background:var(--grid-surface-container)!important;padding:8px 6px!important;white-space:nowrap;min-width:50px;min-height:40px!important;height:auto!important;position:relative;visibility:visible!important;color:var(--grid-on-surface)!important}.pivot-mode .pivot-table .pivot-single-table .pivot-header-container .pivot-table th.sticky-column{position:sticky!important;background:var(--grid-surface-container)!important;border-right:2px solid var(--grid-primary)!important;box-shadow:2px 0 4px #0000001a;z-index:101!important}.pivot-mode .pivot-table .pivot-single-table .pivot-data-container{flex:1;overflow:auto;min-height:300px!important;height:auto!important}.pivot-mode .pivot-table .pivot-single-table .pivot-data-container .pivot-viewport{height:100%!important;width:100%!important;overflow-x:auto!important;overflow-y:auto!important}.pivot-mode .pivot-table .pivot-single-table .pivot-data-container .pivot-table,.pivot-mode .pivot-table .pivot-single-table .pivot-data-container .pivot-data-table{width:auto;min-width:100%;height:auto!important}.pivot-mode .pivot-table .pivot-single-table .pivot-data-container .pivot-table td,.pivot-mode .pivot-table .pivot-single-table .pivot-data-container .pivot-data-table td{padding:8px 6px!important;white-space:nowrap;min-width:50px;min-height:32px!important;height:auto!important;background:var(--grid-surface)!important;color:var(--grid-on-surface)!important;visibility:visible!important}.pivot-mode .pivot-table .pivot-single-table .pivot-data-container .pivot-table td.sticky-column,.pivot-mode .pivot-table .pivot-single-table .pivot-data-container .pivot-data-table td.sticky-column{position:sticky!important;background:var(--grid-surface-container)!important;border-right:2px solid var(--grid-primary)!important;box-shadow:2px 0 4px #0000001a;z-index:100!important}.pivot-mode .pivot-table .pivot-single-table .pivot-data-container .pivot-table tbody tr,.pivot-mode .pivot-table .pivot-single-table .pivot-data-container .pivot-data-table tbody tr{height:auto!important;min-height:50px!important}.pivot-mode .pivot-table .pivot-single-table .pivot-data-container .pivot-table tbody tr.pivot-row,.pivot-mode .pivot-table .pivot-single-table .pivot-data-container .pivot-data-table tbody tr.pivot-row{visibility:visible!important;display:table-row!important}.pivot-mode .pivot-table .collapsed-column-group{background-color:var(--grid-surface-container);border-left:3px solid var(--grid-primary)}.pivot-mode .pivot-table .collapsed-column-group:hover{background-color:var(--grid-surface-container-high)}.pivot-row.subtotal-row{background-color:var(--grid-surface-variant);font-weight:500}.pivot-row.subtotal-row.subtotal-bold{font-weight:500}.pivot-row.subtotal-row.subtotal-italic{font-style:italic}.pivot-row.subtotal-row.subtotal-highlighted{background-color:var(--grid-primary);color:var(--grid-on-primary)}.pivot-row.grand-total-row{background-color:var(--grid-surface-container);font-weight:600}.pivot-row.grand-total-row.grand-total-bold{font-weight:800}.pivot-row.grand-total-row.grand-total-italic{font-style:italic}.pivot-row.grand-total-row.grand-total-highlighted{background-color:var(--grid-primary);color:var(--grid-on-primary)}.pivot-row.first-visible-row{background-color:#6750a41a!important;position:relative}.pivot-row.first-visible-row:before{content:\"\\1f441\\fe0f First Visible\";position:absolute;top:-20px;left:0;background:var(--grid-primary);color:var(--grid-on-primary);padding:2px 6px;font-size:10px;border-radius:2px;z-index:1000}.header-wrap-text{white-space:pre-wrap;word-break:auto-phrase}.action-column{width:40px;min-width:40px;max-width:40px;text-align:center;background-color:var(--grid-surface-container)}.action-column mat-icon{font-family:Material Icons!important;font-size:20px;width:20px;height:20px;line-height:20px;color:var(--grid-on-surface-variant);cursor:pointer}.action-column mat-icon:hover{color:var(--grid-primary)}.mat-mdc-menu-item{min-height:0px!important}.mat-mdc-menu-content{padding:0!important}.action-icon{font-family:Material Icons!important;font-size:20px!important;width:20px!important;height:20px!important;line-height:20px!important;text-transform:none!important;font-weight:400!important;font-style:normal!important;display:inline-flex!important;align-items:center;justify-content:center;margin-right:12px;color:var(--grid-on-surface-variant);cursor:pointer}.action-icon:hover{color:var(--grid-primary)}\n"], dependencies: [{ kind: "component", type: DataCellComponent, selector: "data-cell", inputs: ["eruGridStore", "fieldSize", "columnDatatype", "columnName", "column", "value", "id", "frozenGrandTotalCell", "td", "drillable", "mode", "isEditable"], outputs: ["tdChange"] }, { kind: "ngmodule", type: ScrollingModule }, { kind: "directive", type: i1$2.ɵɵCdkFixedSizeVirtualScroll, selector: "cdk-virtual-scroll-viewport[itemSize]", inputs: ["itemSize", "minBufferPx", "maxBufferPx"] }, { kind: "directive", type: i1$2.ɵɵCdkVirtualForOf, selector: "[cdkVirtualFor][cdkVirtualForOf]", inputs: ["cdkVirtualForOf", "cdkVirtualForTrackBy", "cdkVirtualForTemplate", "cdkVirtualForTemplateCacheSize"] }, { kind: "component", type: i1$2.ɵɵCdkVirtualScrollViewport, selector: "cdk-virtual-scroll-viewport", inputs: ["orientation", "appendOnly"], outputs: ["scrolledIndexChange"] }, { kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2$1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: i1.MatCommonModule }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i4$1.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "directive", type: ResizeColumnDirective, selector: "[resizeColumn]", inputs: ["resizeColumn", "index", "columnConfig", "gridConfig"] }, { kind: "directive", type: ColumnDragDirective, selector: "[columnDraggable]", inputs: ["columnDraggable"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i5$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatMenuModule }, { kind: "component", type: i6$1.MatMenu, selector: "mat-menu", inputs: ["backdropClass", "aria-label", "aria-labelledby", "aria-describedby", "xPosition", "yPosition", "overlapTrigger", "hasBackdrop", "class", "classList"], outputs: ["closed", "close"], exportAs: ["matMenu"] }, { kind: "component", type: i6$1.MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i6$1.MatMenuContent, selector: "ng-template[matMenuContent]" }, { kind: "directive", type: i6$1.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
5848
5551
|
}
|
|
5849
5552
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: EruGridComponent, decorators: [{
|
|
5850
5553
|
type: Component,
|
|
@@ -5861,7 +5564,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.3", ngImpor
|
|
|
5861
5564
|
MatButtonModule,
|
|
5862
5565
|
MatIconModule,
|
|
5863
5566
|
MatMenuModule
|
|
5864
|
-
], template: "<!-- <div style=\"background: #f0f0f0; font-size: 12px; border-bottom: 1px solid #ccc;\">\n currentPivotScrollIndex {{currentPivotScrollIndex()}} | \n firstDataRowIndex {{firstDataRowIndex()}} | \n firstTr {{firstTr}} |\n maxDepth {{maxDepth()}}\n</div> -->\n<div class=\"incremental-row-container eru-grid\" #rowContainer [class.pivot-mode]=\"gridStore.isPivotMode()\"\n [class.table-mode]=\"!gridStore.isPivotMode()\">\n\n <!-- Pivot Mode Template -->\n @if (gridStore.isPivotMode()) {\n <ng-container>\n <div class=\"pivot-container\" style=\"display: flex; flex-direction: column; height: 100%;\"\n [style]=\"'--table-min-height: ' + getInitialMinHeightPx() + 'px; --table-total-width: ' + getInitialTotalWidth() + 'px'\">\n <!-- Debug info for first visible row -->\n\n\n <div class=\"pivot-single-table\"\n style=\"height: 100%; width: 100%; overflow: hidden; display: flex; flex-direction: column;\">\n @if (freezeHeader()) {\n <div #headerScroller class=\"header-shell\">\n <table class=\"eru-grid-table pivot-table\"\n [style]=\"'width: auto; min-width: 100%; --table-total-width: ' + getInitialTotalWidth() + 'px'\"\n [class.show-column-lines]=\"showColumnLines()\" [class.show-row-lines]=\"showRowLines()\">\n <!-- Column Groups for consistent width -->\n <ng-container *ngTemplateOutlet=\"pivotColGroup\"></ng-container>\n\n <ng-container *ngTemplateOutlet=\"pivotTableHead\"></ng-container>\n @if(grandTotalPosition() === 'before' && freezeGrandTotal()) {\n <ng-container *ngTemplateOutlet=\"pivotGrandTotal\"></ng-container>\n }\n </table>\n </div>\n }\n <!-- Virtual Scrolled Table Body -->\n <div>\n <cdk-virtual-scroll-viewport #vp [itemSize]=\"50\" class=\"viewport pivot-viewport\"\n [class.apply-cdk-width]=\"applyCdkWidth()\" (scrolledIndexChange)=\"onPivotScroll($event)\"\n (scroll)=\"onBodyScroll($event)\" style=\"overflow: auto;\">\n <table class=\"eru-grid-table pivot-table\"\n [style]=\"'width: auto; min-width: 100%; --table-total-width: ' + getInitialTotalWidth() + 'px'\"\n [class.show-column-lines]=\"showColumnLines()\" [class.show-row-lines]=\"showRowLines()\">\n <!-- Column Groups for consistent width -->\n <ng-container *ngTemplateOutlet=\"pivotColGroup\"></ng-container>\n\n @if (!freezeHeader()) {\n <ng-container *ngTemplateOutlet=\"pivotTableHead\"></ng-container>\n }\n <!-- Table Body with Virtual Scrolling -->\n <tbody class=\"pivot-tbody\">\n\n <tr *cdkVirtualFor=\"let pivotRow of gridStore.pivotDisplayData(); \n trackBy: trackByPivotRowFn; \n let i = index\" class=\"pivot-row\" [class.subtotal-row]=\"pivotRow._isSubtotal\"\n [class.grand-total-row]=\"pivotRow._isGrandTotal\"\n [class.subtotal-bold]=\"pivotRow._isSubtotal && subTotalStyle() === 'bold'\"\n [class.subtotal-italic]=\"pivotRow._isSubtotal && subTotalStyle() === 'italic'\"\n [class.subtotal-highlighted]=\"pivotRow._isSubtotal && subTotalStyle() === 'highlighted'\"\n [class.grand-total-bold]=\"pivotRow._isGrandTotal && grandTotalStyle() === 'bold'\"\n [class.grand-total-italic]=\"pivotRow._isGrandTotal && grandTotalStyle() === 'italic'\"\n [class.grand-total-highlighted]=\"pivotRow._isGrandTotal && grandTotalStyle() === 'highlighted'\"\n [style.height.px]=\"50\" [attr.data-pivot-row]=\"i\">\n @if ((!pivotRow._isGrandTotal && freezeGrandTotal() ) || (!freezeGrandTotal() )) {\n @for (column of getLeafColumns(); track trackByColumnFn($index, column); let colIndex = $index) {\n @if (!shouldSkipCell(i, column.name)) {\n <td [attr.rowspan]=\"getEffectiveRowspan(i, column.name)\" [style.width.px]=\"column.field_size\"\n [style.minWidth.px]=\"column.field_size\" class=\"pivot-cell\"\n [class.row-dimension-cell]=\"isRowDimensionColumn(column.name)\"\n [class.column-dimension-cell]=\"!isRowDimensionColumn(column.name)\"\n [class.aggregated-value]=\"!isRowDimensionColumn(column.name) && column.datatype === 'number'\"\n [class.rowspan-cell]=\"getEffectiveRowspan(i, column.name) || 1 > 1\"\n [class.sticky-column]=\"isStickyColumn(column.name, colIndex)\"\n [style.position]=\"isStickyColumn(column.name, colIndex) ? 'sticky' : 'static'\"\n [style.left.px]=\"getStickyColumnLeft(column.name, colIndex)\"\n [style.z-index]=\"isStickyColumn(column.name, colIndex) ? 99 : 1\" [style.height.px]=\"50\"\n [attr.xx]=\"i\">\n <div class=\"cell-content pivot-cell-content\">\n <data-cell [class.aggregation]=\"!!column.aggregationFunction\" [fieldSize]=\"column.field_size\"\n [columnDatatype]=\"column.datatype\" [columnName]=\"column.name\"\n [value]=\"getEffectiveCellValue(i,column.name, pivotRow)\" [column]=\"column\"\n [drillable]=\"column.enableDrilldown || false\" [mode]=\"mode()\" [isEditable]=\"isEditable()\"\n [id]=\"'pivot_' + i + '_' + column.name\" [eruGridStore]=\"gridStore\">\n </data-cell>\n </div>\n </td>\n }\n }\n } @else {\n <td [style.height.px]=\"50\" [attr.colspan]=\"getLeafColumns().length\"> </td>\n }\n </tr>\n </tbody>\n </table>\n </cdk-virtual-scroll-viewport>\n\n </div>\n @if (freezeGrandTotal() && grandTotalPosition() === 'after') {\n <div #gtScroller class=\"header-shell gt-shell\" [class.adjust-bottom]=\"!applyCdkWidth()\"\n [class.adjust-bottom-vs]=\"adjustScrollWidth()\">\n <table class=\"eru-grid-table pivot-table\"\n [style]=\"'width: auto; min-width: 100%; --table-total-width: ' + getInitialTotalWidth() + 'px'\"\n [class.show-column-lines]=\"showColumnLines()\" [class.show-row-lines]=\"showRowLines()\">\n <ng-container *ngTemplateOutlet=\"pivotColGroup\"></ng-container>\n\n <ng-container *ngTemplateOutlet=\"pivotGrandTotal\"></ng-container>\n\n </table>\n </div>\n }\n\n\n </div>\n </div>\n </ng-container>\n } @else {\n\n <!-- Table Mode Template -->\n <ng-container>\n <cdk-virtual-scroll-viewport [itemSize]=\"30\" class=\"viewport table-viewport\"\n (scrolledIndexChange)=\"onScroll($event)\"\n [style]=\"'--table-min-height: ' + getInitialMinHeightPx() + 'px; --table-total-width: ' + getInitialTotalWidth() + 'px'\">\n <div class=\"table-wrapper\">\n\n <table class=\"eru-grid-table\" [class.show-column-lines]=\"showColumnLines()\"\n [class.show-row-lines]=\"showRowLines()\">\n <thead>\n <tr>\n @if(gridStore.configuration().config.allowSelection) {\n <th class=\"checkbox-column\"></th>\n }\n @if(shouldShowActionColumn('before')) {\n <th class=\"action-column column-header table-column-header\"\n style=\"width: 40px; min-width: 40px; max-width: 40px;\">\n Action\n </th>\n }\n <th *ngFor=\"let column of columns(); trackBy: trackByColumnFn\" [style.width.px]=\"column.field_size\"\n [resizeColumn]=\"gridStore.isFeatureEnabled('columnResizable')\" [style.minWidth.px]=\"column.field_size\"\n class=\"column-header table-column-header\">\n {{column.label}}\n </th>\n @if(shouldShowActionColumn('after')) {\n <th class=\"action-column column-header table-column-header\"\n style=\"width: 40px; min-width: 40px; max-width: 40px;\">\n Action\n </th>\n }\n </tr>\n </thead>\n <tbody *ngIf=\"columns() as columnsList\">\n <ng-container *cdkVirtualFor=\"let groupItem of groupedRows();\n trackBy: trackByGroupItemFn;\n let i = index;\n let first=first\">\n <tr *ngIf=\"groupItem.type === 'header' && groups().length > 1\" class=\"group-header\"\n (click)=\"toggleGroupExpansion(groupItem.group?.id || '')\">\n\n <td class=\"checkbox-column\" style=\"border: none;\">\n {{ groupItem.group?.isExpanded ? '\u25BC' : '\u25B6' }}\n </td>\n\n <td [attr.colspan]=\"2\" style=\"border: none;\">\n <span class=\"group-title\">\n {{ groupItem.group?.title }}\n </span>\n <span class=\"group-row-count\">\n ({{ groupItem.group?.currentLoadedRows || 0 }}/{{ groupItem.group?.totalRowCount || 0 }})\n </span>\n </td>\n </tr>\n <tr *ngIf=\"groupItem.type === 'table-header' && groups().length > 1\" style=\"background:#fafafa\">\n @if(gridStore.configuration().config.allowSelection) {\n <th class=\"checkbox-column\" style=\"text-align: center;\">\n <input type=\"checkbox\" [checked]=\"isGroupSelected(groupItem.group?.id || '')\"\n (click)=\"$event.stopPropagation()\"\n (change)=\"toggleGroupSelection($event, groupItem.group?.id || '')\">\n </th>\n }\n @if(shouldShowActionColumn('before')) {\n <td class=\"action-column\"\n style=\"width: 40px; min-width: 40px; max-width: 40px; text-align: center; cursor: pointer;\">\n @if (gridActions().length > 0) {\n <mat-icon [matMenuTriggerFor]=\"actionMenu\"\n [matMenuTriggerData]=\"{row: groupItem.row}\">more_horiz</mat-icon>\n } @else {\n <mat-icon (click)=\"onActionClick($event, groupItem.row)\">more_horiz</mat-icon>\n }\n </td>\n }\n <th *ngFor=\"let column of columns(); trackBy: trackByColumnFn;let i =index\" style=\"text-align: center;\"\n [style.width.px]=\"column.field_size\" [style.minWidth.px]=\"column.field_size\" [resizeColumn]=\"true\"\n [columnConfig]=\"column\" [columnDraggable]=\"i\" class=\"column-header\">\n <div class=\"column-drag-handle\"></div>\n {{column.label}} {{column.symbol}}\n </th>\n @if(shouldShowActionColumn('after')) {\n <td class=\"action-column\"\n style=\"width: 40px; min-width: 40px; max-width: 40px; text-align: center; cursor: pointer;\">\n @if (gridActions().length > 0) {\n <mat-icon [matMenuTriggerFor]=\"actionMenu\"\n [matMenuTriggerData]=\"{row: groupItem.row}\">more_horiz</mat-icon>\n } @else {\n <mat-icon (click)=\"onActionClick($event, groupItem.row)\">more_horiz</mat-icon>\n }\n </td>\n }\n </tr>\n <tr *ngIf=\"groupItem.type === 'row' && groupItem.group?.isExpanded\" class=\"row-item\"\n [attr.data-row-id]=\"groupItem.row?.entity_id\" [style.height.px]=\"30\" [style.minHeight.px]=\"30\"\n [style.maxHeight.px]=\"30\">\n @if(gridStore.configuration().config.allowSelection) {\n <td class=\"checkbox-column\" style=\"text-align: center;\">\n <input type=\"checkbox\" [checked]=\"isRowSelected(groupItem.row?.entity_id)\"\n (change)=\"toggleRowSelection($event, groupItem.row)\">\n </td>\n }\n @if(shouldShowActionColumn('before')) {\n <td class=\"action-column\"\n style=\"width: 40px; min-width: 40px; max-width: 40px; text-align: center; cursor: pointer;\">\n @if (gridActions().length > 0) {\n <mat-icon [matMenuTriggerFor]=\"actionMenu\"\n [matMenuTriggerData]=\"{row: groupItem.row}\">more_horiz</mat-icon>\n } @else {\n <mat-icon (click)=\"onActionClick($event, groupItem.row)\">more_horiz</mat-icon>\n }\n </td>\n }\n <td #cell *ngFor=\"let column of columns(); trackBy: trackByColumnFn\"\n [style.width.px]=\"column.field_size\" [style.minWidth.px]=\"column.field_size\" class=\"data-cell\"\n [style.height.px]=\"30\" [style.minHeight.px]=\"30\" [style.maxHeight.px]=\"30\"\n [matTooltipClass]=\"'error-message'\" [matTooltip]=\"datacell.error()?'Error: ' + datacell.error():''\"\n matTooltipPosition=\"below\">\n <div class=\"cell-content\">\n <data-cell #datacell [td]=cell [fieldSize]=\"column.field_size\" [columnDatatype]=\"column.datatype\"\n [columnName]=\"column.name\" [value]=\"groupItem.row?.[column.name] || ''\" [column]=\"column\"\n [mode]=\"mode()\" [isEditable]=\"isEditable()\" [drillable]=\"column.enableDrilldown || false\"\n [id]=\"i + '_' + column.name\" [eruGridStore]=\"gridStore\"></data-cell>\n </div>\n </td>\n @if(shouldShowActionColumn('after')) {\n <td class=\"action-column\"\n style=\"width: 40px; min-width: 40px; max-width: 40px; text-align: center; cursor: pointer;\">\n @if (gridActions().length > 0) {\n <mat-icon [matMenuTriggerFor]=\"actionMenu\"\n [matMenuTriggerData]=\"{row: groupItem.row}\">more_horiz</mat-icon>\n } @else {\n <mat-icon (click)=\"onActionClick($event, groupItem.row)\">more_horiz</mat-icon>\n }\n </td>\n }\n </tr>\n\n <tr *ngIf=\"groupItem.type === 'ghost-loading' && groupItem.group?.isExpanded\" class=\"ghost-loading-row\"\n [style.height.px]=\"30\" [style.minHeight.px]=\"30\" [style.maxHeight.px]=\"30\">\n @if(gridStore.configuration().config.allowSelection) {\n <th class=\"checkbox-column\"></th>\n }\n @if(shouldShowActionColumn('before')) {\n <td class=\"action-column ghost-cell-container\" style=\"width: 40px; min-width: 40px; max-width: 40px;\">\n <div class=\"ghost-cell\"></div>\n </td>\n }\n <td *ngFor=\"let column of columns(); trackBy: trackByColumnFn\" [style.width.px]=\"column.field_size\"\n [style.minWidth.px]=\"column.field_size\" class=\"ghost-cell-container\">\n <div class=\"ghost-cell\"></div>\n </td>\n @if(shouldShowActionColumn('after')) {\n <td class=\"action-column ghost-cell-container\" style=\"width: 40px; min-width: 40px; max-width: 40px;\">\n <div class=\"ghost-cell\"></div>\n </td>\n }\n </tr>\n\n <tr *ngIf=\"groupItem.type === 'row-place-holder'\" class=\"group-separator\">\n <td [attr.colspan]=\"groupSeperatorColSpan()\" class=\"separator-cell\"></td>\n </tr>\n </ng-container>\n </tbody>\n </table>\n </div>\n </cdk-virtual-scroll-viewport>\n </ng-container>\n }\n</div>\n\n<!-- Pivot Table Header Template -->\n<ng-template #pivotTableHead>\n <thead>\n @if (hasNestedHeaders()) {\n <ng-container>\n @for (headerRow of getHeaderRows(); track headerRow; let rowIndex = $index) {\n <tr class=\"pivot-header pivot-header-container\" [class.pivot-header-level]=\"'level-' + rowIndex\">\n @for (header of headerRow; track trackByHeaderFn($index, header); let colIndex = $index) {\n <th [attr.colspan]=\"header.colspan\" [attr.rowspan]=\"header.rowspan\"\n [resizeColumn]=\"gridStore.isFeatureEnabled('columnResizable') && header.level === 0\"\n class=\"column-header pivot-column-header nested-header\"\n [class.row-dimension-header]=\"isRowDimensionHeader(header)\"\n [class.column-dimension-header]=\"!isRowDimensionHeader(header)\" [class.expanded]=\"header.isExpanded\"\n [class.collapsed]=\"!header.isExpanded\" [class.sticky-column]=\"isStickyColumn(header.name, colIndex)\"\n [style.position]=\"isStickyColumn(header.name, colIndex) ? 'sticky' : 'static'\"\n [style.left.px]=\"getStickyColumnLeft(header.name, colIndex)\"\n [style.z-index]=\"isStickyColumn(header.name, colIndex) ? 100 : 1\"\n style=\"min-height: 40px; height: auto; padding: 8px 6px;\">\n <div class=\"header-content\">\n\n <data-cell [fieldSize]=\"header.field_size\" [columnDatatype]=\"header.dataType\" [columnName]=\"header.name\"\n [value]=\"header.label\" [column]=\"header\" [frozenGrandTotalCell]=\"true\"\n [drillable]=\"header.enableDrilldown || false\" [mode]=\"mode()\" [isEditable]=\"isEditable()\"\n [id]=\"'pivot_' + $index + '_' + header.name\" [eruGridStore]=\"gridStore\">\n </data-cell>\n <!-- <span class=\"header-label header-wrap-text\">{{header.label}}</span> -->\n <!-- <button *ngIf=\"!isRowDimensionHeader(header)\" \n class=\"collapse-toggle-btn\"\n [title]=\"header.isExpanded ? 'Collapse group' : 'Expand group'\"\n (click)=\"toggleColumnGroup(header.groupKey)\"\n type=\"button\">\n <span class=\"collapse-icon\">+</span>\n </button> -->\n </div>\n </th>\n }\n </tr>\n }\n </ng-container>\n } @else {\n <!-- Simple header fallback -->\n <ng-container>\n <tr class=\"pivot-header\" [class.freeze-header-enabled]=\"freezeHeader()\">\n @for (column of getLeafColumns(); track trackByColumnFn($index, column); let colIndex = $index) {\n <th [style.width.px]=\"column.field_size\" [style.minWidth.px]=\"column.field_size\"\n [resizeColumn]=\"gridStore.isFeatureEnabled('columnResizable')\" [columnConfig]=\"column\"\n class=\"column-header pivot-column-header\" [class.sticky-column]=\"isStickyColumn(column.name, colIndex)\"\n [style.position]=\"isStickyColumn(column.name, colIndex) ? 'sticky' : 'static'\"\n [style.left.px]=\"getStickyColumnLeft(column.name, colIndex)\"\n [style.z-index]=\"isStickyColumn(column.name, colIndex) ? 100 : 1\"\n style=\"min-height: 40px;height: auto;padding: 8px 6px;position: relative;left: 0px;z-index: 1\">\n {{column.label}}\n </th>\n }\n </tr>\n </ng-container>\n }\n\n </thead>\n</ng-template>\n\n<!-- Column Group Template for consistent column widths -->\n<ng-template #pivotColGroup>\n <colgroup>\n @for (column of getLeafColumns(); track trackByColumnFn($index, column)) {\n <col\n [style]=\"'width: ' + column.field_size + 'px !important; min-width: ' + column.field_size + 'px !important; max-width: ' + column.field_size + 'px !important; --col-width: ' + column.field_size + 'px'\">\n }\n </colgroup>\n</ng-template>\n\n<ng-template #pivotGrandTotal>\n <tbody class=\"pivot-tbody\">\n @for (pivotRow of gridStore.pivotGrandTotalData(); track trackByPivotRowFn($index, pivotRow); let i = $index) {\n <tr class=\"pivot-row grand-total-row\"\n [class.grand-total-bold]=\"pivotRow._isGrandTotal && grandTotalStyle() === 'bold'\"\n [class.grand-total-italic]=\"pivotRow._isGrandTotal && grandTotalStyle() === 'italic'\"\n [class.grand-total-highlighted]=\"pivotRow._isGrandTotal && grandTotalStyle() === 'highlighted'\"\n [style.height.px]=\"50\" [attr.data-pivot-row]=\"i\">\n <!-- <td colspan=\"20\">{{pivotRow | json}}</td> -->\n @for (column of getLeafColumns(); track trackByColumnFn($index, column); let colIndex = $index) {\n <td [attr.rowspan]=\"getEffectiveRowspan(i, column.name)\" [style.width.px]=\"column.field_size\"\n [style.minWidth.px]=\"column.field_size\" class=\"pivot-cell\"\n [class.row-dimension-cell]=\"isRowDimensionColumn(column.name)\"\n [class.column-dimension-cell]=\"!isRowDimensionColumn(column.name)\"\n [class.aggregated-value]=\"!isRowDimensionColumn(column.name) && column.datatype === 'number'\"\n [class.rowspan-cell]=\"getEffectiveRowspan(i, column.name) || 1 > 1\"\n [class.sticky-column]=\"isStickyColumn(column.name, colIndex)\"\n [style.position]=\"isStickyColumn(column.name, colIndex) ? 'sticky' : 'static'\"\n [style.left.px]=\"getStickyColumnLeft(column.name, colIndex)\"\n [style.z-index]=\"isStickyColumn(column.name, colIndex) ? 99 : 1\" [style.height.px]=\"50\" [attr.xx]=\"i\">\n <div class=\"cell-content pivot-cell-content\">\n <data-cell [fieldSize]=\"column.field_size\" [columnDatatype]=\"column.datatype\" [columnName]=\"column.name\"\n [value]=\"getEffectiveCellValue(i,column.name, pivotRow)\" [column]=\"column\" [frozenGrandTotalCell]=\"true\"\n [drillable]=\"column.enableDrilldown || false\" [mode]=\"mode()\" [isEditable]=\"isEditable()\"\n [id]=\"'pivot_' + i + '_' + column.name\" [eruGridStore]=\"gridStore\">\n </data-cell>\n </div>\n </td>\n }\n </tr>\n }\n </tbody>\n</ng-template>\n\n<mat-menu #actionMenu=\"matMenu\">\n <ng-template matMenuContent let-row=\"row\">\n @for (item of gridActions(); track item.action) {\n <button mat-menu-item (click)=\"onActionClick($event, row, item)\">\n @if (item.icon) {\n <mat-icon class=\"action-icon\" fontIcon=\"{{item.icon}}\"></mat-icon>\n }\n <span>{{item.menu}}</span>\n </button>\n }\n </ng-template>\n</mat-menu>", styles: ["@charset \"UTF-8\";:host{display:block;width:100%;height:100%;font-family:var(--grid-font-family);--grid-primary: #6750a4;--grid-on-primary: #ffffff;--grid-surface: #fef7ff;--grid-surface-variant: #e7e0ec;--grid-surface-container: #f3edf7;--grid-surface-container-high: #ede7f0;--grid-on-surface: #1d1b20;--grid-on-surface-variant: #49454f;--grid-outline: #79757f;--grid-outline-variant: #cac4d0;--grid-error: #ba1a1a;--grid-error-container: #ffdad6;--grid-font-family: \"Poppins\", \"Roboto\", -apple-system, BlinkMacSystemFont, \"Segoe UI\", sans-serif;--grid-font-size-body: 12px;--grid-font-size-caption: 12px !important;--grid-line-height-body: 1;--grid-aggregation-text-align: right;--grid-number-text-align: right;--grid-spacing-xxs: 2px;--grid-spacing-xs: 4px;--grid-spacing-sm: 8px;--grid-spacing-md: 16px;--grid-spacing-lg: 24px;--grid-border-radius: 4px;--grid-elevation-1: 0px 1px 2px 0px rgba(0, 0, 0, .3), 0px 1px 3px 1px rgba(0, 0, 0, .15);--grid-elevation-2: 0px 1px 2px 0px rgba(0, 0, 0, .3), 0px 2px 6px 2px rgba(0, 0, 0, .15)}.incremental-row-container{padding:10px;width:100%;height:100%;min-height:var(--table-min-height, 400px);max-height:none;overflow:auto;position:relative;background-color:var(--grid-surface);border-radius:var(--grid-border-radius);box-shadow:var(--grid-elevation-1);font-family:var(--grid-font-family)}.viewport{overflow-x:auto;overflow-y:auto;background-color:var(--grid-surface);scrollbar-gutter:stable}.viewport.apply-cdk-width{width:calc(var(--table-total-width) + 10px)!important}.table-viewport{background-color:var(--grid-surface);height:auto;min-height:var(--table-min-height, 300px);max-height:80vh;overflow-x:auto;overflow-y:auto}.pivot-viewport{min-height:var(--table-min-height, 300px);overflow-x:auto;overflow-y:auto;background-color:var(--grid-surface)}.pivot-viewport .cdk-virtual-scroll-content-wrapper{width:auto;height:auto}.table-wrapper{min-width:100%;overflow-x:visible}.incremental-row-container .eru-grid-table,.eru-grid-table{width:100%!important;border-collapse:separate;border-spacing:0;table-layout:fixed!important;background-color:var(--grid-surface);color:var(--grid-on-surface);font-size:var(--grid-font-size-body);line-height:var(--grid-line-height-body)}.eru-grid-table th,.eru-grid-table td{text-align:left;overflow:hidden!important;text-overflow:ellipsis!important;white-space:nowrap!important;background-color:var(--grid-surface);color:var(--grid-on-surface);min-width:0;max-width:100%!important;box-sizing:border-box;position:relative}.eru-grid-table th:hover,.eru-grid-table td:hover{background-color:var(--grid-surface-variant)}.eru-grid-table thead{background-color:var(--grid-surface-container);transform:translateZ(0);will-change:transform;backface-visibility:hidden}.eru-grid-table thead.freeze-header-enabled{box-shadow:0 2px 4px #0000001a;border-bottom:2px solid var(--grid-outline)}.eru-grid-table thead th{background-color:var(--grid-surface-container);color:var(--grid-on-surface);font-weight:500;font-size:var(--grid-font-size-caption)}.checkbox-column{width:50px;min-width:50px;max-width:50px;text-align:center;background-color:var(--grid-surface-container)}.checkbox-column input[type=checkbox]{width:16px;height:16px;cursor:pointer;accent-color:var(--grid-primary);border-radius:var(--grid-border-radius)}.checkbox-column input[type=checkbox]:focus{outline:2px solid var(--grid-primary);outline-offset:2px}.group-header{background-color:var(--grid-surface-container);color:var(--grid-on-surface);font-size:var(--grid-font-size-caption);font-weight:500;border-bottom:1px solid var(--grid-outline);cursor:pointer;transition:background-color .2s ease}.group-header:hover{background-color:var(--grid-surface-container-high)}.group-header .group-title{font-weight:600;color:var(--grid-primary)}.group-header .group-row-count{color:var(--grid-on-surface-variant);font-size:var(--grid-font-size-caption);margin-left:var(--grid-spacing-sm)}.row-item{border:1px solid var(--grid-outline);background-color:var(--grid-surface);transition:background-color .2s ease,box-shadow .2s ease}.row-item:hover{background-color:var(--grid-surface-variant);box-shadow:var(--grid-elevation-1)}.table-column-header{padding:12px 8px}.column-header{font-weight:500;text-align:center!important;font-size:var(--grid-font-size-caption, 12px);position:relative;-webkit-user-select:none;user-select:none;background-color:var(--grid-surface-container);color:var(--grid-on-surface)}.column-header:hover{background-color:var(--grid-surface-container-high)}.column-drag-handle{position:absolute;left:0;top:0;bottom:0;width:12px;cursor:grab;opacity:0;transition:opacity .2s ease,background-color .2s ease;z-index:2;display:flex;align-items:center;justify-content:center;border-right:1px solid transparent}.column-drag-handle:after{content:\"\\22ee\\22ee\";font-size:14px;color:var(--grid-on-surface-variant);transform:rotate(90deg)}.column-drag-handle:hover{background-color:var(--grid-surface-container-high);border-right-color:var(--grid-outline)}.column-header:hover .column-drag-handle{opacity:1}.column-drag-handle:active{cursor:grabbing}.dragging{opacity:1;background-color:var(--grid-surface-container);box-shadow:var(--grid-elevation-2)}.drag-over{background-color:var(--grid-surface-container);border-color:var(--grid-primary)}.data-cell{background-color:var(--grid-surface);color:var(--grid-on-surface);font-size:var(--grid-font-size-body)}.cell-content{align-items:center}.cell-content .mdc-text-field{padding:0px var(--grid-spacing-xxs)!important}.cell-display-text{align-items:center;padding:0px var(--grid-spacing-xs)}.ghost-loading-row{background-color:transparent}.ghost-cell-container{padding:var(--grid-spacing-sm)}.ghost-cell{height:20px;width:100%;background-color:var(--grid-surface-container);animation:pulse 1.5s ease-in-out infinite;border-radius:var(--grid-border-radius)}@keyframes pulse{0%,to{opacity:1}50%{opacity:.5}}.resizing{cursor:col-resize;-webkit-user-select:none;user-select:none}.column-resizer{position:absolute;right:0;top:0;bottom:0;width:4px;cursor:col-resize;background-color:transparent;transition:background-color .2s ease}.column-resizer:hover{background-color:var(--grid-primary)}.group-separator{height:var(--grid-spacing-sm);background-color:var(--grid-surface-variant)}.group-separator .separator-cell{background-color:var(--grid-surface-variant);border:none;height:var(--grid-spacing-sm)}.error-state{background-color:var(--grid-error-container);color:var(--grid-error);border-color:var(--grid-error)}.error-message{background-color:var(--grid-error);color:#fff;padding:var(--grid-spacing-sm);border-radius:var(--grid-border-radius);font-size:var(--grid-font-size-caption)}.incremental-row-container .eru-grid-table tbody,.incremental-row-container .eru-grid-table{position:relative}.incremental-row-container .eru-grid-table.show-column-lines{border-right:var(--grid-outline-width, 1px) solid var(--grid-outline, #e0e0e0)!important;border-top:var(--grid-outline-width, 1px) solid var(--grid-outline, #e0e0e0)!important;border-bottom:var(--grid-outline-width, 1px) solid var(--grid-outline, #e0e0e0)!important}.incremental-row-container .eru-grid-table:not(.show-column-lines){border:var(--grid-outline-width, 1px) solid var(--grid-outline, #e0e0e0)!important}.incremental-row-container .eru-grid-table thead:after{content:\"\";position:absolute;bottom:0;left:0;right:0;height:calc(var(--grid-outline-width, 1px) * 2);background-color:var(--grid-outline, #e0e0e0);pointer-events:none;z-index:10}.incremental-row-container .eru-grid-table.show-column-lines thead th{border-left:var(--grid-outline-width, 1px) solid var(--grid-outline, #e0e0e0)!important;border-bottom:var(--grid-outline-width, 1px) solid var(--grid-outline, #e0e0e0)!important}.incremental-row-container .eru-grid-table.show-column-lines tbody td{border-left:var(--grid-outline-width, 1px) solid var(--grid-outline, #e0e0e0)!important}.incremental-row-container .eru-grid-table.show-row-lines thead th{border-left:var(--grid-outline-width, 1px) solid var(--grid-outline, #e0e0e0)!important;border-bottom:var(--grid-outline-width, 1px) solid var(--grid-outline, #e0e0e0)!important}.incremental-row-container .eru-grid-table.show-row-lines tbody td{border-bottom:var(--grid-outline-width, 1px) solid var(--grid-outline, #e0e0e0)!important}@media (max-width: 768px){.incremental-row-container{height:600px}.eru-grid-table th,.eru-grid-table td{font-size:var(--grid-font-size-caption)}.checkbox-column{width:40px;min-width:40px;max-width:40px}}@media (prefers-contrast: high){.eru-grid-table th,.eru-grid-table td{border-width:2px}.row-item:hover{border-width:2px;border-color:var(--grid-primary)}}@media (prefers-reduced-motion: reduce){.row-item,.column-drag-handle,.ghost-cell{transition:none;animation:none}}.pivot-table .nested-header{text-align:center;font-weight:600;background:var(--grid-surface-container)}.pivot-table .nested-header.row-dimension-header{background:var(--grid-surface-container);font-weight:600}.pivot-table .pivot-header-leafcols{padding:0;margin:0;height:0}.pivot-table .pivot-header-level.level-0 .nested-header{font-size:14px;padding:12px 8px}.pivot-table .pivot-header-level.level-1 .nested-header{font-size:13px;padding:10px 6px}.pivot-table .pivot-header-level.level-2 .nested-header{font-size:12px;padding:8px 4px}.pivot-table .nested-header:hover{background:var(--grid-surface-variant);color:var(--grid-primary);transition:all .2s ease}.pivot-table .pivot-cell.aggregated-value{font-weight:500;font-family:Roboto Mono,monospace}.pivot-table .pivot-cell-content{display:flex;justify-content:center;align-items:center;min-height:38px}.pivot-table .rowspan-cell{vertical-align:middle}.pivot-table .rowspan-cell .pivot-cell-content{height:100%}.pivot-mode .incremental-row-container{display:flex;flex-direction:column;height:auto;max-height:85vh;overflow:auto}.pivot-mode .h-shell{position:relative;width:calc(100% - var(--scrollbar-width, 17px))!important;top:0;z-index:1;overflow-x:hidden;overflow-y:hidden;scrollbar-width:none;-ms-overflow-style:none}.pivot-mode .h-shell::-webkit-scrollbar{display:none}.pivot-mode .gt-shell{position:relative;bottom:50px;flex-shrink:0;overflow-x:hidden;overflow-y:hidden;scrollbar-width:none;-ms-overflow-style:none}.pivot-mode .gt-shell::-webkit-scrollbar{display:none}.pivot-mode .gt-shell table{border-bottom:var(--grid-outline-width, 1px) solid var(--grid-outline, #e0e0e0)!important}.pivot-mode .gt-shell.adjust-bottom-vs{bottom:66px!important}.pivot-mode .gt-shell.adjust-bottom:not(.adjust-bottom-vs){bottom:calc(66px - var(--scrollbar-width, 17px))!important}.pivot-mode .header-shell{flex-shrink:0;width:100%;box-sizing:border-box;padding-right:var(--scrollbar-width, 17px);overflow-x:auto;overflow-y:hidden;scrollbar-width:none;-ms-overflow-style:none}.pivot-mode .header-shell::-webkit-scrollbar{display:none}.pivot-mode .header-shell.apply-cdk-width{width:calc(var(--table-total-width) + 10px)!important}.pivot-mode .header-shell .eru-grid-table{margin-bottom:0;width:100%;table-layout:fixed}.pivot-mode .header-shell .eru-grid-table thead{background:var(--grid-surface-container)}.pivot-mode .header-shell .eru-grid-table thead th{background:var(--grid-surface-container);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;width:var(--col-width)!important;min-width:var(--col-width)!important;max-width:var(--col-width)!important}.pivot-mode .header-shell .eru-grid-table thead th.sticky-column{position:sticky;background:var(--grid-surface-container);z-index:111}.pivot-mode .header-shell .eru-grid-table tbody td{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;width:var(--col-width)!important;min-width:var(--col-width)!important;max-width:var(--col-width)!important}.pivot-mode .pivot-container{display:flex;flex-direction:column;height:100%;width:100%;overflow:hidden}.pivot-mode .pivot-table{width:auto!important;min-width:100%!important;table-layout:fixed!important;width:100%!important}.pivot-mode .pivot-table colgroup col{width:var(--col-width)!important;min-width:var(--col-width)!important;max-width:var(--col-width)!important;flex:none!important;flex-shrink:0!important;flex-grow:0!important}.pivot-mode .pivot-table td,.pivot-mode .pivot-table th{box-sizing:border-box!important;flex:none!important;flex-shrink:0!important;flex-grow:0!important;word-wrap:break-word!important;word-break:break-all!important}.pivot-mode .pivot-table *{max-width:var(--col-width)!important;box-sizing:border-box!important}.pivot-mode .pivot-table colgroup{width:100%!important}.pivot-mode .pivot-table colgroup col{width:var(--col-width)!important;min-width:var(--col-width)!important;max-width:var(--col-width)!important;flex-basis:var(--col-width)!important;flex:0 0 var(--col-width)!important}.pivot-mode .pivot-table table{width:100%!important;table-layout:fixed!important;border-collapse:collapse!important;border-spacing:0!important}.pivot-mode .pivot-table[style*=--table-total-width]{width:var(--table-total-width)!important;min-width:var(--table-total-width)!important;max-width:var(--table-total-width)!important}.pivot-mode .pivot-table colgroup col{width:var(--col-width)!important;min-width:var(--col-width)!important;max-width:var(--col-width)!important;flex:0 0 var(--col-width)!important;flex-basis:var(--col-width)!important;flex-grow:0!important;flex-shrink:0!important;overflow:hidden!important}.pivot-mode .pivot-table tbody td,.pivot-mode .pivot-table thead th{width:var(--col-width)!important;min-width:var(--col-width)!important;max-width:var(--col-width)!important;overflow:hidden!important;text-overflow:ellipsis!important;white-space:nowrap!important}.pivot-mode .pivot-table .cell-content,.pivot-mode .pivot-table data-cell{width:100%!important;max-width:100%!important;overflow:hidden!important;text-overflow:ellipsis!important;white-space:nowrap!important;display:block!important}.pivot-mode .pivot-table table{width:var(--table-total-width)!important;min-width:var(--table-total-width)!important;max-width:var(--table-total-width)!important;table-layout:fixed!important;border-collapse:collapse!important;border-spacing:0!important;word-wrap:break-word!important;word-break:break-all!important}.pivot-mode .pivot-tbody tr.pivot-row{min-height:50px!important;height:50px!important}.pivot-mode .pivot-tbody tr.pivot-row:hover{background-color:var(--grid-surface-variant)}.pivot-mode .pivot-tbody tr.pivot-row:nth-child(2n){background-color:#00000005}.pivot-mode .pivot-tbody tr.pivot-row td{min-height:50px!important;height:50px!important;vertical-align:middle;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;width:var(--col-width)!important;min-width:var(--col-width)!important;max-width:var(--col-width)!important}.pivot-mode .pivot-tbody tr.pivot-row td .cell-content{min-height:48px;display:flex;align-items:center;justify-content:center}.pivot-mode .pivot-tbody tr.pivot-row td .cell-content data-cell{width:100%;min-height:46px;display:flex;align-items:center;justify-content:center;overflow:hidden;flex-shrink:0}.pivot-mode .pivot-cell{vertical-align:middle;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;width:var(--col-width)!important;min-width:var(--col-width)!important;max-width:var(--col-width)!important}.pivot-mode .pivot-cell.aggregated-value{font-weight:500;font-family:Roboto Mono,monospace}.pivot-mode .pivot-cell .cell-content{display:flex;justify-content:center;align-items:center;min-height:40px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;flex-shrink:0}.pivot-mode .pivot-table .subtotal-row{background-color:var(--grid-surface-container)!important;font-weight:600}.pivot-mode .pivot-table .subtotal-row td{background-color:var(--grid-surface-container);color:var(--grid-on-surface-variant)}.pivot-mode .pivot-table .subtotal-row td:first-child{color:var(--grid-primary)}.pivot-mode .pivot-table .subtotal-row td.aggregated-value{font-weight:500;color:var(--grid-primary)}.pivot-mode .pivot-table .subtotal-row:hover{background-color:var(--grid-surface-container-high)!important}.pivot-mode .pivot-table .subtotal-row:hover td{background-color:var(--grid-surface-container-high)}.pivot-mode .pivot-table .subtotal-bold td{font-weight:600!important;font-style:normal!important}.pivot-mode .pivot-table .subtotal-bold td.aggregated-value{font-weight:600!important}.pivot-mode .pivot-table .subtotal-italic td{font-style:italic!important}.pivot-mode .pivot-table .subtotal-italic td:first-child{font-weight:600!important}.pivot-mode .pivot-table .subtotal-italic td.aggregated-value{font-style:italic!important;font-weight:500!important}.pivot-mode .pivot-table .subtotal-highlighted{background-color:var(--grid-surface-variant)!important}.pivot-mode .pivot-table .subtotal-highlighted td{background-color:var(--grid-surface-variant)!important;font-weight:700!important;font-style:normal!important;color:var(--grid-primary)!important}.pivot-mode .pivot-table .subtotal-highlighted td.aggregated-value{font-weight:500!important;color:var(--grid-primary)!important}.pivot-mode .pivot-table .subtotal-highlighted:hover,.pivot-mode .pivot-table .subtotal-highlighted:hover td{background-color:var(--grid-surface-container-high)!important}.pivot-mode .pivot-table .grand-total-row{background-color:var(--grid-surface-container-high)!important;font-weight:700;font-size:var(--grid-font-size-body)}.pivot-mode .pivot-table .grand-total-row td{background-color:var(--grid-surface-container-high)!important;color:var(--grid-on-surface)}.pivot-mode .pivot-table .grand-total-row td:first-child{font-style:normal;font-weight:800;color:var(--grid-primary)}.pivot-mode .pivot-table .grand-total-row td.aggregated-value{font-weight:500;color:var(--grid-primary);font-family:Roboto Mono,monospace}.pivot-mode .pivot-table .grand-total-row:hover,.pivot-mode .pivot-table .grand-total-row:hover td{background-color:var(--grid-surface-container-high)!important}.pivot-mode .pivot-table .grand-total-bold td{font-weight:700!important;font-style:normal!important}.pivot-mode .pivot-table .grand-total-bold td.aggregated-value{font-weight:700!important}.pivot-mode .pivot-table .grand-total-italic td,.pivot-mode .pivot-table .grand-total-italic td.aggregated-value{font-style:italic!important;font-weight:500!important}.pivot-mode .pivot-table .grand-total-highlighted{background-color:var(--grid-primary)!important;box-shadow:var(--grid-elevation-2)!important}.pivot-mode .pivot-table .grand-total-highlighted td{background-color:var(--grid-primary)!important;color:var(--grid-on-primary)!important;font-weight:500!important;font-style:normal!important}.pivot-mode .pivot-table .grand-total-highlighted td.aggregated-value{color:var(--grid-on-primary)!important;font-weight:500!important}.pivot-mode .pivot-table .grand-total-highlighted:hover,.pivot-mode .pivot-table .grand-total-highlighted:hover td{background-color:var(--grid-primary)!important}.pivot-mode .pivot-table .collapsible-header{position:relative}.pivot-mode .pivot-table .collapsible-header .header-content{display:flex;align-items:center;justify-content:space-between;gap:var(--grid-spacing-xs);padding:var(--grid-spacing-xs) var(--grid-spacing-sm)}.pivot-mode .pivot-table .collapsible-header .header-label{flex:1;font-weight:600}.pivot-mode .pivot-table .collapsible-header .collapse-toggle-btn{background:none;border:none;cursor:pointer;padding:var(--grid-spacing-xxs);margin:0;display:flex;align-items:center;justify-content:center;width:20px;height:20px;border-radius:var(--grid-border-radius);color:var(--grid-on-surface-variant);transition:all .2s ease;font-size:12px;font-weight:600}.pivot-mode .pivot-table .collapsible-header .collapse-toggle-btn:hover{background-color:var(--grid-surface-container);color:var(--grid-primary);transform:scale(1.1)}.pivot-mode .pivot-table .collapsible-header .collapse-toggle-btn:focus{outline:2px solid var(--grid-primary);outline-offset:1px}.pivot-mode .pivot-table .collapsible-header .collapse-toggle-btn .collapse-icon{display:block;line-height:1;font-family:monospace;font-size:14px}.pivot-mode .pivot-table .collapsible-header.expanded .collapse-toggle-btn .collapse-icon{color:var(--grid-primary)}.pivot-mode .pivot-table .collapsible-header.collapsed{background-color:var(--grid-surface-variant)}.pivot-mode .pivot-table .collapsible-header.collapsed .header-label{font-style:italic;color:var(--grid-on-surface-variant)}.pivot-mode .pivot-table .collapsible-header.collapsed .collapse-toggle-btn .collapse-icon{color:var(--grid-outline)}.pivot-mode .pivot-table .collapsible-header:hover{background-color:var(--grid-surface-container)}.pivot-mode .pivot-table .collapsible-header:hover .header-label{color:var(--grid-on-surface)}.pivot-mode .pivot-table .pivot-single-table{display:flex;flex-direction:column;height:100%;width:100%;overflow:hidden;min-height:var(--table-min-height)!important}.pivot-mode .pivot-table .pivot-single-table .pivot-header-container{flex-shrink:0;background:var(--grid-surface)!important;overflow-x:auto;overflow-y:hidden;min-height:100px!important;height:auto!important}.pivot-mode .pivot-table .pivot-single-table .pivot-header-container .pivot-table{width:auto;min-width:100%;height:auto!important;min-height:100px!important}.pivot-mode .pivot-table .pivot-single-table .pivot-header-container .pivot-table th{background:var(--grid-surface-container)!important;padding:8px 6px!important;white-space:nowrap;min-width:50px;min-height:40px!important;height:auto!important;position:relative;visibility:visible!important;color:var(--grid-on-surface)!important}.pivot-mode .pivot-table .pivot-single-table .pivot-header-container .pivot-table th.sticky-column{position:sticky!important;background:var(--grid-surface-container)!important;border-right:2px solid var(--grid-primary)!important;box-shadow:2px 0 4px #0000001a;z-index:101!important}.pivot-mode .pivot-table .pivot-single-table .pivot-data-container{flex:1;overflow:auto;min-height:300px!important;height:auto!important}.pivot-mode .pivot-table .pivot-single-table .pivot-data-container .pivot-viewport{height:100%!important;width:100%!important;overflow-x:auto!important;overflow-y:auto!important}.pivot-mode .pivot-table .pivot-single-table .pivot-data-container .pivot-table,.pivot-mode .pivot-table .pivot-single-table .pivot-data-container .pivot-data-table{width:auto;min-width:100%;height:auto!important}.pivot-mode .pivot-table .pivot-single-table .pivot-data-container .pivot-table td,.pivot-mode .pivot-table .pivot-single-table .pivot-data-container .pivot-data-table td{padding:8px 6px!important;white-space:nowrap;min-width:50px;min-height:32px!important;height:auto!important;background:var(--grid-surface)!important;color:var(--grid-on-surface)!important;visibility:visible!important}.pivot-mode .pivot-table .pivot-single-table .pivot-data-container .pivot-table td.sticky-column,.pivot-mode .pivot-table .pivot-single-table .pivot-data-container .pivot-data-table td.sticky-column{position:sticky!important;background:var(--grid-surface-container)!important;border-right:2px solid var(--grid-primary)!important;box-shadow:2px 0 4px #0000001a;z-index:100!important}.pivot-mode .pivot-table .pivot-single-table .pivot-data-container .pivot-table tbody tr,.pivot-mode .pivot-table .pivot-single-table .pivot-data-container .pivot-data-table tbody tr{height:auto!important;min-height:50px!important}.pivot-mode .pivot-table .pivot-single-table .pivot-data-container .pivot-table tbody tr.pivot-row,.pivot-mode .pivot-table .pivot-single-table .pivot-data-container .pivot-data-table tbody tr.pivot-row{visibility:visible!important;display:table-row!important}.pivot-mode .pivot-table .collapsed-column-group{background-color:var(--grid-surface-container);border-left:3px solid var(--grid-primary)}.pivot-mode .pivot-table .collapsed-column-group:hover{background-color:var(--grid-surface-container-high)}.pivot-row.subtotal-row{background-color:var(--grid-surface-variant);font-weight:500}.pivot-row.subtotal-row.subtotal-bold{font-weight:500}.pivot-row.subtotal-row.subtotal-italic{font-style:italic}.pivot-row.subtotal-row.subtotal-highlighted{background-color:var(--grid-primary);color:var(--grid-on-primary)}.pivot-row.grand-total-row{background-color:var(--grid-surface-container);font-weight:600}.pivot-row.grand-total-row.grand-total-bold{font-weight:800}.pivot-row.grand-total-row.grand-total-italic{font-style:italic}.pivot-row.grand-total-row.grand-total-highlighted{background-color:var(--grid-primary);color:var(--grid-on-primary)}.pivot-row.first-visible-row{background-color:#6750a41a!important;position:relative}.pivot-row.first-visible-row:before{content:\"\\1f441\\fe0f First Visible\";position:absolute;top:-20px;left:0;background:var(--grid-primary);color:var(--grid-on-primary);padding:2px 6px;font-size:10px;border-radius:2px;z-index:1000}.header-wrap-text{white-space:pre-wrap;word-break:auto-phrase}.action-column{width:40px;min-width:40px;max-width:40px;text-align:center;background-color:var(--grid-surface-container)}.action-column mat-icon{font-family:Material Icons!important;font-size:20px;width:20px;height:20px;line-height:20px;color:var(--grid-on-surface-variant);cursor:pointer}.action-column mat-icon:hover{color:var(--grid-primary)}.mat-mdc-menu-item{min-height:0px!important}.mat-mdc-menu-content{padding:0!important}.action-icon{font-family:Material Icons!important;font-size:20px!important;width:20px!important;height:20px!important;line-height:20px!important;text-transform:none!important;font-weight:400!important;font-style:normal!important;display:inline-flex!important;align-items:center;justify-content:center;margin-right:12px;color:var(--grid-on-surface-variant);cursor:pointer}.action-icon:hover{color:var(--grid-primary)}\n"] }]
|
|
5567
|
+
], template: "<!-- <div style=\"background: #f0f0f0; font-size: 12px; border-bottom: 1px solid #ccc;\">\n currentPivotScrollIndex {{currentPivotScrollIndex()}} | \n firstDataRowIndex {{firstDataRowIndex()}} | \n firstTr {{firstTr}} |\n maxDepth {{maxDepth()}}\n</div> -->\n<div class=\"incremental-row-container eru-grid\" #rowContainer [class.pivot-mode]=\"gridStore.isPivotMode()\"\n [class.table-mode]=\"!gridStore.isPivotMode()\">\n\n <!-- Pivot Mode Template -->\n @if (gridStore.isPivotMode()) {\n <ng-container>\n <div class=\"pivot-container\" style=\"display: flex; flex-direction: column; height: 100%;\"\n [style]=\"'--table-min-height: ' + getInitialMinHeightPx() + 'px; --table-total-width: ' + getInitialTotalWidth() + 'px'\">\n <!-- Debug info for first visible row -->\n\n\n <div class=\"pivot-single-table\"\n style=\"height: 100%; width: 100%; overflow: hidden; display: flex; flex-direction: column;\">\n @if (freezeHeader()) {\n <div #headerScroller class=\"header-shell\">\n <table class=\"eru-grid-table pivot-table\"\n [style]=\"'width: auto; min-width: 100%; --table-total-width: ' + getInitialTotalWidth() + 'px'\"\n [class.show-column-lines]=\"showColumnLines()\" [class.show-row-lines]=\"showRowLines()\">\n <!-- Column Groups for consistent width -->\n <ng-container *ngTemplateOutlet=\"pivotColGroup\"></ng-container>\n\n <ng-container *ngTemplateOutlet=\"pivotTableHead\"></ng-container>\n @if(grandTotalPosition() === 'before' && freezeGrandTotal()) {\n <ng-container *ngTemplateOutlet=\"pivotGrandTotal\"></ng-container>\n }\n </table>\n </div>\n }\n <!-- Virtual Scrolled Table Body -->\n <div>\n <cdk-virtual-scroll-viewport #vp [itemSize]=\"50\" class=\"viewport pivot-viewport\"\n [class.apply-cdk-width]=\"applyCdkWidth()\" (scrolledIndexChange)=\"onPivotScroll($event)\"\n (scroll)=\"onBodyScroll($event)\" style=\"overflow: auto;\">\n <table class=\"eru-grid-table pivot-table\"\n [style]=\"'width: auto; min-width: 100%; --table-total-width: ' + getInitialTotalWidth() + 'px'\"\n [class.show-column-lines]=\"showColumnLines()\" [class.show-row-lines]=\"showRowLines()\">\n <!-- Column Groups for consistent width -->\n <ng-container *ngTemplateOutlet=\"pivotColGroup\"></ng-container>\n\n @if (!freezeHeader()) {\n <ng-container *ngTemplateOutlet=\"pivotTableHead\"></ng-container>\n }\n <!-- Table Body with Virtual Scrolling -->\n <tbody class=\"pivot-tbody\">\n\n <tr *cdkVirtualFor=\"let pivotRow of gridStore.pivotDisplayData(); \n trackBy: trackByPivotRowFn; \n let i = index\" class=\"pivot-row\" [class.subtotal-row]=\"pivotRow._isSubtotal\"\n [class.grand-total-row]=\"pivotRow._isGrandTotal\"\n [class.subtotal-bold]=\"pivotRow._isSubtotal && subTotalStyle() === 'bold'\"\n [class.subtotal-italic]=\"pivotRow._isSubtotal && subTotalStyle() === 'italic'\"\n [class.subtotal-highlighted]=\"pivotRow._isSubtotal && subTotalStyle() === 'highlighted'\"\n [class.grand-total-bold]=\"pivotRow._isGrandTotal && grandTotalStyle() === 'bold'\"\n [class.grand-total-italic]=\"pivotRow._isGrandTotal && grandTotalStyle() === 'italic'\"\n [class.grand-total-highlighted]=\"pivotRow._isGrandTotal && grandTotalStyle() === 'highlighted'\"\n [style.height.px]=\"50\" [attr.data-pivot-row]=\"i\">\n @if ((!pivotRow._isGrandTotal && freezeGrandTotal() ) || (!freezeGrandTotal() )) {\n @for (column of getLeafColumns(); track trackByColumnFn($index, column); let colIndex = $index) {\n @if (!shouldSkipCell(i, column.name)) {\n <td [attr.rowspan]=\"getEffectiveRowspan(i, column.name)\" [style.width.px]=\"column.field_size\"\n [style.minWidth.px]=\"column.field_size\" class=\"pivot-cell\"\n [class.row-dimension-cell]=\"isRowDimensionColumn(column.name)\"\n [class.column-dimension-cell]=\"!isRowDimensionColumn(column.name)\"\n [class.aggregated-value]=\"!isRowDimensionColumn(column.name) && column.datatype === 'number'\"\n [class.rowspan-cell]=\"getEffectiveRowspan(i, column.name) || 1 > 1\"\n [class.sticky-column]=\"isStickyColumn(column.name, colIndex)\"\n [style.position]=\"isStickyColumn(column.name, colIndex) ? 'sticky' : 'static'\"\n [style.left.px]=\"getStickyColumnLeft(column.name, colIndex)\"\n [style.z-index]=\"isStickyColumn(column.name, colIndex) ? 99 : 1\" [style.height.px]=\"50\"\n [attr.xx]=\"i\">\n <div class=\"cell-content pivot-cell-content\">\n <data-cell [class.aggregation]=\"!!column.aggregationFunction\" [fieldSize]=\"column.field_size\"\n [columnDatatype]=\"column.datatype\" [columnName]=\"column.name\"\n [value]=\"getEffectiveCellValue(i,column.name, pivotRow)\" [column]=\"column\"\n [drillable]=\"column.enableDrilldown || false\" [mode]=\"mode()\" [isEditable]=\"isEditable()\"\n [id]=\"'pivot_' + i + '_' + column.name\" [eruGridStore]=\"gridStore\">\n </data-cell>\n </div>\n </td>\n }\n }\n } @else {\n <td [style.height.px]=\"50\" [attr.colspan]=\"getLeafColumns().length\"> </td>\n }\n </tr>\n </tbody>\n </table>\n </cdk-virtual-scroll-viewport>\n\n </div>\n @if (freezeGrandTotal() && grandTotalPosition() === 'after') {\n <div #gtScroller class=\"header-shell gt-shell\" [class.adjust-bottom]=\"!applyCdkWidth()\"\n [class.adjust-bottom-vs]=\"adjustScrollWidth()\">\n <table class=\"eru-grid-table pivot-table\"\n [style]=\"'width: auto; min-width: 100%; --table-total-width: ' + getInitialTotalWidth() + 'px'\"\n [class.show-column-lines]=\"showColumnLines()\" [class.show-row-lines]=\"showRowLines()\">\n <ng-container *ngTemplateOutlet=\"pivotColGroup\"></ng-container>\n\n <ng-container *ngTemplateOutlet=\"pivotGrandTotal\"></ng-container>\n\n </table>\n </div>\n }\n\n\n </div>\n </div>\n </ng-container>\n } @else {\n\n <!-- Table Mode Template -->\n <ng-container>\n @if (freezeHeader()) {\n <div #headerScroller class=\"header-shell\">\n <table class=\"eru-grid-table\" [class.show-column-lines]=\"showColumnLines()\"\n [class.show-row-lines]=\"showRowLines()\">\n <ng-container *ngTemplateOutlet=\"tableHeaderTpl\"></ng-container>\n </table>\n </div>\n }\n <cdk-virtual-scroll-viewport [itemSize]=\"30\" class=\"viewport table-viewport\"\n (scrolledIndexChange)=\"onScroll($event)\"\n (scroll)=\"onBodyScroll($event)\"\n [style]=\"'--table-min-height: ' + getInitialMinHeightPx() + 'px; --table-total-width: ' + getInitialTotalWidth() + 'px'\">\n <div class=\"table-wrapper\">\n\n <table class=\"eru-grid-table\" [class.show-column-lines]=\"showColumnLines()\"\n [class.show-row-lines]=\"showRowLines()\">\n @if (!freezeHeader()) {\n <ng-container *ngTemplateOutlet=\"tableHeaderTpl\"></ng-container>\n }\n <tbody *ngIf=\"columns() as columnsList\">\n <ng-container *cdkVirtualFor=\"let groupItem of groupedRows();\n trackBy: trackByGroupItemFn;\n let i = index;\n let first=first\">\n <tr *ngIf=\"groupItem.type === 'header' && groups().length > 1\" class=\"group-header\"\n (click)=\"toggleGroupExpansion(groupItem.group?.id || '')\">\n\n <td class=\"checkbox-column\" style=\"border: none;\">\n {{ groupItem.group?.isExpanded ? '\u25BC' : '\u25B6' }}\n </td>\n\n <td [attr.colspan]=\"2\" style=\"border: none;\">\n <span class=\"group-title\">\n {{ groupItem.group?.title }}\n </span>\n <span class=\"group-row-count\">\n ({{ groupItem.group?.currentLoadedRows || 0 }}/{{ groupItem.group?.totalRowCount || 0 }})\n </span>\n </td>\n </tr>\n <tr *ngIf=\"groupItem.type === 'table-header' && groups().length > 1\" style=\"background:#fafafa\">\n @if(gridStore.configuration().config.allowSelection) {\n <th class=\"checkbox-column\" style=\"text-align: center;\">\n <input type=\"checkbox\" [checked]=\"isGroupSelected(groupItem.group?.id || '')\"\n (click)=\"$event.stopPropagation()\"\n (change)=\"toggleGroupSelection($event, groupItem.group?.id || '')\">\n </th>\n }\n @if(shouldShowActionColumn('before')) {\n <td class=\"action-column\"\n style=\"width: 40px; min-width: 40px; max-width: 40px; text-align: center; cursor: pointer;\">\n @if (gridActions().length > 0) {\n <mat-icon [matMenuTriggerFor]=\"actionMenu\"\n [matMenuTriggerData]=\"{row: groupItem.row}\">more_horiz</mat-icon>\n } @else {\n <mat-icon (click)=\"onActionClick($event, groupItem.row)\">more_horiz</mat-icon>\n }\n </td>\n }\n <th *ngFor=\"let column of columns(); trackBy: trackByColumnFn;let i =index\" style=\"text-align: center;\"\n [style.width.px]=\"column.field_size\" [style.minWidth.px]=\"column.field_size\" [resizeColumn]=\"true\"\n [columnConfig]=\"column\" [columnDraggable]=\"i\" class=\"column-header\">\n <div class=\"column-drag-handle\"></div>\n {{column.label}} {{column.symbol}}\n </th>\n @if(shouldShowActionColumn('after')) {\n <td class=\"action-column\"\n style=\"width: 40px; min-width: 40px; max-width: 40px; text-align: center; cursor: pointer;\">\n @if (gridActions().length > 0) {\n <mat-icon [matMenuTriggerFor]=\"actionMenu\"\n [matMenuTriggerData]=\"{row: groupItem.row}\">more_horiz</mat-icon>\n } @else {\n <mat-icon (click)=\"onActionClick($event, groupItem.row)\">more_horiz</mat-icon>\n }\n </td>\n }\n </tr>\n <tr *ngIf=\"groupItem.type === 'row' && groupItem.group?.isExpanded\" class=\"row-item\"\n [attr.data-row-id]=\"groupItem.row?.entity_id\" [style.height.px]=\"30\" [style.minHeight.px]=\"30\"\n [style.maxHeight.px]=\"30\">\n @if(gridStore.configuration().config.allowSelection) {\n <td class=\"checkbox-column\" style=\"text-align: center;\">\n <input type=\"checkbox\" [checked]=\"isRowSelected(groupItem.row?.entity_id)\"\n (change)=\"toggleRowSelection($event, groupItem.row)\">\n </td>\n }\n @if(shouldShowActionColumn('before')) {\n <td class=\"action-column\"\n style=\"width: 40px; min-width: 40px; max-width: 40px; text-align: center; cursor: pointer;\">\n @if (gridActions().length > 0) {\n <mat-icon [matMenuTriggerFor]=\"actionMenu\"\n [matMenuTriggerData]=\"{row: groupItem.row}\">more_horiz</mat-icon>\n } @else {\n <mat-icon (click)=\"onActionClick($event, groupItem.row)\">more_horiz</mat-icon>\n }\n </td>\n }\n <td #cell *ngFor=\"let column of columns(); trackBy: trackByColumnFn\"\n [style.width.px]=\"column.field_size\" [style.minWidth.px]=\"column.field_size\" class=\"data-cell\"\n [style.height.px]=\"30\" [style.minHeight.px]=\"30\" [style.maxHeight.px]=\"30\"\n [matTooltipClass]=\"'error-message'\" [matTooltip]=\"datacell.error()?'Error: ' + datacell.error():''\"\n matTooltipPosition=\"below\">\n <div class=\"cell-content\">\n <data-cell #datacell [td]=cell [fieldSize]=\"column.field_size\" [columnDatatype]=\"column.datatype\"\n [columnName]=\"column.name\" [value]=\"groupItem.row?.[column.name] || ''\" [column]=\"column\"\n [mode]=\"mode()\" [isEditable]=\"isEditable()\" [drillable]=\"column.enableDrilldown || false\"\n [id]=\"i + '_' + column.name\" [eruGridStore]=\"gridStore\"></data-cell>\n </div>\n </td>\n @if(shouldShowActionColumn('after')) {\n <td class=\"action-column\"\n style=\"width: 40px; min-width: 40px; max-width: 40px; text-align: center; cursor: pointer;\">\n @if (gridActions().length > 0) {\n <mat-icon [matMenuTriggerFor]=\"actionMenu\"\n [matMenuTriggerData]=\"{row: groupItem.row}\">more_horiz</mat-icon>\n } @else {\n <mat-icon (click)=\"onActionClick($event, groupItem.row)\">more_horiz</mat-icon>\n }\n </td>\n }\n </tr>\n\n <tr *ngIf=\"groupItem.type === 'ghost-loading' && groupItem.group?.isExpanded\" class=\"ghost-loading-row\"\n [style.height.px]=\"30\" [style.minHeight.px]=\"30\" [style.maxHeight.px]=\"30\">\n @if(gridStore.configuration().config.allowSelection) {\n <th class=\"checkbox-column\"></th>\n }\n @if(shouldShowActionColumn('before')) {\n <td class=\"action-column ghost-cell-container\" style=\"width: 40px; min-width: 40px; max-width: 40px;\">\n <div class=\"ghost-cell\"></div>\n </td>\n }\n <td *ngFor=\"let column of columns(); trackBy: trackByColumnFn\" [style.width.px]=\"column.field_size\"\n [style.minWidth.px]=\"column.field_size\" class=\"ghost-cell-container\">\n <div class=\"ghost-cell\"></div>\n </td>\n @if(shouldShowActionColumn('after')) {\n <td class=\"action-column ghost-cell-container\" style=\"width: 40px; min-width: 40px; max-width: 40px;\">\n <div class=\"ghost-cell\"></div>\n </td>\n }\n </tr>\n\n <tr *ngIf=\"groupItem.type === 'row-place-holder'\" class=\"group-separator\">\n <td [attr.colspan]=\"groupSeperatorColSpan()\" class=\"separator-cell\"></td>\n </tr>\n </ng-container>\n </tbody>\n </table>\n </div>\n </cdk-virtual-scroll-viewport>\n </ng-container>\n }\n</div>\n\n<!-- Pivot Table Header Template -->\n<ng-template #pivotTableHead>\n <thead>\n @if (hasNestedHeaders()) {\n <ng-container>\n @for (headerRow of getHeaderRows(); track headerRow; let rowIndex = $index) {\n <tr class=\"pivot-header pivot-header-container\" [class.pivot-header-level]=\"'level-' + rowIndex\">\n @for (header of headerRow; track trackByHeaderFn($index, header); let colIndex = $index) {\n <th [attr.colspan]=\"header.colspan\" [attr.rowspan]=\"header.rowspan\"\n [resizeColumn]=\"gridStore.isFeatureEnabled('columnResizable') && header.level === 0\"\n class=\"column-header pivot-column-header nested-header\"\n [class.row-dimension-header]=\"isRowDimensionHeader(header)\"\n [class.column-dimension-header]=\"!isRowDimensionHeader(header)\" [class.expanded]=\"header.isExpanded\"\n [class.collapsed]=\"!header.isExpanded\" [class.sticky-column]=\"isStickyColumn(header.name, colIndex)\"\n [style.position]=\"isStickyColumn(header.name, colIndex) ? 'sticky' : 'static'\"\n [style.left.px]=\"getStickyColumnLeft(header.name, colIndex)\"\n [style.z-index]=\"isStickyColumn(header.name, colIndex) ? 100 : 1\"\n style=\"min-height: 40px; height: auto; padding: 8px 6px;\">\n <div class=\"header-content\">\n\n <data-cell [fieldSize]=\"header.field_size\" [columnDatatype]=\"header.dataType\" [columnName]=\"header.name\"\n [value]=\"header.label\" [column]=\"header\" [frozenGrandTotalCell]=\"true\"\n [drillable]=\"header.enableDrilldown || false\" [mode]=\"mode()\" [isEditable]=\"isEditable()\"\n [id]=\"'pivot_' + $index + '_' + header.name\" [eruGridStore]=\"gridStore\">\n </data-cell>\n <!-- <span class=\"header-label header-wrap-text\">{{header.label}}</span> -->\n <!-- <button *ngIf=\"!isRowDimensionHeader(header)\" \n class=\"collapse-toggle-btn\"\n [title]=\"header.isExpanded ? 'Collapse group' : 'Expand group'\"\n (click)=\"toggleColumnGroup(header.groupKey)\"\n type=\"button\">\n <span class=\"collapse-icon\">+</span>\n </button> -->\n </div>\n </th>\n }\n </tr>\n }\n </ng-container>\n } @else {\n <!-- Simple header fallback -->\n <ng-container>\n <tr class=\"pivot-header\" [class.freeze-header-enabled]=\"freezeHeader()\">\n @for (column of getLeafColumns(); track trackByColumnFn($index, column); let colIndex = $index) {\n <th [style.width.px]=\"column.field_size\" [style.minWidth.px]=\"column.field_size\"\n [resizeColumn]=\"gridStore.isFeatureEnabled('columnResizable')\" [columnConfig]=\"column\"\n class=\"column-header pivot-column-header\" [class.sticky-column]=\"isStickyColumn(column.name, colIndex)\"\n [style.position]=\"isStickyColumn(column.name, colIndex) ? 'sticky' : 'static'\"\n [style.left.px]=\"getStickyColumnLeft(column.name, colIndex)\"\n [style.z-index]=\"isStickyColumn(column.name, colIndex) ? 100 : 1\"\n style=\"min-height: 40px;height: auto;padding: 8px 6px;position: relative;left: 0px;z-index: 1\">\n {{column.label}}\n </th>\n }\n </tr>\n </ng-container>\n }\n\n </thead>\n</ng-template>\n\n<!-- Column Group Template for consistent column widths -->\n<ng-template #pivotColGroup>\n <colgroup>\n @for (column of getLeafColumns(); track trackByColumnFn($index, column)) {\n <col\n [style]=\"'width: ' + column.field_size + 'px !important; min-width: ' + column.field_size + 'px !important; max-width: ' + column.field_size + 'px !important; --col-width: ' + column.field_size + 'px'\">\n }\n </colgroup>\n</ng-template>\n\n<ng-template #pivotGrandTotal>\n <tbody class=\"pivot-tbody\">\n @for (pivotRow of gridStore.pivotGrandTotalData(); track trackByPivotRowFn($index, pivotRow); let i = $index) {\n <tr class=\"pivot-row grand-total-row\"\n [class.grand-total-bold]=\"pivotRow._isGrandTotal && grandTotalStyle() === 'bold'\"\n [class.grand-total-italic]=\"pivotRow._isGrandTotal && grandTotalStyle() === 'italic'\"\n [class.grand-total-highlighted]=\"pivotRow._isGrandTotal && grandTotalStyle() === 'highlighted'\"\n [style.height.px]=\"50\" [attr.data-pivot-row]=\"i\">\n <!-- <td colspan=\"20\">{{pivotRow | json}}</td> -->\n @for (column of getLeafColumns(); track trackByColumnFn($index, column); let colIndex = $index) {\n <td [attr.rowspan]=\"getEffectiveRowspan(i, column.name)\" [style.width.px]=\"column.field_size\"\n [style.minWidth.px]=\"column.field_size\" class=\"pivot-cell\"\n [class.row-dimension-cell]=\"isRowDimensionColumn(column.name)\"\n [class.column-dimension-cell]=\"!isRowDimensionColumn(column.name)\"\n [class.aggregated-value]=\"!isRowDimensionColumn(column.name) && column.datatype === 'number'\"\n [class.rowspan-cell]=\"getEffectiveRowspan(i, column.name) || 1 > 1\"\n [class.sticky-column]=\"isStickyColumn(column.name, colIndex)\"\n [style.position]=\"isStickyColumn(column.name, colIndex) ? 'sticky' : 'static'\"\n [style.left.px]=\"getStickyColumnLeft(column.name, colIndex)\"\n [style.z-index]=\"isStickyColumn(column.name, colIndex) ? 99 : 1\" [style.height.px]=\"50\" [attr.xx]=\"i\">\n <div class=\"cell-content pivot-cell-content\">\n <data-cell [fieldSize]=\"column.field_size\" [columnDatatype]=\"column.datatype\" [columnName]=\"column.name\"\n [value]=\"getEffectiveCellValue(i,column.name, pivotRow)\" [column]=\"column\" [frozenGrandTotalCell]=\"true\"\n [drillable]=\"column.enableDrilldown || false\" [mode]=\"mode()\" [isEditable]=\"isEditable()\"\n [id]=\"'pivot_' + i + '_' + column.name\" [eruGridStore]=\"gridStore\">\n </data-cell>\n </div>\n </td>\n }\n </tr>\n }\n </tbody>\n</ng-template>\n\n<!-- Table Mode Header Template -->\n<ng-template #tableHeaderTpl>\n <thead>\n <tr>\n @if(gridStore.configuration().config.allowSelection) {\n <th class=\"checkbox-column\"></th>\n }\n @if(shouldShowActionColumn('before')) {\n <th class=\"action-column column-header table-column-header\"\n style=\"width: 40px; min-width: 40px; max-width: 40px;\">\n Action\n </th>\n }\n <th *ngFor=\"let column of columns(); trackBy: trackByColumnFn\" [style.width.px]=\"column.field_size\"\n [resizeColumn]=\"gridStore.isFeatureEnabled('columnResizable')\" [style.minWidth.px]=\"column.field_size\"\n class=\"column-header table-column-header\">\n {{column.label}}\n </th>\n @if(shouldShowActionColumn('after')) {\n <th class=\"action-column column-header table-column-header\"\n style=\"width: 40px; min-width: 40px; max-width: 40px;\">\n Action\n </th>\n }\n </tr>\n </thead>\n</ng-template>\n\n<mat-menu #actionMenu=\"matMenu\">\n <ng-template matMenuContent let-row=\"row\">\n @for (item of gridActions(); track item.action) {\n <button mat-menu-item (click)=\"onActionClick($event, row, item)\">\n @if (item.icon) {\n <mat-icon class=\"action-icon\" fontIcon=\"{{item.icon}}\"></mat-icon>\n }\n <span>{{item.menu}}</span>\n </button>\n }\n </ng-template>\n</mat-menu>", styles: ["@charset \"UTF-8\";:host{display:block;width:100%;height:100%;font-family:var(--grid-font-family);--grid-primary: #6750a4;--grid-on-primary: #ffffff;--grid-surface: #fef7ff;--grid-surface-variant: #e7e0ec;--grid-surface-container: #f3edf7;--grid-surface-container-high: #ede7f0;--grid-on-surface: #1d1b20;--grid-on-surface-variant: #49454f;--grid-outline: #79757f;--grid-outline-variant: #cac4d0;--grid-error: #ba1a1a;--grid-error-container: #ffdad6;--grid-font-family: \"Poppins\", \"Roboto\", -apple-system, BlinkMacSystemFont, \"Segoe UI\", sans-serif;--grid-font-size-body: 12px;--grid-font-size-caption: 12px !important;--grid-line-height-body: 1;--grid-aggregation-text-align: right;--grid-number-text-align: right;--grid-spacing-xxs: 2px;--grid-spacing-xs: 4px;--grid-spacing-sm: 8px;--grid-spacing-md: 16px;--grid-spacing-lg: 24px;--grid-border-radius: 4px;--grid-elevation-1: 0px 1px 2px 0px rgba(0, 0, 0, .3), 0px 1px 3px 1px rgba(0, 0, 0, .15);--grid-elevation-2: 0px 1px 2px 0px rgba(0, 0, 0, .3), 0px 2px 6px 2px rgba(0, 0, 0, .15)}.incremental-row-container{padding:10px;width:100%;height:100%;min-height:var(--table-min-height, 400px);max-height:none;overflow:auto;position:relative;background-color:var(--grid-surface);border-radius:var(--grid-border-radius);box-shadow:var(--grid-elevation-1);font-family:var(--grid-font-family)}.viewport{overflow-x:auto;overflow-y:auto;background-color:var(--grid-surface);scrollbar-gutter:stable}.viewport.apply-cdk-width{width:calc(var(--table-total-width) + 10px)!important}.table-viewport{background-color:var(--grid-surface);height:auto;min-height:var(--table-min-height, 300px);max-height:80vh;overflow-x:auto;overflow-y:auto}.pivot-viewport{min-height:var(--table-min-height, 300px);overflow-x:auto;overflow-y:auto;background-color:var(--grid-surface)}.pivot-viewport .cdk-virtual-scroll-content-wrapper{width:auto;height:auto}.table-wrapper{min-width:100%;overflow-x:visible}.incremental-row-container .eru-grid-table,.eru-grid-table{width:100%!important;border-collapse:separate;border-spacing:0;table-layout:fixed!important;background-color:var(--grid-surface);color:var(--grid-on-surface);font-size:var(--grid-font-size-body);line-height:var(--grid-line-height-body)}.eru-grid-table th,.eru-grid-table td{text-align:left;overflow:hidden!important;text-overflow:ellipsis!important;white-space:nowrap!important;background-color:var(--grid-surface);color:var(--grid-on-surface);min-width:0;max-width:100%!important;box-sizing:border-box;position:relative}.eru-grid-table th:hover,.eru-grid-table td:hover{background-color:var(--grid-surface-variant)}.eru-grid-table thead{background-color:var(--grid-surface-container);transform:translateZ(0);will-change:transform;backface-visibility:hidden}.eru-grid-table thead.freeze-header-enabled{box-shadow:0 2px 4px #0000001a;border-bottom:2px solid var(--grid-outline)}.eru-grid-table thead th{background-color:var(--grid-surface-container);color:var(--grid-on-surface);font-weight:500;font-size:var(--grid-font-size-caption)}.checkbox-column{width:50px;min-width:50px;max-width:50px;text-align:center;background-color:var(--grid-surface-container)}.checkbox-column input[type=checkbox]{width:16px;height:16px;cursor:pointer;accent-color:var(--grid-primary);border-radius:var(--grid-border-radius)}.checkbox-column input[type=checkbox]:focus{outline:2px solid var(--grid-primary);outline-offset:2px}.group-header{background-color:var(--grid-surface-container);color:var(--grid-on-surface);font-size:var(--grid-font-size-caption);font-weight:500;border-bottom:1px solid var(--grid-outline);cursor:pointer;transition:background-color .2s ease}.group-header:hover{background-color:var(--grid-surface-container-high)}.group-header .group-title{font-weight:600;color:var(--grid-primary)}.group-header .group-row-count{color:var(--grid-on-surface-variant);font-size:var(--grid-font-size-caption);margin-left:var(--grid-spacing-sm)}.row-item{border:1px solid var(--grid-outline);background-color:var(--grid-surface);transition:background-color .2s ease,box-shadow .2s ease}.row-item:hover{background-color:var(--grid-surface-variant);box-shadow:var(--grid-elevation-1)}.table-column-header{padding:12px 8px}.column-header{font-weight:500;text-align:center!important;font-size:var(--grid-font-size-caption, 12px);position:relative;-webkit-user-select:none;user-select:none;background-color:var(--grid-surface-container);color:var(--grid-on-surface)}.column-header:hover{background-color:var(--grid-surface-container-high)}.column-drag-handle{position:absolute;left:0;top:0;bottom:0;width:12px;cursor:grab;opacity:0;transition:opacity .2s ease,background-color .2s ease;z-index:2;display:flex;align-items:center;justify-content:center;border-right:1px solid transparent}.column-drag-handle:after{content:\"\\22ee\\22ee\";font-size:14px;color:var(--grid-on-surface-variant);transform:rotate(90deg)}.column-drag-handle:hover{background-color:var(--grid-surface-container-high);border-right-color:var(--grid-outline)}.column-header:hover .column-drag-handle{opacity:1}.column-drag-handle:active{cursor:grabbing}.dragging{opacity:1;background-color:var(--grid-surface-container);box-shadow:var(--grid-elevation-2)}.drag-over{background-color:var(--grid-surface-container);border-color:var(--grid-primary)}.data-cell{background-color:var(--grid-surface);color:var(--grid-on-surface);font-size:var(--grid-font-size-body)}.cell-content{align-items:center}.cell-content .mdc-text-field{padding:0px var(--grid-spacing-xxs)!important}.cell-display-text{align-items:center;padding:0px var(--grid-spacing-xs)}.ghost-loading-row{background-color:transparent}.ghost-cell-container{padding:var(--grid-spacing-sm)}.ghost-cell{height:20px;width:100%;background-color:var(--grid-surface-container);animation:pulse 1.5s ease-in-out infinite;border-radius:var(--grid-border-radius)}@keyframes pulse{0%,to{opacity:1}50%{opacity:.5}}.resizing{cursor:col-resize;-webkit-user-select:none;user-select:none}.column-resizer{position:absolute;right:0;top:0;bottom:0;width:4px;cursor:col-resize;background-color:transparent;transition:background-color .2s ease}.column-resizer:hover{background-color:var(--grid-primary)}.group-separator{height:var(--grid-spacing-sm);background-color:var(--grid-surface-variant)}.group-separator .separator-cell{background-color:var(--grid-surface-variant);border:none;height:var(--grid-spacing-sm)}.error-state{background-color:var(--grid-error-container);color:var(--grid-error);border-color:var(--grid-error)}.error-message{background-color:var(--grid-error);color:#fff;padding:var(--grid-spacing-sm);border-radius:var(--grid-border-radius);font-size:var(--grid-font-size-caption)}.incremental-row-container .eru-grid-table tbody,.incremental-row-container .eru-grid-table{position:relative}.incremental-row-container .eru-grid-table.show-column-lines{border-right:var(--grid-outline-width, 1px) solid var(--grid-outline, #e0e0e0)!important;border-top:var(--grid-outline-width, 1px) solid var(--grid-outline, #e0e0e0)!important;border-bottom:var(--grid-outline-width, 1px) solid var(--grid-outline, #e0e0e0)!important}.incremental-row-container .eru-grid-table:not(.show-column-lines){border:var(--grid-outline-width, 1px) solid var(--grid-outline, #e0e0e0)!important}.incremental-row-container .eru-grid-table thead:after{content:\"\";position:absolute;bottom:0;left:0;right:0;height:calc(var(--grid-outline-width, 1px) * 2);background-color:var(--grid-outline, #e0e0e0);pointer-events:none;z-index:10}.incremental-row-container .eru-grid-table.show-column-lines thead th{border-left:var(--grid-outline-width, 1px) solid var(--grid-outline, #e0e0e0)!important;border-bottom:var(--grid-outline-width, 1px) solid var(--grid-outline, #e0e0e0)!important}.incremental-row-container .eru-grid-table.show-column-lines tbody td{border-left:var(--grid-outline-width, 1px) solid var(--grid-outline, #e0e0e0)!important}.incremental-row-container .eru-grid-table.show-row-lines thead th{border-left:var(--grid-outline-width, 1px) solid var(--grid-outline, #e0e0e0)!important;border-bottom:var(--grid-outline-width, 1px) solid var(--grid-outline, #e0e0e0)!important}.incremental-row-container .eru-grid-table.show-row-lines tbody td{border-bottom:var(--grid-outline-width, 1px) solid var(--grid-outline, #e0e0e0)!important}@media (max-width: 768px){.incremental-row-container{height:600px}.eru-grid-table th,.eru-grid-table td{font-size:var(--grid-font-size-caption)}.checkbox-column{width:40px;min-width:40px;max-width:40px}}@media (prefers-contrast: high){.eru-grid-table th,.eru-grid-table td{border-width:2px}.row-item:hover{border-width:2px;border-color:var(--grid-primary)}}@media (prefers-reduced-motion: reduce){.row-item,.column-drag-handle,.ghost-cell{transition:none;animation:none}}.pivot-table .nested-header{text-align:center;font-weight:600;background:var(--grid-surface-container)}.pivot-table .nested-header.row-dimension-header{background:var(--grid-surface-container);font-weight:600}.pivot-table .pivot-header-leafcols{padding:0;margin:0;height:0}.pivot-table .pivot-header-level.level-0 .nested-header{font-size:14px;padding:12px 8px}.pivot-table .pivot-header-level.level-1 .nested-header{font-size:13px;padding:10px 6px}.pivot-table .pivot-header-level.level-2 .nested-header{font-size:12px;padding:8px 4px}.pivot-table .nested-header:hover{background:var(--grid-surface-variant);color:var(--grid-primary);transition:all .2s ease}.pivot-table .pivot-cell.aggregated-value{font-weight:500;font-family:Roboto Mono,monospace}.pivot-table .pivot-cell-content{display:flex;justify-content:center;align-items:center;min-height:38px}.pivot-table .rowspan-cell{vertical-align:middle}.pivot-table .rowspan-cell .pivot-cell-content{height:100%}.pivot-mode .incremental-row-container{display:flex;flex-direction:column;height:auto;max-height:85vh;overflow:auto}.pivot-mode .h-shell{position:relative;width:calc(100% - var(--scrollbar-width, 17px))!important;top:0;z-index:1;overflow-x:hidden;overflow-y:hidden;scrollbar-width:none;-ms-overflow-style:none}.pivot-mode .h-shell::-webkit-scrollbar{display:none}.pivot-mode .gt-shell{position:relative;bottom:50px;flex-shrink:0;overflow-x:hidden;overflow-y:hidden;scrollbar-width:none;-ms-overflow-style:none}.pivot-mode .gt-shell::-webkit-scrollbar{display:none}.pivot-mode .gt-shell table{border-bottom:var(--grid-outline-width, 1px) solid var(--grid-outline, #e0e0e0)!important}.pivot-mode .gt-shell.adjust-bottom-vs{bottom:66px!important}.pivot-mode .gt-shell.adjust-bottom:not(.adjust-bottom-vs){bottom:calc(66px - var(--scrollbar-width, 17px))!important}.pivot-mode .header-shell{flex-shrink:0;width:100%;box-sizing:border-box;padding-right:var(--scrollbar-width, 17px);overflow-x:auto;overflow-y:hidden;scrollbar-width:none;-ms-overflow-style:none}.pivot-mode .header-shell::-webkit-scrollbar{display:none}.pivot-mode .header-shell.apply-cdk-width{width:calc(var(--table-total-width) + 10px)!important}.pivot-mode .header-shell .eru-grid-table{margin-bottom:0;width:100%;table-layout:fixed}.pivot-mode .header-shell .eru-grid-table thead{background:var(--grid-surface-container)}.pivot-mode .header-shell .eru-grid-table thead th{background:var(--grid-surface-container);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;width:var(--col-width)!important;min-width:var(--col-width)!important;max-width:var(--col-width)!important}.pivot-mode .header-shell .eru-grid-table thead th.sticky-column{position:sticky;background:var(--grid-surface-container);z-index:111}.pivot-mode .header-shell .eru-grid-table tbody td{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;width:var(--col-width)!important;min-width:var(--col-width)!important;max-width:var(--col-width)!important}.pivot-mode .pivot-container{display:flex;flex-direction:column;height:100%;width:100%;overflow:hidden}.pivot-mode .pivot-table{width:auto!important;min-width:100%!important;table-layout:fixed!important;width:100%!important}.pivot-mode .pivot-table colgroup col{width:var(--col-width)!important;min-width:var(--col-width)!important;max-width:var(--col-width)!important;flex:none!important;flex-shrink:0!important;flex-grow:0!important}.pivot-mode .pivot-table td,.pivot-mode .pivot-table th{box-sizing:border-box!important;flex:none!important;flex-shrink:0!important;flex-grow:0!important;word-wrap:break-word!important;word-break:break-all!important}.pivot-mode .pivot-table *{max-width:var(--col-width)!important;box-sizing:border-box!important}.pivot-mode .pivot-table colgroup{width:100%!important}.pivot-mode .pivot-table colgroup col{width:var(--col-width)!important;min-width:var(--col-width)!important;max-width:var(--col-width)!important;flex-basis:var(--col-width)!important;flex:0 0 var(--col-width)!important}.pivot-mode .pivot-table table{width:100%!important;table-layout:fixed!important;border-collapse:collapse!important;border-spacing:0!important}.pivot-mode .pivot-table[style*=--table-total-width]{width:var(--table-total-width)!important;min-width:var(--table-total-width)!important;max-width:var(--table-total-width)!important}.pivot-mode .pivot-table colgroup col{width:var(--col-width)!important;min-width:var(--col-width)!important;max-width:var(--col-width)!important;flex:0 0 var(--col-width)!important;flex-basis:var(--col-width)!important;flex-grow:0!important;flex-shrink:0!important;overflow:hidden!important}.pivot-mode .pivot-table tbody td,.pivot-mode .pivot-table thead th{width:var(--col-width)!important;min-width:var(--col-width)!important;max-width:var(--col-width)!important;overflow:hidden!important;text-overflow:ellipsis!important;white-space:nowrap!important}.pivot-mode .pivot-table .cell-content,.pivot-mode .pivot-table data-cell{width:100%!important;max-width:100%!important;overflow:hidden!important;text-overflow:ellipsis!important;white-space:nowrap!important;display:block!important}.pivot-mode .pivot-table table{width:var(--table-total-width)!important;min-width:var(--table-total-width)!important;max-width:var(--table-total-width)!important;table-layout:fixed!important;border-collapse:collapse!important;border-spacing:0!important;word-wrap:break-word!important;word-break:break-all!important}.pivot-mode .pivot-tbody tr.pivot-row{min-height:50px!important;height:50px!important}.pivot-mode .pivot-tbody tr.pivot-row:hover{background-color:var(--grid-surface-variant)}.pivot-mode .pivot-tbody tr.pivot-row:nth-child(2n){background-color:#00000005}.pivot-mode .pivot-tbody tr.pivot-row td{min-height:50px!important;height:50px!important;vertical-align:middle;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;width:var(--col-width)!important;min-width:var(--col-width)!important;max-width:var(--col-width)!important}.pivot-mode .pivot-tbody tr.pivot-row td .cell-content{min-height:48px;display:flex;align-items:center;justify-content:center}.pivot-mode .pivot-tbody tr.pivot-row td .cell-content data-cell{width:100%;min-height:46px;display:flex;align-items:center;justify-content:center;overflow:hidden;flex-shrink:0}.pivot-mode .pivot-cell{vertical-align:middle;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;width:var(--col-width)!important;min-width:var(--col-width)!important;max-width:var(--col-width)!important}.pivot-mode .pivot-cell.aggregated-value{font-weight:500;font-family:Roboto Mono,monospace}.pivot-mode .pivot-cell .cell-content{display:flex;justify-content:center;align-items:center;min-height:40px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;flex-shrink:0}.pivot-mode .pivot-table .subtotal-row{background-color:var(--grid-surface-container)!important;font-weight:600}.pivot-mode .pivot-table .subtotal-row td{background-color:var(--grid-surface-container);color:var(--grid-on-surface-variant)}.pivot-mode .pivot-table .subtotal-row td:first-child{color:var(--grid-primary)}.pivot-mode .pivot-table .subtotal-row td.aggregated-value{font-weight:500;color:var(--grid-primary)}.pivot-mode .pivot-table .subtotal-row:hover{background-color:var(--grid-surface-container-high)!important}.pivot-mode .pivot-table .subtotal-row:hover td{background-color:var(--grid-surface-container-high)}.pivot-mode .pivot-table .subtotal-bold td{font-weight:600!important;font-style:normal!important}.pivot-mode .pivot-table .subtotal-bold td.aggregated-value{font-weight:600!important}.pivot-mode .pivot-table .subtotal-italic td{font-style:italic!important}.pivot-mode .pivot-table .subtotal-italic td:first-child{font-weight:600!important}.pivot-mode .pivot-table .subtotal-italic td.aggregated-value{font-style:italic!important;font-weight:500!important}.pivot-mode .pivot-table .subtotal-highlighted{background-color:var(--grid-surface-variant)!important}.pivot-mode .pivot-table .subtotal-highlighted td{background-color:var(--grid-surface-variant)!important;font-weight:700!important;font-style:normal!important;color:var(--grid-primary)!important}.pivot-mode .pivot-table .subtotal-highlighted td.aggregated-value{font-weight:500!important;color:var(--grid-primary)!important}.pivot-mode .pivot-table .subtotal-highlighted:hover,.pivot-mode .pivot-table .subtotal-highlighted:hover td{background-color:var(--grid-surface-container-high)!important}.pivot-mode .pivot-table .grand-total-row{background-color:var(--grid-surface-container-high)!important;font-weight:700;font-size:var(--grid-font-size-body)}.pivot-mode .pivot-table .grand-total-row td{background-color:var(--grid-surface-container-high)!important;color:var(--grid-on-surface)}.pivot-mode .pivot-table .grand-total-row td:first-child{font-style:normal;font-weight:800;color:var(--grid-primary)}.pivot-mode .pivot-table .grand-total-row td.aggregated-value{font-weight:500;color:var(--grid-primary);font-family:Roboto Mono,monospace}.pivot-mode .pivot-table .grand-total-row:hover,.pivot-mode .pivot-table .grand-total-row:hover td{background-color:var(--grid-surface-container-high)!important}.pivot-mode .pivot-table .grand-total-bold td{font-weight:700!important;font-style:normal!important}.pivot-mode .pivot-table .grand-total-bold td.aggregated-value{font-weight:700!important}.pivot-mode .pivot-table .grand-total-italic td,.pivot-mode .pivot-table .grand-total-italic td.aggregated-value{font-style:italic!important;font-weight:500!important}.pivot-mode .pivot-table .grand-total-highlighted{background-color:var(--grid-primary)!important;box-shadow:var(--grid-elevation-2)!important}.pivot-mode .pivot-table .grand-total-highlighted td{background-color:var(--grid-primary)!important;color:var(--grid-on-primary)!important;font-weight:500!important;font-style:normal!important}.pivot-mode .pivot-table .grand-total-highlighted td.aggregated-value{color:var(--grid-on-primary)!important;font-weight:500!important}.pivot-mode .pivot-table .grand-total-highlighted:hover,.pivot-mode .pivot-table .grand-total-highlighted:hover td{background-color:var(--grid-primary)!important}.pivot-mode .pivot-table .collapsible-header{position:relative}.pivot-mode .pivot-table .collapsible-header .header-content{display:flex;align-items:center;justify-content:space-between;gap:var(--grid-spacing-xs);padding:var(--grid-spacing-xs) var(--grid-spacing-sm)}.pivot-mode .pivot-table .collapsible-header .header-label{flex:1;font-weight:600}.pivot-mode .pivot-table .collapsible-header .collapse-toggle-btn{background:none;border:none;cursor:pointer;padding:var(--grid-spacing-xxs);margin:0;display:flex;align-items:center;justify-content:center;width:20px;height:20px;border-radius:var(--grid-border-radius);color:var(--grid-on-surface-variant);transition:all .2s ease;font-size:12px;font-weight:600}.pivot-mode .pivot-table .collapsible-header .collapse-toggle-btn:hover{background-color:var(--grid-surface-container);color:var(--grid-primary);transform:scale(1.1)}.pivot-mode .pivot-table .collapsible-header .collapse-toggle-btn:focus{outline:2px solid var(--grid-primary);outline-offset:1px}.pivot-mode .pivot-table .collapsible-header .collapse-toggle-btn .collapse-icon{display:block;line-height:1;font-family:monospace;font-size:14px}.pivot-mode .pivot-table .collapsible-header.expanded .collapse-toggle-btn .collapse-icon{color:var(--grid-primary)}.pivot-mode .pivot-table .collapsible-header.collapsed{background-color:var(--grid-surface-variant)}.pivot-mode .pivot-table .collapsible-header.collapsed .header-label{font-style:italic;color:var(--grid-on-surface-variant)}.pivot-mode .pivot-table .collapsible-header.collapsed .collapse-toggle-btn .collapse-icon{color:var(--grid-outline)}.pivot-mode .pivot-table .collapsible-header:hover{background-color:var(--grid-surface-container)}.pivot-mode .pivot-table .collapsible-header:hover .header-label{color:var(--grid-on-surface)}.pivot-mode .pivot-table .pivot-single-table{display:flex;flex-direction:column;height:100%;width:100%;overflow:hidden;min-height:var(--table-min-height)!important}.pivot-mode .pivot-table .pivot-single-table .pivot-header-container{flex-shrink:0;background:var(--grid-surface)!important;overflow-x:auto;overflow-y:hidden;min-height:100px!important;height:auto!important}.pivot-mode .pivot-table .pivot-single-table .pivot-header-container .pivot-table{width:auto;min-width:100%;height:auto!important;min-height:100px!important}.pivot-mode .pivot-table .pivot-single-table .pivot-header-container .pivot-table th{background:var(--grid-surface-container)!important;padding:8px 6px!important;white-space:nowrap;min-width:50px;min-height:40px!important;height:auto!important;position:relative;visibility:visible!important;color:var(--grid-on-surface)!important}.pivot-mode .pivot-table .pivot-single-table .pivot-header-container .pivot-table th.sticky-column{position:sticky!important;background:var(--grid-surface-container)!important;border-right:2px solid var(--grid-primary)!important;box-shadow:2px 0 4px #0000001a;z-index:101!important}.pivot-mode .pivot-table .pivot-single-table .pivot-data-container{flex:1;overflow:auto;min-height:300px!important;height:auto!important}.pivot-mode .pivot-table .pivot-single-table .pivot-data-container .pivot-viewport{height:100%!important;width:100%!important;overflow-x:auto!important;overflow-y:auto!important}.pivot-mode .pivot-table .pivot-single-table .pivot-data-container .pivot-table,.pivot-mode .pivot-table .pivot-single-table .pivot-data-container .pivot-data-table{width:auto;min-width:100%;height:auto!important}.pivot-mode .pivot-table .pivot-single-table .pivot-data-container .pivot-table td,.pivot-mode .pivot-table .pivot-single-table .pivot-data-container .pivot-data-table td{padding:8px 6px!important;white-space:nowrap;min-width:50px;min-height:32px!important;height:auto!important;background:var(--grid-surface)!important;color:var(--grid-on-surface)!important;visibility:visible!important}.pivot-mode .pivot-table .pivot-single-table .pivot-data-container .pivot-table td.sticky-column,.pivot-mode .pivot-table .pivot-single-table .pivot-data-container .pivot-data-table td.sticky-column{position:sticky!important;background:var(--grid-surface-container)!important;border-right:2px solid var(--grid-primary)!important;box-shadow:2px 0 4px #0000001a;z-index:100!important}.pivot-mode .pivot-table .pivot-single-table .pivot-data-container .pivot-table tbody tr,.pivot-mode .pivot-table .pivot-single-table .pivot-data-container .pivot-data-table tbody tr{height:auto!important;min-height:50px!important}.pivot-mode .pivot-table .pivot-single-table .pivot-data-container .pivot-table tbody tr.pivot-row,.pivot-mode .pivot-table .pivot-single-table .pivot-data-container .pivot-data-table tbody tr.pivot-row{visibility:visible!important;display:table-row!important}.pivot-mode .pivot-table .collapsed-column-group{background-color:var(--grid-surface-container);border-left:3px solid var(--grid-primary)}.pivot-mode .pivot-table .collapsed-column-group:hover{background-color:var(--grid-surface-container-high)}.pivot-row.subtotal-row{background-color:var(--grid-surface-variant);font-weight:500}.pivot-row.subtotal-row.subtotal-bold{font-weight:500}.pivot-row.subtotal-row.subtotal-italic{font-style:italic}.pivot-row.subtotal-row.subtotal-highlighted{background-color:var(--grid-primary);color:var(--grid-on-primary)}.pivot-row.grand-total-row{background-color:var(--grid-surface-container);font-weight:600}.pivot-row.grand-total-row.grand-total-bold{font-weight:800}.pivot-row.grand-total-row.grand-total-italic{font-style:italic}.pivot-row.grand-total-row.grand-total-highlighted{background-color:var(--grid-primary);color:var(--grid-on-primary)}.pivot-row.first-visible-row{background-color:#6750a41a!important;position:relative}.pivot-row.first-visible-row:before{content:\"\\1f441\\fe0f First Visible\";position:absolute;top:-20px;left:0;background:var(--grid-primary);color:var(--grid-on-primary);padding:2px 6px;font-size:10px;border-radius:2px;z-index:1000}.header-wrap-text{white-space:pre-wrap;word-break:auto-phrase}.action-column{width:40px;min-width:40px;max-width:40px;text-align:center;background-color:var(--grid-surface-container)}.action-column mat-icon{font-family:Material Icons!important;font-size:20px;width:20px;height:20px;line-height:20px;color:var(--grid-on-surface-variant);cursor:pointer}.action-column mat-icon:hover{color:var(--grid-primary)}.mat-mdc-menu-item{min-height:0px!important}.mat-mdc-menu-content{padding:0!important}.action-icon{font-family:Material Icons!important;font-size:20px!important;width:20px!important;height:20px!important;line-height:20px!important;text-transform:none!important;font-weight:400!important;font-style:normal!important;display:inline-flex!important;align-items:center;justify-content:center;margin-right:12px;color:var(--grid-on-surface-variant);cursor:pointer}.action-icon:hover{color:var(--grid-primary)}\n"] }]
|
|
5865
5568
|
}], ctorParameters: () => [{ type: i0.ChangeDetectorRef }], propDecorators: { viewport: [{
|
|
5866
5569
|
type: ViewChild,
|
|
5867
5570
|
args: [CdkVirtualScrollViewport]
|