eru-grid 0.0.6 → 0.0.7
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 +227 -191
- package/fesm2022/eru-grid.mjs.map +1 -1
- package/index.d.ts +39 -58
- package/package.json +1 -1
package/fesm2022/eru-grid.mjs
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
2
|
import { Injectable, inject, signal, computed, DOCUMENT, effect, Directive, InjectionToken, forwardRef, Input, Component, ElementRef, ChangeDetectorRef, input, model, Renderer2, ViewChild, ViewEncapsulation, ChangeDetectionStrategy, HostListener } from '@angular/core';
|
|
3
3
|
import { of, delay } from 'rxjs';
|
|
4
|
-
import * as
|
|
4
|
+
import * as i2$1 from '@angular/common';
|
|
5
5
|
import { NgFor, NgIf, NgClass, DatePipe, CommonModule } from '@angular/common';
|
|
6
6
|
import { CdkListbox, CdkOption } from '@angular/cdk/listbox';
|
|
7
7
|
import * as i2 from '@angular/cdk/menu';
|
|
8
8
|
import { CdkMenuModule, CdkMenuTrigger, CdkMenu } from '@angular/cdk/menu';
|
|
9
9
|
import * as i1$1 from '@angular/forms';
|
|
10
10
|
import { FormControl, Validators, ReactiveFormsModule, FormsModule, NG_VALUE_ACCESSOR } from '@angular/forms';
|
|
11
|
-
import * as i2$
|
|
11
|
+
import * as i2$2 from '@angular/material/form-field';
|
|
12
12
|
import { MatFormFieldModule } from '@angular/material/form-field';
|
|
13
13
|
import * as i3 from '@angular/material/input';
|
|
14
14
|
import { MatInputModule } from '@angular/material/input';
|
|
@@ -25,7 +25,7 @@ import { NativeDateAdapter, DateAdapter, MAT_DATE_FORMATS, MatNativeDateModule }
|
|
|
25
25
|
import * as i9 from '@angular/material/datepicker';
|
|
26
26
|
import { MatDatepickerModule, MatDatepickerToggle } from '@angular/material/datepicker';
|
|
27
27
|
import { DomSanitizer } from '@angular/platform-browser';
|
|
28
|
-
import * as i1$
|
|
28
|
+
import * as i1$2 from '@angular/cdk/overlay';
|
|
29
29
|
import { OverlayModule } from '@angular/cdk/overlay';
|
|
30
30
|
import { ScrollingModule, CdkVirtualScrollViewport } from '@angular/cdk/scrolling';
|
|
31
31
|
import * as i3$1 from '@angular/material/tooltip';
|
|
@@ -120,8 +120,9 @@ class PivotTransformService {
|
|
|
120
120
|
const enableRowSubtotals = gridConfiguration?.config?.enableRowSubtotals ?? false;
|
|
121
121
|
const enableColumnSubtotals = gridConfiguration?.config?.enableColumnSubtotals ?? false;
|
|
122
122
|
const enableGrandTotal = gridConfiguration?.config?.enableGrandTotal ?? false;
|
|
123
|
+
const grandTotalPosition = gridConfiguration?.config?.grandTotalPosition ?? 'after';
|
|
123
124
|
if (enableRowSubtotals || enableColumnSubtotals || enableGrandTotal) {
|
|
124
|
-
pivotRows = this.addSubtotals(pivotRows, configuration, pivotColumns, gridConfiguration);
|
|
125
|
+
pivotRows = this.addSubtotals(pivotRows, configuration, pivotColumns, gridConfiguration, grandTotalPosition);
|
|
125
126
|
}
|
|
126
127
|
// Step 5: Generate column definitions (including subtotal columns)
|
|
127
128
|
const columnDefinitions = this.generateColumnDefinitions(rowDimensionFields, pivotColumns, configuration.aggregations, gridConfiguration);
|
|
@@ -136,6 +137,15 @@ class PivotTransformService {
|
|
|
136
137
|
processingTime: endTime - startTime,
|
|
137
138
|
dataSize: sourceData.length
|
|
138
139
|
};
|
|
140
|
+
/* console.log({
|
|
141
|
+
data: pivotRows,
|
|
142
|
+
columnDefinitions,
|
|
143
|
+
rowCount: pivotRows.length,
|
|
144
|
+
metadata,
|
|
145
|
+
configuration,
|
|
146
|
+
headerStructure,
|
|
147
|
+
columnGroupState: this.columnGroupState
|
|
148
|
+
}); */
|
|
139
149
|
return {
|
|
140
150
|
data: pivotRows,
|
|
141
151
|
columnDefinitions,
|
|
@@ -806,7 +816,7 @@ class PivotTransformService {
|
|
|
806
816
|
/**
|
|
807
817
|
* Add subtotals to pivot data based on configuration
|
|
808
818
|
*/
|
|
809
|
-
addSubtotals(pivotRows, configuration, pivotColumns, gridConfiguration) {
|
|
819
|
+
addSubtotals(pivotRows, configuration, pivotColumns, gridConfiguration, grandTotalPosition) {
|
|
810
820
|
const enableRowSubtotals = gridConfiguration?.config?.enableRowSubtotals ?? false;
|
|
811
821
|
const enableGrandTotal = gridConfiguration?.config?.enableGrandTotal ?? false;
|
|
812
822
|
if (!enableRowSubtotals && !enableGrandTotal) {
|
|
@@ -819,7 +829,7 @@ class PivotTransformService {
|
|
|
819
829
|
}
|
|
820
830
|
// Add grand total row
|
|
821
831
|
if (enableGrandTotal) {
|
|
822
|
-
result = this.addGrandTotalRow(result, configuration, pivotColumns, gridConfiguration);
|
|
832
|
+
result = this.addGrandTotalRow(result, configuration, pivotColumns, gridConfiguration, grandTotalPosition);
|
|
823
833
|
}
|
|
824
834
|
return result;
|
|
825
835
|
}
|
|
@@ -879,7 +889,7 @@ class PivotTransformService {
|
|
|
879
889
|
/**
|
|
880
890
|
* Add grand total row
|
|
881
891
|
*/
|
|
882
|
-
addGrandTotalRow(pivotRows, configuration, pivotColumns, gridConfiguration) {
|
|
892
|
+
addGrandTotalRow(pivotRows, configuration, pivotColumns, gridConfiguration, grandTotalPosition) {
|
|
883
893
|
const grandTotalRow = this.calculateGrandTotalRow(pivotRows.filter(row => !row._isSubtotal), // Exclude existing subtotals
|
|
884
894
|
configuration, 'Grand Total', gridConfiguration);
|
|
885
895
|
grandTotalRow._isGrandTotal = true;
|
|
@@ -895,6 +905,9 @@ class PivotTransformService {
|
|
|
895
905
|
grandTotalRow[dimField] = '';
|
|
896
906
|
}
|
|
897
907
|
}
|
|
908
|
+
if (grandTotalPosition === 'before') {
|
|
909
|
+
return [grandTotalRow, ...pivotRows];
|
|
910
|
+
}
|
|
898
911
|
return [...pivotRows, grandTotalRow];
|
|
899
912
|
}
|
|
900
913
|
/**
|
|
@@ -1373,8 +1386,32 @@ class EruGridStore {
|
|
|
1373
1386
|
return this.rows();
|
|
1374
1387
|
}, ...(ngDevMode ? [{ debugName: "displayData" }] : []));
|
|
1375
1388
|
// Type-safe accessors for specific modes
|
|
1389
|
+
pivotGrandTotalData = computed(() => {
|
|
1390
|
+
let pd = [];
|
|
1391
|
+
if (this.isPivotMode() && this.pivotResult()) {
|
|
1392
|
+
if (this.configuration().config?.enableGrandTotal) {
|
|
1393
|
+
if (this.configuration().config?.freezeGrandTotal) {
|
|
1394
|
+
if (this.configuration().config?.grandTotalPosition === 'before') {
|
|
1395
|
+
pd = [this.pivotResult().data[0]];
|
|
1396
|
+
}
|
|
1397
|
+
else {
|
|
1398
|
+
pd = [this.pivotResult().data[this.pivotResult().data.length - 1]];
|
|
1399
|
+
}
|
|
1400
|
+
}
|
|
1401
|
+
}
|
|
1402
|
+
}
|
|
1403
|
+
console.log('pd', pd);
|
|
1404
|
+
return pd;
|
|
1405
|
+
}, ...(ngDevMode ? [{ debugName: "pivotGrandTotalData" }] : []));
|
|
1406
|
+
// Type-safe accessors for specific modes
|
|
1376
1407
|
pivotDisplayData = computed(() => {
|
|
1377
1408
|
if (this.isPivotMode() && this.pivotResult()) {
|
|
1409
|
+
if (this.configuration().config?.enableGrandTotal && this.configuration().config?.freezeGrandTotal) {
|
|
1410
|
+
if (this.configuration().config?.grandTotalPosition === 'before') {
|
|
1411
|
+
return this.pivotResult().data.slice(1);
|
|
1412
|
+
}
|
|
1413
|
+
return this.pivotResult().data;
|
|
1414
|
+
}
|
|
1378
1415
|
return this.pivotResult().data;
|
|
1379
1416
|
}
|
|
1380
1417
|
return [];
|
|
@@ -1772,6 +1809,18 @@ class EruGridStore {
|
|
|
1772
1809
|
getFreezeField() {
|
|
1773
1810
|
return this.configuration().config?.freezeField || null;
|
|
1774
1811
|
}
|
|
1812
|
+
/**
|
|
1813
|
+
* Check if freeze header is enabled
|
|
1814
|
+
*/
|
|
1815
|
+
isFreezeHeaderEnabled() {
|
|
1816
|
+
return this.configuration().config?.freezeHeader ?? false;
|
|
1817
|
+
}
|
|
1818
|
+
/**
|
|
1819
|
+
* Check if freeze grand total is enabled
|
|
1820
|
+
*/
|
|
1821
|
+
isFreezeGrandTotalEnabled() {
|
|
1822
|
+
return this.configuration().config?.freezeGrandTotal ?? false;
|
|
1823
|
+
}
|
|
1775
1824
|
setPivotDrilldown(drilldown, columnValues) {
|
|
1776
1825
|
drilldown.rowData = this.pivotResult()?.data[parseInt(drilldown.rowId)];
|
|
1777
1826
|
const columnValuesArray = columnValues.split('|');
|
|
@@ -3351,7 +3400,7 @@ class DataCellComponent {
|
|
|
3351
3400
|
provide: CELL_VALIDATORS,
|
|
3352
3401
|
useValue: cellValidators
|
|
3353
3402
|
}
|
|
3354
|
-
], viewQueries: [{ propertyName: "attachmentTrigger", first: true, predicate: ["attachmentTrigger"], descendants: true }, { propertyName: "singleSelectTrigger", first: true, predicate: ["singleSelectTrigger"], descendants: true }, { propertyName: "multiSelectTrigger", first: true, predicate: ["multiSelectTrigger"], descendants: true }, { propertyName: "peopleTrigger", first: true, predicate: ["peopleTrigger"], descendants: true }], ngImport: i0, template: "<div class=\"container\">\n @switch (columnDatatype()) {\n @case ('textbox') {\n @if(isActive()){\n <mat-form-field appearance=\"outline\" class=\"cell-form-field\">\n <input matInput type=\"text\" [id]=\"'input-' + columnName()+ id()\" [name]=\"'input-' + columnName()+ id()\"\n [(ngModel)]=\"currentValue\" (blur)=\"onTextboxBlur()\">\n </mat-form-field>\n } @else {\n <div class=\"cell-display-text\" (dblclick)=\"setActive(true)\"\n [class.cell-display-text-editable]=\"isEditable()\">\n @if (drillable()) {\n <span class=\"drillable-value\" (click)=\"onDrillableClick($event)\">{{currentValue()}}</span>\n } @else {\n {{currentValue()}}\n }\n </div>\n }\n }\n @case ('currency') {\n @if(isActive()){\n <mat-form-field appearance=\"outline\" class=\"cell-form-field\">\n <input matInput type=\"text\" [id]=\"'currency-' + columnName()+ id()\" [name]=\"'currency-' + columnName()+ id()\"\n [ngModel]=\"currentValue()\" (ngModelChange)=\"setField($event)\" placeholder=\"Number\" (blur)=\"onNumberBlur()\">\n <span matTextPrefix>$</span>\n </mat-form-field>\n } @else {\n <div class=\"cell-display-text cell-display-number\" (dblclick)=\"setActive(true)\"\n [class.cell-display-text-editable]=\"isEditable()\">\n @if (drillable()) {\n <span class=\"drillable-value\" (click)=\"onDrillableClick($event)\">{{formatNumberSignal()}}</span>\n } @else {\n {{formatNumberSignal()}}\n }\n </div>\n }\n }\n @case ('number') {\n @if(isActive()){\n <mat-form-field appearance=\"outline\" class=\"cell-form-field\">\n <input matInput type=\"text\" [id]=\"'number-' + columnName()+ id()\" [name]=\"'number-' + columnName()+ id()\"\n [ngModel]=\"currentValue()\" (ngModelChange)=\"setField($event)\" placeholder=\"Number\" (blur)=\"onNumberBlur()\">\n </mat-form-field>\n } @else {\n <div class=\"cell-display-text cell-display-number\" (dblclick)=\"setActive(true)\"\n[class.cell-display-text-editable]=\"isEditable()\"\n >\n @if (drillable() && currentValue() !== 0) {\n <span class=\"drillable-value\" ><a class=\"drillable-link\" (click)=\"onDrillableClick($event)\">{{formatNumberSignal()}}</a></span>\n } @else {\n {{formatNumberSignal()}}\n }\n </div>\n }\n }\n @case ('location') {\n @if(isActive()){\n <mat-form-field appearance=\"outline\" class=\"cell-form-field\">\n <input matInput type=\"text\" [id]=\"'location-' + columnName()+ id()\" [name]=\"'location-' + columnName()+ id()\"\n [(ngModel)]=\"currentValue\" placeholder=\"location\" (blur)=\"onLocationBlur()\">\n </mat-form-field>\n } @else {\n <div class=\"cell-display-text\" (dblclick)=\"setActive(true)\"\n [class.cell-display-text-editable]=\"isEditable()\">\n @if (drillable()) {\n <span class=\"drillable-value\" (click)=\"onDrillableClick($event)\">{{currentValue()}}</span>\n } @else {\n {{currentValue()}}\n }\n </div>\n }\n }\n @case ('email') {\n @if(isActive()){\n <mat-form-field appearance=\"outline\" class=\"cell-form-field\">\n <input matInput type=\"email\" [id]=\"'email-' + columnName()+ id()\" [name]=\"'email-' + columnName()+ id()\"\n [(ngModel)]=\"currentValue\" placeholder=\"email\" matTooltipPosition=\"below\" (blur)=\"onEmailBlur()\">\n </mat-form-field>\n } @else {\n <div class=\"cell-display-text\" (dblclick)=\"setActive(true)\"\n [class.cell-display-text-editable]=\"isEditable()\">\n @if (drillable()) {\n <span class=\"drillable-value\" (click)=\"onDrillableClick($event)\">{{currentValue()}}</span>\n } @else {\n {{currentValue()}}\n }\n </div>\n }\n }\n @case ('dropdown_multi_select') {\n <div class=\"cell-display-text\" (dblclick)=\"toggleOverlayMenu($event)\" #multiSelectTrigger\n [class.cell-display-text-editable]=\"isEditable()\">\n @if (drillable()) {\n <span class=\"drillable-value\" (click)=\"onDrillableClick($event)\">{{formattedMultiSelectValue(currentColumnWidth()) || 'Click to select'}}</span>\n } @else {\n {{formattedMultiSelectValue(currentColumnWidth()) || 'Click to select'}}\n }\n </div>\n }\n\n @case ('dropdown_single_select') {\n <div class=\"cell-display-text\" (dblclick)=\"toggleOverlayMenu($event)\" [cdkMenuTriggerFor]=\"singleSelectTrigger\" #singleSelectTrigger\n [class.cell-display-text-editable]=\"isEditable()\">\n @if (drillable()) {\n <span class=\"drillable-value\" (click)=\"onDrillableClick($event)\">{{currentValue()}}</span>\n } @else {\n {{currentValue()}}\n }\n </div>\n }\n\n @case ('checkbox') {\n <div class=\"cell-form-field cell-checkbox\">\n <mat-checkbox [(ngModel)]=\"currentValue\">\n </mat-checkbox>\n </div>\n }\n\n @case ('people') {\n <div class=\"assignee-avatars \" (dblclick)=\"toggleOverlayMenu($event)\" #peopleTrigger>\n @if (isAssigneeArray(currentValue()) && currentValue().length > 0) {\n @if (drillable()) {\n <span class=\"drillable-value\" (click)=\"onDrillableClick($event)\">\n @for (assignee of currentValue(); track $index) {\n @if ($index < 3) {\n <div class=\"avatar-circle\" [style.z-index]=\"currentValue().length - $index\">\n {{ getInitials(assignee) }}\n </div>\n }\n }\n @if (currentValue().length > 3) {\n <div class=\"avatar-circle count-circle\" [style.z-index]=\"1\">\n +{{ currentValue().length - 3 }}\n </div>\n }\n </span>\n } @else {\n @for (assignee of currentValue(); track $index) {\n @if ($index < 3) {\n <div class=\"avatar-circle\" [style.z-index]=\"currentValue().length - $index\">\n {{ getInitials(assignee) }}\n </div>\n }\n }\n @if (currentValue().length > 3) {\n <div class=\"avatar-circle count-circle\" [style.z-index]=\"1\">\n +{{ currentValue().length - 3 }}\n </div>\n }\n }\n }\n </div>\n }\n\n\n @case ('date') {\n <div class=\"cell-date-container\">\n @if (drillable()) {\n <span class=\"drillable-value\" (click)=\"onDrillableClick($event)\">\n <input type=\"text\" [id]=\"'date-' + columnName()+ id()\" [name]=\"'date-' + columnName()+ id()\"\n [matDatepicker]=\"picker\" appCustomDatePicker class=\"inputRef date-picker\" [ngModel]=\"currentValue()\"\n (ngModelChange)=\"onDateChange($event)\" (click)=\"picker.open()\" readonly>\n <mat-datepicker-toggle hidden matIconSuffix [for]=\"picker\"></mat-datepicker-toggle>\n <mat-datepicker #picker></mat-datepicker>\n </span>\n } @else {\n <input type=\"text\" [id]=\"'date-' + columnName()+ id()\" [name]=\"'date-' + columnName()+ id()\"\n [matDatepicker]=\"picker\" appCustomDatePicker class=\"inputRef date-picker\" [ngModel]=\"currentValue()\"\n (ngModelChange)=\"onDateChange($event)\" (click)=\"picker.open()\" readonly>\n <mat-datepicker-toggle hidden matIconSuffix [for]=\"picker\"></mat-datepicker-toggle>\n <mat-datepicker #picker></mat-datepicker>\n }\n </div>\n }\n\n\n @case ('priority') {\n <button mat-stroked-button [cdkMenuTriggerFor]=\"prioritySelectMenu\" class=\"dropdown-trigger\">\n <div class=\"cell-priority-content\">\n <div [innerHTML]=\"getPriorityIcon()\"></div>\n @if (drillable()) {\n <div class=\"drillable-value\" (click)=\"onDrillableClick($event)\">{{currentValue()}}</div>\n } @else {\n <div>{{currentValue()}}</div>\n }\n </div>\n </button>\n }\n @case ('progress') {\n @if(isActive()){\n <div class=\"progress-input-container\">\n <mat-slider class=\"progress-slider\" [min]=\"0\" [max]=\"100\" [step]=\"1\" [discrete]=\"true\">\n <input matSliderThumb [ngModel]=\"currentValue()\" (ngModelChange)=\"setProgressValue($event)\">\n </mat-slider>\n <span class=\"progress-value\">{{currentValue()}}%</span>\n </div>\n } @else {\n <div class=\"progress-bar-container\" [attr.data-progress]=\"currentValue()\">\n <div class=\"progress-bar\" [style.width.%]=\"currentValue()\"></div>\n @if (drillable()) {\n <span class=\"progress-text drillable-value\" (click)=\"onDrillableClick($event)\">{{currentValue()}}%</span>\n } @else {\n <span class=\"progress-text\">{{currentValue()}}%</span>\n }\n </div>\n }\n }\n\n @case ('rating') {\n @if(isActive()){\n <div class=\"rating-input-container\">\n @for (star of getRatingStars(); track star) {\n <span class=\"rating-star\" [class.active]=\"currentValue() >= star\" (click)=\"setRatingValue(star)\"\n (mouseenter)=\"hoverRating = star\" (mouseleave)=\"hoverRating = 0\">\n {{getEmojiForRating(star)}}\n </span>\n }\n <span class=\"rating-value\">{{currentValue()}}/{{columnCellConfiguration()?.end_value || 5}}</span>\n </div>\n } @else {\n <div class=\"rating-display-container\">\n @for (star of getRatingStars(); track star) {\n <span class=\"rating-star\" [class.active]=\"currentValue() >= star\">\n {{getEmojiForRating(star)}}\n </span>\n }\n @if (drillable()) {\n <span class=\"drillable-value\" (click)=\"onDrillableClick($event)\">{{currentValue()}}/{{columnCellConfiguration()?.end_value || 5}}</span>\n }\n </div>\n }\n }\n\n @case ('status') {\n <button mat-stroked-button [cdkMenuTriggerFor]=\"statusSelectMenu\" class=\"status-dropdown-trigger\"\n [style.background-color]=\"getStatusColor(currentValue()).background\"\n [style.border-color]=\"getStatusColor(currentValue()).border\" [style.color]=\"getStatusColor(currentValue()).text\"\n [style.height.px]=\"30\">\n <div class=\"status-button-content\">\n @if(getStatusButtonDisplay(currentValue()).color) {\n\n }\n @if (drillable()) {\n <span class=\"status-text drillable-value\" (click)=\"onDrillableClick($event)\">\n {{getStatusButtonDisplay(currentValue()).text}}\n </span>\n } @else {\n <span class=\"status-text\">\n {{getStatusButtonDisplay(currentValue()).text}}\n </span>\n }\n </div>\n </button>\n }\n\n @case ('tag') {\n <div class=\"tag-container\" [cdkMenuTriggerFor]=\"tagSelectMenu\">\n\n <div class=\"tag-display\">\n @if (drillable()) {\n <span class=\"drillable-value\" (click)=\"onDrillableClick($event)\">\n @for (tag of getTagDisplay(currentValue()).displayTags; track tag) {\n @if (columnCellConfiguration()) {\n <span class=\"tag\" [style.background]=\"getTagColor(tag).background\" [style.color]=\"getTagColor(tag).color\">\n {{tag}}\n </span>\n } @else {\n <span class=\"tag cell-fallback-tag\">\n {{tag}}\n </span>\n }\n }\n @if(getTagDisplay(currentValue()).moreCount > 0) {\n <span class=\"tag-more\">\n + {{getTagDisplay(currentValue()).moreCount}} more\n </span>\n }\n </span>\n } @else {\n @for (tag of getTagDisplay(currentValue()).displayTags; track tag) {\n @if (columnCellConfiguration()) {\n <span class=\"tag\" [style.background]=\"getTagColor(tag).background\" [style.color]=\"getTagColor(tag).color\">\n {{tag}}\n </span>\n } @else {\n <span class=\"tag cell-fallback-tag\">\n {{tag}}\n </span>\n }\n }\n @if(getTagDisplay(currentValue()).moreCount > 0) {\n <span class=\"tag-more\">\n + {{getTagDisplay(currentValue()).moreCount}} more\n </span>\n }\n }\n </div>\n\n </div>\n }\n\n @case ('phone') {\n <app-mobile-input [(ngModel)]=\"currentValue\"\n [defaultCountry]=\"columnCellConfiguration()?.default_country || 'US'\"></app-mobile-input>\n }\n\n @case ('attachment') {\n <div class=\"attachment-cell-wrapper\" (dblclick)=\"toggleOverlayMenu($event)\" cdkOverlayOrigin #attachmentTrigger=\"cdkOverlayOrigin\">\n @if(currentValue()?.length > 0){\n <div class=\"cell-attachment-container\">\n @if (drillable()) {\n <span class=\"drillable-value\" (click)=\"onDrillableClick($event)\">\n <svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path fill-rule=\"evenodd\" clip-rule=\"evenodd\"\n d=\"M19 12.5C19 14.985 15.866 17 12 17C8.134 17 5 14.985 5 12.5C5 10.015 8.134 8 12 8C15.866 8 19 10.015 19 12.5Z\"\n stroke=\"#7C818C\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n <path fill-rule=\"evenodd\" clip-rule=\"evenodd\"\n d=\"M13.75 12.5001C13.7716 13.1394 13.4429 13.7397 12.8925 14.0657C12.3422 14.3918 11.6578 14.3918 11.1075 14.0657C10.5571 13.7397 10.2284 13.1394 10.25 12.5001C10.2284 11.8608 10.5571 11.2606 11.1075 10.9345C11.6578 10.6084 12.3422 10.6084 12.8925 10.9345C13.4429 11.2606 13.7716 11.8608 13.75 12.5001V12.5001Z\"\n stroke=\"#7C818C\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n </span>\n } @else {\n <svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path fill-rule=\"evenodd\" clip-rule=\"evenodd\"\n d=\"M19 12.5C19 14.985 15.866 17 12 17C8.134 17 5 14.985 5 12.5C5 10.015 8.134 8 12 8C15.866 8 19 10.015 19 12.5Z\"\n stroke=\"#7C818C\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n <path fill-rule=\"evenodd\" clip-rule=\"evenodd\"\n d=\"M13.75 12.5001C13.7716 13.1394 13.4429 13.7397 12.8925 14.0657C12.3422 14.3918 11.6578 14.3918 11.1075 14.0657C10.5571 13.7397 10.2284 13.1394 10.25 12.5001C10.2284 11.8608 10.5571 11.2606 11.1075 10.9345C11.6578 10.6084 12.3422 10.6084 12.8925 10.9345C13.4429 11.2606 13.7716 11.8608 13.75 12.5001V12.5001Z\"\n stroke=\"#7C818C\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n }\n </div>\n }@else {\n <div class=\"cell-attachment-container\">\n @if (drillable()) {\n <span class=\"drillable-value\" (click)=\"onDrillableClick($event)\">\n <svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M14.67 11.053L10.68 15.315C10.3416 15.6932 9.85986 15.9119 9.35236 15.9178C8.84487 15.9237 8.35821 15.7162 8.01104 15.346C7.24412 14.5454 7.257 13.2788 8.04004 12.494L13.399 6.763C13.9902 6.10491 14.8315 5.72677 15.7161 5.72163C16.6006 5.71649 17.4463 6.08482 18.045 6.736C19.3222 8.14736 19.3131 10.2995 18.024 11.7L12.342 17.771C11.5334 18.5827 10.4265 19.0261 9.28113 18.9971C8.13575 18.9682 7.05268 18.4695 6.28604 17.618C4.5337 15.6414 4.57705 12.6549 6.38604 10.73L11.753 5\"\n stroke=\"#363B44\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n </span>\n } @else {\n <svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M14.67 11.053L10.68 15.315C10.3416 15.6932 9.85986 15.9119 9.35236 15.9178C8.84487 15.9237 8.35821 15.7162 8.01104 15.346C7.24412 14.5454 7.257 13.2788 8.04004 12.494L13.399 6.763C13.9902 6.10491 14.8315 5.72677 15.7161 5.72163C16.6006 5.71649 17.4463 6.08482 18.045 6.736C19.3222 8.14736 19.3131 10.2995 18.024 11.7L12.342 17.771C11.5334 18.5827 10.4265 19.0261 9.28113 18.9971C8.13575 18.9682 7.05268 18.4695 6.28604 17.618C4.5337 15.6414 4.57705 12.6549 6.38604 10.73L11.753 5\"\n stroke=\"#363B44\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n }\n </div>\n }\n \n \n </div>\n }\n @default {\n <div class=\"cell-default-display\">\n @if (drillable()) {\n <span class=\"drillable-value\" (click)=\"onDrillableClick($event)\">{{value()}}</span>\n } @else {\n {{value()}}\n }\n </div>\n }\n }\n\n</div>\n\n<ng-template #prioritySelectMenu>\n <div class=\"dropdown-menu\" cdkMenu [style.min-width.px]=\"fieldSize()\" (closed)=\"singleOptionClosed()\">\n <div class=\"listbox-container\">\n <mat-form-field appearance=\"outline\" class=\"search-form-field\">\n <input matInput type=\"search\" placeholder=\"Search...\" [(ngModel)]=\"optionSearchText\">\n </mat-form-field>\n\n <ul cdkListbox [ngModel]=\"currentValue()\" (ngModelChange)=\"selectedSingleSelect($event)\"\n aria-labelledby=\"listbox-label\" class=\"listbox\">\n <li [cdkOption]=\"''\" class=\"listbox-option notext-overflow\">\n None\n </li>\n @for (option of filteredOptions(); track option) {\n <li [cdkOption]=\"option.value\" class=\"listbox-option notext-overflow cell-priority-content\">\n <div [innerHTML]=\"sanitize.bypassSecurityTrustHtml(option.icon)\"></div>\n <div>{{option.label}}</div>\n </li>\n }\n </ul>\n </div>\n </div>\n</ng-template>\n\n<ng-template cdkConnectedOverlay\n[cdkConnectedOverlayOrigin]=\"singleSelectTrigger\"\n[cdkConnectedOverlayOpen]=\"showOverlayMenu('dropdown_single_select')\"\n(detach)=\"isOpen = showOverlayMenu('dropdown_single_select')\">\n <div class=\"dropdown-menu\" cdkMenu [style.width.px]=\"currentColumnWidth()\" (closed)=\"singleOptionClosed()\">\n <div class=\"listbox-container\">\n <mat-form-field appearance=\"outline\" class=\"search-form-field\">\n <input matInput type=\"search\" placeholder=\"Search...\" (click)=\"$event.stopPropagation()\" [(ngModel)]=\"optionSearchText\">\n </mat-form-field>\n <ul cdkListbox [ngModel]=\"currentValue()\" (ngModelChange)=\"selectedSingleSelect($event)\"\n aria-labelledby=\"listbox-label\" class=\"listbox\">\n <li [cdkOption]=\"'None'\" class=\"listbox-option notext-overflow\">\n None\n </li>\n <li [cdkOption]=\"'option 1'\" class=\"listbox-option notext-overflow\">\n option 1\n </li>\n <li [cdkOption]=\"'option 2'\" class=\"listbox-option notext-overflow\">\n option 2\n </li>\n <li [cdkOption]=\"'option 3'\" class=\"listbox-option notext-overflow\">\n option 3\n </li>\n <li [cdkOption]=\"'option 4'\" class=\"listbox-option notext-overflow\">\n option 4\n </li><li [cdkOption]=\"'option 5'\" class=\"listbox-option notext-overflow\">\n option 5\n </li><li [cdkOption]=\"'option 6'\" class=\"listbox-option notext-overflow\">\n option 6\n </li><li [cdkOption]=\"'option 7'\" class=\"listbox-option notext-overflow\">\n option 7\n </li><li [cdkOption]=\"'option 1'\" class=\"listbox-option notext-overflow\">\n option 1\n </li><li [cdkOption]=\"'option 9'\" class=\"listbox-option notext-overflow\">\n option 9\n </li><li [cdkOption]=\"'option 10'\" class=\"listbox-option notext-overflow\">\n option 10\n </li><li [cdkOption]=\"'option 11'\" class=\"listbox-option notext-overflow\">\n option 11\n </li><li [cdkOption]=\"'option 12'\" class=\"listbox-option notext-overflow\">\n option 12\n </li><li [cdkOption]=\"'option 13'\" class=\"listbox-option notext-overflow\">\n option 13\n </li><li [cdkOption]=\"'option 14'\" class=\"listbox-option notext-overflow\">\n option 14\n </li><li [cdkOption]=\"'option 15'\" class=\"listbox-option notext-overflow\">\n option 15\n </li><li [cdkOption]=\"'option 16'\" class=\"listbox-option notext-overflow\">\n option 16\n </li><li [cdkOption]=\"'option 17'\" class=\"listbox-option notext-overflow\">\n option 17\n </li><li [cdkOption]=\"'option 18'\" class=\"listbox-option notext-overflow\">\n option 18\n </li>\n @for (option of filteredOptions(); track option) {\n <li [cdkOption]=\"option.value\" class=\"listbox-option notext-overflow\">\n {{option.label}}\n </li>\n }\n </ul>\n </div>\n </div>\n</ng-template>\n\n<ng-template \ncdkConnectedOverlay\n[cdkConnectedOverlayOrigin]=\"multiSelectTrigger\"\n[cdkConnectedOverlayOpen]=\"showOverlayMenu('dropdown_multi_select')\"\n(detach)=\"isOpen = showOverlayMenu('dropdown_multi_select')\">\n <div class=\"dropdown-menu\" cdkMenu [style.width.px]=\"currentColumnWidth()\" (closed)=\"singleOptionClosed()\">\n <div class=\"listbox-container\">\n <mat-form-field appearance=\"outline\" class=\"search-form-field\">\n <input matInput type=\"search\" placeholder=\"Search...\" [ngModel]=\"optionSearchText()\"\n (ngModelChange)=\"optionSearchText.set($event)\" (click)=\"$event.stopPropagation()\">\n </mat-form-field>\n \n <!-- Select All Checkbox -->\n <div class=\"select-all-container\" (click)=\"$event.stopPropagation()\">\n <mat-checkbox \n [checked]=\"isAllSelected()\" \n [indeterminate]=\"isIndeterminate()\"\n (change)=\"toggleSelectAll($event.checked)\">\n <span class=\"select-all-text\">Select All</span>\n </mat-checkbox>\n </div>\n \n <ul cdkListboxMultiple=\"true\" cdkListboxUseActiveDescendant cdkListbox [ngModel]=\"currentValue()\"\n (ngModelChange)=\"selectedMultiSelect($event)\" aria-labelledby=\"listbox-labssel\" class=\"listbox\" (click)=\"$event.stopPropagation()\">\n <li [cdkOption]=\"'None'\" class=\"multi-listbox-option notext-overflow\">\n <div class=\"option-content\">\n <mat-checkbox [checked]=\"isOptionSelected('None')\" (click)=\"$event.stopPropagation();appendMultiSelect('None')\"></mat-checkbox>\n <span class=\"option-text\">None</span>\n </div>\n </li>\n <li [cdkOption]=\"'option 1'\" class=\"multi-listbox-option notext-overflow\">\n <div class=\"option-content\">\n <mat-checkbox [checked]=\"isOptionSelected('option 1')\" (click)=\"$event.stopPropagation();appendMultiSelect('option 1')\"></mat-checkbox>\n <span class=\"option-text\">option 1</span>\n </div>\n </li>\n <li [cdkOption]=\"'option 2'\" class=\"multi-listbox-option notext-overflow\">\n <div class=\"option-content\">\n <mat-checkbox [checked]=\"isOptionSelected('option 2')\" (click)=\"$event.stopPropagation();appendMultiSelect('option 2')\"></mat-checkbox>\n <span class=\"option-text\">option 2</span>\n </div>\n </li>\n <li [cdkOption]=\"'option 3'\" class=\"multi-listbox-option notext-overflow\">\n <div class=\"option-content\">\n <mat-checkbox [checked]=\"isOptionSelected('option 3')\" (click)=\"$event.stopPropagation();appendMultiSelect('option 3')\"></mat-checkbox>\n <span class=\"option-text\">option 3</span>\n </div>\n </li>\n <li [cdkOption]=\"'option 4'\" class=\"multi-listbox-option notext-overflow\">\n <div class=\"option-content\">\n <mat-checkbox [checked]=\"isOptionSelected('option 4')\" (click)=\"$event.stopPropagation();appendMultiSelect('option 4')\"></mat-checkbox>\n <span class=\"option-text\">option 4</span>\n </div>\n </li>\n <li [cdkOption]=\"'option 5'\" class=\"multi-listbox-option notext-overflow\">\n <div class=\"option-content\">\n <mat-checkbox [checked]=\"isOptionSelected('option 5')\" (click)=\"$event.stopPropagation();appendMultiSelect('option 5')\"></mat-checkbox>\n <span class=\"option-text\">option 5</span>\n </div>\n </li>\n <li [cdkOption]=\"'option 6'\" class=\"multi-listbox-option notext-overflow\">\n <div class=\"option-content\">\n <mat-checkbox [checked]=\"isOptionSelected('option 6')\" (click)=\"$event.stopPropagation();appendMultiSelect('option 6')\"></mat-checkbox>\n <span class=\"option-text\">option 6</span>\n </div>\n </li>\n <li [cdkOption]=\"'option 7'\" class=\"multi-listbox-option notext-overflow\">\n <div class=\"option-content\">\n <mat-checkbox [checked]=\"isOptionSelected('option 7')\" (click)=\"$event.stopPropagation();appendMultiSelect('option 7')\"></mat-checkbox>\n <span class=\"option-text\">option 7</span>\n </div>\n </li>\n <li [cdkOption]=\"'option 8'\" class=\"multi-listbox-option notext-overflow\">\n <div class=\"option-content\">\n <mat-checkbox [checked]=\"isOptionSelected('option 8')\" (click)=\"$event.stopPropagation();appendMultiSelect('option 8')\"></mat-checkbox>\n <span class=\"option-text\">option 8</span>\n </div>\n </li>\n <li [cdkOption]=\"'option 9'\" class=\"multi-listbox-option notext-overflow\">\n <div class=\"option-content\">\n <mat-checkbox [checked]=\"isOptionSelected('option 9')\" (click)=\"$event.stopPropagation();appendMultiSelect('option 9')\"></mat-checkbox>\n <span class=\"option-text\">option 9</span>\n </div>\n </li>\n <li [cdkOption]=\"'option 10'\" class=\"multi-listbox-option notext-overflow\">\n <div class=\"option-content\">\n <mat-checkbox [checked]=\"isOptionSelected('option 10')\" (click)=\"$event.stopPropagation();appendMultiSelect('option 10')\"></mat-checkbox>\n <span class=\"option-text\">option 10</span>\n </div>\n </li>\n @for (option of filteredOptions(); track option) {\n <li [cdkOption]=\"option.value\" class=\"multi-listbox-option notext-overflow\">\n <div class=\"option-content\">\n <mat-checkbox [checked]=\"isOptionSelected(option.value)\" (click)=\"$event.stopPropagation();appendMultiSelect(option.value)\"></mat-checkbox>\n <span class=\"option-text\">{{option.label}}</span>\n </div>\n </li>\n }\n </ul>\n </div>\n </div>\n</ng-template>\n\n<ng-template cdkConnectedOverlay\n[cdkConnectedOverlayOrigin]=\"peopleTrigger\"\n[cdkConnectedOverlayOpen]=\"showOverlayMenu('people')\"\n(detach)=\"isOpen = showOverlayMenu('people')\">\n <div class=\"dropdown-menu\" cdkMenu [style.width.px]=\"currentColumnWidth()\" (closed)=\"singleOptionClosed()\">\n <div class=\"listbox-container\">\n <mat-form-field appearance=\"outline\" class=\"search-form-field\">\n <input matInput type=\"search\" placeholder=\"Search...\" [ngModel]=\"optionSearchText()\" (click)=\"$event.stopPropagation()\"\n (ngModelChange)=\"optionSearchText.set($event)\">\n </mat-form-field>\n <ul cdkListboxMultiple=\"true\" cdkListboxUseActiveDescendant cdkListbox [ngModel]=\"currentValue()\"\n (ngModelChange)=\"selectedMultiSelect($event)\" aria-labelledby=\"listbox-labssel\" class=\"listbox\">\n <li [cdkOption]=\"'person0@domain.com'\" class=\"multi-listbox-option notext-overflow\">\n <div class=\"option-content\">\n <div class=\"option-avatar\">{{ getInitials('person0@domain.com') }}</div>\n <span class=\"option-text\">person0@domain.com</span>\n @if (isOptionSelected('person0@domain.com')) {\n <span class=\"checkmark\">\u2713</span>\n }\n </div>\n </li>\n <li [cdkOption]=\"'person1@domain.com'\" class=\"multi-listbox-option notext-overflow\">\n <div class=\"option-content\">\n <div class=\"option-avatar\">{{ getInitials('person1@domain.com') }}</div>\n <span class=\"option-text\">person1@domain.com</span>\n @if (isOptionSelected('person1@domain.com')) {\n <span class=\"checkmark\">\u2713</span>\n }\n </div>\n </li>\n <li [cdkOption]=\"'person2@domain.com'\" class=\"multi-listbox-option notext-overflow\">\n <div class=\"option-content\">\n <div class=\"option-avatar\">{{ getInitials('person2@domain.com') }}</div>\n <span class=\"option-text\">person2@domain.com</span>\n @if (isOptionSelected('person2@domain.com')) {\n <span class=\"checkmark\">\u2713</span>\n }\n </div>\n </li>\n <li [cdkOption]=\"'person3@domain.com'\" class=\"multi-listbox-option notext-overflow\">\n <div class=\"option-content\">\n <div class=\"option-avatar\">{{ getInitials('person3@domain.com') }}</div>\n <span class=\"option-text\">person3@domain.com</span>\n @if (isOptionSelected('person3@domain.com')) {\n <span class=\"checkmark\">\u2713</span>\n }\n </div>\n </li>\n <li [cdkOption]=\"'person4@domain.com'\" class=\"multi-listbox-option notext-overflow\">\n <div class=\"option-content\">\n <div class=\"option-avatar\">{{ getInitials('person4@domain.com') }}</div>\n <span class=\"option-text\">person4@domain.com</span>\n @if (isOptionSelected('person4@domain.com')) {\n <span class=\"checkmark\">\u2713</span>\n }\n </div>\n </li>\n <li [cdkOption]=\"'person5@domain.com'\" class=\"multi-listbox-option notext-overflow\">\n <div class=\"option-content\">\n <div class=\"option-avatar\">{{ getInitials('person5@domain.com') }}</div>\n <span class=\"option-text\">person5@domain.com</span>\n @if (isOptionSelected('person5@domain.com')) {\n <span class=\"checkmark\">\u2713</span>\n }\n </div>\n </li>\n @for (option of filteredOptions(); track option) {\n <li [cdkOption]=\"option.value\" class=\"multi-listbox-option notext-overflow listbox-option_people\">\n <div class=\"option-content\">\n <div class=\"option-avatar\">{{ getInitials(option.value) }}</div>\n <span class=\"option-text\">{{option.label}}</span>\n @if (isOptionSelected(option.value)) {\n <span class=\"checkmark\">\u2713</span>\n }\n </div>\n </li>\n }\n </ul>\n </div>\n </div>\n</ng-template>\n\n<ng-template #statusSelectMenu>\n <div class=\"dropdown-menu status-dropdown-menu\" cdkMenu [style.min-width.px]=\"fieldSize()\"\n (closed)=\"singleOptionClosed()\">\n <div class=\"listbox-container\">\n <mat-form-field appearance=\"outline\" class=\"search-form-field\">\n <input matInput type=\"search\" placeholder=\"Search...\" [(ngModel)]=\"optionSearchText\">\n </mat-form-field>\n\n <ul cdkListbox [ngModel]=\"currentValue()\" (ngModelChange)=\"selectedSingleSelect($event)\"\n aria-labelledby=\"listbox-label\" class=\"listbox status-listbox\">\n <li [cdkOption]=\"''\" class=\"listbox-option notext-overflow\">\n None\n </li>\n @for (option of getStatusOptions(); track option.value) {\n <li [cdkOption]=\"option.value\" class=\"listbox-option status-option\"\n [style.background-color]=\"getStatusColor(option.value).background\"\n [style.border-color]=\"getStatusColor(option.value).border\" [style.color]=\"getStatusColor(option.value).text\">\n @if(option.color) {\n <span class=\"status-color-indicator\" [style.background-color]=\"option.color\"></span>\n }\n {{option.label}}\n </li>\n }\n </ul>\n </div>\n </div>\n</ng-template>\n\n<ng-template #tagSelectMenu>\n <div class=\"dropdown-menu tag-dropdown-menu\" [style.min-width.px]=\"fieldSize()\">\n <div class=\"listbox-container\">\n <mat-form-field appearance=\"outline\" class=\"search-form-field\">\n <input matInput type=\"search\" placeholder=\"Search or add tag...\" [ngModel]=\"optionSearchText()\"\n (ngModelChange)=\"optionSearchText.set($event)\" (keyup.enter)=\"addNewTag(optionSearchText())\"\n [style.min-width.px]=\"fieldSize()\">\n </mat-form-field>\n\n <ul cdkListboxMultiple=\"true\" cdkListbox [ngModel]=\"currentValue()\" (ngModelChange)=\"selectedMultiSelect($event)\"\n class=\"listbox tag-listbox\" [style.min-width.px]=\"fieldSize()\">\n <!-- Predefined tags -->\n @for (option of getTagOptions(); track option.value) {\n <li [cdkOption]=\"option.value\" class=\"listbox-option tag-option\">\n {{option.label}}\n </li>\n }\n\n <!-- New tag input -->\n\n\n\n </ul>\n\n </div>\n </div>\n</ng-template>\n\n<!-- Attachment Menu - Positioned relative to the cell -->\n<ng-template \ncdkConnectedOverlay\n[cdkConnectedOverlayOrigin]=\"attachmentTrigger\"\n[cdkConnectedOverlayOpen]=\"showOverlayMenu('attachment')\"\n(detach)=\"isOpen = showOverlayMenu('attachment')\">\n <div class=\"attachment-menu-overlay\" [style.width.px]=\"currentColumnWidth()\" [style.min-width.px]=\"300\">\n <div class=\"attachment-container\">\n <!-- Header Section -->\n <div class=\"attachment-header\">\n <span class=\"attachment-title\">Add or Drag files</span>\n <button mat-flat-button \n (click)=\"fileInput.click()\" \n class=\"attachment-upload-btn\">\n Upload\n </button>\n </div>\n \n <!-- Drop zone -->\n <div class=\"attachment-drop-zone\" \n (drop)=\"onFileDrop($event)\" \n (dragover)=\"onDragOver($event)\" \n (dragleave)=\"onDragLeave($event)\"\n (paste)=\"onPaste($event)\"\n (click)=\"fileInput.click()\"\n [class.dragging]=\"isDragging()\">\n <div class=\"attachment-drop-content\">\n <div class=\"attachment-drop-icon\">+</div>\n <div class=\"attachment-drop-text\">\n <div class=\"primary-text\">Click to upload or drag files here</div>\n <div class=\"secondary-text\">Support multiple files</div>\n </div>\n </div>\n </div>\n \n <!-- Hidden file input -->\n <input #fileInput \n type=\"file\" \n multiple \n (change)=\"fileInputChange($event)\" \n style=\"display: none;\">\n \n <!-- File list -->\n <div class=\"attachment-file-list\" *ngIf=\"currentValue()?.length > 0\">\n <div class=\"attachment-file-item\" *ngFor=\"let file of currentValue(); trackBy: trackByFile\">\n <div class=\"file-info\">\n <span class=\"file-icon\">\uD83D\uDCC4</span>\n <span class=\"file-name\">{{ file?.split('_')?.[2] || file }}</span>\n </div>\n <div class=\"file-actions\">\n <button class=\"action-btn\" (click)=\"viewFile(file)\" title=\"View\">\uD83D\uDC41\uFE0F</button>\n <button class=\"action-btn\" (click)=\"deleteFile(file)\" title=\"Delete\">\uD83D\uDDD1\uFE0F</button>\n </div>\n </div>\n </div>\n </div>\n </div>\n</ng-template>", styles: [":host{display:block;height:100%;width:100%;position:relative;overflow:hidden!important}.container{height:calc(100% - 2px);width:calc(100% - 2px);position:relative!important;overflow:hidden!important;max-width:100%!important;box-sizing:border-box!important}.container .cell-display-text{text-overflow:ellipsis!important;overflow:hidden!important;white-space:nowrap!important;max-width:100%!important;width:100%!important;display:block!important}.inputRef{height:inherit;width:inherit;border:none}.inputRef:focus{outline:none}.cell-checkbox{text-align:center}.cell-form-field{width:100%!important;height:100%!important;padding:0!important;margin:0!important}.cell-form-field .mat-mdc-form-field-outline,.cell-form-field .mat-mdc-form-field-subscript-wrapper,.cell-form-field .mat-mdc-form-field-text-suffix{display:none!important}.cell-form-field .mat-mdc-form-field-wrapper,.cell-form-field .mat-mdc-form-field-wrapper .mat-mdc-form-field-flex{width:100%!important;height:100%!important;padding:0!important;margin:0!important}.cell-form-field .mat-mdc-form-field-wrapper .mat-mdc-form-field-flex .mat-mdc-form-field-infix{width:100%!important;height:100%!important;padding:0!important;margin:0!important;min-height:auto!important;border-top:none!important}.cell-form-field input[matInput]{width:100%!important;height:100%!important;padding:2px!important;margin:0!important;border:none!important;outline:none!important;background:transparent!important;font-size:14px!important;line-height:normal!important;box-sizing:border-box!important;max-width:none!important;min-width:0!important;flex:none!important}.dropdown-menu{width:100%}.attachment-menu,.dropdown-menu,.dropdown-menu.attachment-menu,[cdkMenu].attachment-menu{background:var(--grid-surface, #fef7ff)!important;background-color:var(--grid-surface, #fef7ff)!important;border-radius:8px!important;box-shadow:var(--grid-elevation-2, 0px 1px 2px 0px rgba(0, 0, 0, .3), 0px 2px 6px 2px rgba(0, 0, 0, .15))!important;border:1px solid var(--grid-outline-variant, #cac4d0)!important}.attachment-menu.cdk-overlay-pane,.dropdown-menu.cdk-overlay-pane,.dropdown-menu.attachment-menu.cdk-overlay-pane,[cdkMenu].attachment-menu.cdk-overlay-pane{background:var(--grid-surface)!important;background-color:var(--grid-surface)!important}.attachment-menu .attachment-container,.dropdown-menu .attachment-container,.dropdown-menu.attachment-menu .attachment-container,[cdkMenu].attachment-menu .attachment-container{padding:4px;background:var(--grid-surface, #fef7ff);border-radius:8px}.attachment-menu .attachment-header,.dropdown-menu .attachment-header,.dropdown-menu.attachment-menu .attachment-header,[cdkMenu].attachment-menu .attachment-header{display:flex!important;justify-content:space-between!important;align-items:center!important;margin-bottom:24px!important;padding:0!important}.attachment-menu .attachment-header .attachment-title,.dropdown-menu .attachment-header .attachment-title,.dropdown-menu.attachment-menu .attachment-header .attachment-title,[cdkMenu].attachment-menu .attachment-header .attachment-title{font-family:var(--grid-font-family, \"Poppins\")!important;font-size:16px!important;font-weight:500!important;color:var(--grid-on-surface, #1d1b20)!important;margin:0!important}.attachment-menu .attachment-header .attachment-upload-btn,.attachment-menu .attachment-header .attachment-upload-btn.mat-mdc-raised-button,.attachment-menu .attachment-header .attachment-upload-btn.mat-mdc-button,.dropdown-menu .attachment-header .attachment-upload-btn,.dropdown-menu .attachment-header .attachment-upload-btn.mat-mdc-raised-button,.dropdown-menu .attachment-header .attachment-upload-btn.mat-mdc-button,.dropdown-menu.attachment-menu .attachment-header .attachment-upload-btn,.dropdown-menu.attachment-menu .attachment-header .attachment-upload-btn.mat-mdc-raised-button,.dropdown-menu.attachment-menu .attachment-header .attachment-upload-btn.mat-mdc-button,[cdkMenu].attachment-menu .attachment-header .attachment-upload-btn,[cdkMenu].attachment-menu .attachment-header .attachment-upload-btn.mat-mdc-raised-button,[cdkMenu].attachment-menu .attachment-header .attachment-upload-btn.mat-mdc-button{background:var(--grid-primary, #6750a4)!important;background-color:var(--grid-primary, #6750a4)!important;color:var(--grid-on-primary, #ffffff)!important;font-family:var(--grid-font-family, \"Poppins\")!important;font-weight:500!important;padding:8px 20px!important;border-radius:6px!important;border:none!important;cursor:pointer!important;font-size:14px!important;letter-spacing:.5px!important;box-shadow:var(--grid-elevation-1, 0px 1px 2px 0px rgba(0, 0, 0, .3), 0px 1px 3px 1px rgba(0, 0, 0, .15))!important;transition:background-color .2s ease!important}.attachment-menu .attachment-header .attachment-upload-btn .mdc-button__label,.attachment-menu .attachment-header .attachment-upload-btn.mat-mdc-raised-button .mdc-button__label,.attachment-menu .attachment-header .attachment-upload-btn.mat-mdc-button .mdc-button__label,.dropdown-menu .attachment-header .attachment-upload-btn .mdc-button__label,.dropdown-menu .attachment-header .attachment-upload-btn.mat-mdc-raised-button .mdc-button__label,.dropdown-menu .attachment-header .attachment-upload-btn.mat-mdc-button .mdc-button__label,.dropdown-menu.attachment-menu .attachment-header .attachment-upload-btn .mdc-button__label,.dropdown-menu.attachment-menu .attachment-header .attachment-upload-btn.mat-mdc-raised-button .mdc-button__label,.dropdown-menu.attachment-menu .attachment-header .attachment-upload-btn.mat-mdc-button .mdc-button__label,[cdkMenu].attachment-menu .attachment-header .attachment-upload-btn .mdc-button__label,[cdkMenu].attachment-menu .attachment-header .attachment-upload-btn.mat-mdc-raised-button .mdc-button__label,[cdkMenu].attachment-menu .attachment-header .attachment-upload-btn.mat-mdc-button .mdc-button__label{color:var(--grid-on-primary, #ffffff)!important}.attachment-menu .attachment-header .attachment-upload-btn:hover,.attachment-menu .attachment-header .attachment-upload-btn.mat-mdc-raised-button:hover,.attachment-menu .attachment-header .attachment-upload-btn.mat-mdc-button:hover,.dropdown-menu .attachment-header .attachment-upload-btn:hover,.dropdown-menu .attachment-header .attachment-upload-btn.mat-mdc-raised-button:hover,.dropdown-menu .attachment-header .attachment-upload-btn.mat-mdc-button:hover,.dropdown-menu.attachment-menu .attachment-header .attachment-upload-btn:hover,.dropdown-menu.attachment-menu .attachment-header .attachment-upload-btn.mat-mdc-raised-button:hover,.dropdown-menu.attachment-menu .attachment-header .attachment-upload-btn.mat-mdc-button:hover,[cdkMenu].attachment-menu .attachment-header .attachment-upload-btn:hover,[cdkMenu].attachment-menu .attachment-header .attachment-upload-btn.mat-mdc-raised-button:hover,[cdkMenu].attachment-menu .attachment-header .attachment-upload-btn.mat-mdc-button:hover{opacity:.9!important}.attachment-menu .attachment-header .attachment-upload-btn:before,.attachment-menu .attachment-header .attachment-upload-btn:after,.attachment-menu .attachment-header .attachment-upload-btn.mat-mdc-raised-button:before,.attachment-menu .attachment-header .attachment-upload-btn.mat-mdc-raised-button:after,.attachment-menu .attachment-header .attachment-upload-btn.mat-mdc-button:before,.attachment-menu .attachment-header .attachment-upload-btn.mat-mdc-button:after,.dropdown-menu .attachment-header .attachment-upload-btn:before,.dropdown-menu .attachment-header .attachment-upload-btn:after,.dropdown-menu .attachment-header .attachment-upload-btn.mat-mdc-raised-button:before,.dropdown-menu .attachment-header .attachment-upload-btn.mat-mdc-raised-button:after,.dropdown-menu .attachment-header .attachment-upload-btn.mat-mdc-button:before,.dropdown-menu .attachment-header .attachment-upload-btn.mat-mdc-button:after,.dropdown-menu.attachment-menu .attachment-header .attachment-upload-btn:before,.dropdown-menu.attachment-menu .attachment-header .attachment-upload-btn:after,.dropdown-menu.attachment-menu .attachment-header .attachment-upload-btn.mat-mdc-raised-button:before,.dropdown-menu.attachment-menu .attachment-header .attachment-upload-btn.mat-mdc-raised-button:after,.dropdown-menu.attachment-menu .attachment-header .attachment-upload-btn.mat-mdc-button:before,.dropdown-menu.attachment-menu .attachment-header .attachment-upload-btn.mat-mdc-button:after,[cdkMenu].attachment-menu .attachment-header .attachment-upload-btn:before,[cdkMenu].attachment-menu .attachment-header .attachment-upload-btn:after,[cdkMenu].attachment-menu .attachment-header .attachment-upload-btn.mat-mdc-raised-button:before,[cdkMenu].attachment-menu .attachment-header .attachment-upload-btn.mat-mdc-raised-button:after,[cdkMenu].attachment-menu .attachment-header .attachment-upload-btn.mat-mdc-button:before,[cdkMenu].attachment-menu .attachment-header .attachment-upload-btn.mat-mdc-button:after{display:none!important}.attachment-menu .attachment-drop-zone,.dropdown-menu .attachment-drop-zone,.dropdown-menu.attachment-menu .attachment-drop-zone,[cdkMenu].attachment-menu .attachment-drop-zone{border:2px dashed var(--grid-outline-variant, #cac4d0)!important;border-radius:8px!important;padding:10px!important;text-align:center!important;cursor:pointer!important;transition:all .3s ease!important;background:var(--grid-surface-variant, #e7e0ec)!important;margin:16px 0!important}.attachment-menu .attachment-drop-zone:hover,.dropdown-menu .attachment-drop-zone:hover,.dropdown-menu.attachment-menu .attachment-drop-zone:hover,[cdkMenu].attachment-menu .attachment-drop-zone:hover{border-color:var(--grid-primary, #6750a4)!important;background:var(--grid-surface-container, #f3edf7)!important}.attachment-menu .attachment-drop-zone.dragging,.dropdown-menu .attachment-drop-zone.dragging,.dropdown-menu.attachment-menu .attachment-drop-zone.dragging,[cdkMenu].attachment-menu .attachment-drop-zone.dragging{border-color:var(--grid-primary, #6750a4)!important;background:var(--grid-surface-container, #f3edf7)!important;transform:scale(1.01)!important}.attachment-menu .attachment-drop-zone .attachment-drop-content,.dropdown-menu .attachment-drop-zone .attachment-drop-content,.dropdown-menu.attachment-menu .attachment-drop-zone .attachment-drop-content,[cdkMenu].attachment-menu .attachment-drop-zone .attachment-drop-content{display:flex!important;flex-direction:column!important;align-items:center!important;gap:12px!important}.attachment-menu .attachment-drop-zone .attachment-drop-icon,.dropdown-menu .attachment-drop-zone .attachment-drop-icon,.dropdown-menu.attachment-menu .attachment-drop-zone .attachment-drop-icon,[cdkMenu].attachment-menu .attachment-drop-zone .attachment-drop-icon{font-size:48px!important;color:var(--grid-primary, #6750a4)!important;font-weight:300!important;line-height:1!important}.attachment-menu .attachment-drop-zone .attachment-drop-text .primary-text,.dropdown-menu .attachment-drop-zone .attachment-drop-text .primary-text,.dropdown-menu.attachment-menu .attachment-drop-zone .attachment-drop-text .primary-text,[cdkMenu].attachment-menu .attachment-drop-zone .attachment-drop-text .primary-text{font-family:var(--grid-font-family, \"Poppins\")!important;font-size:14px!important;color:var(--grid-on-surface-variant, #49454f)!important;font-weight:400!important;margin:0!important}.attachment-menu .attachment-drop-zone .attachment-drop-text .secondary-text,.dropdown-menu .attachment-drop-zone .attachment-drop-text .secondary-text,.dropdown-menu.attachment-menu .attachment-drop-zone .attachment-drop-text .secondary-text,[cdkMenu].attachment-menu .attachment-drop-zone .attachment-drop-text .secondary-text{font-family:var(--grid-font-family, \"Poppins\")!important;font-size:12px!important;color:var(--grid-on-surface-variant, #49454f)!important;margin-top:4px!important;display:block!important}.attachment-menu .attachment-file-list,.dropdown-menu .attachment-file-list,.dropdown-menu.attachment-menu .attachment-file-list,[cdkMenu].attachment-menu .attachment-file-list{display:block!important;margin-top:16px!important;border-top:1px solid var(--grid-outline-variant, #cac4d0)!important;padding-top:16px!important}.attachment-menu .attachment-file-list .attachment-file-item,.dropdown-menu .attachment-file-list .attachment-file-item,.dropdown-menu.attachment-menu .attachment-file-list .attachment-file-item,[cdkMenu].attachment-menu .attachment-file-list .attachment-file-item{display:flex!important;align-items:center!important;justify-content:space-between!important;padding:8px 0!important;border-bottom:1px solid var(--grid-outline-variant, #cac4d0)!important}.attachment-menu .attachment-file-list .attachment-file-item:last-child,.dropdown-menu .attachment-file-list .attachment-file-item:last-child,.dropdown-menu.attachment-menu .attachment-file-list .attachment-file-item:last-child,[cdkMenu].attachment-menu .attachment-file-list .attachment-file-item:last-child{border-bottom:none!important}.attachment-menu .attachment-file-list .attachment-file-item .file-info,.dropdown-menu .attachment-file-list .attachment-file-item .file-info,.dropdown-menu.attachment-menu .attachment-file-list .attachment-file-item .file-info,[cdkMenu].attachment-menu .attachment-file-list .attachment-file-item .file-info{display:flex!important;align-items:center!important;gap:8px!important;flex:1!important}.attachment-menu .attachment-file-list .attachment-file-item .file-info .file-icon,.dropdown-menu .attachment-file-list .attachment-file-item .file-info .file-icon,.dropdown-menu.attachment-menu .attachment-file-list .attachment-file-item .file-info .file-icon,[cdkMenu].attachment-menu .attachment-file-list .attachment-file-item .file-info .file-icon{font-size:16px!important;color:var(--grid-on-surface-variant, #49454f)!important}.attachment-menu .attachment-file-list .attachment-file-item .file-info .file-name,.dropdown-menu .attachment-file-list .attachment-file-item .file-info .file-name,.dropdown-menu.attachment-menu .attachment-file-list .attachment-file-item .file-info .file-name,[cdkMenu].attachment-menu .attachment-file-list .attachment-file-item .file-info .file-name{font-family:var(--grid-font-family, \"Poppins\")!important;font-size:14px!important;color:var(--grid-on-surface, #1d1b20)!important;word-break:break-word!important}.attachment-menu .attachment-file-list .attachment-file-item .file-actions,.dropdown-menu .attachment-file-list .attachment-file-item .file-actions,.dropdown-menu.attachment-menu .attachment-file-list .attachment-file-item .file-actions,[cdkMenu].attachment-menu .attachment-file-list .attachment-file-item .file-actions{display:flex!important;gap:4px!important}.attachment-menu .attachment-file-list .attachment-file-item .file-actions .action-btn,.dropdown-menu .attachment-file-list .attachment-file-item .file-actions .action-btn,.dropdown-menu.attachment-menu .attachment-file-list .attachment-file-item .file-actions .action-btn,[cdkMenu].attachment-menu .attachment-file-list .attachment-file-item .file-actions .action-btn{width:24px!important;height:24px!important;border:none!important;background:transparent!important;cursor:pointer!important;border-radius:4px!important;font-size:14px!important;color:var(--grid-on-surface-variant, #49454f)!important;transition:background-color .2s ease!important}.attachment-menu .attachment-file-list .attachment-file-item .file-actions .action-btn:hover,.dropdown-menu .attachment-file-list .attachment-file-item .file-actions .action-btn:hover,.dropdown-menu.attachment-menu .attachment-file-list .attachment-file-item .file-actions .action-btn:hover,[cdkMenu].attachment-menu .attachment-file-list .attachment-file-item .file-actions .action-btn:hover{background:var(--grid-surface-container, #f3edf7)!important}.cdk-overlay-container .cdk-overlay-pane .attachment-menu,.cdk-overlay-container .attachment-menu,.cdk-overlay-pane .attachment-menu{background:var(--grid-surface, #fef7ff)!important;background-color:var(--grid-surface, #fef7ff)!important;border:1px solid var(--grid-outline-variant, #cac4d0)!important;box-shadow:var(--grid-elevation-2, 0px 1px 2px 0px rgba(0, 0, 0, .3), 0px 2px 6px 2px rgba(0, 0, 0, .15))!important;border-radius:8px!important;font-family:var(--grid-font-family, \"Poppins\")!important}.cdk-overlay-container .cdk-overlay-pane .attachment-menu .attachment-container,.cdk-overlay-container .attachment-menu .attachment-container,.cdk-overlay-pane .attachment-menu .attachment-container{padding:4px;background:var(--grid-surface, #fef7ff)!important}.cdk-overlay-container .cdk-overlay-pane .attachment-menu .attachment-header,.cdk-overlay-container .attachment-menu .attachment-header,.cdk-overlay-pane .attachment-menu .attachment-header{display:flex!important;justify-content:space-between!important;align-items:center!important;margin-bottom:24px!important;padding:0!important}.cdk-overlay-container .cdk-overlay-pane .attachment-menu .attachment-header .attachment-title,.cdk-overlay-container .attachment-menu .attachment-header .attachment-title,.cdk-overlay-pane .attachment-menu .attachment-header .attachment-title{font-family:var(--grid-font-family, \"Poppins\")!important;font-size:16px!important;font-weight:500!important;color:var(--grid-on-surface, #1d1b20)!important;margin:0!important}.cdk-overlay-container .cdk-overlay-pane .attachment-menu .attachment-header .attachment-upload-btn,.cdk-overlay-container .attachment-menu .attachment-header .attachment-upload-btn,.cdk-overlay-pane .attachment-menu .attachment-header .attachment-upload-btn{background:var(--grid-primary, #6750a4)!important;background-color:var(--grid-primary, #6750a4)!important;color:var(--grid-on-primary, #ffffff)!important;font-family:var(--grid-font-family, \"Poppins\")!important;font-weight:500!important;padding:8px 20px!important;border-radius:6px!important;border:none!important;cursor:pointer!important;font-size:14px!important;letter-spacing:.5px!important;box-shadow:var(--grid-elevation-1, 0px 1px 2px 0px rgba(0, 0, 0, .3), 0px 1px 3px 1px rgba(0, 0, 0, .15))!important;transition:background-color .2s ease!important}.cdk-overlay-container .cdk-overlay-pane .attachment-menu .attachment-header .attachment-upload-btn:hover,.cdk-overlay-container .attachment-menu .attachment-header .attachment-upload-btn:hover,.cdk-overlay-pane .attachment-menu .attachment-header .attachment-upload-btn:hover{opacity:.9!important}.cdk-overlay-container .cdk-overlay-pane .attachment-menu .attachment-header .attachment-upload-btn .mdc-button__label,.cdk-overlay-container .attachment-menu .attachment-header .attachment-upload-btn .mdc-button__label,.cdk-overlay-pane .attachment-menu .attachment-header .attachment-upload-btn .mdc-button__label{color:var(--grid-on-primary, #ffffff)!important}.cdk-overlay-container .cdk-overlay-pane .attachment-menu .attachment-drop-zone,.cdk-overlay-container .attachment-menu .attachment-drop-zone,.cdk-overlay-pane .attachment-menu .attachment-drop-zone{border:2px dashed var(--grid-outline-variant, #cac4d0)!important;border-radius:8px!important;padding:40px 20px!important;text-align:center!important;cursor:pointer!important;transition:all .3s ease!important;background:var(--grid-surface-variant, #e7e0ec)!important;margin:16px 0!important}.cdk-overlay-container .cdk-overlay-pane .attachment-menu .attachment-drop-zone:hover,.cdk-overlay-container .attachment-menu .attachment-drop-zone:hover,.cdk-overlay-pane .attachment-menu .attachment-drop-zone:hover{border-color:var(--grid-primary, #6750a4)!important;background:var(--grid-surface-container, #f3edf7)!important}.cdk-overlay-container .cdk-overlay-pane .attachment-menu .attachment-drop-zone.dragging,.cdk-overlay-container .attachment-menu .attachment-drop-zone.dragging,.cdk-overlay-pane .attachment-menu .attachment-drop-zone.dragging{border-color:var(--grid-primary, #6750a4)!important;background:var(--grid-surface-container, #f3edf7)!important;transform:scale(1.01)!important}.cdk-overlay-container .cdk-overlay-pane .attachment-menu .attachment-drop-zone .attachment-drop-content,.cdk-overlay-container .attachment-menu .attachment-drop-zone .attachment-drop-content,.cdk-overlay-pane .attachment-menu .attachment-drop-zone .attachment-drop-content{display:flex!important;flex-direction:column!important;align-items:center!important;gap:12px!important}.cdk-overlay-container .cdk-overlay-pane .attachment-menu .attachment-drop-zone .attachment-drop-icon,.cdk-overlay-container .attachment-menu .attachment-drop-zone .attachment-drop-icon,.cdk-overlay-pane .attachment-menu .attachment-drop-zone .attachment-drop-icon{font-size:48px!important;color:var(--grid-primary, #6750a4)!important;font-weight:300!important;line-height:1!important}.cdk-overlay-container .cdk-overlay-pane .attachment-menu .attachment-drop-zone .attachment-drop-text .primary-text,.cdk-overlay-container .attachment-menu .attachment-drop-zone .attachment-drop-text .primary-text,.cdk-overlay-pane .attachment-menu .attachment-drop-zone .attachment-drop-text .primary-text{font-family:var(--grid-font-family, \"Poppins\")!important;font-size:14px!important;color:var(--grid-on-surface-variant, #49454f)!important;font-weight:400!important;margin:0!important}.cdk-overlay-container .cdk-overlay-pane .attachment-menu .attachment-drop-zone .attachment-drop-text .secondary-text,.cdk-overlay-container .attachment-menu .attachment-drop-zone .attachment-drop-text .secondary-text,.cdk-overlay-pane .attachment-menu .attachment-drop-zone .attachment-drop-text .secondary-text{font-family:var(--grid-font-family, \"Poppins\")!important;font-size:12px!important;color:var(--grid-on-surface-variant, #49454f)!important;margin-top:4px!important;display:block!important}.cdk-overlay-container .cdk-overlay-pane .attachment-menu .attachment-file-list,.cdk-overlay-container .attachment-menu .attachment-file-list,.cdk-overlay-pane .attachment-menu .attachment-file-list{display:block!important;margin-top:16px!important;border-top:1px solid var(--grid-outline-variant, #cac4d0)!important;padding-top:16px!important}.cdk-overlay-container .cdk-overlay-pane .attachment-menu .attachment-file-list .attachment-file-item,.cdk-overlay-container .attachment-menu .attachment-file-list .attachment-file-item,.cdk-overlay-pane .attachment-menu .attachment-file-list .attachment-file-item{display:flex!important;align-items:center!important;justify-content:space-between!important;padding:8px 0!important;border-bottom:1px solid var(--grid-outline-variant, #cac4d0)!important}.cdk-overlay-container .cdk-overlay-pane .attachment-menu .attachment-file-list .attachment-file-item:last-child,.cdk-overlay-container .attachment-menu .attachment-file-list .attachment-file-item:last-child,.cdk-overlay-pane .attachment-menu .attachment-file-list .attachment-file-item:last-child{border-bottom:none!important}.cdk-overlay-container .cdk-overlay-pane .attachment-menu .attachment-file-list .attachment-file-item .file-info,.cdk-overlay-container .attachment-menu .attachment-file-list .attachment-file-item .file-info,.cdk-overlay-pane .attachment-menu .attachment-file-list .attachment-file-item .file-info{display:flex!important;align-items:center!important;gap:8px!important;flex:1!important}.cdk-overlay-container .cdk-overlay-pane .attachment-menu .attachment-file-list .attachment-file-item .file-info .file-icon,.cdk-overlay-container .attachment-menu .attachment-file-list .attachment-file-item .file-info .file-icon,.cdk-overlay-pane .attachment-menu .attachment-file-list .attachment-file-item .file-info .file-icon{font-size:16px!important;color:var(--grid-on-surface-variant, #49454f)!important}.cdk-overlay-container .cdk-overlay-pane .attachment-menu .attachment-file-list .attachment-file-item .file-info .file-name,.cdk-overlay-container .attachment-menu .attachment-file-list .attachment-file-item .file-info .file-name,.cdk-overlay-pane .attachment-menu .attachment-file-list .attachment-file-item .file-info .file-name{font-family:var(--grid-font-family, \"Poppins\")!important;font-size:14px!important;color:var(--grid-on-surface, #1d1b20)!important;word-break:break-word!important}.cdk-overlay-container .cdk-overlay-pane .attachment-menu .attachment-file-list .attachment-file-item .file-actions,.cdk-overlay-container .attachment-menu .attachment-file-list .attachment-file-item .file-actions,.cdk-overlay-pane .attachment-menu .attachment-file-list .attachment-file-item .file-actions{display:flex!important;gap:4px!important}.cdk-overlay-container .cdk-overlay-pane .attachment-menu .attachment-file-list .attachment-file-item .file-actions .action-btn,.cdk-overlay-container .attachment-menu .attachment-file-list .attachment-file-item .file-actions .action-btn,.cdk-overlay-pane .attachment-menu .attachment-file-list .attachment-file-item .file-actions .action-btn{width:24px!important;height:24px!important;border:none!important;background:transparent!important;cursor:pointer!important;border-radius:4px!important;font-size:14px!important;color:var(--grid-on-surface-variant, #49454f)!important;transition:background-color .2s ease!important}.cdk-overlay-container .cdk-overlay-pane .attachment-menu .attachment-file-list .attachment-file-item .file-actions .action-btn:hover,.cdk-overlay-container .attachment-menu .attachment-file-list .attachment-file-item .file-actions .action-btn:hover,.cdk-overlay-pane .attachment-menu .attachment-file-list .attachment-file-item .file-actions .action-btn:hover{background:var(--grid-surface-container, #f3edf7)!important}.cdk-overlay-container .cdk-overlay-pane .attachment-menu,.cdk-overlay-container .attachment-menu{background:var(--grid-surface, #fef7ff)!important;background-color:var(--grid-surface, #fef7ff)!important;border:1px solid var(--grid-outline-variant, #cac4d0)!important;box-shadow:var(--grid-elevation-2, 0px 1px 2px 0px rgba(0, 0, 0, .3), 0px 2px 6px 2px rgba(0, 0, 0, .15))!important}.attachment-cell-wrapper{position:relative;display:block;width:100%;height:100%;text-align:center;overflow:visible}.attachment-menu-overlay{position:absolute;z-index:1000;background:var(--grid-surface, #fef7ff);border:1px solid var(--grid-outline-variant, #cac4d0);box-shadow:var(--grid-elevation-2, 0px 1px 2px 0px rgba(0, 0, 0, .3), 0px 2px 6px 2px rgba(0, 0, 0, .15));border-radius:8px;font-family:var(--grid-font-family, \"Poppins\");color:var(--grid-on-surface, #1d1b20);overflow:visible;z-index:9999}.attachment-menu-overlay .attachment-container{padding:16px;background:var(--grid-surface, #fef7ff)}.attachment-menu-overlay .attachment-header{display:flex;justify-content:space-between;align-items:center;margin-bottom:24px;padding:0}.attachment-menu-overlay .attachment-header .attachment-title{font-family:var(--grid-font-family, \"Poppins\");font-size:16px;font-weight:500;color:var(--grid-on-surface, #1d1b20);margin:0}.attachment-menu-overlay .attachment-header .attachment-upload-btn{background:var(--grid-primary, #6750a4);background-color:var(--grid-primary, #6750a4);color:var(--grid-on-primary, #ffffff);font-family:var(--grid-font-family, \"Poppins\");font-weight:500;padding:8px 20px;border-radius:6px;border:none;cursor:pointer;font-size:14px;letter-spacing:.5px;box-shadow:var(--grid-elevation-1, 0px 1px 2px 0px rgba(0, 0, 0, .3), 0px 1px 3px 1px rgba(0, 0, 0, .15));transition:background-color .2s ease}.attachment-menu-overlay .attachment-header .attachment-upload-btn:hover{opacity:.9}.attachment-menu-overlay .attachment-header .attachment-upload-btn .mdc-button__label{color:var(--grid-on-primary, #ffffff)}.attachment-menu-overlay .attachment-drop-zone{border:2px dashed var(--grid-outline-variant, #cac4d0);border-radius:8px;padding:10px;text-align:center;cursor:pointer;transition:all .3s ease;background:var(--grid-surface-variant, #e7e0ec);margin:16px 0}.attachment-menu-overlay .attachment-drop-zone:hover{border-color:var(--grid-primary, #6750a4);background:var(--grid-surface-container, #f3edf7)}.attachment-menu-overlay .attachment-drop-zone.dragging{border-color:var(--grid-primary, #6750a4);background:var(--grid-surface-container, #f3edf7);transform:scale(1.01)}.attachment-menu-overlay .attachment-drop-zone .attachment-drop-content{display:flex;flex-direction:column;align-items:center;gap:12px}.attachment-menu-overlay .attachment-drop-zone .attachment-drop-icon{font-size:48px;color:var(--grid-primary, #6750a4);font-weight:300;line-height:1}.attachment-menu-overlay .attachment-drop-zone .attachment-drop-text .primary-text{font-family:var(--grid-font-family, \"Poppins\");font-size:14px;color:var(--grid-on-surface-variant, #49454f);font-weight:400;margin:0}.attachment-menu-overlay .attachment-drop-zone .attachment-drop-text .secondary-text{font-family:var(--grid-font-family, \"Poppins\");font-size:12px;color:var(--grid-on-surface-variant, #49454f);margin-top:4px;display:block}.attachment-menu-overlay .attachment-file-list{display:block;margin-top:16px;border-top:1px solid var(--grid-outline-variant, #cac4d0);padding-top:16px}.attachment-menu-overlay .attachment-file-list .attachment-file-item{display:flex;align-items:center;justify-content:space-between;padding:8px 0;border-bottom:1px solid var(--grid-outline-variant, #cac4d0)}.attachment-menu-overlay .attachment-file-list .attachment-file-item:last-child{border-bottom:none}.attachment-menu-overlay .attachment-file-list .attachment-file-item .file-info{display:flex;align-items:center;gap:8px;flex:1}.attachment-menu-overlay .attachment-file-list .attachment-file-item .file-info .file-icon{font-size:16px;color:var(--grid-on-surface-variant, #49454f)}.attachment-menu-overlay .attachment-file-list .attachment-file-item .file-info .file-name{font-family:var(--grid-font-family, \"Poppins\");font-size:14px;color:var(--grid-on-surface, #1d1b20);word-break:break-word}.attachment-menu-overlay .attachment-file-list .attachment-file-item .file-actions{display:flex;gap:4px}.attachment-menu-overlay .attachment-file-list .attachment-file-item .file-actions .action-btn{width:24px;height:24px;border:none;background:transparent;cursor:pointer;border-radius:4px;font-size:14px;color:var(--grid-on-surface-variant, #49454f);transition:background-color .2s ease}.attachment-menu-overlay .attachment-file-list .attachment-file-item .file-actions .action-btn:hover{background:var(--grid-surface-container, #f3edf7)}.cdk-overlay-container .cdk-overlay-pane .dropdown-menu,.cdk-overlay-container .dropdown-menu,.cdk-overlay-pane .dropdown-menu{background:var(--grid-surface, #fef7ff)!important;background-color:var(--grid-surface, #fef7ff)!important;border:1px solid var(--grid-outline-variant, #cac4d0)!important;box-shadow:var(--grid-elevation-2, 0px 1px 2px 0px rgba(0, 0, 0, .3), 0px 2px 6px 2px rgba(0, 0, 0, .15))!important;border-radius:8px!important;font-family:var(--grid-font-family, \"Poppins\")!important;color:var(--grid-on-surface, #1d1b20)!important;overflow:hidden!important;box-sizing:border-box!important}.cdk-overlay-container .cdk-overlay-pane .dropdown-menu .listbox-container,.cdk-overlay-container .dropdown-menu .listbox-container,.cdk-overlay-pane .dropdown-menu .listbox-container{padding:8px!important;background:var(--grid-surface, #fef7ff)!important}.cdk-overlay-container .cdk-overlay-pane .dropdown-menu .search-form-field,.cdk-overlay-container .dropdown-menu .search-form-field,.cdk-overlay-pane .dropdown-menu .search-form-field{width:100%!important;margin-bottom:8px!important}.cdk-overlay-container .cdk-overlay-pane .dropdown-menu .search-form-field .mat-mdc-form-field,.cdk-overlay-container .dropdown-menu .search-form-field .mat-mdc-form-field,.cdk-overlay-pane .dropdown-menu .search-form-field .mat-mdc-form-field{width:100%!important}.cdk-overlay-container .cdk-overlay-pane .dropdown-menu .search-form-field .mat-mdc-text-field-wrapper,.cdk-overlay-container .dropdown-menu .search-form-field .mat-mdc-text-field-wrapper,.cdk-overlay-pane .dropdown-menu .search-form-field .mat-mdc-text-field-wrapper{background:var(--grid-surface, #fffbfe)!important;border-radius:4px!important}.cdk-overlay-container .cdk-overlay-pane .dropdown-menu .search-form-field .mat-mdc-form-field-focus-overlay,.cdk-overlay-container .dropdown-menu .search-form-field .mat-mdc-form-field-focus-overlay,.cdk-overlay-pane .dropdown-menu .search-form-field .mat-mdc-form-field-focus-overlay{background:var(--grid-surface, #fffbfe)!important}.cdk-overlay-container .cdk-overlay-pane .dropdown-menu .search-form-field .mat-mdc-form-field-subscript-wrapper,.cdk-overlay-container .dropdown-menu .search-form-field .mat-mdc-form-field-subscript-wrapper,.cdk-overlay-pane .dropdown-menu .search-form-field .mat-mdc-form-field-subscript-wrapper{display:none!important}.cdk-overlay-container .cdk-overlay-pane .dropdown-menu .search-form-field input,.cdk-overlay-container .dropdown-menu .search-form-field input,.cdk-overlay-pane .dropdown-menu .search-form-field input{font-family:var(--grid-font-family, \"Poppins\")!important;font-size:14px!important;color:var(--grid-on-surface, #1d1b20)!important}.cdk-overlay-container .cdk-overlay-pane .dropdown-menu .select-all-container,.cdk-overlay-container .dropdown-menu .select-all-container,.cdk-overlay-pane .dropdown-menu .select-all-container{padding:8px 12px!important;border-bottom:1px solid var(--grid-outline-variant, #cac4d0)!important;margin-bottom:4px!important}.cdk-overlay-container .cdk-overlay-pane .dropdown-menu .select-all-container .select-all-text,.cdk-overlay-container .dropdown-menu .select-all-container .select-all-text,.cdk-overlay-pane .dropdown-menu .select-all-container .select-all-text{font-family:var(--grid-font-family, \"Poppins\")!important;font-size:14px!important;font-weight:500!important;color:var(--grid-on-surface, #1d1b20)!important;margin-left:8px!important}.cdk-overlay-container .cdk-overlay-pane .dropdown-menu .select-all-container mat-checkbox .mdc-checkbox .mdc-checkbox__checkmark,.cdk-overlay-container .dropdown-menu .select-all-container mat-checkbox .mdc-checkbox .mdc-checkbox__checkmark,.cdk-overlay-pane .dropdown-menu .select-all-container mat-checkbox .mdc-checkbox .mdc-checkbox__checkmark{color:var(--grid-on-primary, #ffffff)!important}.cdk-overlay-container .cdk-overlay-pane .dropdown-menu .select-all-container mat-checkbox.mat-mdc-checkbox-checked .mdc-checkbox__background,.cdk-overlay-container .dropdown-menu .select-all-container mat-checkbox.mat-mdc-checkbox-checked .mdc-checkbox__background,.cdk-overlay-pane .dropdown-menu .select-all-container mat-checkbox.mat-mdc-checkbox-checked .mdc-checkbox__background{background-color:var(--grid-primary, #6750a4)!important;border-color:var(--grid-primary, #6750a4)!important}.cdk-overlay-container .cdk-overlay-pane .dropdown-menu .select-all-container mat-checkbox.mat-mdc-checkbox-indeterminate .mdc-checkbox__background,.cdk-overlay-container .dropdown-menu .select-all-container mat-checkbox.mat-mdc-checkbox-indeterminate .mdc-checkbox__background,.cdk-overlay-pane .dropdown-menu .select-all-container mat-checkbox.mat-mdc-checkbox-indeterminate .mdc-checkbox__background{background-color:var(--grid-primary, #6750a4)!important;border-color:var(--grid-primary, #6750a4)!important}.cdk-overlay-container .cdk-overlay-pane .dropdown-menu .listbox,.cdk-overlay-container .dropdown-menu .listbox,.cdk-overlay-pane .dropdown-menu .listbox{list-style:none!important;margin:0!important;padding:0!important;max-height:200px!important;overflow-y:auto!important;background:var(--grid-surface, #fef7ff)!important}.cdk-overlay-container .cdk-overlay-pane .dropdown-menu .listbox::-webkit-scrollbar,.cdk-overlay-container .dropdown-menu .listbox::-webkit-scrollbar,.cdk-overlay-pane .dropdown-menu .listbox::-webkit-scrollbar{width:8px!important}.cdk-overlay-container .cdk-overlay-pane .dropdown-menu .listbox::-webkit-scrollbar-track,.cdk-overlay-container .dropdown-menu .listbox::-webkit-scrollbar-track,.cdk-overlay-pane .dropdown-menu .listbox::-webkit-scrollbar-track{background:var(--grid-surface-variant, #e7e0ec)!important;border-radius:4px!important}.cdk-overlay-container .cdk-overlay-pane .dropdown-menu .listbox::-webkit-scrollbar-thumb,.cdk-overlay-container .dropdown-menu .listbox::-webkit-scrollbar-thumb,.cdk-overlay-pane .dropdown-menu .listbox::-webkit-scrollbar-thumb{background:var(--grid-primary, #6750a4)!important;border-radius:4px!important}.cdk-overlay-container .cdk-overlay-pane .dropdown-menu .listbox::-webkit-scrollbar-thumb:hover,.cdk-overlay-container .dropdown-menu .listbox::-webkit-scrollbar-thumb:hover,.cdk-overlay-pane .dropdown-menu .listbox::-webkit-scrollbar-thumb:hover{background:var(--grid-primary, #6750a4)!important;opacity:.8!important}.cdk-overlay-container .cdk-overlay-pane .dropdown-menu .multi-listbox-option,.cdk-overlay-container .dropdown-menu .multi-listbox-option,.cdk-overlay-pane .dropdown-menu .multi-listbox-option{padding:4px 8px!important;margin:2px 0!important;border-radius:4px!important;cursor:pointer!important;font-family:var(--grid-font-family, \"Poppins\")!important;font-size:14px!important;color:var(--grid-on-surface, #1d1b20)!important;background:transparent!important;transition:background-color .2s ease!important;border:none!important;text-align:left!important;width:100%!important}.cdk-overlay-container .cdk-overlay-pane .dropdown-menu .multi-listbox-option:hover,.cdk-overlay-container .dropdown-menu .multi-listbox-option:hover,.cdk-overlay-pane .dropdown-menu .multi-listbox-option:hover{background:var(--grid-surface-container, #f3edf7)!important}.cdk-overlay-container .cdk-overlay-pane .dropdown-menu .multi-listbox-option.notext-overflow,.cdk-overlay-container .dropdown-menu .multi-listbox-option.notext-overflow,.cdk-overlay-pane .dropdown-menu .multi-listbox-option.notext-overflow{white-space:nowrap!important;overflow:hidden!important;text-overflow:ellipsis!important}.cdk-overlay-container .cdk-overlay-pane .dropdown-menu .multi-listbox-option .option-content,.cdk-overlay-container .dropdown-menu .multi-listbox-option .option-content,.cdk-overlay-pane .dropdown-menu .multi-listbox-option .option-content{display:flex!important;align-items:center!important;gap:8px!important;width:100%!important}.cdk-overlay-container .cdk-overlay-pane .dropdown-menu .multi-listbox-option .option-content .option-text,.cdk-overlay-container .dropdown-menu .multi-listbox-option .option-content .option-text,.cdk-overlay-pane .dropdown-menu .multi-listbox-option .option-content .option-text{flex:1!important;font-family:var(--grid-font-family, \"Poppins\")!important;font-size:14px!important;color:inherit!important}.cdk-overlay-container .cdk-overlay-pane .dropdown-menu .multi-listbox-option .option-content mat-checkbox,.cdk-overlay-container .dropdown-menu .multi-listbox-option .option-content mat-checkbox,.cdk-overlay-pane .dropdown-menu .multi-listbox-option .option-content mat-checkbox{flex-shrink:0!important}.cdk-overlay-container .cdk-overlay-pane .dropdown-menu .multi-listbox-option .option-content mat-checkbox .mdc-checkbox .mdc-checkbox__background,.cdk-overlay-container .dropdown-menu .multi-listbox-option .option-content mat-checkbox .mdc-checkbox .mdc-checkbox__background,.cdk-overlay-pane .dropdown-menu .multi-listbox-option .option-content mat-checkbox .mdc-checkbox .mdc-checkbox__background{border-color:var(--grid-outline, #79757f)!important}.cdk-overlay-container .cdk-overlay-pane .dropdown-menu .multi-listbox-option .option-content mat-checkbox .mdc-checkbox .mdc-checkbox__checkmark,.cdk-overlay-container .dropdown-menu .multi-listbox-option .option-content mat-checkbox .mdc-checkbox .mdc-checkbox__checkmark,.cdk-overlay-pane .dropdown-menu .multi-listbox-option .option-content mat-checkbox .mdc-checkbox .mdc-checkbox__checkmark{color:var(--grid-on-primary, #ffffff)!important}.cdk-overlay-container .cdk-overlay-pane .dropdown-menu .multi-listbox-option .option-content mat-checkbox.mat-mdc-checkbox-checked .mdc-checkbox__background,.cdk-overlay-container .dropdown-menu .multi-listbox-option .option-content mat-checkbox.mat-mdc-checkbox-checked .mdc-checkbox__background,.cdk-overlay-pane .dropdown-menu .multi-listbox-option .option-content mat-checkbox.mat-mdc-checkbox-checked .mdc-checkbox__background{background-color:var(--grid-primary, #6750a4)!important;border-color:var(--grid-primary, #6750a4)!important}.cdk-overlay-container .cdk-overlay-pane .dropdown-menu .listbox-option,.cdk-overlay-container .dropdown-menu .listbox-option,.cdk-overlay-pane .dropdown-menu .listbox-option{padding:4px 8px!important;margin:2px 0!important;border-radius:4px!important;cursor:pointer!important;font-family:var(--grid-font-family, \"Poppins\")!important;font-size:14px!important;color:var(--grid-on-surface, #1d1b20)!important;background:transparent!important;transition:background-color .2s ease!important;border:none!important;text-align:left!important;width:100%!important}.cdk-overlay-container .cdk-overlay-pane .dropdown-menu .listbox-option:hover,.cdk-overlay-container .dropdown-menu .listbox-option:hover,.cdk-overlay-pane .dropdown-menu .listbox-option:hover{background:var(--grid-surface-container, #f3edf7)!important}.cdk-overlay-container .cdk-overlay-pane .dropdown-menu .listbox-option.cdk-option-active,.cdk-overlay-container .dropdown-menu .listbox-option.cdk-option-active,.cdk-overlay-pane .dropdown-menu .listbox-option.cdk-option-active,.cdk-overlay-container .cdk-overlay-pane .dropdown-menu .listbox-option.cdk-option-selected,.cdk-overlay-container .dropdown-menu .listbox-option.cdk-option-selected,.cdk-overlay-pane .dropdown-menu .listbox-option.cdk-option-selected{background:var(--grid-primary, #6750a4)!important;color:var(--grid-on-primary, #ffffff)!important}.cdk-overlay-container .cdk-overlay-pane .dropdown-menu .listbox-option.notext-overflow,.cdk-overlay-container .dropdown-menu .listbox-option.notext-overflow,.cdk-overlay-pane .dropdown-menu .listbox-option.notext-overflow{white-space:nowrap!important;overflow:hidden!important;text-overflow:ellipsis!important}.cdk-overlay-container .cdk-overlay-pane .dropdown-menu .listbox-option .option-content,.cdk-overlay-container .dropdown-menu .listbox-option .option-content,.cdk-overlay-pane .dropdown-menu .listbox-option .option-content{display:flex!important;align-items:center!important;gap:8px!important;width:100%!important}.cdk-overlay-container .cdk-overlay-pane .dropdown-menu .listbox-option .option-content .option-text,.cdk-overlay-container .dropdown-menu .listbox-option .option-content .option-text,.cdk-overlay-pane .dropdown-menu .listbox-option .option-content .option-text{flex:1!important;font-family:var(--grid-font-family, \"Poppins\")!important;font-size:14px!important;color:inherit!important}.cell-display-text-editable{cursor:pointer!important}.cell-display-text{width:100%!important;height:100%!important;min-height:20px!important;display:block!important;padding:4px 8px!important;font-family:var(--grid-font-family, \"Poppins\")!important;font-size:var(--grid-font-size-body, 12px)!important;color:var(--grid-on-surface, #1d1b20)!important;background:transparent!important;border:none!important;outline:none!important;text-overflow:ellipsis!important;overflow:hidden!important;white-space:nowrap!important;max-width:100%!important;box-sizing:border-box!important;transition:background-color .2s ease!important;line-height:1.4!important}.cell-display-text,.cell-display-text>*{text-overflow:ellipsis!important;overflow:hidden!important;white-space:nowrap!important;max-width:100%!important;width:100%!important;display:block!important}.cell-display-text:empty:before{content:\"Click to select\"!important;color:var(--grid-on-surface-variant, #49454f)!important;font-style:italic!important}.cell-display-number{text-align:right!important}.assignee-avatars{display:flex;align-items:center;padding:4px 8px;min-height:20px}.avatar-circle{width:28px;height:28px;border-radius:50%;background-color:var(--grid-primary, #6750a4);color:#fff;display:flex;align-items:center;justify-content:center;font-size:12px;font-weight:600;border:2px solid var(--grid-surface, #fef7ff);margin-left:-8px;position:relative;z-index:1}.avatar-circle:first-child{margin-left:0}.avatar-circle.count-circle{background-color:var(--grid-surface-variant, #e7e0ec);color:var(--grid-on-surface-variant, #49454f);font-size:11px;font-weight:500}.no-assignees{color:var(--grid-on-surface-variant, #49454f);font-style:italic;font-size:12px}.option-content{display:flex;align-items:center;gap:8px;width:100%}.option-avatar{width:24px;height:24px;border-radius:50%;background-color:var(--grid-primary, #6750a4);color:#fff;display:flex;align-items:center;justify-content:center;font-size:10px;font-weight:600;flex-shrink:0}.option-text{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.checkmark{color:var(--grid-primary, #6750a4);font-weight:700;font-size:14px;flex-shrink:0}.drillable-value{color:var(--grid-primary, #6750a4);text-decoration:underline;text-decoration-color:var(--grid-primary, #6750a4);text-decoration-thickness:1px;text-underline-offset:2px;transition:all .2s ease}.drillable-link{cursor:pointer;padding:4px}\n"], dependencies: [{ kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i2$1.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i2$1.MatPrefix, selector: "[matPrefix], [matIconPrefix], [matTextPrefix]", inputs: ["matTextPrefix"] }, { kind: "directive", type: i2$1.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i3.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i4.MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatCheckboxModule }, { kind: "component", type: i5.MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "aria-expanded", "aria-controls", "aria-owns", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "disabledInteractive", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { kind: "ngmodule", type: MatSliderModule }, { kind: "component", type: i6.MatSlider, selector: "mat-slider", inputs: ["disabled", "discrete", "showTickMarks", "min", "color", "disableRipple", "max", "step", "displayWith"], exportAs: ["matSlider"] }, { kind: "directive", type: i6.MatSliderThumb, selector: "input[matSliderThumb]", inputs: ["value"], outputs: ["valueChange", "dragStart", "dragEnd"], exportAs: ["matSliderThumb"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "directive", type: CdkMenuTrigger, selector: "[cdkMenuTriggerFor]", inputs: ["cdkMenuTriggerFor", "cdkMenuPosition", "cdkMenuTriggerData"], outputs: ["cdkMenuOpened", "cdkMenuClosed"], exportAs: ["cdkMenuTriggerFor"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: CdkListbox, selector: "[cdkListbox]", inputs: ["id", "tabindex", "cdkListboxValue", "cdkListboxMultiple", "cdkListboxDisabled", "cdkListboxUseActiveDescendant", "cdkListboxOrientation", "cdkListboxCompareWith", "cdkListboxNavigationWrapDisabled", "cdkListboxNavigatesDisabledOptions"], outputs: ["cdkListboxValueChange"], exportAs: ["cdkListbox"] }, { kind: "directive", type: CdkOption, selector: "[cdkOption]", inputs: ["id", "cdkOption", "cdkOptionTypeaheadLabel", "cdkOptionDisabled", "tabindex"], exportAs: ["cdkOption"] }, { kind: "directive", type: CdkMenu, selector: "[cdkMenu]", outputs: ["closed"], exportAs: ["cdkMenu"] }, { kind: "ngmodule", type: OverlayModule }, { kind: "directive", type: i1$3.CdkConnectedOverlay, selector: "[cdk-connected-overlay], [connected-overlay], [cdkConnectedOverlay]", inputs: ["cdkConnectedOverlayOrigin", "cdkConnectedOverlayPositions", "cdkConnectedOverlayPositionStrategy", "cdkConnectedOverlayOffsetX", "cdkConnectedOverlayOffsetY", "cdkConnectedOverlayWidth", "cdkConnectedOverlayHeight", "cdkConnectedOverlayMinWidth", "cdkConnectedOverlayMinHeight", "cdkConnectedOverlayBackdropClass", "cdkConnectedOverlayPanelClass", "cdkConnectedOverlayViewportMargin", "cdkConnectedOverlayScrollStrategy", "cdkConnectedOverlayOpen", "cdkConnectedOverlayDisableClose", "cdkConnectedOverlayTransformOriginOn", "cdkConnectedOverlayHasBackdrop", "cdkConnectedOverlayLockPosition", "cdkConnectedOverlayFlexibleDimensions", "cdkConnectedOverlayGrowAfterOpen", "cdkConnectedOverlayPush", "cdkConnectedOverlayDisposeOnNavigation"], outputs: ["backdropClick", "positionChange", "attach", "detach", "overlayKeydown", "overlayOutsideClick"], exportAs: ["cdkConnectedOverlay"] }, { kind: "directive", type: i1$3.CdkOverlayOrigin, selector: "[cdk-overlay-origin], [overlay-origin], [cdkOverlayOrigin]", exportAs: ["cdkOverlayOrigin"] }, { kind: "directive", type: CustomDatePickerDirective, selector: "[appCustomDatePicker]" }, { kind: "ngmodule", type: MatDatepickerModule }, { kind: "component", type: i9.MatDatepicker, selector: "mat-datepicker", exportAs: ["matDatepicker"] }, { kind: "directive", type: i9.MatDatepickerInput, selector: "input[matDatepicker]", inputs: ["matDatepicker", "min", "max", "matDatepickerFilter"], exportAs: ["matDatepickerInput"] }, { kind: "component", type: i9.MatDatepickerToggle, selector: "mat-datepicker-toggle", inputs: ["for", "tabIndex", "aria-label", "disabled", "disableRipple"], exportAs: ["matDatepickerToggle"] }, { kind: "ngmodule", type: MatNativeDateModule }, { kind: "component", type: MobileInputComponent, selector: "app-mobile-input", inputs: ["defaultCountry"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
3403
|
+
], viewQueries: [{ propertyName: "attachmentTrigger", first: true, predicate: ["attachmentTrigger"], descendants: true }, { propertyName: "singleSelectTrigger", first: true, predicate: ["singleSelectTrigger"], descendants: true }, { propertyName: "multiSelectTrigger", first: true, predicate: ["multiSelectTrigger"], descendants: true }, { propertyName: "peopleTrigger", first: true, predicate: ["peopleTrigger"], descendants: true }], ngImport: i0, template: "<div class=\"container\">\n @switch (columnDatatype()) {\n @case ('textbox') {\n @if(isActive()){\n <mat-form-field appearance=\"outline\" class=\"cell-form-field\">\n <input matInput type=\"text\" [id]=\"'input-' + columnName()+ id()\" [name]=\"'input-' + columnName()+ id()\"\n [(ngModel)]=\"currentValue\" (blur)=\"onTextboxBlur()\">\n </mat-form-field>\n } @else {\n <div class=\"cell-display-text\" (dblclick)=\"setActive(true)\"\n [class.cell-display-text-editable]=\"isEditable()\">\n @if (drillable()) {\n <span class=\"drillable-value\" (click)=\"onDrillableClick($event)\">{{currentValue()}}</span>\n } @else {\n {{currentValue()}}\n }\n </div>\n }\n }\n @case ('currency') {\n @if(isActive()){\n <mat-form-field appearance=\"outline\" class=\"cell-form-field\">\n <input matInput type=\"text\" [id]=\"'currency-' + columnName()+ id()\" [name]=\"'currency-' + columnName()+ id()\"\n [ngModel]=\"currentValue()\" (ngModelChange)=\"setField($event)\" placeholder=\"Number\" (blur)=\"onNumberBlur()\">\n <span matTextPrefix>$</span>\n </mat-form-field>\n } @else {\n <div class=\"cell-display-text cell-display-number\" (dblclick)=\"setActive(true)\"\n [class.cell-display-text-editable]=\"isEditable()\">\n @if (drillable()) {\n <span class=\"drillable-value\" (click)=\"onDrillableClick($event)\">{{formatNumberSignal()}}</span>\n } @else {\n {{formatNumberSignal()}}\n }\n </div>\n }\n }\n @case ('number') {\n @if(isActive()){\n <mat-form-field appearance=\"outline\" class=\"cell-form-field\">\n <input matInput type=\"text\" [id]=\"'number-' + columnName()+ id()\" [name]=\"'number-' + columnName()+ id()\"\n [ngModel]=\"currentValue()\" (ngModelChange)=\"setField($event)\" placeholder=\"Number\" (blur)=\"onNumberBlur()\">\n </mat-form-field>\n } @else {\n <div class=\"cell-display-text cell-display-number\" (dblclick)=\"setActive(true)\"\n[class.cell-display-text-editable]=\"isEditable()\"\n >\n @if (drillable() && currentValue() !== 0) {\n <span class=\"drillable-value\" ><a class=\"drillable-link\" (click)=\"onDrillableClick($event)\">{{formatNumberSignal()}}</a></span>\n } @else {\n {{formatNumberSignal()}}\n }\n </div>\n }\n }\n @case ('location') {\n @if(isActive()){\n <mat-form-field appearance=\"outline\" class=\"cell-form-field\">\n <input matInput type=\"text\" [id]=\"'location-' + columnName()+ id()\" [name]=\"'location-' + columnName()+ id()\"\n [(ngModel)]=\"currentValue\" placeholder=\"location\" (blur)=\"onLocationBlur()\">\n </mat-form-field>\n } @else {\n <div class=\"cell-display-text\" (dblclick)=\"setActive(true)\"\n [class.cell-display-text-editable]=\"isEditable()\">\n @if (drillable()) {\n <span class=\"drillable-value\" (click)=\"onDrillableClick($event)\">{{currentValue()}}</span>\n } @else {\n {{currentValue()}}\n }\n </div>\n }\n }\n @case ('email') {\n @if(isActive()){\n <mat-form-field appearance=\"outline\" class=\"cell-form-field\">\n <input matInput type=\"email\" [id]=\"'email-' + columnName()+ id()\" [name]=\"'email-' + columnName()+ id()\"\n [(ngModel)]=\"currentValue\" placeholder=\"email\" matTooltipPosition=\"below\" (blur)=\"onEmailBlur()\">\n </mat-form-field>\n } @else {\n <div class=\"cell-display-text\" (dblclick)=\"setActive(true)\"\n [class.cell-display-text-editable]=\"isEditable()\">\n @if (drillable()) {\n <span class=\"drillable-value\" (click)=\"onDrillableClick($event)\">{{currentValue()}}</span>\n } @else {\n {{currentValue()}}\n }\n </div>\n }\n }\n @case ('dropdown_multi_select') {\n <div class=\"cell-display-text\" (dblclick)=\"toggleOverlayMenu($event)\" #multiSelectTrigger\n [class.cell-display-text-editable]=\"isEditable()\">\n @if (drillable()) {\n <span class=\"drillable-value\" (click)=\"onDrillableClick($event)\">{{formattedMultiSelectValue(currentColumnWidth()) || 'Click to select'}}</span>\n } @else {\n {{formattedMultiSelectValue(currentColumnWidth()) || 'Click to select'}}\n }\n </div>\n }\n\n @case ('dropdown_single_select') {\n <div class=\"cell-display-text\" (dblclick)=\"toggleOverlayMenu($event)\" [cdkMenuTriggerFor]=\"singleSelectTrigger\" #singleSelectTrigger\n [class.cell-display-text-editable]=\"isEditable()\">\n @if (drillable()) {\n <span class=\"drillable-value\" (click)=\"onDrillableClick($event)\">{{currentValue()}}</span>\n } @else {\n {{currentValue()}}\n }\n </div>\n }\n\n @case ('checkbox') {\n <div class=\"cell-form-field cell-checkbox\">\n <mat-checkbox [(ngModel)]=\"currentValue\">\n </mat-checkbox>\n </div>\n }\n\n @case ('people') {\n <div class=\"assignee-avatars \" (dblclick)=\"toggleOverlayMenu($event)\" #peopleTrigger>\n @if (isAssigneeArray(currentValue()) && currentValue().length > 0) {\n @if (drillable()) {\n <span class=\"drillable-value\" (click)=\"onDrillableClick($event)\">\n @for (assignee of currentValue(); track $index) {\n @if ($index < 3) {\n <div class=\"avatar-circle\" [style.z-index]=\"currentValue().length - $index\">\n {{ getInitials(assignee) }}\n </div>\n }\n }\n @if (currentValue().length > 3) {\n <div class=\"avatar-circle count-circle\" [style.z-index]=\"1\">\n +{{ currentValue().length - 3 }}\n </div>\n }\n </span>\n } @else {\n @for (assignee of currentValue(); track $index) {\n @if ($index < 3) {\n <div class=\"avatar-circle\" [style.z-index]=\"currentValue().length - $index\">\n {{ getInitials(assignee) }}\n </div>\n }\n }\n @if (currentValue().length > 3) {\n <div class=\"avatar-circle count-circle\" [style.z-index]=\"1\">\n +{{ currentValue().length - 3 }}\n </div>\n }\n }\n }\n </div>\n }\n\n\n @case ('date') {\n <div class=\"cell-date-container\">\n @if (drillable()) {\n <span class=\"drillable-value\" (click)=\"onDrillableClick($event)\">\n <input type=\"text\" [id]=\"'date-' + columnName()+ id()\" [name]=\"'date-' + columnName()+ id()\"\n [matDatepicker]=\"picker\" appCustomDatePicker class=\"inputRef date-picker\" [ngModel]=\"currentValue()\"\n (ngModelChange)=\"onDateChange($event)\" (click)=\"picker.open()\" readonly>\n <mat-datepicker-toggle hidden matIconSuffix [for]=\"picker\"></mat-datepicker-toggle>\n <mat-datepicker #picker></mat-datepicker>\n </span>\n } @else {\n <input type=\"text\" [id]=\"'date-' + columnName()+ id()\" [name]=\"'date-' + columnName()+ id()\"\n [matDatepicker]=\"picker\" appCustomDatePicker class=\"inputRef date-picker\" [ngModel]=\"currentValue()\"\n (ngModelChange)=\"onDateChange($event)\" (click)=\"picker.open()\" readonly>\n <mat-datepicker-toggle hidden matIconSuffix [for]=\"picker\"></mat-datepicker-toggle>\n <mat-datepicker #picker></mat-datepicker>\n }\n </div>\n }\n\n\n @case ('priority') {\n <button mat-stroked-button [cdkMenuTriggerFor]=\"prioritySelectMenu\" class=\"dropdown-trigger\">\n <div class=\"cell-priority-content\">\n <div [innerHTML]=\"getPriorityIcon()\"></div>\n @if (drillable()) {\n <div class=\"drillable-value\" (click)=\"onDrillableClick($event)\">{{currentValue()}}</div>\n } @else {\n <div>{{currentValue()}}</div>\n }\n </div>\n </button>\n }\n @case ('progress') {\n @if(isActive()){\n <div class=\"progress-input-container\">\n <mat-slider class=\"progress-slider\" [min]=\"0\" [max]=\"100\" [step]=\"1\" [discrete]=\"true\">\n <input matSliderThumb [ngModel]=\"currentValue()\" (ngModelChange)=\"setProgressValue($event)\">\n </mat-slider>\n <span class=\"progress-value\">{{currentValue()}}%</span>\n </div>\n } @else {\n <div class=\"progress-bar-container\" [attr.data-progress]=\"currentValue()\">\n <div class=\"progress-bar\" [style.width.%]=\"currentValue()\"></div>\n @if (drillable()) {\n <span class=\"progress-text drillable-value\" (click)=\"onDrillableClick($event)\">{{currentValue()}}%</span>\n } @else {\n <span class=\"progress-text\">{{currentValue()}}%</span>\n }\n </div>\n }\n }\n\n @case ('rating') {\n @if(isActive()){\n <div class=\"rating-input-container\">\n @for (star of getRatingStars(); track star) {\n <span class=\"rating-star\" [class.active]=\"currentValue() >= star\" (click)=\"setRatingValue(star)\"\n (mouseenter)=\"hoverRating = star\" (mouseleave)=\"hoverRating = 0\">\n {{getEmojiForRating(star)}}\n </span>\n }\n <span class=\"rating-value\">{{currentValue()}}/{{columnCellConfiguration()?.end_value || 5}}</span>\n </div>\n } @else {\n <div class=\"rating-display-container\">\n @for (star of getRatingStars(); track star) {\n <span class=\"rating-star\" [class.active]=\"currentValue() >= star\">\n {{getEmojiForRating(star)}}\n </span>\n }\n @if (drillable()) {\n <span class=\"drillable-value\" (click)=\"onDrillableClick($event)\">{{currentValue()}}/{{columnCellConfiguration()?.end_value || 5}}</span>\n }\n </div>\n }\n }\n\n @case ('status') {\n <button mat-stroked-button [cdkMenuTriggerFor]=\"statusSelectMenu\" class=\"status-dropdown-trigger\"\n [style.background-color]=\"getStatusColor(currentValue()).background\"\n [style.border-color]=\"getStatusColor(currentValue()).border\" [style.color]=\"getStatusColor(currentValue()).text\"\n [style.height.px]=\"30\">\n <div class=\"status-button-content\">\n @if(getStatusButtonDisplay(currentValue()).color) {\n\n }\n @if (drillable()) {\n <span class=\"status-text drillable-value\" (click)=\"onDrillableClick($event)\">\n {{getStatusButtonDisplay(currentValue()).text}}\n </span>\n } @else {\n <span class=\"status-text\">\n {{getStatusButtonDisplay(currentValue()).text}}\n </span>\n }\n </div>\n </button>\n }\n\n @case ('tag') {\n <div class=\"tag-container\" [cdkMenuTriggerFor]=\"tagSelectMenu\">\n\n <div class=\"tag-display\">\n @if (drillable()) {\n <span class=\"drillable-value\" (click)=\"onDrillableClick($event)\">\n @for (tag of getTagDisplay(currentValue()).displayTags; track tag) {\n @if (columnCellConfiguration()) {\n <span class=\"tag\" [style.background]=\"getTagColor(tag).background\" [style.color]=\"getTagColor(tag).color\">\n {{tag}}\n </span>\n } @else {\n <span class=\"tag cell-fallback-tag\">\n {{tag}}\n </span>\n }\n }\n @if(getTagDisplay(currentValue()).moreCount > 0) {\n <span class=\"tag-more\">\n + {{getTagDisplay(currentValue()).moreCount}} more\n </span>\n }\n </span>\n } @else {\n @for (tag of getTagDisplay(currentValue()).displayTags; track tag) {\n @if (columnCellConfiguration()) {\n <span class=\"tag\" [style.background]=\"getTagColor(tag).background\" [style.color]=\"getTagColor(tag).color\">\n {{tag}}\n </span>\n } @else {\n <span class=\"tag cell-fallback-tag\">\n {{tag}}\n </span>\n }\n }\n @if(getTagDisplay(currentValue()).moreCount > 0) {\n <span class=\"tag-more\">\n + {{getTagDisplay(currentValue()).moreCount}} more\n </span>\n }\n }\n </div>\n\n </div>\n }\n\n @case ('phone') {\n <app-mobile-input [(ngModel)]=\"currentValue\"\n [defaultCountry]=\"columnCellConfiguration()?.default_country || 'US'\"></app-mobile-input>\n }\n\n @case ('attachment') {\n <div class=\"attachment-cell-wrapper\" (dblclick)=\"toggleOverlayMenu($event)\" cdkOverlayOrigin #attachmentTrigger=\"cdkOverlayOrigin\">\n @if(currentValue()?.length > 0){\n <div class=\"cell-attachment-container\">\n @if (drillable()) {\n <span class=\"drillable-value\" (click)=\"onDrillableClick($event)\">\n <svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path fill-rule=\"evenodd\" clip-rule=\"evenodd\"\n d=\"M19 12.5C19 14.985 15.866 17 12 17C8.134 17 5 14.985 5 12.5C5 10.015 8.134 8 12 8C15.866 8 19 10.015 19 12.5Z\"\n stroke=\"#7C818C\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n <path fill-rule=\"evenodd\" clip-rule=\"evenodd\"\n d=\"M13.75 12.5001C13.7716 13.1394 13.4429 13.7397 12.8925 14.0657C12.3422 14.3918 11.6578 14.3918 11.1075 14.0657C10.5571 13.7397 10.2284 13.1394 10.25 12.5001C10.2284 11.8608 10.5571 11.2606 11.1075 10.9345C11.6578 10.6084 12.3422 10.6084 12.8925 10.9345C13.4429 11.2606 13.7716 11.8608 13.75 12.5001V12.5001Z\"\n stroke=\"#7C818C\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n </span>\n } @else {\n <svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path fill-rule=\"evenodd\" clip-rule=\"evenodd\"\n d=\"M19 12.5C19 14.985 15.866 17 12 17C8.134 17 5 14.985 5 12.5C5 10.015 8.134 8 12 8C15.866 8 19 10.015 19 12.5Z\"\n stroke=\"#7C818C\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n <path fill-rule=\"evenodd\" clip-rule=\"evenodd\"\n d=\"M13.75 12.5001C13.7716 13.1394 13.4429 13.7397 12.8925 14.0657C12.3422 14.3918 11.6578 14.3918 11.1075 14.0657C10.5571 13.7397 10.2284 13.1394 10.25 12.5001C10.2284 11.8608 10.5571 11.2606 11.1075 10.9345C11.6578 10.6084 12.3422 10.6084 12.8925 10.9345C13.4429 11.2606 13.7716 11.8608 13.75 12.5001V12.5001Z\"\n stroke=\"#7C818C\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n }\n </div>\n }@else {\n <div class=\"cell-attachment-container\">\n @if (drillable()) {\n <span class=\"drillable-value\" (click)=\"onDrillableClick($event)\">\n <svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M14.67 11.053L10.68 15.315C10.3416 15.6932 9.85986 15.9119 9.35236 15.9178C8.84487 15.9237 8.35821 15.7162 8.01104 15.346C7.24412 14.5454 7.257 13.2788 8.04004 12.494L13.399 6.763C13.9902 6.10491 14.8315 5.72677 15.7161 5.72163C16.6006 5.71649 17.4463 6.08482 18.045 6.736C19.3222 8.14736 19.3131 10.2995 18.024 11.7L12.342 17.771C11.5334 18.5827 10.4265 19.0261 9.28113 18.9971C8.13575 18.9682 7.05268 18.4695 6.28604 17.618C4.5337 15.6414 4.57705 12.6549 6.38604 10.73L11.753 5\"\n stroke=\"#363B44\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n </span>\n } @else {\n <svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M14.67 11.053L10.68 15.315C10.3416 15.6932 9.85986 15.9119 9.35236 15.9178C8.84487 15.9237 8.35821 15.7162 8.01104 15.346C7.24412 14.5454 7.257 13.2788 8.04004 12.494L13.399 6.763C13.9902 6.10491 14.8315 5.72677 15.7161 5.72163C16.6006 5.71649 17.4463 6.08482 18.045 6.736C19.3222 8.14736 19.3131 10.2995 18.024 11.7L12.342 17.771C11.5334 18.5827 10.4265 19.0261 9.28113 18.9971C8.13575 18.9682 7.05268 18.4695 6.28604 17.618C4.5337 15.6414 4.57705 12.6549 6.38604 10.73L11.753 5\"\n stroke=\"#363B44\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n }\n </div>\n }\n \n \n </div>\n }\n @default {\n <div class=\"cell-default-display\">\n @if (drillable()) {\n <span class=\"drillable-value\" (click)=\"onDrillableClick($event)\">{{value()}}</span>\n } @else {\n {{value()}}\n }\n </div>\n }\n }\n\n</div>\n\n<ng-template #prioritySelectMenu>\n <div class=\"dropdown-menu\" cdkMenu [style.min-width.px]=\"fieldSize()\" (closed)=\"singleOptionClosed()\">\n <div class=\"listbox-container\">\n <mat-form-field appearance=\"outline\" class=\"search-form-field\">\n <input matInput type=\"search\" placeholder=\"Search...\" [(ngModel)]=\"optionSearchText\">\n </mat-form-field>\n\n <ul cdkListbox [ngModel]=\"currentValue()\" (ngModelChange)=\"selectedSingleSelect($event)\"\n aria-labelledby=\"listbox-label\" class=\"listbox\">\n <li [cdkOption]=\"''\" class=\"listbox-option notext-overflow\">\n None\n </li>\n @for (option of filteredOptions(); track option) {\n <li [cdkOption]=\"option.value\" class=\"listbox-option notext-overflow cell-priority-content\">\n <div [innerHTML]=\"sanitize.bypassSecurityTrustHtml(option.icon)\"></div>\n <div>{{option.label}}</div>\n </li>\n }\n </ul>\n </div>\n </div>\n</ng-template>\n\n<ng-template cdkConnectedOverlay\n[cdkConnectedOverlayOrigin]=\"singleSelectTrigger\"\n[cdkConnectedOverlayOpen]=\"showOverlayMenu('dropdown_single_select')\"\n(detach)=\"isOpen = showOverlayMenu('dropdown_single_select')\">\n <div class=\"dropdown-menu\" cdkMenu [style.width.px]=\"currentColumnWidth()\" (closed)=\"singleOptionClosed()\">\n <div class=\"listbox-container\">\n <mat-form-field appearance=\"outline\" class=\"search-form-field\">\n <input matInput type=\"search\" placeholder=\"Search...\" (click)=\"$event.stopPropagation()\" [(ngModel)]=\"optionSearchText\">\n </mat-form-field>\n <ul cdkListbox [ngModel]=\"currentValue()\" (ngModelChange)=\"selectedSingleSelect($event)\"\n aria-labelledby=\"listbox-label\" class=\"listbox\">\n <li [cdkOption]=\"'None'\" class=\"listbox-option notext-overflow\">\n None\n </li>\n <li [cdkOption]=\"'option 1'\" class=\"listbox-option notext-overflow\">\n option 1\n </li>\n <li [cdkOption]=\"'option 2'\" class=\"listbox-option notext-overflow\">\n option 2\n </li>\n <li [cdkOption]=\"'option 3'\" class=\"listbox-option notext-overflow\">\n option 3\n </li>\n <li [cdkOption]=\"'option 4'\" class=\"listbox-option notext-overflow\">\n option 4\n </li><li [cdkOption]=\"'option 5'\" class=\"listbox-option notext-overflow\">\n option 5\n </li><li [cdkOption]=\"'option 6'\" class=\"listbox-option notext-overflow\">\n option 6\n </li><li [cdkOption]=\"'option 7'\" class=\"listbox-option notext-overflow\">\n option 7\n </li><li [cdkOption]=\"'option 1'\" class=\"listbox-option notext-overflow\">\n option 1\n </li><li [cdkOption]=\"'option 9'\" class=\"listbox-option notext-overflow\">\n option 9\n </li><li [cdkOption]=\"'option 10'\" class=\"listbox-option notext-overflow\">\n option 10\n </li><li [cdkOption]=\"'option 11'\" class=\"listbox-option notext-overflow\">\n option 11\n </li><li [cdkOption]=\"'option 12'\" class=\"listbox-option notext-overflow\">\n option 12\n </li><li [cdkOption]=\"'option 13'\" class=\"listbox-option notext-overflow\">\n option 13\n </li><li [cdkOption]=\"'option 14'\" class=\"listbox-option notext-overflow\">\n option 14\n </li><li [cdkOption]=\"'option 15'\" class=\"listbox-option notext-overflow\">\n option 15\n </li><li [cdkOption]=\"'option 16'\" class=\"listbox-option notext-overflow\">\n option 16\n </li><li [cdkOption]=\"'option 17'\" class=\"listbox-option notext-overflow\">\n option 17\n </li><li [cdkOption]=\"'option 18'\" class=\"listbox-option notext-overflow\">\n option 18\n </li>\n @for (option of filteredOptions(); track option) {\n <li [cdkOption]=\"option.value\" class=\"listbox-option notext-overflow\">\n {{option.label}}\n </li>\n }\n </ul>\n </div>\n </div>\n</ng-template>\n\n<ng-template \ncdkConnectedOverlay\n[cdkConnectedOverlayOrigin]=\"multiSelectTrigger\"\n[cdkConnectedOverlayOpen]=\"showOverlayMenu('dropdown_multi_select')\"\n(detach)=\"isOpen = showOverlayMenu('dropdown_multi_select')\">\n <div class=\"dropdown-menu\" cdkMenu [style.width.px]=\"currentColumnWidth()\" (closed)=\"singleOptionClosed()\">\n <div class=\"listbox-container\">\n <mat-form-field appearance=\"outline\" class=\"search-form-field\">\n <input matInput type=\"search\" placeholder=\"Search...\" [ngModel]=\"optionSearchText()\"\n (ngModelChange)=\"optionSearchText.set($event)\" (click)=\"$event.stopPropagation()\">\n </mat-form-field>\n \n <!-- Select All Checkbox -->\n <div class=\"select-all-container\" (click)=\"$event.stopPropagation()\">\n <mat-checkbox \n [checked]=\"isAllSelected()\" \n [indeterminate]=\"isIndeterminate()\"\n (change)=\"toggleSelectAll($event.checked)\">\n <span class=\"select-all-text\">Select All</span>\n </mat-checkbox>\n </div>\n \n <ul cdkListboxMultiple=\"true\" cdkListboxUseActiveDescendant cdkListbox [ngModel]=\"currentValue()\"\n (ngModelChange)=\"selectedMultiSelect($event)\" aria-labelledby=\"listbox-labssel\" class=\"listbox\" (click)=\"$event.stopPropagation()\">\n <li [cdkOption]=\"'None'\" class=\"multi-listbox-option notext-overflow\">\n <div class=\"option-content\">\n <mat-checkbox [checked]=\"isOptionSelected('None')\" (click)=\"$event.stopPropagation();appendMultiSelect('None')\"></mat-checkbox>\n <span class=\"option-text\">None</span>\n </div>\n </li>\n <li [cdkOption]=\"'option 1'\" class=\"multi-listbox-option notext-overflow\">\n <div class=\"option-content\">\n <mat-checkbox [checked]=\"isOptionSelected('option 1')\" (click)=\"$event.stopPropagation();appendMultiSelect('option 1')\"></mat-checkbox>\n <span class=\"option-text\">option 1</span>\n </div>\n </li>\n <li [cdkOption]=\"'option 2'\" class=\"multi-listbox-option notext-overflow\">\n <div class=\"option-content\">\n <mat-checkbox [checked]=\"isOptionSelected('option 2')\" (click)=\"$event.stopPropagation();appendMultiSelect('option 2')\"></mat-checkbox>\n <span class=\"option-text\">option 2</span>\n </div>\n </li>\n <li [cdkOption]=\"'option 3'\" class=\"multi-listbox-option notext-overflow\">\n <div class=\"option-content\">\n <mat-checkbox [checked]=\"isOptionSelected('option 3')\" (click)=\"$event.stopPropagation();appendMultiSelect('option 3')\"></mat-checkbox>\n <span class=\"option-text\">option 3</span>\n </div>\n </li>\n <li [cdkOption]=\"'option 4'\" class=\"multi-listbox-option notext-overflow\">\n <div class=\"option-content\">\n <mat-checkbox [checked]=\"isOptionSelected('option 4')\" (click)=\"$event.stopPropagation();appendMultiSelect('option 4')\"></mat-checkbox>\n <span class=\"option-text\">option 4</span>\n </div>\n </li>\n <li [cdkOption]=\"'option 5'\" class=\"multi-listbox-option notext-overflow\">\n <div class=\"option-content\">\n <mat-checkbox [checked]=\"isOptionSelected('option 5')\" (click)=\"$event.stopPropagation();appendMultiSelect('option 5')\"></mat-checkbox>\n <span class=\"option-text\">option 5</span>\n </div>\n </li>\n <li [cdkOption]=\"'option 6'\" class=\"multi-listbox-option notext-overflow\">\n <div class=\"option-content\">\n <mat-checkbox [checked]=\"isOptionSelected('option 6')\" (click)=\"$event.stopPropagation();appendMultiSelect('option 6')\"></mat-checkbox>\n <span class=\"option-text\">option 6</span>\n </div>\n </li>\n <li [cdkOption]=\"'option 7'\" class=\"multi-listbox-option notext-overflow\">\n <div class=\"option-content\">\n <mat-checkbox [checked]=\"isOptionSelected('option 7')\" (click)=\"$event.stopPropagation();appendMultiSelect('option 7')\"></mat-checkbox>\n <span class=\"option-text\">option 7</span>\n </div>\n </li>\n <li [cdkOption]=\"'option 8'\" class=\"multi-listbox-option notext-overflow\">\n <div class=\"option-content\">\n <mat-checkbox [checked]=\"isOptionSelected('option 8')\" (click)=\"$event.stopPropagation();appendMultiSelect('option 8')\"></mat-checkbox>\n <span class=\"option-text\">option 8</span>\n </div>\n </li>\n <li [cdkOption]=\"'option 9'\" class=\"multi-listbox-option notext-overflow\">\n <div class=\"option-content\">\n <mat-checkbox [checked]=\"isOptionSelected('option 9')\" (click)=\"$event.stopPropagation();appendMultiSelect('option 9')\"></mat-checkbox>\n <span class=\"option-text\">option 9</span>\n </div>\n </li>\n <li [cdkOption]=\"'option 10'\" class=\"multi-listbox-option notext-overflow\">\n <div class=\"option-content\">\n <mat-checkbox [checked]=\"isOptionSelected('option 10')\" (click)=\"$event.stopPropagation();appendMultiSelect('option 10')\"></mat-checkbox>\n <span class=\"option-text\">option 10</span>\n </div>\n </li>\n @for (option of filteredOptions(); track option) {\n <li [cdkOption]=\"option.value\" class=\"multi-listbox-option notext-overflow\">\n <div class=\"option-content\">\n <mat-checkbox [checked]=\"isOptionSelected(option.value)\" (click)=\"$event.stopPropagation();appendMultiSelect(option.value)\"></mat-checkbox>\n <span class=\"option-text\">{{option.label}}</span>\n </div>\n </li>\n }\n </ul>\n </div>\n </div>\n</ng-template>\n\n<ng-template cdkConnectedOverlay\n[cdkConnectedOverlayOrigin]=\"peopleTrigger\"\n[cdkConnectedOverlayOpen]=\"showOverlayMenu('people')\"\n(detach)=\"isOpen = showOverlayMenu('people')\">\n <div class=\"dropdown-menu\" cdkMenu [style.width.px]=\"currentColumnWidth()\" (closed)=\"singleOptionClosed()\">\n <div class=\"listbox-container\">\n <mat-form-field appearance=\"outline\" class=\"search-form-field\">\n <input matInput type=\"search\" placeholder=\"Search...\" [ngModel]=\"optionSearchText()\" (click)=\"$event.stopPropagation()\"\n (ngModelChange)=\"optionSearchText.set($event)\">\n </mat-form-field>\n <ul cdkListboxMultiple=\"true\" cdkListboxUseActiveDescendant cdkListbox [ngModel]=\"currentValue()\"\n (ngModelChange)=\"selectedMultiSelect($event)\" aria-labelledby=\"listbox-labssel\" class=\"listbox\">\n <li [cdkOption]=\"'person0@domain.com'\" class=\"multi-listbox-option notext-overflow\">\n <div class=\"option-content\">\n <div class=\"option-avatar\">{{ getInitials('person0@domain.com') }}</div>\n <span class=\"option-text\">person0@domain.com</span>\n @if (isOptionSelected('person0@domain.com')) {\n <span class=\"checkmark\">\u2713</span>\n }\n </div>\n </li>\n <li [cdkOption]=\"'person1@domain.com'\" class=\"multi-listbox-option notext-overflow\">\n <div class=\"option-content\">\n <div class=\"option-avatar\">{{ getInitials('person1@domain.com') }}</div>\n <span class=\"option-text\">person1@domain.com</span>\n @if (isOptionSelected('person1@domain.com')) {\n <span class=\"checkmark\">\u2713</span>\n }\n </div>\n </li>\n <li [cdkOption]=\"'person2@domain.com'\" class=\"multi-listbox-option notext-overflow\">\n <div class=\"option-content\">\n <div class=\"option-avatar\">{{ getInitials('person2@domain.com') }}</div>\n <span class=\"option-text\">person2@domain.com</span>\n @if (isOptionSelected('person2@domain.com')) {\n <span class=\"checkmark\">\u2713</span>\n }\n </div>\n </li>\n <li [cdkOption]=\"'person3@domain.com'\" class=\"multi-listbox-option notext-overflow\">\n <div class=\"option-content\">\n <div class=\"option-avatar\">{{ getInitials('person3@domain.com') }}</div>\n <span class=\"option-text\">person3@domain.com</span>\n @if (isOptionSelected('person3@domain.com')) {\n <span class=\"checkmark\">\u2713</span>\n }\n </div>\n </li>\n <li [cdkOption]=\"'person4@domain.com'\" class=\"multi-listbox-option notext-overflow\">\n <div class=\"option-content\">\n <div class=\"option-avatar\">{{ getInitials('person4@domain.com') }}</div>\n <span class=\"option-text\">person4@domain.com</span>\n @if (isOptionSelected('person4@domain.com')) {\n <span class=\"checkmark\">\u2713</span>\n }\n </div>\n </li>\n <li [cdkOption]=\"'person5@domain.com'\" class=\"multi-listbox-option notext-overflow\">\n <div class=\"option-content\">\n <div class=\"option-avatar\">{{ getInitials('person5@domain.com') }}</div>\n <span class=\"option-text\">person5@domain.com</span>\n @if (isOptionSelected('person5@domain.com')) {\n <span class=\"checkmark\">\u2713</span>\n }\n </div>\n </li>\n @for (option of filteredOptions(); track option) {\n <li [cdkOption]=\"option.value\" class=\"multi-listbox-option notext-overflow listbox-option_people\">\n <div class=\"option-content\">\n <div class=\"option-avatar\">{{ getInitials(option.value) }}</div>\n <span class=\"option-text\">{{option.label}}</span>\n @if (isOptionSelected(option.value)) {\n <span class=\"checkmark\">\u2713</span>\n }\n </div>\n </li>\n }\n </ul>\n </div>\n </div>\n</ng-template>\n\n<ng-template #statusSelectMenu>\n <div class=\"dropdown-menu status-dropdown-menu\" cdkMenu [style.min-width.px]=\"fieldSize()\"\n (closed)=\"singleOptionClosed()\">\n <div class=\"listbox-container\">\n <mat-form-field appearance=\"outline\" class=\"search-form-field\">\n <input matInput type=\"search\" placeholder=\"Search...\" [(ngModel)]=\"optionSearchText\">\n </mat-form-field>\n\n <ul cdkListbox [ngModel]=\"currentValue()\" (ngModelChange)=\"selectedSingleSelect($event)\"\n aria-labelledby=\"listbox-label\" class=\"listbox status-listbox\">\n <li [cdkOption]=\"''\" class=\"listbox-option notext-overflow\">\n None\n </li>\n @for (option of getStatusOptions(); track option.value) {\n <li [cdkOption]=\"option.value\" class=\"listbox-option status-option\"\n [style.background-color]=\"getStatusColor(option.value).background\"\n [style.border-color]=\"getStatusColor(option.value).border\" [style.color]=\"getStatusColor(option.value).text\">\n @if(option.color) {\n <span class=\"status-color-indicator\" [style.background-color]=\"option.color\"></span>\n }\n {{option.label}}\n </li>\n }\n </ul>\n </div>\n </div>\n</ng-template>\n\n<ng-template #tagSelectMenu>\n <div class=\"dropdown-menu tag-dropdown-menu\" [style.min-width.px]=\"fieldSize()\">\n <div class=\"listbox-container\">\n <mat-form-field appearance=\"outline\" class=\"search-form-field\">\n <input matInput type=\"search\" placeholder=\"Search or add tag...\" [ngModel]=\"optionSearchText()\"\n (ngModelChange)=\"optionSearchText.set($event)\" (keyup.enter)=\"addNewTag(optionSearchText())\"\n [style.min-width.px]=\"fieldSize()\">\n </mat-form-field>\n\n <ul cdkListboxMultiple=\"true\" cdkListbox [ngModel]=\"currentValue()\" (ngModelChange)=\"selectedMultiSelect($event)\"\n class=\"listbox tag-listbox\" [style.min-width.px]=\"fieldSize()\">\n <!-- Predefined tags -->\n @for (option of getTagOptions(); track option.value) {\n <li [cdkOption]=\"option.value\" class=\"listbox-option tag-option\">\n {{option.label}}\n </li>\n }\n\n <!-- New tag input -->\n\n\n\n </ul>\n\n </div>\n </div>\n</ng-template>\n\n<!-- Attachment Menu - Positioned relative to the cell -->\n<ng-template \ncdkConnectedOverlay\n[cdkConnectedOverlayOrigin]=\"attachmentTrigger\"\n[cdkConnectedOverlayOpen]=\"showOverlayMenu('attachment')\"\n(detach)=\"isOpen = showOverlayMenu('attachment')\">\n <div class=\"attachment-menu-overlay\" [style.width.px]=\"currentColumnWidth()\" [style.min-width.px]=\"300\">\n <div class=\"attachment-container\">\n <!-- Header Section -->\n <div class=\"attachment-header\">\n <span class=\"attachment-title\">Add or Drag files</span>\n <button mat-flat-button \n (click)=\"fileInput.click()\" \n class=\"attachment-upload-btn\">\n Upload\n </button>\n </div>\n \n <!-- Drop zone -->\n <div class=\"attachment-drop-zone\" \n (drop)=\"onFileDrop($event)\" \n (dragover)=\"onDragOver($event)\" \n (dragleave)=\"onDragLeave($event)\"\n (paste)=\"onPaste($event)\"\n (click)=\"fileInput.click()\"\n [class.dragging]=\"isDragging()\">\n <div class=\"attachment-drop-content\">\n <div class=\"attachment-drop-icon\">+</div>\n <div class=\"attachment-drop-text\">\n <div class=\"primary-text\">Click to upload or drag files here</div>\n <div class=\"secondary-text\">Support multiple files</div>\n </div>\n </div>\n </div>\n \n <!-- Hidden file input -->\n <input #fileInput \n type=\"file\" \n multiple \n (change)=\"fileInputChange($event)\" \n style=\"display: none;\">\n \n <!-- File list -->\n <div class=\"attachment-file-list\" *ngIf=\"currentValue()?.length > 0\">\n <div class=\"attachment-file-item\" *ngFor=\"let file of currentValue(); trackBy: trackByFile\">\n <div class=\"file-info\">\n <span class=\"file-icon\">\uD83D\uDCC4</span>\n <span class=\"file-name\">{{ file?.split('_')?.[2] || file }}</span>\n </div>\n <div class=\"file-actions\">\n <button class=\"action-btn\" (click)=\"viewFile(file)\" title=\"View\">\uD83D\uDC41\uFE0F</button>\n <button class=\"action-btn\" (click)=\"deleteFile(file)\" title=\"Delete\">\uD83D\uDDD1\uFE0F</button>\n </div>\n </div>\n </div>\n </div>\n </div>\n</ng-template>", styles: [":host{display:block;height:100%;width:100%;position:relative;overflow:hidden!important}.container{height:calc(100% - 2px);width:calc(100% - 2px);position:relative!important;overflow:hidden!important;max-width:100%!important;box-sizing:border-box!important}.container .cell-display-text{text-overflow:ellipsis!important;overflow:hidden!important;white-space:nowrap!important;max-width:100%!important;width:100%!important;display:block!important}.inputRef{height:inherit;width:inherit;border:none}.inputRef:focus{outline:none}.cell-checkbox{text-align:center}.cell-form-field{width:100%!important;height:100%!important;padding:0!important;margin:0!important}.cell-form-field .mat-mdc-form-field-outline,.cell-form-field .mat-mdc-form-field-subscript-wrapper,.cell-form-field .mat-mdc-form-field-text-suffix{display:none!important}.cell-form-field .mat-mdc-form-field-wrapper,.cell-form-field .mat-mdc-form-field-wrapper .mat-mdc-form-field-flex{width:100%!important;height:100%!important;padding:0!important;margin:0!important}.cell-form-field .mat-mdc-form-field-wrapper .mat-mdc-form-field-flex .mat-mdc-form-field-infix{width:100%!important;height:100%!important;padding:0!important;margin:0!important;min-height:auto!important;border-top:none!important}.cell-form-field input[matInput]{width:100%!important;height:100%!important;padding:2px!important;margin:0!important;border:none!important;outline:none!important;background:transparent!important;font-size:14px!important;line-height:normal!important;box-sizing:border-box!important;max-width:none!important;min-width:0!important;flex:none!important}.dropdown-menu{width:100%}.attachment-menu,.dropdown-menu,.dropdown-menu.attachment-menu,[cdkMenu].attachment-menu{background:var(--grid-surface, #fef7ff)!important;background-color:var(--grid-surface, #fef7ff)!important;border-radius:8px!important;box-shadow:var(--grid-elevation-2, 0px 1px 2px 0px rgba(0, 0, 0, .3), 0px 2px 6px 2px rgba(0, 0, 0, .15))!important;border:1px solid var(--grid-outline-variant, #cac4d0)!important}.attachment-menu.cdk-overlay-pane,.dropdown-menu.cdk-overlay-pane,.dropdown-menu.attachment-menu.cdk-overlay-pane,[cdkMenu].attachment-menu.cdk-overlay-pane{background:var(--grid-surface)!important;background-color:var(--grid-surface)!important}.attachment-menu .attachment-container,.dropdown-menu .attachment-container,.dropdown-menu.attachment-menu .attachment-container,[cdkMenu].attachment-menu .attachment-container{padding:4px;background:var(--grid-surface, #fef7ff);border-radius:8px}.attachment-menu .attachment-header,.dropdown-menu .attachment-header,.dropdown-menu.attachment-menu .attachment-header,[cdkMenu].attachment-menu .attachment-header{display:flex!important;justify-content:space-between!important;align-items:center!important;margin-bottom:24px!important;padding:0!important}.attachment-menu .attachment-header .attachment-title,.dropdown-menu .attachment-header .attachment-title,.dropdown-menu.attachment-menu .attachment-header .attachment-title,[cdkMenu].attachment-menu .attachment-header .attachment-title{font-family:var(--grid-font-family, \"Poppins\")!important;font-size:16px!important;font-weight:500!important;color:var(--grid-on-surface, #1d1b20)!important;margin:0!important}.attachment-menu .attachment-header .attachment-upload-btn,.attachment-menu .attachment-header .attachment-upload-btn.mat-mdc-raised-button,.attachment-menu .attachment-header .attachment-upload-btn.mat-mdc-button,.dropdown-menu .attachment-header .attachment-upload-btn,.dropdown-menu .attachment-header .attachment-upload-btn.mat-mdc-raised-button,.dropdown-menu .attachment-header .attachment-upload-btn.mat-mdc-button,.dropdown-menu.attachment-menu .attachment-header .attachment-upload-btn,.dropdown-menu.attachment-menu .attachment-header .attachment-upload-btn.mat-mdc-raised-button,.dropdown-menu.attachment-menu .attachment-header .attachment-upload-btn.mat-mdc-button,[cdkMenu].attachment-menu .attachment-header .attachment-upload-btn,[cdkMenu].attachment-menu .attachment-header .attachment-upload-btn.mat-mdc-raised-button,[cdkMenu].attachment-menu .attachment-header .attachment-upload-btn.mat-mdc-button{background:var(--grid-primary, #6750a4)!important;background-color:var(--grid-primary, #6750a4)!important;color:var(--grid-on-primary, #ffffff)!important;font-family:var(--grid-font-family, \"Poppins\")!important;font-weight:500!important;padding:8px 20px!important;border-radius:6px!important;border:none!important;cursor:pointer!important;font-size:14px!important;letter-spacing:.5px!important;box-shadow:var(--grid-elevation-1, 0px 1px 2px 0px rgba(0, 0, 0, .3), 0px 1px 3px 1px rgba(0, 0, 0, .15))!important;transition:background-color .2s ease!important}.attachment-menu .attachment-header .attachment-upload-btn .mdc-button__label,.attachment-menu .attachment-header .attachment-upload-btn.mat-mdc-raised-button .mdc-button__label,.attachment-menu .attachment-header .attachment-upload-btn.mat-mdc-button .mdc-button__label,.dropdown-menu .attachment-header .attachment-upload-btn .mdc-button__label,.dropdown-menu .attachment-header .attachment-upload-btn.mat-mdc-raised-button .mdc-button__label,.dropdown-menu .attachment-header .attachment-upload-btn.mat-mdc-button .mdc-button__label,.dropdown-menu.attachment-menu .attachment-header .attachment-upload-btn .mdc-button__label,.dropdown-menu.attachment-menu .attachment-header .attachment-upload-btn.mat-mdc-raised-button .mdc-button__label,.dropdown-menu.attachment-menu .attachment-header .attachment-upload-btn.mat-mdc-button .mdc-button__label,[cdkMenu].attachment-menu .attachment-header .attachment-upload-btn .mdc-button__label,[cdkMenu].attachment-menu .attachment-header .attachment-upload-btn.mat-mdc-raised-button .mdc-button__label,[cdkMenu].attachment-menu .attachment-header .attachment-upload-btn.mat-mdc-button .mdc-button__label{color:var(--grid-on-primary, #ffffff)!important}.attachment-menu .attachment-header .attachment-upload-btn:hover,.attachment-menu .attachment-header .attachment-upload-btn.mat-mdc-raised-button:hover,.attachment-menu .attachment-header .attachment-upload-btn.mat-mdc-button:hover,.dropdown-menu .attachment-header .attachment-upload-btn:hover,.dropdown-menu .attachment-header .attachment-upload-btn.mat-mdc-raised-button:hover,.dropdown-menu .attachment-header .attachment-upload-btn.mat-mdc-button:hover,.dropdown-menu.attachment-menu .attachment-header .attachment-upload-btn:hover,.dropdown-menu.attachment-menu .attachment-header .attachment-upload-btn.mat-mdc-raised-button:hover,.dropdown-menu.attachment-menu .attachment-header .attachment-upload-btn.mat-mdc-button:hover,[cdkMenu].attachment-menu .attachment-header .attachment-upload-btn:hover,[cdkMenu].attachment-menu .attachment-header .attachment-upload-btn.mat-mdc-raised-button:hover,[cdkMenu].attachment-menu .attachment-header .attachment-upload-btn.mat-mdc-button:hover{opacity:.9!important}.attachment-menu .attachment-header .attachment-upload-btn:before,.attachment-menu .attachment-header .attachment-upload-btn:after,.attachment-menu .attachment-header .attachment-upload-btn.mat-mdc-raised-button:before,.attachment-menu .attachment-header .attachment-upload-btn.mat-mdc-raised-button:after,.attachment-menu .attachment-header .attachment-upload-btn.mat-mdc-button:before,.attachment-menu .attachment-header .attachment-upload-btn.mat-mdc-button:after,.dropdown-menu .attachment-header .attachment-upload-btn:before,.dropdown-menu .attachment-header .attachment-upload-btn:after,.dropdown-menu .attachment-header .attachment-upload-btn.mat-mdc-raised-button:before,.dropdown-menu .attachment-header .attachment-upload-btn.mat-mdc-raised-button:after,.dropdown-menu .attachment-header .attachment-upload-btn.mat-mdc-button:before,.dropdown-menu .attachment-header .attachment-upload-btn.mat-mdc-button:after,.dropdown-menu.attachment-menu .attachment-header .attachment-upload-btn:before,.dropdown-menu.attachment-menu .attachment-header .attachment-upload-btn:after,.dropdown-menu.attachment-menu .attachment-header .attachment-upload-btn.mat-mdc-raised-button:before,.dropdown-menu.attachment-menu .attachment-header .attachment-upload-btn.mat-mdc-raised-button:after,.dropdown-menu.attachment-menu .attachment-header .attachment-upload-btn.mat-mdc-button:before,.dropdown-menu.attachment-menu .attachment-header .attachment-upload-btn.mat-mdc-button:after,[cdkMenu].attachment-menu .attachment-header .attachment-upload-btn:before,[cdkMenu].attachment-menu .attachment-header .attachment-upload-btn:after,[cdkMenu].attachment-menu .attachment-header .attachment-upload-btn.mat-mdc-raised-button:before,[cdkMenu].attachment-menu .attachment-header .attachment-upload-btn.mat-mdc-raised-button:after,[cdkMenu].attachment-menu .attachment-header .attachment-upload-btn.mat-mdc-button:before,[cdkMenu].attachment-menu .attachment-header .attachment-upload-btn.mat-mdc-button:after{display:none!important}.attachment-menu .attachment-drop-zone,.dropdown-menu .attachment-drop-zone,.dropdown-menu.attachment-menu .attachment-drop-zone,[cdkMenu].attachment-menu .attachment-drop-zone{border:2px dashed var(--grid-outline-variant, #cac4d0)!important;border-radius:8px!important;padding:10px!important;text-align:center!important;cursor:pointer!important;transition:all .3s ease!important;background:var(--grid-surface-variant, #e7e0ec)!important;margin:16px 0!important}.attachment-menu .attachment-drop-zone:hover,.dropdown-menu .attachment-drop-zone:hover,.dropdown-menu.attachment-menu .attachment-drop-zone:hover,[cdkMenu].attachment-menu .attachment-drop-zone:hover{border-color:var(--grid-primary, #6750a4)!important;background:var(--grid-surface-container, #f3edf7)!important}.attachment-menu .attachment-drop-zone.dragging,.dropdown-menu .attachment-drop-zone.dragging,.dropdown-menu.attachment-menu .attachment-drop-zone.dragging,[cdkMenu].attachment-menu .attachment-drop-zone.dragging{border-color:var(--grid-primary, #6750a4)!important;background:var(--grid-surface-container, #f3edf7)!important;transform:scale(1.01)!important}.attachment-menu .attachment-drop-zone .attachment-drop-content,.dropdown-menu .attachment-drop-zone .attachment-drop-content,.dropdown-menu.attachment-menu .attachment-drop-zone .attachment-drop-content,[cdkMenu].attachment-menu .attachment-drop-zone .attachment-drop-content{display:flex!important;flex-direction:column!important;align-items:center!important;gap:12px!important}.attachment-menu .attachment-drop-zone .attachment-drop-icon,.dropdown-menu .attachment-drop-zone .attachment-drop-icon,.dropdown-menu.attachment-menu .attachment-drop-zone .attachment-drop-icon,[cdkMenu].attachment-menu .attachment-drop-zone .attachment-drop-icon{font-size:48px!important;color:var(--grid-primary, #6750a4)!important;font-weight:300!important;line-height:1!important}.attachment-menu .attachment-drop-zone .attachment-drop-text .primary-text,.dropdown-menu .attachment-drop-zone .attachment-drop-text .primary-text,.dropdown-menu.attachment-menu .attachment-drop-zone .attachment-drop-text .primary-text,[cdkMenu].attachment-menu .attachment-drop-zone .attachment-drop-text .primary-text{font-family:var(--grid-font-family, \"Poppins\")!important;font-size:14px!important;color:var(--grid-on-surface-variant, #49454f)!important;font-weight:400!important;margin:0!important}.attachment-menu .attachment-drop-zone .attachment-drop-text .secondary-text,.dropdown-menu .attachment-drop-zone .attachment-drop-text .secondary-text,.dropdown-menu.attachment-menu .attachment-drop-zone .attachment-drop-text .secondary-text,[cdkMenu].attachment-menu .attachment-drop-zone .attachment-drop-text .secondary-text{font-family:var(--grid-font-family, \"Poppins\")!important;font-size:12px!important;color:var(--grid-on-surface-variant, #49454f)!important;margin-top:4px!important;display:block!important}.attachment-menu .attachment-file-list,.dropdown-menu .attachment-file-list,.dropdown-menu.attachment-menu .attachment-file-list,[cdkMenu].attachment-menu .attachment-file-list{display:block!important;margin-top:16px!important;border-top:1px solid var(--grid-outline-variant, #cac4d0)!important;padding-top:16px!important}.attachment-menu .attachment-file-list .attachment-file-item,.dropdown-menu .attachment-file-list .attachment-file-item,.dropdown-menu.attachment-menu .attachment-file-list .attachment-file-item,[cdkMenu].attachment-menu .attachment-file-list .attachment-file-item{display:flex!important;align-items:center!important;justify-content:space-between!important;padding:8px 0!important;border-bottom:1px solid var(--grid-outline-variant, #cac4d0)!important}.attachment-menu .attachment-file-list .attachment-file-item:last-child,.dropdown-menu .attachment-file-list .attachment-file-item:last-child,.dropdown-menu.attachment-menu .attachment-file-list .attachment-file-item:last-child,[cdkMenu].attachment-menu .attachment-file-list .attachment-file-item:last-child{border-bottom:none!important}.attachment-menu .attachment-file-list .attachment-file-item .file-info,.dropdown-menu .attachment-file-list .attachment-file-item .file-info,.dropdown-menu.attachment-menu .attachment-file-list .attachment-file-item .file-info,[cdkMenu].attachment-menu .attachment-file-list .attachment-file-item .file-info{display:flex!important;align-items:center!important;gap:8px!important;flex:1!important}.attachment-menu .attachment-file-list .attachment-file-item .file-info .file-icon,.dropdown-menu .attachment-file-list .attachment-file-item .file-info .file-icon,.dropdown-menu.attachment-menu .attachment-file-list .attachment-file-item .file-info .file-icon,[cdkMenu].attachment-menu .attachment-file-list .attachment-file-item .file-info .file-icon{font-size:16px!important;color:var(--grid-on-surface-variant, #49454f)!important}.attachment-menu .attachment-file-list .attachment-file-item .file-info .file-name,.dropdown-menu .attachment-file-list .attachment-file-item .file-info .file-name,.dropdown-menu.attachment-menu .attachment-file-list .attachment-file-item .file-info .file-name,[cdkMenu].attachment-menu .attachment-file-list .attachment-file-item .file-info .file-name{font-family:var(--grid-font-family, \"Poppins\")!important;font-size:14px!important;color:var(--grid-on-surface, #1d1b20)!important;word-break:break-word!important}.attachment-menu .attachment-file-list .attachment-file-item .file-actions,.dropdown-menu .attachment-file-list .attachment-file-item .file-actions,.dropdown-menu.attachment-menu .attachment-file-list .attachment-file-item .file-actions,[cdkMenu].attachment-menu .attachment-file-list .attachment-file-item .file-actions{display:flex!important;gap:4px!important}.attachment-menu .attachment-file-list .attachment-file-item .file-actions .action-btn,.dropdown-menu .attachment-file-list .attachment-file-item .file-actions .action-btn,.dropdown-menu.attachment-menu .attachment-file-list .attachment-file-item .file-actions .action-btn,[cdkMenu].attachment-menu .attachment-file-list .attachment-file-item .file-actions .action-btn{width:24px!important;height:24px!important;border:none!important;background:transparent!important;cursor:pointer!important;border-radius:4px!important;font-size:14px!important;color:var(--grid-on-surface-variant, #49454f)!important;transition:background-color .2s ease!important}.attachment-menu .attachment-file-list .attachment-file-item .file-actions .action-btn:hover,.dropdown-menu .attachment-file-list .attachment-file-item .file-actions .action-btn:hover,.dropdown-menu.attachment-menu .attachment-file-list .attachment-file-item .file-actions .action-btn:hover,[cdkMenu].attachment-menu .attachment-file-list .attachment-file-item .file-actions .action-btn:hover{background:var(--grid-surface-container, #f3edf7)!important}.cdk-overlay-container .cdk-overlay-pane .attachment-menu,.cdk-overlay-container .attachment-menu,.cdk-overlay-pane .attachment-menu{background:var(--grid-surface, #fef7ff)!important;background-color:var(--grid-surface, #fef7ff)!important;border:1px solid var(--grid-outline-variant, #cac4d0)!important;box-shadow:var(--grid-elevation-2, 0px 1px 2px 0px rgba(0, 0, 0, .3), 0px 2px 6px 2px rgba(0, 0, 0, .15))!important;border-radius:8px!important;font-family:var(--grid-font-family, \"Poppins\")!important}.cdk-overlay-container .cdk-overlay-pane .attachment-menu .attachment-container,.cdk-overlay-container .attachment-menu .attachment-container,.cdk-overlay-pane .attachment-menu .attachment-container{padding:4px;background:var(--grid-surface, #fef7ff)!important}.cdk-overlay-container .cdk-overlay-pane .attachment-menu .attachment-header,.cdk-overlay-container .attachment-menu .attachment-header,.cdk-overlay-pane .attachment-menu .attachment-header{display:flex!important;justify-content:space-between!important;align-items:center!important;margin-bottom:24px!important;padding:0!important}.cdk-overlay-container .cdk-overlay-pane .attachment-menu .attachment-header .attachment-title,.cdk-overlay-container .attachment-menu .attachment-header .attachment-title,.cdk-overlay-pane .attachment-menu .attachment-header .attachment-title{font-family:var(--grid-font-family, \"Poppins\")!important;font-size:16px!important;font-weight:500!important;color:var(--grid-on-surface, #1d1b20)!important;margin:0!important}.cdk-overlay-container .cdk-overlay-pane .attachment-menu .attachment-header .attachment-upload-btn,.cdk-overlay-container .attachment-menu .attachment-header .attachment-upload-btn,.cdk-overlay-pane .attachment-menu .attachment-header .attachment-upload-btn{background:var(--grid-primary, #6750a4)!important;background-color:var(--grid-primary, #6750a4)!important;color:var(--grid-on-primary, #ffffff)!important;font-family:var(--grid-font-family, \"Poppins\")!important;font-weight:500!important;padding:8px 20px!important;border-radius:6px!important;border:none!important;cursor:pointer!important;font-size:14px!important;letter-spacing:.5px!important;box-shadow:var(--grid-elevation-1, 0px 1px 2px 0px rgba(0, 0, 0, .3), 0px 1px 3px 1px rgba(0, 0, 0, .15))!important;transition:background-color .2s ease!important}.cdk-overlay-container .cdk-overlay-pane .attachment-menu .attachment-header .attachment-upload-btn:hover,.cdk-overlay-container .attachment-menu .attachment-header .attachment-upload-btn:hover,.cdk-overlay-pane .attachment-menu .attachment-header .attachment-upload-btn:hover{opacity:.9!important}.cdk-overlay-container .cdk-overlay-pane .attachment-menu .attachment-header .attachment-upload-btn .mdc-button__label,.cdk-overlay-container .attachment-menu .attachment-header .attachment-upload-btn .mdc-button__label,.cdk-overlay-pane .attachment-menu .attachment-header .attachment-upload-btn .mdc-button__label{color:var(--grid-on-primary, #ffffff)!important}.cdk-overlay-container .cdk-overlay-pane .attachment-menu .attachment-drop-zone,.cdk-overlay-container .attachment-menu .attachment-drop-zone,.cdk-overlay-pane .attachment-menu .attachment-drop-zone{border:2px dashed var(--grid-outline-variant, #cac4d0)!important;border-radius:8px!important;padding:40px 20px!important;text-align:center!important;cursor:pointer!important;transition:all .3s ease!important;background:var(--grid-surface-variant, #e7e0ec)!important;margin:16px 0!important}.cdk-overlay-container .cdk-overlay-pane .attachment-menu .attachment-drop-zone:hover,.cdk-overlay-container .attachment-menu .attachment-drop-zone:hover,.cdk-overlay-pane .attachment-menu .attachment-drop-zone:hover{border-color:var(--grid-primary, #6750a4)!important;background:var(--grid-surface-container, #f3edf7)!important}.cdk-overlay-container .cdk-overlay-pane .attachment-menu .attachment-drop-zone.dragging,.cdk-overlay-container .attachment-menu .attachment-drop-zone.dragging,.cdk-overlay-pane .attachment-menu .attachment-drop-zone.dragging{border-color:var(--grid-primary, #6750a4)!important;background:var(--grid-surface-container, #f3edf7)!important;transform:scale(1.01)!important}.cdk-overlay-container .cdk-overlay-pane .attachment-menu .attachment-drop-zone .attachment-drop-content,.cdk-overlay-container .attachment-menu .attachment-drop-zone .attachment-drop-content,.cdk-overlay-pane .attachment-menu .attachment-drop-zone .attachment-drop-content{display:flex!important;flex-direction:column!important;align-items:center!important;gap:12px!important}.cdk-overlay-container .cdk-overlay-pane .attachment-menu .attachment-drop-zone .attachment-drop-icon,.cdk-overlay-container .attachment-menu .attachment-drop-zone .attachment-drop-icon,.cdk-overlay-pane .attachment-menu .attachment-drop-zone .attachment-drop-icon{font-size:48px!important;color:var(--grid-primary, #6750a4)!important;font-weight:300!important;line-height:1!important}.cdk-overlay-container .cdk-overlay-pane .attachment-menu .attachment-drop-zone .attachment-drop-text .primary-text,.cdk-overlay-container .attachment-menu .attachment-drop-zone .attachment-drop-text .primary-text,.cdk-overlay-pane .attachment-menu .attachment-drop-zone .attachment-drop-text .primary-text{font-family:var(--grid-font-family, \"Poppins\")!important;font-size:14px!important;color:var(--grid-on-surface-variant, #49454f)!important;font-weight:400!important;margin:0!important}.cdk-overlay-container .cdk-overlay-pane .attachment-menu .attachment-drop-zone .attachment-drop-text .secondary-text,.cdk-overlay-container .attachment-menu .attachment-drop-zone .attachment-drop-text .secondary-text,.cdk-overlay-pane .attachment-menu .attachment-drop-zone .attachment-drop-text .secondary-text{font-family:var(--grid-font-family, \"Poppins\")!important;font-size:12px!important;color:var(--grid-on-surface-variant, #49454f)!important;margin-top:4px!important;display:block!important}.cdk-overlay-container .cdk-overlay-pane .attachment-menu .attachment-file-list,.cdk-overlay-container .attachment-menu .attachment-file-list,.cdk-overlay-pane .attachment-menu .attachment-file-list{display:block!important;margin-top:16px!important;border-top:1px solid var(--grid-outline-variant, #cac4d0)!important;padding-top:16px!important}.cdk-overlay-container .cdk-overlay-pane .attachment-menu .attachment-file-list .attachment-file-item,.cdk-overlay-container .attachment-menu .attachment-file-list .attachment-file-item,.cdk-overlay-pane .attachment-menu .attachment-file-list .attachment-file-item{display:flex!important;align-items:center!important;justify-content:space-between!important;padding:8px 0!important;border-bottom:1px solid var(--grid-outline-variant, #cac4d0)!important}.cdk-overlay-container .cdk-overlay-pane .attachment-menu .attachment-file-list .attachment-file-item:last-child,.cdk-overlay-container .attachment-menu .attachment-file-list .attachment-file-item:last-child,.cdk-overlay-pane .attachment-menu .attachment-file-list .attachment-file-item:last-child{border-bottom:none!important}.cdk-overlay-container .cdk-overlay-pane .attachment-menu .attachment-file-list .attachment-file-item .file-info,.cdk-overlay-container .attachment-menu .attachment-file-list .attachment-file-item .file-info,.cdk-overlay-pane .attachment-menu .attachment-file-list .attachment-file-item .file-info{display:flex!important;align-items:center!important;gap:8px!important;flex:1!important}.cdk-overlay-container .cdk-overlay-pane .attachment-menu .attachment-file-list .attachment-file-item .file-info .file-icon,.cdk-overlay-container .attachment-menu .attachment-file-list .attachment-file-item .file-info .file-icon,.cdk-overlay-pane .attachment-menu .attachment-file-list .attachment-file-item .file-info .file-icon{font-size:16px!important;color:var(--grid-on-surface-variant, #49454f)!important}.cdk-overlay-container .cdk-overlay-pane .attachment-menu .attachment-file-list .attachment-file-item .file-info .file-name,.cdk-overlay-container .attachment-menu .attachment-file-list .attachment-file-item .file-info .file-name,.cdk-overlay-pane .attachment-menu .attachment-file-list .attachment-file-item .file-info .file-name{font-family:var(--grid-font-family, \"Poppins\")!important;font-size:14px!important;color:var(--grid-on-surface, #1d1b20)!important;word-break:break-word!important}.cdk-overlay-container .cdk-overlay-pane .attachment-menu .attachment-file-list .attachment-file-item .file-actions,.cdk-overlay-container .attachment-menu .attachment-file-list .attachment-file-item .file-actions,.cdk-overlay-pane .attachment-menu .attachment-file-list .attachment-file-item .file-actions{display:flex!important;gap:4px!important}.cdk-overlay-container .cdk-overlay-pane .attachment-menu .attachment-file-list .attachment-file-item .file-actions .action-btn,.cdk-overlay-container .attachment-menu .attachment-file-list .attachment-file-item .file-actions .action-btn,.cdk-overlay-pane .attachment-menu .attachment-file-list .attachment-file-item .file-actions .action-btn{width:24px!important;height:24px!important;border:none!important;background:transparent!important;cursor:pointer!important;border-radius:4px!important;font-size:14px!important;color:var(--grid-on-surface-variant, #49454f)!important;transition:background-color .2s ease!important}.cdk-overlay-container .cdk-overlay-pane .attachment-menu .attachment-file-list .attachment-file-item .file-actions .action-btn:hover,.cdk-overlay-container .attachment-menu .attachment-file-list .attachment-file-item .file-actions .action-btn:hover,.cdk-overlay-pane .attachment-menu .attachment-file-list .attachment-file-item .file-actions .action-btn:hover{background:var(--grid-surface-container, #f3edf7)!important}.cdk-overlay-container .cdk-overlay-pane .attachment-menu,.cdk-overlay-container .attachment-menu{background:var(--grid-surface, #fef7ff)!important;background-color:var(--grid-surface, #fef7ff)!important;border:1px solid var(--grid-outline-variant, #cac4d0)!important;box-shadow:var(--grid-elevation-2, 0px 1px 2px 0px rgba(0, 0, 0, .3), 0px 2px 6px 2px rgba(0, 0, 0, .15))!important}.attachment-cell-wrapper{position:relative;display:block;width:100%;height:100%;text-align:center;overflow:visible}.attachment-menu-overlay{position:absolute;z-index:1000;background:var(--grid-surface, #fef7ff);border:1px solid var(--grid-outline-variant, #cac4d0);box-shadow:var(--grid-elevation-2, 0px 1px 2px 0px rgba(0, 0, 0, .3), 0px 2px 6px 2px rgba(0, 0, 0, .15));border-radius:8px;font-family:var(--grid-font-family, \"Poppins\");color:var(--grid-on-surface, #1d1b20);overflow:visible;z-index:9999}.attachment-menu-overlay .attachment-container{padding:16px;background:var(--grid-surface, #fef7ff)}.attachment-menu-overlay .attachment-header{display:flex;justify-content:space-between;align-items:center;margin-bottom:24px;padding:0}.attachment-menu-overlay .attachment-header .attachment-title{font-family:var(--grid-font-family, \"Poppins\");font-size:16px;font-weight:500;color:var(--grid-on-surface, #1d1b20);margin:0}.attachment-menu-overlay .attachment-header .attachment-upload-btn{background:var(--grid-primary, #6750a4);background-color:var(--grid-primary, #6750a4);color:var(--grid-on-primary, #ffffff);font-family:var(--grid-font-family, \"Poppins\");font-weight:500;padding:8px 20px;border-radius:6px;border:none;cursor:pointer;font-size:14px;letter-spacing:.5px;box-shadow:var(--grid-elevation-1, 0px 1px 2px 0px rgba(0, 0, 0, .3), 0px 1px 3px 1px rgba(0, 0, 0, .15));transition:background-color .2s ease}.attachment-menu-overlay .attachment-header .attachment-upload-btn:hover{opacity:.9}.attachment-menu-overlay .attachment-header .attachment-upload-btn .mdc-button__label{color:var(--grid-on-primary, #ffffff)}.attachment-menu-overlay .attachment-drop-zone{border:2px dashed var(--grid-outline-variant, #cac4d0);border-radius:8px;padding:10px;text-align:center;cursor:pointer;transition:all .3s ease;background:var(--grid-surface-variant, #e7e0ec);margin:16px 0}.attachment-menu-overlay .attachment-drop-zone:hover{border-color:var(--grid-primary, #6750a4);background:var(--grid-surface-container, #f3edf7)}.attachment-menu-overlay .attachment-drop-zone.dragging{border-color:var(--grid-primary, #6750a4);background:var(--grid-surface-container, #f3edf7);transform:scale(1.01)}.attachment-menu-overlay .attachment-drop-zone .attachment-drop-content{display:flex;flex-direction:column;align-items:center;gap:12px}.attachment-menu-overlay .attachment-drop-zone .attachment-drop-icon{font-size:48px;color:var(--grid-primary, #6750a4);font-weight:300;line-height:1}.attachment-menu-overlay .attachment-drop-zone .attachment-drop-text .primary-text{font-family:var(--grid-font-family, \"Poppins\");font-size:14px;color:var(--grid-on-surface-variant, #49454f);font-weight:400;margin:0}.attachment-menu-overlay .attachment-drop-zone .attachment-drop-text .secondary-text{font-family:var(--grid-font-family, \"Poppins\");font-size:12px;color:var(--grid-on-surface-variant, #49454f);margin-top:4px;display:block}.attachment-menu-overlay .attachment-file-list{display:block;margin-top:16px;border-top:1px solid var(--grid-outline-variant, #cac4d0);padding-top:16px}.attachment-menu-overlay .attachment-file-list .attachment-file-item{display:flex;align-items:center;justify-content:space-between;padding:8px 0;border-bottom:1px solid var(--grid-outline-variant, #cac4d0)}.attachment-menu-overlay .attachment-file-list .attachment-file-item:last-child{border-bottom:none}.attachment-menu-overlay .attachment-file-list .attachment-file-item .file-info{display:flex;align-items:center;gap:8px;flex:1}.attachment-menu-overlay .attachment-file-list .attachment-file-item .file-info .file-icon{font-size:16px;color:var(--grid-on-surface-variant, #49454f)}.attachment-menu-overlay .attachment-file-list .attachment-file-item .file-info .file-name{font-family:var(--grid-font-family, \"Poppins\");font-size:14px;color:var(--grid-on-surface, #1d1b20);word-break:break-word}.attachment-menu-overlay .attachment-file-list .attachment-file-item .file-actions{display:flex;gap:4px}.attachment-menu-overlay .attachment-file-list .attachment-file-item .file-actions .action-btn{width:24px;height:24px;border:none;background:transparent;cursor:pointer;border-radius:4px;font-size:14px;color:var(--grid-on-surface-variant, #49454f);transition:background-color .2s ease}.attachment-menu-overlay .attachment-file-list .attachment-file-item .file-actions .action-btn:hover{background:var(--grid-surface-container, #f3edf7)}.cdk-overlay-container .cdk-overlay-pane .dropdown-menu,.cdk-overlay-container .dropdown-menu,.cdk-overlay-pane .dropdown-menu{background:var(--grid-surface, #fef7ff)!important;background-color:var(--grid-surface, #fef7ff)!important;border:1px solid var(--grid-outline-variant, #cac4d0)!important;box-shadow:var(--grid-elevation-2, 0px 1px 2px 0px rgba(0, 0, 0, .3), 0px 2px 6px 2px rgba(0, 0, 0, .15))!important;border-radius:8px!important;font-family:var(--grid-font-family, \"Poppins\")!important;color:var(--grid-on-surface, #1d1b20)!important;overflow:hidden!important;box-sizing:border-box!important}.cdk-overlay-container .cdk-overlay-pane .dropdown-menu .listbox-container,.cdk-overlay-container .dropdown-menu .listbox-container,.cdk-overlay-pane .dropdown-menu .listbox-container{padding:8px!important;background:var(--grid-surface, #fef7ff)!important}.cdk-overlay-container .cdk-overlay-pane .dropdown-menu .search-form-field,.cdk-overlay-container .dropdown-menu .search-form-field,.cdk-overlay-pane .dropdown-menu .search-form-field{width:100%!important;margin-bottom:8px!important}.cdk-overlay-container .cdk-overlay-pane .dropdown-menu .search-form-field .mat-mdc-form-field,.cdk-overlay-container .dropdown-menu .search-form-field .mat-mdc-form-field,.cdk-overlay-pane .dropdown-menu .search-form-field .mat-mdc-form-field{width:100%!important}.cdk-overlay-container .cdk-overlay-pane .dropdown-menu .search-form-field .mat-mdc-text-field-wrapper,.cdk-overlay-container .dropdown-menu .search-form-field .mat-mdc-text-field-wrapper,.cdk-overlay-pane .dropdown-menu .search-form-field .mat-mdc-text-field-wrapper{background:var(--grid-surface, #fffbfe)!important;border-radius:4px!important}.cdk-overlay-container .cdk-overlay-pane .dropdown-menu .search-form-field .mat-mdc-form-field-focus-overlay,.cdk-overlay-container .dropdown-menu .search-form-field .mat-mdc-form-field-focus-overlay,.cdk-overlay-pane .dropdown-menu .search-form-field .mat-mdc-form-field-focus-overlay{background:var(--grid-surface, #fffbfe)!important}.cdk-overlay-container .cdk-overlay-pane .dropdown-menu .search-form-field .mat-mdc-form-field-subscript-wrapper,.cdk-overlay-container .dropdown-menu .search-form-field .mat-mdc-form-field-subscript-wrapper,.cdk-overlay-pane .dropdown-menu .search-form-field .mat-mdc-form-field-subscript-wrapper{display:none!important}.cdk-overlay-container .cdk-overlay-pane .dropdown-menu .search-form-field input,.cdk-overlay-container .dropdown-menu .search-form-field input,.cdk-overlay-pane .dropdown-menu .search-form-field input{font-family:var(--grid-font-family, \"Poppins\")!important;font-size:14px!important;color:var(--grid-on-surface, #1d1b20)!important}.cdk-overlay-container .cdk-overlay-pane .dropdown-menu .select-all-container,.cdk-overlay-container .dropdown-menu .select-all-container,.cdk-overlay-pane .dropdown-menu .select-all-container{padding:8px 12px!important;border-bottom:1px solid var(--grid-outline-variant, #cac4d0)!important;margin-bottom:4px!important}.cdk-overlay-container .cdk-overlay-pane .dropdown-menu .select-all-container .select-all-text,.cdk-overlay-container .dropdown-menu .select-all-container .select-all-text,.cdk-overlay-pane .dropdown-menu .select-all-container .select-all-text{font-family:var(--grid-font-family, \"Poppins\")!important;font-size:14px!important;font-weight:500!important;color:var(--grid-on-surface, #1d1b20)!important;margin-left:8px!important}.cdk-overlay-container .cdk-overlay-pane .dropdown-menu .select-all-container mat-checkbox .mdc-checkbox .mdc-checkbox__checkmark,.cdk-overlay-container .dropdown-menu .select-all-container mat-checkbox .mdc-checkbox .mdc-checkbox__checkmark,.cdk-overlay-pane .dropdown-menu .select-all-container mat-checkbox .mdc-checkbox .mdc-checkbox__checkmark{color:var(--grid-on-primary, #ffffff)!important}.cdk-overlay-container .cdk-overlay-pane .dropdown-menu .select-all-container mat-checkbox.mat-mdc-checkbox-checked .mdc-checkbox__background,.cdk-overlay-container .dropdown-menu .select-all-container mat-checkbox.mat-mdc-checkbox-checked .mdc-checkbox__background,.cdk-overlay-pane .dropdown-menu .select-all-container mat-checkbox.mat-mdc-checkbox-checked .mdc-checkbox__background{background-color:var(--grid-primary, #6750a4)!important;border-color:var(--grid-primary, #6750a4)!important}.cdk-overlay-container .cdk-overlay-pane .dropdown-menu .select-all-container mat-checkbox.mat-mdc-checkbox-indeterminate .mdc-checkbox__background,.cdk-overlay-container .dropdown-menu .select-all-container mat-checkbox.mat-mdc-checkbox-indeterminate .mdc-checkbox__background,.cdk-overlay-pane .dropdown-menu .select-all-container mat-checkbox.mat-mdc-checkbox-indeterminate .mdc-checkbox__background{background-color:var(--grid-primary, #6750a4)!important;border-color:var(--grid-primary, #6750a4)!important}.cdk-overlay-container .cdk-overlay-pane .dropdown-menu .listbox,.cdk-overlay-container .dropdown-menu .listbox,.cdk-overlay-pane .dropdown-menu .listbox{list-style:none!important;margin:0!important;padding:0!important;max-height:200px!important;overflow-y:auto!important;background:var(--grid-surface, #fef7ff)!important}.cdk-overlay-container .cdk-overlay-pane .dropdown-menu .listbox::-webkit-scrollbar,.cdk-overlay-container .dropdown-menu .listbox::-webkit-scrollbar,.cdk-overlay-pane .dropdown-menu .listbox::-webkit-scrollbar{width:8px!important}.cdk-overlay-container .cdk-overlay-pane .dropdown-menu .listbox::-webkit-scrollbar-track,.cdk-overlay-container .dropdown-menu .listbox::-webkit-scrollbar-track,.cdk-overlay-pane .dropdown-menu .listbox::-webkit-scrollbar-track{background:var(--grid-surface-variant, #e7e0ec)!important;border-radius:4px!important}.cdk-overlay-container .cdk-overlay-pane .dropdown-menu .listbox::-webkit-scrollbar-thumb,.cdk-overlay-container .dropdown-menu .listbox::-webkit-scrollbar-thumb,.cdk-overlay-pane .dropdown-menu .listbox::-webkit-scrollbar-thumb{background:var(--grid-primary, #6750a4)!important;border-radius:4px!important}.cdk-overlay-container .cdk-overlay-pane .dropdown-menu .listbox::-webkit-scrollbar-thumb:hover,.cdk-overlay-container .dropdown-menu .listbox::-webkit-scrollbar-thumb:hover,.cdk-overlay-pane .dropdown-menu .listbox::-webkit-scrollbar-thumb:hover{background:var(--grid-primary, #6750a4)!important;opacity:.8!important}.cdk-overlay-container .cdk-overlay-pane .dropdown-menu .multi-listbox-option,.cdk-overlay-container .dropdown-menu .multi-listbox-option,.cdk-overlay-pane .dropdown-menu .multi-listbox-option{padding:4px 8px!important;margin:2px 0!important;border-radius:4px!important;cursor:pointer!important;font-family:var(--grid-font-family, \"Poppins\")!important;font-size:14px!important;color:var(--grid-on-surface, #1d1b20)!important;background:transparent!important;transition:background-color .2s ease!important;border:none!important;text-align:left!important;width:100%!important}.cdk-overlay-container .cdk-overlay-pane .dropdown-menu .multi-listbox-option:hover,.cdk-overlay-container .dropdown-menu .multi-listbox-option:hover,.cdk-overlay-pane .dropdown-menu .multi-listbox-option:hover{background:var(--grid-surface-container, #f3edf7)!important}.cdk-overlay-container .cdk-overlay-pane .dropdown-menu .multi-listbox-option.notext-overflow,.cdk-overlay-container .dropdown-menu .multi-listbox-option.notext-overflow,.cdk-overlay-pane .dropdown-menu .multi-listbox-option.notext-overflow{white-space:nowrap!important;overflow:hidden!important;text-overflow:ellipsis!important}.cdk-overlay-container .cdk-overlay-pane .dropdown-menu .multi-listbox-option .option-content,.cdk-overlay-container .dropdown-menu .multi-listbox-option .option-content,.cdk-overlay-pane .dropdown-menu .multi-listbox-option .option-content{display:flex!important;align-items:center!important;gap:8px!important;width:100%!important}.cdk-overlay-container .cdk-overlay-pane .dropdown-menu .multi-listbox-option .option-content .option-text,.cdk-overlay-container .dropdown-menu .multi-listbox-option .option-content .option-text,.cdk-overlay-pane .dropdown-menu .multi-listbox-option .option-content .option-text{flex:1!important;font-family:var(--grid-font-family, \"Poppins\")!important;font-size:14px!important;color:inherit!important}.cdk-overlay-container .cdk-overlay-pane .dropdown-menu .multi-listbox-option .option-content mat-checkbox,.cdk-overlay-container .dropdown-menu .multi-listbox-option .option-content mat-checkbox,.cdk-overlay-pane .dropdown-menu .multi-listbox-option .option-content mat-checkbox{flex-shrink:0!important}.cdk-overlay-container .cdk-overlay-pane .dropdown-menu .multi-listbox-option .option-content mat-checkbox .mdc-checkbox .mdc-checkbox__background,.cdk-overlay-container .dropdown-menu .multi-listbox-option .option-content mat-checkbox .mdc-checkbox .mdc-checkbox__background,.cdk-overlay-pane .dropdown-menu .multi-listbox-option .option-content mat-checkbox .mdc-checkbox .mdc-checkbox__background{border-color:var(--grid-outline, #79757f)!important}.cdk-overlay-container .cdk-overlay-pane .dropdown-menu .multi-listbox-option .option-content mat-checkbox .mdc-checkbox .mdc-checkbox__checkmark,.cdk-overlay-container .dropdown-menu .multi-listbox-option .option-content mat-checkbox .mdc-checkbox .mdc-checkbox__checkmark,.cdk-overlay-pane .dropdown-menu .multi-listbox-option .option-content mat-checkbox .mdc-checkbox .mdc-checkbox__checkmark{color:var(--grid-on-primary, #ffffff)!important}.cdk-overlay-container .cdk-overlay-pane .dropdown-menu .multi-listbox-option .option-content mat-checkbox.mat-mdc-checkbox-checked .mdc-checkbox__background,.cdk-overlay-container .dropdown-menu .multi-listbox-option .option-content mat-checkbox.mat-mdc-checkbox-checked .mdc-checkbox__background,.cdk-overlay-pane .dropdown-menu .multi-listbox-option .option-content mat-checkbox.mat-mdc-checkbox-checked .mdc-checkbox__background{background-color:var(--grid-primary, #6750a4)!important;border-color:var(--grid-primary, #6750a4)!important}.cdk-overlay-container .cdk-overlay-pane .dropdown-menu .listbox-option,.cdk-overlay-container .dropdown-menu .listbox-option,.cdk-overlay-pane .dropdown-menu .listbox-option{padding:4px 8px!important;margin:2px 0!important;border-radius:4px!important;cursor:pointer!important;font-family:var(--grid-font-family, \"Poppins\")!important;font-size:14px!important;color:var(--grid-on-surface, #1d1b20)!important;background:transparent!important;transition:background-color .2s ease!important;border:none!important;text-align:left!important;width:100%!important}.cdk-overlay-container .cdk-overlay-pane .dropdown-menu .listbox-option:hover,.cdk-overlay-container .dropdown-menu .listbox-option:hover,.cdk-overlay-pane .dropdown-menu .listbox-option:hover{background:var(--grid-surface-container, #f3edf7)!important}.cdk-overlay-container .cdk-overlay-pane .dropdown-menu .listbox-option.cdk-option-active,.cdk-overlay-container .dropdown-menu .listbox-option.cdk-option-active,.cdk-overlay-pane .dropdown-menu .listbox-option.cdk-option-active,.cdk-overlay-container .cdk-overlay-pane .dropdown-menu .listbox-option.cdk-option-selected,.cdk-overlay-container .dropdown-menu .listbox-option.cdk-option-selected,.cdk-overlay-pane .dropdown-menu .listbox-option.cdk-option-selected{background:var(--grid-primary, #6750a4)!important;color:var(--grid-on-primary, #ffffff)!important}.cdk-overlay-container .cdk-overlay-pane .dropdown-menu .listbox-option.notext-overflow,.cdk-overlay-container .dropdown-menu .listbox-option.notext-overflow,.cdk-overlay-pane .dropdown-menu .listbox-option.notext-overflow{white-space:nowrap!important;overflow:hidden!important;text-overflow:ellipsis!important}.cdk-overlay-container .cdk-overlay-pane .dropdown-menu .listbox-option .option-content,.cdk-overlay-container .dropdown-menu .listbox-option .option-content,.cdk-overlay-pane .dropdown-menu .listbox-option .option-content{display:flex!important;align-items:center!important;gap:8px!important;width:100%!important}.cdk-overlay-container .cdk-overlay-pane .dropdown-menu .listbox-option .option-content .option-text,.cdk-overlay-container .dropdown-menu .listbox-option .option-content .option-text,.cdk-overlay-pane .dropdown-menu .listbox-option .option-content .option-text{flex:1!important;font-family:var(--grid-font-family, \"Poppins\")!important;font-size:14px!important;color:inherit!important}.cell-display-text-editable{cursor:pointer!important}.cell-display-text{width:100%!important;height:100%!important;min-height:20px!important;display:block!important;padding:4px 8px!important;font-family:var(--grid-font-family, \"Poppins\")!important;font-size:var(--grid-font-size-body, 12px)!important;color:var(--grid-on-surface, #1d1b20)!important;background:transparent!important;border:none!important;outline:none!important;text-overflow:ellipsis!important;overflow:hidden!important;white-space:nowrap!important;max-width:100%!important;box-sizing:border-box!important;transition:background-color .2s ease!important;line-height:1.4!important}.cell-display-text,.cell-display-text>*{text-overflow:ellipsis!important;overflow:hidden!important;white-space:nowrap!important;max-width:100%!important;width:100%!important;display:block!important}.cell-display-text:empty:before{content:\"Click to select\"!important;color:var(--grid-on-surface-variant, #49454f)!important;font-style:italic!important}.cell-display-number{text-align:right!important}.assignee-avatars{display:flex;align-items:center;padding:4px 8px;min-height:20px}.avatar-circle{width:28px;height:28px;border-radius:50%;background-color:var(--grid-primary, #6750a4);color:#fff;display:flex;align-items:center;justify-content:center;font-size:12px;font-weight:600;border:2px solid var(--grid-surface, #fef7ff);margin-left:-8px;position:relative;z-index:1}.avatar-circle:first-child{margin-left:0}.avatar-circle.count-circle{background-color:var(--grid-surface-variant, #e7e0ec);color:var(--grid-on-surface-variant, #49454f);font-size:11px;font-weight:500}.no-assignees{color:var(--grid-on-surface-variant, #49454f);font-style:italic;font-size:12px}.option-content{display:flex;align-items:center;gap:8px;width:100%}.option-avatar{width:24px;height:24px;border-radius:50%;background-color:var(--grid-primary, #6750a4);color:#fff;display:flex;align-items:center;justify-content:center;font-size:10px;font-weight:600;flex-shrink:0}.option-text{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.checkmark{color:var(--grid-primary, #6750a4);font-weight:700;font-size:14px;flex-shrink:0}.drillable-value{color:var(--grid-primary, #6750a4);text-decoration:underline;text-decoration-color:var(--grid-primary, #6750a4);text-decoration-thickness:1px;text-underline-offset:2px;transition:all .2s ease}.drillable-link{cursor:pointer;padding:4px}\n"], dependencies: [{ kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i2$2.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i2$2.MatPrefix, selector: "[matPrefix], [matIconPrefix], [matTextPrefix]", inputs: ["matTextPrefix"] }, { kind: "directive", type: i2$2.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i3.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i4.MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatCheckboxModule }, { kind: "component", type: i5.MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "aria-expanded", "aria-controls", "aria-owns", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "disabledInteractive", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { kind: "ngmodule", type: MatSliderModule }, { kind: "component", type: i6.MatSlider, selector: "mat-slider", inputs: ["disabled", "discrete", "showTickMarks", "min", "color", "disableRipple", "max", "step", "displayWith"], exportAs: ["matSlider"] }, { kind: "directive", type: i6.MatSliderThumb, selector: "input[matSliderThumb]", inputs: ["value"], outputs: ["valueChange", "dragStart", "dragEnd"], exportAs: ["matSliderThumb"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "directive", type: CdkMenuTrigger, selector: "[cdkMenuTriggerFor]", inputs: ["cdkMenuTriggerFor", "cdkMenuPosition", "cdkMenuTriggerData"], outputs: ["cdkMenuOpened", "cdkMenuClosed"], exportAs: ["cdkMenuTriggerFor"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: CdkListbox, selector: "[cdkListbox]", inputs: ["id", "tabindex", "cdkListboxValue", "cdkListboxMultiple", "cdkListboxDisabled", "cdkListboxUseActiveDescendant", "cdkListboxOrientation", "cdkListboxCompareWith", "cdkListboxNavigationWrapDisabled", "cdkListboxNavigatesDisabledOptions"], outputs: ["cdkListboxValueChange"], exportAs: ["cdkListbox"] }, { kind: "directive", type: CdkOption, selector: "[cdkOption]", inputs: ["id", "cdkOption", "cdkOptionTypeaheadLabel", "cdkOptionDisabled", "tabindex"], exportAs: ["cdkOption"] }, { kind: "directive", type: CdkMenu, selector: "[cdkMenu]", outputs: ["closed"], exportAs: ["cdkMenu"] }, { kind: "ngmodule", type: OverlayModule }, { kind: "directive", type: i1$2.CdkConnectedOverlay, selector: "[cdk-connected-overlay], [connected-overlay], [cdkConnectedOverlay]", inputs: ["cdkConnectedOverlayOrigin", "cdkConnectedOverlayPositions", "cdkConnectedOverlayPositionStrategy", "cdkConnectedOverlayOffsetX", "cdkConnectedOverlayOffsetY", "cdkConnectedOverlayWidth", "cdkConnectedOverlayHeight", "cdkConnectedOverlayMinWidth", "cdkConnectedOverlayMinHeight", "cdkConnectedOverlayBackdropClass", "cdkConnectedOverlayPanelClass", "cdkConnectedOverlayViewportMargin", "cdkConnectedOverlayScrollStrategy", "cdkConnectedOverlayOpen", "cdkConnectedOverlayDisableClose", "cdkConnectedOverlayTransformOriginOn", "cdkConnectedOverlayHasBackdrop", "cdkConnectedOverlayLockPosition", "cdkConnectedOverlayFlexibleDimensions", "cdkConnectedOverlayGrowAfterOpen", "cdkConnectedOverlayPush", "cdkConnectedOverlayDisposeOnNavigation"], outputs: ["backdropClick", "positionChange", "attach", "detach", "overlayKeydown", "overlayOutsideClick"], exportAs: ["cdkConnectedOverlay"] }, { kind: "directive", type: i1$2.CdkOverlayOrigin, selector: "[cdk-overlay-origin], [overlay-origin], [cdkOverlayOrigin]", exportAs: ["cdkOverlayOrigin"] }, { kind: "directive", type: CustomDatePickerDirective, selector: "[appCustomDatePicker]" }, { kind: "ngmodule", type: MatDatepickerModule }, { kind: "component", type: i9.MatDatepicker, selector: "mat-datepicker", exportAs: ["matDatepicker"] }, { kind: "directive", type: i9.MatDatepickerInput, selector: "input[matDatepicker]", inputs: ["matDatepicker", "min", "max", "matDatepickerFilter"], exportAs: ["matDatepickerInput"] }, { kind: "component", type: i9.MatDatepickerToggle, selector: "mat-datepicker-toggle", inputs: ["for", "tabIndex", "aria-label", "disabled", "disableRipple"], exportAs: ["matDatepickerToggle"] }, { kind: "ngmodule", type: MatNativeDateModule }, { kind: "component", type: MobileInputComponent, selector: "app-mobile-input", inputs: ["defaultCountry"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
3355
3404
|
}
|
|
3356
3405
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: DataCellComponent, decorators: [{
|
|
3357
3406
|
type: Component,
|
|
@@ -3661,8 +3710,12 @@ class EruGridComponent {
|
|
|
3661
3710
|
gridStore = inject(EruGridStore);
|
|
3662
3711
|
resizeObserver = null;
|
|
3663
3712
|
isColumnReordering = signal(false, ...(ngDevMode ? [{ debugName: "isColumnReordering" }] : []));
|
|
3713
|
+
firstTr = 0;
|
|
3664
3714
|
viewport;
|
|
3665
3715
|
rowContainer;
|
|
3716
|
+
headerScroller;
|
|
3717
|
+
gtScroller;
|
|
3718
|
+
vp;
|
|
3666
3719
|
rowLoadQueue = [];
|
|
3667
3720
|
isProcessingQueue = false;
|
|
3668
3721
|
// Computed properties using the new GridStore
|
|
@@ -3692,7 +3745,13 @@ class EruGridComponent {
|
|
|
3692
3745
|
const config = this.gridStore.configuration();
|
|
3693
3746
|
return config?.config?.showRowLines ?? false;
|
|
3694
3747
|
}, ...(ngDevMode ? [{ debugName: "showRowLines" }] : []));
|
|
3695
|
-
maxDepth = computed(() =>
|
|
3748
|
+
maxDepth = computed(() => {
|
|
3749
|
+
const maxDepth = this.gridStore.pivotResult()?.headerStructure?.maxDepth ?? 0;
|
|
3750
|
+
/* if (this.grandTotalPosition() === 'before' && this.freezeGrandTotal()) {
|
|
3751
|
+
return maxDepth + 1 ;
|
|
3752
|
+
} */
|
|
3753
|
+
return maxDepth;
|
|
3754
|
+
}, ...(ngDevMode ? [{ debugName: "maxDepth" }] : []));
|
|
3696
3755
|
//maxDepth = signal(0);
|
|
3697
3756
|
// Subtotal and Grand Total styling computed properties
|
|
3698
3757
|
subTotalStyle = computed(() => {
|
|
@@ -3703,6 +3762,22 @@ class EruGridComponent {
|
|
|
3703
3762
|
const config = this.gridStore.configuration();
|
|
3704
3763
|
return config?.styles?.grandTotalStyle ?? 'bold';
|
|
3705
3764
|
}, ...(ngDevMode ? [{ debugName: "grandTotalStyle" }] : []));
|
|
3765
|
+
// Freeze configuration computed properties
|
|
3766
|
+
freezeHeader = computed(() => {
|
|
3767
|
+
const config = this.gridStore.configuration();
|
|
3768
|
+
if (this.grandTotalPosition() === 'before' && this.freezeGrandTotal()) {
|
|
3769
|
+
return true;
|
|
3770
|
+
}
|
|
3771
|
+
return config?.config?.freezeHeader ?? false;
|
|
3772
|
+
}, ...(ngDevMode ? [{ debugName: "freezeHeader" }] : []));
|
|
3773
|
+
freezeGrandTotal = computed(() => {
|
|
3774
|
+
const config = this.gridStore.configuration();
|
|
3775
|
+
return config?.config?.freezeGrandTotal ?? false;
|
|
3776
|
+
}, ...(ngDevMode ? [{ debugName: "freezeGrandTotal" }] : []));
|
|
3777
|
+
grandTotalPosition = computed(() => {
|
|
3778
|
+
const config = this.gridStore.configuration();
|
|
3779
|
+
return config?.config?.grandTotalPosition ?? 'after';
|
|
3780
|
+
}, ...(ngDevMode ? [{ debugName: "grandTotalPosition" }] : []));
|
|
3706
3781
|
/**
|
|
3707
3782
|
* Check if a row is the first visible row in the pivot viewport
|
|
3708
3783
|
* @param rowIndex The index of the row in the virtual scroll
|
|
@@ -3711,21 +3786,13 @@ class EruGridComponent {
|
|
|
3711
3786
|
isFirstVisiblePivotRow(rowIndex) {
|
|
3712
3787
|
return rowIndex === this.firstDataRowIndex();
|
|
3713
3788
|
}
|
|
3714
|
-
/**
|
|
3715
|
-
* Check if a specific row is the first visible row by comparing with scroll index
|
|
3716
|
-
* @param rowIndex The index of the row to check
|
|
3717
|
-
* @returns true if this row is the first visible row
|
|
3718
|
-
*/
|
|
3719
|
-
isRowFirstVisible(rowIndex) {
|
|
3720
|
-
return this.isFirstVisiblePivotRow(rowIndex);
|
|
3721
|
-
}
|
|
3722
3789
|
/**
|
|
3723
3790
|
* Handle scroll events for pivot mode
|
|
3724
3791
|
* @param scrollIndex The current scroll index
|
|
3725
3792
|
*/
|
|
3726
3793
|
onPivotScroll(scrollIndex) {
|
|
3727
3794
|
this.currentPivotScrollIndex.set(scrollIndex);
|
|
3728
|
-
if (scrollIndex
|
|
3795
|
+
if (scrollIndex < this.maxDepth()) {
|
|
3729
3796
|
this.firstDataRowIndex.set(0);
|
|
3730
3797
|
}
|
|
3731
3798
|
else {
|
|
@@ -3733,46 +3800,12 @@ class EruGridComponent {
|
|
|
3733
3800
|
}
|
|
3734
3801
|
// Clear virtual rowspan cache when scrolling to recalculate
|
|
3735
3802
|
this._virtualRowspanCache.clear();
|
|
3803
|
+
this.viewport?.getRenderedRange();
|
|
3804
|
+
this.firstTr = this.viewport?.getRenderedRange()?.start || 0;
|
|
3736
3805
|
}
|
|
3737
|
-
|
|
3738
|
-
|
|
3739
|
-
|
|
3740
|
-
*/
|
|
3741
|
-
getFirstVisiblePivotDataIndex() {
|
|
3742
|
-
return this.firstDataRowIndex();
|
|
3743
|
-
}
|
|
3744
|
-
/**
|
|
3745
|
-
* Get the truly visible range (what's actually visible on screen)
|
|
3746
|
-
* @returns Object with start, end, and count of visible items
|
|
3747
|
-
*/
|
|
3748
|
-
getVisibleRange() {
|
|
3749
|
-
if (!this.viewport) {
|
|
3750
|
-
return { start: 0, end: 0, count: 0 };
|
|
3751
|
-
}
|
|
3752
|
-
const scrollIndex = this.currentPivotScrollIndex();
|
|
3753
|
-
const dataLength = this.viewport.getDataLength();
|
|
3754
|
-
// Calculate actual visible items based on viewport height and item size
|
|
3755
|
-
const actualVisibleCount = this.getActualVisibleItemCount();
|
|
3756
|
-
const visibleStart = scrollIndex;
|
|
3757
|
-
const visibleEnd = Math.min(scrollIndex + actualVisibleCount, dataLength);
|
|
3758
|
-
const visibleCount = visibleEnd - visibleStart;
|
|
3759
|
-
return { start: visibleStart, end: visibleEnd, count: visibleCount };
|
|
3760
|
-
}
|
|
3761
|
-
/**
|
|
3762
|
-
* Calculate the actual number of items visible in the viewport
|
|
3763
|
-
* This accounts for headers, padding, and actual viewport dimensions
|
|
3764
|
-
*/
|
|
3765
|
-
getActualVisibleItemCount() {
|
|
3766
|
-
if (!this.viewport)
|
|
3767
|
-
return 0;
|
|
3768
|
-
const viewportElement = this.viewport.elementRef.nativeElement;
|
|
3769
|
-
const viewportRect = viewportElement.getBoundingClientRect();
|
|
3770
|
-
const itemSize = 50; // This matches [itemSize]="50" in template
|
|
3771
|
-
// Get the actual available height for data rows
|
|
3772
|
-
const availableHeight = viewportRect.height;
|
|
3773
|
-
// Calculate how many items can fit in the available height
|
|
3774
|
-
const visibleCount = Math.floor(availableHeight / itemSize);
|
|
3775
|
-
return Math.max(1, visibleCount); // At least 1 item should be visible
|
|
3806
|
+
getTotalTableWidth() {
|
|
3807
|
+
const columns = this.getLeafColumns();
|
|
3808
|
+
return columns.reduce((total, column) => total + column.field_size, 0);
|
|
3776
3809
|
}
|
|
3777
3810
|
/**
|
|
3778
3811
|
* Get the rendered range (what's in the DOM including buffer)
|
|
@@ -3786,45 +3819,28 @@ class EruGridComponent {
|
|
|
3786
3819
|
const count = range.end - range.start;
|
|
3787
3820
|
return { start: range.start, end: range.end, count };
|
|
3788
3821
|
}
|
|
3789
|
-
/**
|
|
3790
|
-
* Get current scroll and visibility information for debugging
|
|
3791
|
-
* @returns Object with current scroll state and ranges
|
|
3792
|
-
*/
|
|
3793
|
-
getCurrentScrollInfo() {
|
|
3794
|
-
if (!this.viewport) {
|
|
3795
|
-
return {
|
|
3796
|
-
scrollIndex: 0,
|
|
3797
|
-
visibleRange: { start: 0, end: 0, count: 0 },
|
|
3798
|
-
renderedRange: { start: 0, end: 0, count: 0 },
|
|
3799
|
-
cdkViewportSize: 0,
|
|
3800
|
-
actualVisibleCount: 0,
|
|
3801
|
-
dataLength: 0,
|
|
3802
|
-
viewportHeight: 0
|
|
3803
|
-
};
|
|
3804
|
-
}
|
|
3805
|
-
const viewportElement = this.viewport.elementRef.nativeElement;
|
|
3806
|
-
const viewportRect = viewportElement.getBoundingClientRect();
|
|
3807
|
-
return {
|
|
3808
|
-
scrollIndex: this.currentPivotScrollIndex(),
|
|
3809
|
-
visibleRange: this.getVisibleRange(),
|
|
3810
|
-
renderedRange: this.getRenderedRange(),
|
|
3811
|
-
cdkViewportSize: this.viewport.getViewportSize(),
|
|
3812
|
-
actualVisibleCount: this.getActualVisibleItemCount(),
|
|
3813
|
-
dataLength: this.viewport.getDataLength(),
|
|
3814
|
-
viewportHeight: viewportRect.height
|
|
3815
|
-
};
|
|
3816
|
-
}
|
|
3817
3822
|
ROWS_PER_PAGE = 50;
|
|
3818
3823
|
SCROLL_THRESHOLD = 10;
|
|
3819
3824
|
lastLoadedGroupIds = new Set();
|
|
3820
3825
|
constructor(changeDetectorRef) {
|
|
3821
3826
|
this.changeDetectorRef = changeDetectorRef;
|
|
3822
|
-
// Effect to clear rowspan cache when pivot data changes
|
|
3823
3827
|
effect(() => {
|
|
3824
|
-
|
|
3825
|
-
this.gridStore.
|
|
3826
|
-
|
|
3827
|
-
|
|
3828
|
+
const pivotResult = this.gridStore.pivotResult();
|
|
3829
|
+
const pivotConfig = this.gridStore.pivotConfiguration();
|
|
3830
|
+
const pivotTransformService = this.gridStore.getPivotTransformService();
|
|
3831
|
+
if (pivotResult && pivotConfig && pivotTransformService) {
|
|
3832
|
+
this._rowspanInfo = pivotTransformService.calculateRowspanInfo(this.gridStore.pivotDisplayData(), pivotConfig.rows);
|
|
3833
|
+
}
|
|
3834
|
+
else {
|
|
3835
|
+
this._rowspanInfo = new Map();
|
|
3836
|
+
}
|
|
3837
|
+
});
|
|
3838
|
+
// Effect to adjust header scrollbar compensation when freeze header changes
|
|
3839
|
+
effect(() => {
|
|
3840
|
+
// Track freeze header changes
|
|
3841
|
+
this.freezeHeader();
|
|
3842
|
+
// Adjust scrollbar compensation after DOM updates
|
|
3843
|
+
setTimeout(() => this.adjustHeaderScrollbarCompensation(), 200);
|
|
3828
3844
|
});
|
|
3829
3845
|
}
|
|
3830
3846
|
applyTokens() {
|
|
@@ -3843,6 +3859,11 @@ class EruGridComponent {
|
|
|
3843
3859
|
}
|
|
3844
3860
|
ngAfterViewInit() {
|
|
3845
3861
|
this.applyTokens();
|
|
3862
|
+
this.adjustHeaderScrollbarCompensation();
|
|
3863
|
+
// For debugging: expose method to window
|
|
3864
|
+
if (typeof window !== 'undefined') {
|
|
3865
|
+
window.recalculateScrollbar = () => this.recalculateScrollbarCompensation();
|
|
3866
|
+
}
|
|
3846
3867
|
}
|
|
3847
3868
|
ngOnDestroy() {
|
|
3848
3869
|
if (this.resizeObserver) {
|
|
@@ -3877,13 +3898,6 @@ class EruGridComponent {
|
|
|
3877
3898
|
});
|
|
3878
3899
|
return flattenedRows;
|
|
3879
3900
|
}
|
|
3880
|
-
// Column observable is now handled by GridStore signals
|
|
3881
|
-
recalculateViewport() {
|
|
3882
|
-
if (this.viewport) {
|
|
3883
|
-
this.viewport.checkViewportSize();
|
|
3884
|
-
this.changeDetectorRef.markForCheck();
|
|
3885
|
-
}
|
|
3886
|
-
}
|
|
3887
3901
|
initializeGroups() {
|
|
3888
3902
|
this.fetchInitialRows();
|
|
3889
3903
|
}
|
|
@@ -3935,14 +3949,6 @@ class EruGridComponent {
|
|
|
3935
3949
|
});
|
|
3936
3950
|
});
|
|
3937
3951
|
}
|
|
3938
|
-
// Group loading state is now managed by GridStore
|
|
3939
|
-
updateGroupLoadingState(groupId, isLoading) {
|
|
3940
|
-
this.gridStore.updateGroupLoadingState(groupId, isLoading);
|
|
3941
|
-
}
|
|
3942
|
-
// Group after loading is now managed by GridStore
|
|
3943
|
-
updateGroupAfterLoading(groupId, loadedCount, fullyExhausted = false) {
|
|
3944
|
-
this.gridStore.updateGroupAfterLoading(groupId, loadedCount, fullyExhausted);
|
|
3945
|
-
}
|
|
3946
3952
|
onScroll(scrollIndex) {
|
|
3947
3953
|
const groups = this.gridStore.groups();
|
|
3948
3954
|
const visibleGroups = this.getVisibleGroups();
|
|
@@ -4023,60 +4029,6 @@ class EruGridComponent {
|
|
|
4023
4029
|
this.processRowLoadQueue();
|
|
4024
4030
|
}
|
|
4025
4031
|
}
|
|
4026
|
-
adjustColumnWidths() {
|
|
4027
|
-
// Disabled: This method was constraining columns to fit container width
|
|
4028
|
-
// Instead, let columns maintain their configured widths and allow horizontal scroll
|
|
4029
|
-
if (this.viewport && this.rowContainer) {
|
|
4030
|
-
const table = this.rowContainer.nativeElement.querySelector('.row-table');
|
|
4031
|
-
if (table) {
|
|
4032
|
-
// Calculate total width of all columns
|
|
4033
|
-
const columns = table.querySelectorAll('th');
|
|
4034
|
-
let totalWidth = 0;
|
|
4035
|
-
columns.forEach((col) => {
|
|
4036
|
-
// Don't constrain width - let it use the configured width
|
|
4037
|
-
const configuredWidth = col.style.width;
|
|
4038
|
-
if (configuredWidth) {
|
|
4039
|
-
totalWidth += parseInt(configuredWidth) || 150;
|
|
4040
|
-
}
|
|
4041
|
-
else {
|
|
4042
|
-
totalWidth += 150; // default width
|
|
4043
|
-
}
|
|
4044
|
-
});
|
|
4045
|
-
// Set table minimum width to sum of all column widths
|
|
4046
|
-
table.style.minWidth = `${totalWidth}px`;
|
|
4047
|
-
}
|
|
4048
|
-
}
|
|
4049
|
-
}
|
|
4050
|
-
ensureHorizontalScroll() {
|
|
4051
|
-
if (this.rowContainer && this.viewport) {
|
|
4052
|
-
const tableWrapper = this.rowContainer.nativeElement.querySelector('.table-wrapper');
|
|
4053
|
-
const table = this.rowContainer.nativeElement.querySelector('.row-table');
|
|
4054
|
-
const container = this.rowContainer.nativeElement;
|
|
4055
|
-
if (tableWrapper && table) {
|
|
4056
|
-
// Fix container height and overflow to ensure scrollbar is visible
|
|
4057
|
-
container.style.setProperty('height', '600px', 'important');
|
|
4058
|
-
container.style.setProperty('overflow', 'visible', 'important');
|
|
4059
|
-
container.style.setProperty('overflow-x', 'visible', 'important');
|
|
4060
|
-
container.style.setProperty('overflow-y', 'visible', 'important');
|
|
4061
|
-
// Force table layout and width styles to override old compiled CSS
|
|
4062
|
-
table.style.setProperty('table-layout', 'auto', 'important');
|
|
4063
|
-
table.style.setProperty('width', 'auto', 'important');
|
|
4064
|
-
table.style.setProperty('min-width', 'max-content', 'important');
|
|
4065
|
-
// Ensure the viewport handles horizontal scrolling with proper settings
|
|
4066
|
-
const viewportEl = this.viewport.elementRef.nativeElement;
|
|
4067
|
-
viewportEl.style.setProperty('overflow-x', 'auto', 'important');
|
|
4068
|
-
viewportEl.style.setProperty('overflow-y', 'auto', 'important');
|
|
4069
|
-
// Calculate total column width based on configured widths
|
|
4070
|
-
const columns = this.gridStore.columns();
|
|
4071
|
-
const totalWidth = columns.reduce((sum, col) => sum + (col.field_size || 150), 0);
|
|
4072
|
-
const checkboxWidth = 50; // checkbox column width
|
|
4073
|
-
const finalWidth = totalWidth + checkboxWidth;
|
|
4074
|
-
// Set table minimum width to force horizontal scroll if needed
|
|
4075
|
-
table.style.setProperty('min-width', `${finalWidth}px`, 'important');
|
|
4076
|
-
tableWrapper.style.setProperty('min-width', `${finalWidth}px`, 'important');
|
|
4077
|
-
}
|
|
4078
|
-
}
|
|
4079
|
-
}
|
|
4080
4032
|
trackByColumnFn(index, column) {
|
|
4081
4033
|
return column.name;
|
|
4082
4034
|
}
|
|
@@ -4139,14 +4091,7 @@ class EruGridComponent {
|
|
|
4139
4091
|
});
|
|
4140
4092
|
this.gridStore.setColumns(normalizedColumns);
|
|
4141
4093
|
}
|
|
4142
|
-
|
|
4143
|
-
if (this.rowContainer && this.rowContainer.nativeElement) {
|
|
4144
|
-
const container = this.rowContainer.nativeElement;
|
|
4145
|
-
container.style.height = `${container.offsetHeight}px`;
|
|
4146
|
-
container.style.width = `${container.offsetWidth}px`;
|
|
4147
|
-
}
|
|
4148
|
-
}
|
|
4149
|
-
// Enhanced method to normalize task data
|
|
4094
|
+
// Enhanced method to normalize row data
|
|
4150
4095
|
normalizeRowData(rows, group) {
|
|
4151
4096
|
return rows.map(row => ({
|
|
4152
4097
|
...row,
|
|
@@ -4289,25 +4234,7 @@ class EruGridComponent {
|
|
|
4289
4234
|
*/
|
|
4290
4235
|
_stickyDebugCount = 0;
|
|
4291
4236
|
getRowspanInfo() {
|
|
4292
|
-
|
|
4293
|
-
const pivotResult = this.gridStore.pivotResult();
|
|
4294
|
-
const pivotConfig = this.gridStore.pivotConfiguration();
|
|
4295
|
-
const pivotTransformService = this.gridStore.getPivotTransformService();
|
|
4296
|
-
if (pivotResult && pivotConfig && pivotTransformService) {
|
|
4297
|
-
this._rowspanInfo = pivotTransformService.calculateRowspanInfo(pivotResult.data, pivotConfig.rows);
|
|
4298
|
-
}
|
|
4299
|
-
else {
|
|
4300
|
-
this._rowspanInfo = new Map();
|
|
4301
|
-
}
|
|
4302
|
-
}
|
|
4303
|
-
return this._rowspanInfo;
|
|
4304
|
-
}
|
|
4305
|
-
/**
|
|
4306
|
-
* Clear rowspan cache when pivot data changes
|
|
4307
|
-
*/
|
|
4308
|
-
clearRowspanCache() {
|
|
4309
|
-
this._rowspanInfo = null;
|
|
4310
|
-
this._virtualRowspanCache.clear();
|
|
4237
|
+
return this._rowspanInfo ?? new Map();
|
|
4311
4238
|
}
|
|
4312
4239
|
/**
|
|
4313
4240
|
* Get the effective rowspan for a cell in virtual scrolling context
|
|
@@ -4323,32 +4250,39 @@ class EruGridComponent {
|
|
|
4323
4250
|
shouldSkipCell(rowIndex, columnName) {
|
|
4324
4251
|
const currentRowspan = this.getRowspanInfo().get(`${rowIndex}_${columnName}`)?.rowspan || 1;
|
|
4325
4252
|
const previousRowspan = this.getRowspanInfo().get(`${rowIndex - 1}_${columnName}`)?.rowspan || 1;
|
|
4253
|
+
if (this.firstDataRowIndex() > rowIndex) {
|
|
4254
|
+
return true;
|
|
4255
|
+
}
|
|
4326
4256
|
if (this.isFirstVisiblePivotRow(rowIndex) && !(currentRowspan > previousRowspan)) {
|
|
4327
4257
|
return false;
|
|
4328
4258
|
}
|
|
4329
4259
|
else if (this.getRowspanInfo().get(`${rowIndex}_${columnName}`)) {
|
|
4330
4260
|
if (this.getRowspanInfo().get(`${rowIndex}_${columnName}`)?.rowspan || 1 > 0) {
|
|
4331
|
-
if (currentRowspan > previousRowspan && rowIndex >= this.
|
|
4261
|
+
if (currentRowspan > previousRowspan && rowIndex >= this.firstDataRowIndex()) {
|
|
4262
|
+
/* if (rowIndex >= 6 && rowIndex <= 7) {console.log('inside 2a');} */
|
|
4332
4263
|
return false;
|
|
4333
4264
|
}
|
|
4334
4265
|
else {
|
|
4266
|
+
/* if (rowIndex >= 6 && rowIndex <= 7) {console.log('inside 2b');} */
|
|
4335
4267
|
return true;
|
|
4336
4268
|
}
|
|
4337
4269
|
}
|
|
4338
4270
|
}
|
|
4339
4271
|
else if (!this.getRowspanInfo().get(`${rowIndex}_${columnName}`)) {
|
|
4272
|
+
/* if (rowIndex >= 6 && rowIndex <= 7) {console.log('inside 3');} */
|
|
4340
4273
|
return false;
|
|
4341
4274
|
}
|
|
4342
4275
|
else {
|
|
4276
|
+
/* if (rowIndex >= 6 && rowIndex <= 7) {console.log('inside 4');} */
|
|
4343
4277
|
return true;
|
|
4344
4278
|
}
|
|
4279
|
+
/* if (rowIndex >= 6 && rowIndex <= 7) {console.log('inside 5');} */
|
|
4345
4280
|
return true;
|
|
4346
4281
|
}
|
|
4347
4282
|
/**
|
|
4348
4283
|
* Get the effective cell value, considering virtual parents for virtual scrolling
|
|
4349
4284
|
*/
|
|
4350
4285
|
getEffectiveCellValue(index, columnName, pivotRow) {
|
|
4351
|
-
// First try to get the direct value
|
|
4352
4286
|
const directValue = pivotRow[columnName];
|
|
4353
4287
|
return directValue;
|
|
4354
4288
|
}
|
|
@@ -4537,8 +4471,101 @@ class EruGridComponent {
|
|
|
4537
4471
|
return false;
|
|
4538
4472
|
return pivotConfig.rows.some(row => row.toLowerCase() === columnName.toLowerCase());
|
|
4539
4473
|
}
|
|
4474
|
+
/**
|
|
4475
|
+
* Handle body scroll to synchronize header and grand total horizontal scroll
|
|
4476
|
+
*/
|
|
4477
|
+
onBodyScroll(event) {
|
|
4478
|
+
const target = event.target;
|
|
4479
|
+
if (!target)
|
|
4480
|
+
return;
|
|
4481
|
+
const scrollLeft = target.scrollLeft;
|
|
4482
|
+
// Sync header if freezeHeader is enabled
|
|
4483
|
+
if (this.freezeHeader() && this.headerScroller?.nativeElement) {
|
|
4484
|
+
const headerScrollLeft = this.headerScroller.nativeElement.scrollLeft;
|
|
4485
|
+
// Only sync if there's a difference to avoid infinite loops
|
|
4486
|
+
if (Math.abs(scrollLeft - headerScrollLeft) > 1) {
|
|
4487
|
+
this.headerScroller.nativeElement.scrollLeft = scrollLeft;
|
|
4488
|
+
console.log('Body scroll sync header:', {
|
|
4489
|
+
bodyScrollLeft: scrollLeft,
|
|
4490
|
+
headerScrollLeft: headerScrollLeft,
|
|
4491
|
+
difference: Math.abs(scrollLeft - headerScrollLeft)
|
|
4492
|
+
});
|
|
4493
|
+
}
|
|
4494
|
+
}
|
|
4495
|
+
// Sync grand total footer if freezeGrandTotal is enabled
|
|
4496
|
+
if (this.freezeGrandTotal() && this.gtScroller?.nativeElement) {
|
|
4497
|
+
const gtScrollLeft = this.gtScroller.nativeElement.scrollLeft;
|
|
4498
|
+
// Only sync if there's a difference to avoid infinite loops
|
|
4499
|
+
if (Math.abs(scrollLeft - gtScrollLeft) > 1) {
|
|
4500
|
+
this.gtScroller.nativeElement.scrollLeft = scrollLeft;
|
|
4501
|
+
console.log('Body scroll sync grand total:', {
|
|
4502
|
+
bodyScrollLeft: scrollLeft,
|
|
4503
|
+
gtScrollLeft: gtScrollLeft,
|
|
4504
|
+
difference: Math.abs(scrollLeft - gtScrollLeft)
|
|
4505
|
+
});
|
|
4506
|
+
}
|
|
4507
|
+
}
|
|
4508
|
+
}
|
|
4509
|
+
/**
|
|
4510
|
+
* Handle header scroll to synchronize body horizontal scroll
|
|
4511
|
+
*/
|
|
4512
|
+
onHeaderScroll(event) {
|
|
4513
|
+
if (!this.freezeHeader() || !this.viewport)
|
|
4514
|
+
return;
|
|
4515
|
+
const target = event.target;
|
|
4516
|
+
if (target && this.viewport?.elementRef?.nativeElement) {
|
|
4517
|
+
// Synchronize horizontal scroll only
|
|
4518
|
+
this.viewport.elementRef.nativeElement.scrollLeft = target.scrollLeft;
|
|
4519
|
+
}
|
|
4520
|
+
}
|
|
4521
|
+
/**
|
|
4522
|
+
* Manually trigger scrollbar compensation recalculation (for testing)
|
|
4523
|
+
*/
|
|
4524
|
+
recalculateScrollbarCompensation() {
|
|
4525
|
+
console.log('Manual recalculation triggered');
|
|
4526
|
+
this.adjustHeaderScrollbarCompensation();
|
|
4527
|
+
}
|
|
4528
|
+
/**
|
|
4529
|
+
* Adjust header padding to compensate for body table scrollbar width
|
|
4530
|
+
* This ensures perfect column alignment between header and body tables
|
|
4531
|
+
*/
|
|
4532
|
+
adjustHeaderScrollbarCompensation() {
|
|
4533
|
+
if (!this.freezeHeader() || !this.rowContainer)
|
|
4534
|
+
return;
|
|
4535
|
+
setTimeout(() => {
|
|
4536
|
+
const container = this.rowContainer?.nativeElement;
|
|
4537
|
+
if (!container)
|
|
4538
|
+
return;
|
|
4539
|
+
const headerShell = container.querySelector('.header-shell');
|
|
4540
|
+
const viewport = container.querySelector('.pivot-viewport');
|
|
4541
|
+
if (headerShell && viewport) {
|
|
4542
|
+
// Calculate scrollbar width by comparing viewport dimensions
|
|
4543
|
+
let scrollbarWidth = viewport.offsetWidth - viewport.clientWidth;
|
|
4544
|
+
// Alternative method if the first one doesn't work or returns 0
|
|
4545
|
+
if (scrollbarWidth === 0) {
|
|
4546
|
+
// Create a temporary element to measure scrollbar width
|
|
4547
|
+
const scrollDiv = document.createElement('div');
|
|
4548
|
+
scrollDiv.style.cssText = `
|
|
4549
|
+
width: 100px;
|
|
4550
|
+
height: 100px;
|
|
4551
|
+
overflow: scroll;
|
|
4552
|
+
position: absolute;
|
|
4553
|
+
top: -9999px;
|
|
4554
|
+
`;
|
|
4555
|
+
document.body.appendChild(scrollDiv);
|
|
4556
|
+
scrollbarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth;
|
|
4557
|
+
document.body.removeChild(scrollDiv);
|
|
4558
|
+
}
|
|
4559
|
+
// Apply the calculated scrollbar width as padding-right
|
|
4560
|
+
headerShell.style.setProperty('--scrollbar-width', `${scrollbarWidth}px`);
|
|
4561
|
+
// Debug: Log detailed measurements
|
|
4562
|
+
const headerTable = headerShell.querySelector('.eru-grid-table');
|
|
4563
|
+
const bodyTable = viewport.querySelector('.eru-grid-table');
|
|
4564
|
+
}
|
|
4565
|
+
}, 100);
|
|
4566
|
+
}
|
|
4540
4567
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: EruGridComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
|
|
4541
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.3", type: EruGridComponent, isStandalone: true, selector: "eru-grid", viewQueries: [{ propertyName: "viewport", first: true, predicate: CdkVirtualScrollViewport, descendants: true }, { propertyName: "rowContainer", first: true, predicate: ["rowContainer"], descendants: true }], ngImport: i0, template: "<!-- <div style=\"background: #f0f0f0; font-size: 12px; border-bottom: 1px solid #ccc;\">\n First Visible Row: Virtual Index {{currentPivotScrollIndex()}} | \n Data Index {{getFirstVisiblePivotDataIndex()}} | \n Total Rows {{gridStore.pivotDisplayData().length}}\n</div> -->\n<div class=\"incremental-row-container eru-grid\" #rowContainer \n [class.pivot-mode]=\"gridStore.isPivotMode()\"\n [class.table-mode]=\"!gridStore.isPivotMode()\">\n \n <!-- Pivot Mode Template -->\n <ng-container *ngIf=\"gridStore.isPivotMode(); else tableMode\">\n <div class=\"pivot-container\" style=\"display: flex; flex-direction: column; height: 100%; width: 100%;\">\n <!-- Debug info for first visible row -->\n \n \n <div class=\"pivot-single-table\" style=\"height: 100%; width: 100%; overflow: hidden; display: flex; flex-direction: column;\">\n \n <!-- Virtual Scrolled Table Body -->\n <div style=\"flex: 1; overflow: auto;\">\n <cdk-virtual-scroll-viewport\n [itemSize]=\"50\"\n class=\"viewport pivot-viewport\"\n (scrolledIndexChange)=\"onPivotScroll($event)\"\n style=\"height: 100%; overflow: auto;\">\n <table class=\"eru-grid-table pivot-table\" style=\"width: auto; min-width: 100%;\"\n [class.show-column-lines]=\"showColumnLines()\" \n [class.show-row-lines]=\"showRowLines()\">\n <!-- Hidden column sizing row to match header -->\n <thead>\n <tr style=\"visibility:hidden; height:0;\">\n <th *ngFor=\"let column of getLeafColumns(); trackBy: trackByColumnFn\"\n [style.width.px]=\"column.field_size\"\n [style.minWidth.px]=\"column.field_size\"\n class=\"pivot-header-leafcols\"\n >\n </th>\n </tr>\n\n <ng-container *ngIf=\"hasNestedHeaders(); else simpleHeader\">\n <tr *ngFor=\"let headerRow of getHeaderRows(); let rowIndex = index\" \n class=\"pivot-header\" \n [class.pivot-header-level]=\"'level-' + rowIndex\">\n <th *ngFor=\"let header of headerRow; trackBy: trackByHeaderFn; let colIndex = index\"\n [attr.colspan]=\"header.colspan\"\n [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)\"\n [class.sticky-column]=\"isStickyColumn(header.name, colIndex)\"\n [class.expanded]=\"header.isExpanded\"\n [class.collapsed]=\"!header.isExpanded\"\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 <span class=\"header-label\">{{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 </tr>\n \n </ng-container>\n \n <!-- Simple header fallback -->\n <ng-template #simpleHeader>\n <tr class=\"pivot-header\">\n <th *ngFor=\"let column of getLeafColumns(); trackBy: trackByColumnFn; let colIndex = index\"\n [style.width.px]=\"column.field_size\"\n [style.minWidth.px]=\"column.field_size\"\n [resizeColumn]=\"gridStore.isFeatureEnabled('columnResizable')\"\n [columnConfig]=\"column\"\n class=\"column-header pivot-column-header\"\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) ? 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 </tr>\n </ng-template>\n </thead>\n <!-- Table Body with Virtual Scrolling -->\n <tbody class=\"pivot-tbody\">\n <tr *cdkVirtualFor=\"let pivotRow of gridStore.pivotDisplayData(); \n trackBy: trackByPivotRowFn; \n let i = index\"\n class=\"pivot-row\"\n [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\"\n [attr.data-pivot-row]=\"i\">\n <!-- <td colspan=\"20\">{{pivotRow | json}}</td> -->\n <ng-container *ngFor=\"let column of getLeafColumns(); trackBy: trackByColumnFn; let colIndex = index\">\n <td *ngIf=\"!shouldSkipCell(i, column.name)\"\n [attr.rowspan]=\"getEffectiveRowspan(i, column.name)\"\n [style.width.px]=\"column.field_size\"\n [style.minWidth.px]=\"column.field_size\"\n 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\"\n [style.height.px]=\"50\"\n [attr.xx]=\"i\"> \n <div class=\"cell-content pivot-cell-content\">\n <data-cell\n [fieldSize]=\"column.field_size\"\n [columnDatatype]=\"column.datatype\"\n [columnName]=\"column.name\"\n [value]=\"getEffectiveCellValue(i,column.name, pivotRow)\"\n [column]=\"column\"\n [drillable]=\"column.enableDrilldown || false\"\n [mode]=\"mode()\"\n [isEditable]=\"isEditable()\"\n [id]=\"'pivot_' + i + '_' + column.name\">\n </data-cell>\n </div>\n </td>\n </ng-container>\n </tr>\n </tbody>\n </table>\n </cdk-virtual-scroll-viewport>\n </div>\n </div>\n </div>\n </ng-container>\n\n <!-- Table Mode Template -->\n <ng-template #tableMode>\n <cdk-virtual-scroll-viewport\n [itemSize]=\"50\"\n class=\"viewport table-viewport\"\n (scrolledIndexChange)=\"onScroll($event)\"\n >\n <div class=\"table-wrapper\">\n <table class=\"eru-grid-table\">\n <thead>\n <tr style=\"visibility:hidden;\">\n <th class=\"checkbox-column\"></th>\n <th *ngFor=\"let column of columns(); trackBy: trackByColumnFn\"\n [style.width.px]=\"column.field_size\"\n [style.minWidth.px]=\"column.field_size\"\n class=\"column-header\">\n {{column.label}}\n </th>\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 <!-- Group Header -->\n <tr\n *ngIf=\"groupItem.type === 'header'\"\n 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 <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 <!-- Column Header -->\n <tr *ngIf=\"groupItem.type === 'table-header'\" style=\"background:#fafafa\">\n <th class=\"checkbox-column\" style=\"text-align: center;\">\n <input\n type=\"checkbox\"\n [checked]=\"isGroupSelected(groupItem.group?.id || '')\"\n (click)=\"$event.stopPropagation()\"\n (change)=\"toggleGroupSelection($event, groupItem.group?.id || '')\"\n >\n </th>\n <th *ngFor=\"let column of columns(); trackBy: trackByColumnFn;let i =index\"\n style=\"text-align: center;\"\n [style.width.px]=\"column.field_size\"\n [style.minWidth.px]=\"column.field_size\"\n [resizeColumn]=\"true\"\n [columnConfig]=\"column\"\n [columnDraggable]=\"i\"\n class=\"column-header\">\n <div class=\"column-drag-handle\"></div>\n {{column.label}} {{column.symbol}}\n </th>\n </tr>\n <!-- Row -->\n <tr\n *ngIf=\"groupItem.type === 'row' && groupItem.group?.isExpanded\"\n class=\"row-item\"\n [attr.data-row-id]=\"groupItem.row?.entity_id\"\n [style.height.px]=\"30\"\n [style.minHeight.px]=\"30\"\n [style.maxHeight.px]=\"30\"\n >\n <td class=\"checkbox-column\" style=\"text-align: center;\">\n <input\n type=\"checkbox\"\n [checked]=\"isRowSelected(groupItem.row?.entity_id)\"\n (change)=\"toggleRowSelection($event, groupItem.row)\"\n >\n </td>\n <td #cell *ngFor=\"let column of columns(); trackBy: trackByColumnFn\"\n [style.width.px]=\"column.field_size\"\n [style.minWidth.px]=\"column.field_size\"\n class=\"data-cell\"\n [style.height.px]=\"30\"\n [style.minHeight.px]=\"30\"\n [style.maxHeight.px]=\"30\"\n [matTooltipClass]=\"'error-message'\"\n [matTooltip]=\"datacell.error()?'Error: ' + datacell.error():''\"\n matTooltipPosition=\"below\"\n >\n <div class=\"cell-content\">\n <data-cell\n #datacell \n [td]=cell\n [fieldSize]=\"column.field_size\"\n [columnDatatype]=\"column.datatype\"\n [columnName]=\"column.name\"\n [value]=\"groupItem.row?.[column.name] || ''\"\n [column]=\"column\"\n [mode]=\"mode()\"\n [isEditable]=\"isEditable()\"\n [drillable]=\"column.enableDrilldown || false\"\n [id]=\"groupItem.row?.['entity_id'] || '_' ||column.name\"\n ></data-cell>\n </div>\n </td>\n </tr>\n\n <!-- Ghost Loading Rows -->\n <tr\n *ngIf=\"groupItem.type === 'ghost-loading' && groupItem.group?.isExpanded\"\n class=\"ghost-loading-row\"\n [style.height.px]=\"30\"\n [style.minHeight.px]=\"30\"\n [style.maxHeight.px]=\"30\"\n >\n <td class=\"checkbox-column\"></td>\n <td *ngFor=\"let column of columns(); trackBy: trackByColumnFn\"\n [style.width.px]=\"column.field_size\"\n [style.minWidth.px]=\"column.field_size\"\n class=\"ghost-cell-container\"\n >\n <div class=\"ghost-cell\"></div>\n </td>\n </tr>\n\n <!-- Group Separator Row -->\n <tr\n *ngIf=\"groupItem.type === 'row-place-holder'\"\n class=\"group-separator\"\n >\n <td [attr.colspan]=\"columns().length + 1\" class=\"separator-cell\"></td>\n </tr>\n </ng-container>\n </tbody>\n </table>\n </div>\n </cdk-virtual-scroll-viewport>\n </ng-template>\n</div>", 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-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: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,.pivot-viewport{height:calc(100% - 60px);width:100%;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:collapse;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);position:sticky;top:0;z-index:10;transform:translateZ(0);will-change:transform;backface-visibility:hidden}.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;border:1px solid var(--grid-outline);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)}.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{border-collapse:collapse}.incremental-row-container .eru-grid-table tbody{position:relative;border-left:var(--grid-outline-width, 1px) solid var(--grid-outline, #e0e0e0);border-right:var(--grid-outline-width, 1px) solid var(--grid-outline, #e0e0e0);border-bottom:var(--grid-outline-width, 1px) solid var(--grid-outline, #e0e0e0)}.incremental-row-container .eru-grid-table thead{position:relative;border-left:var(--grid-outline-width, 1px) solid var(--grid-outline, #e0e0e0);border-right:var(--grid-outline-width, 1px) solid var(--grid-outline, #e0e0e0);border-top:var(--grid-outline-width, 1px) solid var(--grid-outline, #e0e0e0)}.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;min-height:500px;max-height:85vh;overflow:auto}.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:auto!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}.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}.pivot-mode .pivot-cell{vertical-align:middle}.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}.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:400px!important}.pivot-mode .pivot-table .pivot-single-table .pivot-header-container{flex-shrink:0;position:sticky;top:0;z-index:20;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}\n"], dependencies: [{ kind: "component", type: DataCellComponent, selector: "data-cell", inputs: ["fieldSize", "columnDatatype", "columnName", "column", "value", "id", "replaceZeroValue", "td", "drillable", "mode", "isEditable"], outputs: ["tdChange"] }, { kind: "ngmodule", type: ScrollingModule }, { kind: "directive", type: i1$3.ɵɵCdkFixedSizeVirtualScroll, selector: "cdk-virtual-scroll-viewport[itemSize]", inputs: ["itemSize", "minBufferPx", "maxBufferPx"] }, { kind: "directive", type: i1$3.ɵɵCdkVirtualForOf, selector: "[cdkVirtualFor][cdkVirtualForOf]", inputs: ["cdkVirtualForOf", "cdkVirtualForTrackBy", "cdkVirtualForTemplate", "cdkVirtualForTemplateCacheSize"] }, { kind: "component", type: i1$3.ɵɵCdkVirtualScrollViewport, selector: "cdk-virtual-scroll-viewport", inputs: ["orientation", "appendOnly"], outputs: ["scrolledIndexChange"] }, { kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i3$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"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
4568
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.3", type: EruGridComponent, isStandalone: true, selector: "eru-grid", 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 \n [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%; width: 100%;\">\n <!-- Debug info for first visible row -->\n \n \n <div class=\"pivot-single-table\" 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: ' + getTotalTableWidth() + 'px'\"\n [class.show-column-lines]=\"showColumnLines()\" \n [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 style=\"flex: 1;\">\n <cdk-virtual-scroll-viewport\n #vp\n [itemSize]=\"50\"\n class=\"viewport pivot-viewport\"\n (scrolledIndexChange)=\"onPivotScroll($event)\"\n (scroll)=\"onBodyScroll($event)\"\n style=\"height: 100%; overflow: auto;\">\n <table class=\"eru-grid-table pivot-table\" \n [style]=\"'width: auto; min-width: 100%; --table-total-width: ' + getTotalTableWidth() + 'px'\"\n [class.show-column-lines]=\"showColumnLines()\" \n [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\"\n class=\"pivot-row\"\n [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\"\n [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\n [attr.rowspan]=\"getEffectiveRowspan(i, column.name)\"\n [style.width.px]=\"column.field_size\"\n [style.minWidth.px]=\"column.field_size\"\n 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\"\n [style.height.px]=\"50\"\n [attr.xx]=\"i\"> \n <div class=\"cell-content pivot-cell-content\">\n <data-cell\n [fieldSize]=\"column.field_size\"\n [columnDatatype]=\"column.datatype\"\n [columnName]=\"column.name\"\n [value]=\"getEffectiveCellValue(i,column.name, pivotRow)\"\n [column]=\"column\"\n [drillable]=\"column.enableDrilldown || false\"\n [mode]=\"mode()\"\n [isEditable]=\"isEditable()\"\n [id]=\"'pivot_' + i + '_' + column.name\">\n </data-cell>\n </div>\n </td>\n }\n }\n }\n </tr> \n </tbody>\n </table>\n </cdk-virtual-scroll-viewport>\n @if (freezeGrandTotal() && grandTotalPosition() === 'after') {\n <div #gtScroller class=\"header-shell gt-shell\">\n <table class=\"eru-grid-table pivot-table\" \n [style]=\"'width: auto; min-width: 100%; --table-total-width: ' + getTotalTableWidth() + 'px'\"\n [class.show-column-lines]=\"showColumnLines()\" \n [class.show-row-lines]=\"showRowLines()\">\n <!-- Column Groups for consistent width -->\n <ng-container *ngTemplateOutlet=\"pivotColGroup\"></ng-container>\n \n <ng-container *ngTemplateOutlet=\"pivotGrandTotal\"></ng-container>\n \n </table> \n </div>\n }\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\n [itemSize]=\"50\"\n class=\"viewport table-viewport\"\n (scrolledIndexChange)=\"onScroll($event)\"\n >\n <div class=\"table-wrapper\">\n <table class=\"eru-grid-table\" [class.show-column-lines]=\"showColumnLines()\" [class.show-column-lines]=\"showColumnLines()\">\n <thead>\n <tr style=\"visibility:hidden;\">\n <th class=\"checkbox-column\"></th>\n <th *ngFor=\"let column of columns(); trackBy: trackByColumnFn\"\n [style.width.px]=\"column.field_size\"\n [style.minWidth.px]=\"column.field_size\"\n class=\"column-header\">\n {{column.label}}\n </th>\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\n *ngIf=\"groupItem.type === 'header'\"\n 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 <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'\" style=\"background:#fafafa\">\n <th class=\"checkbox-column\" style=\"text-align: center;\">\n <input\n type=\"checkbox\"\n [checked]=\"isGroupSelected(groupItem.group?.id || '')\"\n (click)=\"$event.stopPropagation()\"\n (change)=\"toggleGroupSelection($event, groupItem.group?.id || '')\"\n >\n </th>\n <th *ngFor=\"let column of columns(); trackBy: trackByColumnFn;let i =index\"\n style=\"text-align: center;\"\n [style.width.px]=\"column.field_size\"\n [style.minWidth.px]=\"column.field_size\"\n [resizeColumn]=\"true\"\n [columnConfig]=\"column\"\n [columnDraggable]=\"i\"\n class=\"column-header\">\n <div class=\"column-drag-handle\"></div>\n {{column.label}} {{column.symbol}}\n </th>\n </tr>\n <tr\n *ngIf=\"groupItem.type === 'row' && groupItem.group?.isExpanded\"\n class=\"row-item\"\n [attr.data-row-id]=\"groupItem.row?.entity_id\"\n [style.height.px]=\"30\"\n [style.minHeight.px]=\"30\"\n [style.maxHeight.px]=\"30\"\n >\n <td class=\"checkbox-column\" style=\"text-align: center;\">\n <input\n type=\"checkbox\"\n [checked]=\"isRowSelected(groupItem.row?.entity_id)\"\n (change)=\"toggleRowSelection($event, groupItem.row)\"\n >\n </td>\n <td #cell *ngFor=\"let column of columns(); trackBy: trackByColumnFn\"\n [style.width.px]=\"column.field_size\"\n [style.minWidth.px]=\"column.field_size\"\n class=\"data-cell\"\n [style.height.px]=\"30\"\n [style.minHeight.px]=\"30\"\n [style.maxHeight.px]=\"30\"\n [matTooltipClass]=\"'error-message'\"\n [matTooltip]=\"datacell.error()?'Error: ' + datacell.error():''\"\n matTooltipPosition=\"below\"\n >\n <div class=\"cell-content\">\n <data-cell\n #datacell \n [td]=cell\n [fieldSize]=\"column.field_size\"\n [columnDatatype]=\"column.datatype\"\n [columnName]=\"column.name\"\n [value]=\"groupItem.row?.[column.name] || ''\"\n [column]=\"column\"\n [mode]=\"mode()\"\n [isEditable]=\"isEditable()\"\n [drillable]=\"column.enableDrilldown || false\"\n [id]=\"groupItem.row?.['entity_id'] || '_' ||column.name\"\n ></data-cell>\n </div>\n </td>\n </tr>\n\n <tr\n *ngIf=\"groupItem.type === 'ghost-loading' && groupItem.group?.isExpanded\"\n class=\"ghost-loading-row\"\n [style.height.px]=\"30\"\n [style.minHeight.px]=\"30\"\n [style.maxHeight.px]=\"30\"\n >\n <td class=\"checkbox-column\"></td>\n <td *ngFor=\"let column of columns(); trackBy: trackByColumnFn\"\n [style.width.px]=\"column.field_size\"\n [style.minWidth.px]=\"column.field_size\"\n class=\"ghost-cell-container\"\n >\n <div class=\"ghost-cell\"></div>\n </td>\n </tr>\n\n <tr\n *ngIf=\"groupItem.type === 'row-place-holder'\"\n class=\"group-separator\"\n >\n <td [attr.colspan]=\"columns().length + 1\" 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\" \n [class.pivot-header-level]=\"'level-' + rowIndex\">\n @for (header of headerRow; track trackByHeaderFn($index, header); let colIndex = $index) {\n <th\n [attr.colspan]=\"header.colspan\"\n [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)\"\n [class.sticky-column]=\"isStickyColumn(header.name, colIndex)\"\n [class.expanded]=\"header.isExpanded\"\n [class.collapsed]=\"!header.isExpanded\"\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 <span class=\"header-label\">{{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\"\n [style.minWidth.px]=\"column.field_size\"\n [resizeColumn]=\"gridStore.isFeatureEnabled('columnResizable')\"\n [columnConfig]=\"column\"\n class=\"column-header pivot-column-header\"\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) ? 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 [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 \n 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\"\n [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\n [attr.rowspan]=\"getEffectiveRowspan(i, column.name)\" \n [style.width.px]=\"column.field_size\"\n [style.minWidth.px]=\"column.field_size\"\n 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\"\n [style.height.px]=\"50\"\n [attr.xx]=\"i\"> \n <div class=\"cell-content pivot-cell-content\">\n <data-cell\n [fieldSize]=\"column.field_size\"\n [columnDatatype]=\"column.datatype\"\n [columnName]=\"column.name\"\n [value]=\"getEffectiveCellValue(i,column.name, pivotRow)\"\n [column]=\"column\"\n [drillable]=\"column.enableDrilldown || false\"\n [mode]=\"mode()\"\n [isEditable]=\"isEditable()\"\n [id]=\"'pivot_' + i + '_' + column.name\">\n </data-cell>\n </div>\n </td>\n }\n </tr>\n}\n</tbody>\n</ng-template>\n", 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-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: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{height:calc(100% - 60px);width:100%;overflow-x:auto;overflow-y:auto;background-color:var(--grid-surface);scrollbar-gutter:stable}.pivot-viewport{height:calc(100% - 60px);width:100%;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-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;border:1px solid var(--grid-outline);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)}.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{position:relative;border-left:var(--grid-outline-width, 1px) solid var(--grid-outline, #e0e0e0);border-right:var(--grid-outline-width, 1px) solid var(--grid-outline, #e0e0e0);border-bottom:var(--grid-outline-width, 1px) solid var(--grid-outline, #e0e0e0)}.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}.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;min-height:500px;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;width:calc(100% - var(--scrollbar-width, 17px))!important;bottom:65px;z-index:1;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 .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 .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:400px!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}\n"], dependencies: [{ kind: "component", type: DataCellComponent, selector: "data-cell", inputs: ["fieldSize", "columnDatatype", "columnName", "column", "value", "id", "replaceZeroValue", "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: MatTooltipModule }, { kind: "directive", type: i3$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"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
4542
4569
|
}
|
|
4543
4570
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: EruGridComponent, decorators: [{
|
|
4544
4571
|
type: Component,
|
|
@@ -4549,13 +4576,22 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.3", ngImpor
|
|
|
4549
4576
|
MatTooltipModule,
|
|
4550
4577
|
ResizeColumnDirective,
|
|
4551
4578
|
ColumnDragDirective
|
|
4552
|
-
], template: "<!-- <div style=\"background: #f0f0f0; font-size: 12px; border-bottom: 1px solid #ccc;\">\n First Visible Row: Virtual Index {{currentPivotScrollIndex()}} | \n Data Index {{getFirstVisiblePivotDataIndex()}} | \n Total Rows {{gridStore.pivotDisplayData().length}}\n</div> -->\n<div class=\"incremental-row-container eru-grid\" #rowContainer \n [class.pivot-mode]=\"gridStore.isPivotMode()\"\n [class.table-mode]=\"!gridStore.isPivotMode()\">\n \n <!-- Pivot Mode Template -->\n <ng-container *ngIf=\"gridStore.isPivotMode(); else tableMode\">\n <div class=\"pivot-container\" style=\"display: flex; flex-direction: column; height: 100%; width: 100%;\">\n <!-- Debug info for first visible row -->\n \n \n <div class=\"pivot-single-table\" style=\"height: 100%; width: 100%; overflow: hidden; display: flex; flex-direction: column;\">\n \n <!-- Virtual Scrolled Table Body -->\n <div style=\"flex: 1; overflow: auto;\">\n <cdk-virtual-scroll-viewport\n [itemSize]=\"50\"\n class=\"viewport pivot-viewport\"\n (scrolledIndexChange)=\"onPivotScroll($event)\"\n style=\"height: 100%; overflow: auto;\">\n <table class=\"eru-grid-table pivot-table\" style=\"width: auto; min-width: 100%;\"\n [class.show-column-lines]=\"showColumnLines()\" \n [class.show-row-lines]=\"showRowLines()\">\n <!-- Hidden column sizing row to match header -->\n <thead>\n <tr style=\"visibility:hidden; height:0;\">\n <th *ngFor=\"let column of getLeafColumns(); trackBy: trackByColumnFn\"\n [style.width.px]=\"column.field_size\"\n [style.minWidth.px]=\"column.field_size\"\n class=\"pivot-header-leafcols\"\n >\n </th>\n </tr>\n\n <ng-container *ngIf=\"hasNestedHeaders(); else simpleHeader\">\n <tr *ngFor=\"let headerRow of getHeaderRows(); let rowIndex = index\" \n class=\"pivot-header\" \n [class.pivot-header-level]=\"'level-' + rowIndex\">\n <th *ngFor=\"let header of headerRow; trackBy: trackByHeaderFn; let colIndex = index\"\n [attr.colspan]=\"header.colspan\"\n [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)\"\n [class.sticky-column]=\"isStickyColumn(header.name, colIndex)\"\n [class.expanded]=\"header.isExpanded\"\n [class.collapsed]=\"!header.isExpanded\"\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 <span class=\"header-label\">{{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 </tr>\n \n </ng-container>\n \n <!-- Simple header fallback -->\n <ng-template #simpleHeader>\n <tr class=\"pivot-header\">\n <th *ngFor=\"let column of getLeafColumns(); trackBy: trackByColumnFn; let colIndex = index\"\n [style.width.px]=\"column.field_size\"\n [style.minWidth.px]=\"column.field_size\"\n [resizeColumn]=\"gridStore.isFeatureEnabled('columnResizable')\"\n [columnConfig]=\"column\"\n class=\"column-header pivot-column-header\"\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) ? 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 </tr>\n </ng-template>\n </thead>\n <!-- Table Body with Virtual Scrolling -->\n <tbody class=\"pivot-tbody\">\n <tr *cdkVirtualFor=\"let pivotRow of gridStore.pivotDisplayData(); \n trackBy: trackByPivotRowFn; \n let i = index\"\n class=\"pivot-row\"\n [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\"\n [attr.data-pivot-row]=\"i\">\n <!-- <td colspan=\"20\">{{pivotRow | json}}</td> -->\n <ng-container *ngFor=\"let column of getLeafColumns(); trackBy: trackByColumnFn; let colIndex = index\">\n <td *ngIf=\"!shouldSkipCell(i, column.name)\"\n [attr.rowspan]=\"getEffectiveRowspan(i, column.name)\"\n [style.width.px]=\"column.field_size\"\n [style.minWidth.px]=\"column.field_size\"\n 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\"\n [style.height.px]=\"50\"\n [attr.xx]=\"i\"> \n <div class=\"cell-content pivot-cell-content\">\n <data-cell\n [fieldSize]=\"column.field_size\"\n [columnDatatype]=\"column.datatype\"\n [columnName]=\"column.name\"\n [value]=\"getEffectiveCellValue(i,column.name, pivotRow)\"\n [column]=\"column\"\n [drillable]=\"column.enableDrilldown || false\"\n [mode]=\"mode()\"\n [isEditable]=\"isEditable()\"\n [id]=\"'pivot_' + i + '_' + column.name\">\n </data-cell>\n </div>\n </td>\n </ng-container>\n </tr>\n </tbody>\n </table>\n </cdk-virtual-scroll-viewport>\n </div>\n </div>\n </div>\n </ng-container>\n\n <!-- Table Mode Template -->\n <ng-template #tableMode>\n <cdk-virtual-scroll-viewport\n [itemSize]=\"50\"\n class=\"viewport table-viewport\"\n (scrolledIndexChange)=\"onScroll($event)\"\n >\n <div class=\"table-wrapper\">\n <table class=\"eru-grid-table\">\n <thead>\n <tr style=\"visibility:hidden;\">\n <th class=\"checkbox-column\"></th>\n <th *ngFor=\"let column of columns(); trackBy: trackByColumnFn\"\n [style.width.px]=\"column.field_size\"\n [style.minWidth.px]=\"column.field_size\"\n class=\"column-header\">\n {{column.label}}\n </th>\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 <!-- Group Header -->\n <tr\n *ngIf=\"groupItem.type === 'header'\"\n 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 <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 <!-- Column Header -->\n <tr *ngIf=\"groupItem.type === 'table-header'\" style=\"background:#fafafa\">\n <th class=\"checkbox-column\" style=\"text-align: center;\">\n <input\n type=\"checkbox\"\n [checked]=\"isGroupSelected(groupItem.group?.id || '')\"\n (click)=\"$event.stopPropagation()\"\n (change)=\"toggleGroupSelection($event, groupItem.group?.id || '')\"\n >\n </th>\n <th *ngFor=\"let column of columns(); trackBy: trackByColumnFn;let i =index\"\n style=\"text-align: center;\"\n [style.width.px]=\"column.field_size\"\n [style.minWidth.px]=\"column.field_size\"\n [resizeColumn]=\"true\"\n [columnConfig]=\"column\"\n [columnDraggable]=\"i\"\n class=\"column-header\">\n <div class=\"column-drag-handle\"></div>\n {{column.label}} {{column.symbol}}\n </th>\n </tr>\n <!-- Row -->\n <tr\n *ngIf=\"groupItem.type === 'row' && groupItem.group?.isExpanded\"\n class=\"row-item\"\n [attr.data-row-id]=\"groupItem.row?.entity_id\"\n [style.height.px]=\"30\"\n [style.minHeight.px]=\"30\"\n [style.maxHeight.px]=\"30\"\n >\n <td class=\"checkbox-column\" style=\"text-align: center;\">\n <input\n type=\"checkbox\"\n [checked]=\"isRowSelected(groupItem.row?.entity_id)\"\n (change)=\"toggleRowSelection($event, groupItem.row)\"\n >\n </td>\n <td #cell *ngFor=\"let column of columns(); trackBy: trackByColumnFn\"\n [style.width.px]=\"column.field_size\"\n [style.minWidth.px]=\"column.field_size\"\n class=\"data-cell\"\n [style.height.px]=\"30\"\n [style.minHeight.px]=\"30\"\n [style.maxHeight.px]=\"30\"\n [matTooltipClass]=\"'error-message'\"\n [matTooltip]=\"datacell.error()?'Error: ' + datacell.error():''\"\n matTooltipPosition=\"below\"\n >\n <div class=\"cell-content\">\n <data-cell\n #datacell \n [td]=cell\n [fieldSize]=\"column.field_size\"\n [columnDatatype]=\"column.datatype\"\n [columnName]=\"column.name\"\n [value]=\"groupItem.row?.[column.name] || ''\"\n [column]=\"column\"\n [mode]=\"mode()\"\n [isEditable]=\"isEditable()\"\n [drillable]=\"column.enableDrilldown || false\"\n [id]=\"groupItem.row?.['entity_id'] || '_' ||column.name\"\n ></data-cell>\n </div>\n </td>\n </tr>\n\n <!-- Ghost Loading Rows -->\n <tr\n *ngIf=\"groupItem.type === 'ghost-loading' && groupItem.group?.isExpanded\"\n class=\"ghost-loading-row\"\n [style.height.px]=\"30\"\n [style.minHeight.px]=\"30\"\n [style.maxHeight.px]=\"30\"\n >\n <td class=\"checkbox-column\"></td>\n <td *ngFor=\"let column of columns(); trackBy: trackByColumnFn\"\n [style.width.px]=\"column.field_size\"\n [style.minWidth.px]=\"column.field_size\"\n class=\"ghost-cell-container\"\n >\n <div class=\"ghost-cell\"></div>\n </td>\n </tr>\n\n <!-- Group Separator Row -->\n <tr\n *ngIf=\"groupItem.type === 'row-place-holder'\"\n class=\"group-separator\"\n >\n <td [attr.colspan]=\"columns().length + 1\" class=\"separator-cell\"></td>\n </tr>\n </ng-container>\n </tbody>\n </table>\n </div>\n </cdk-virtual-scroll-viewport>\n </ng-template>\n</div>", 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-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: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,.pivot-viewport{height:calc(100% - 60px);width:100%;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:collapse;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);position:sticky;top:0;z-index:10;transform:translateZ(0);will-change:transform;backface-visibility:hidden}.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;border:1px solid var(--grid-outline);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)}.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{border-collapse:collapse}.incremental-row-container .eru-grid-table tbody{position:relative;border-left:var(--grid-outline-width, 1px) solid var(--grid-outline, #e0e0e0);border-right:var(--grid-outline-width, 1px) solid var(--grid-outline, #e0e0e0);border-bottom:var(--grid-outline-width, 1px) solid var(--grid-outline, #e0e0e0)}.incremental-row-container .eru-grid-table thead{position:relative;border-left:var(--grid-outline-width, 1px) solid var(--grid-outline, #e0e0e0);border-right:var(--grid-outline-width, 1px) solid var(--grid-outline, #e0e0e0);border-top:var(--grid-outline-width, 1px) solid var(--grid-outline, #e0e0e0)}.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;min-height:500px;max-height:85vh;overflow:auto}.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:auto!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}.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}.pivot-mode .pivot-cell{vertical-align:middle}.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}.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:400px!important}.pivot-mode .pivot-table .pivot-single-table .pivot-header-container{flex-shrink:0;position:sticky;top:0;z-index:20;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}\n"] }]
|
|
4579
|
+
], 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 \n [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%; width: 100%;\">\n <!-- Debug info for first visible row -->\n \n \n <div class=\"pivot-single-table\" 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: ' + getTotalTableWidth() + 'px'\"\n [class.show-column-lines]=\"showColumnLines()\" \n [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 style=\"flex: 1;\">\n <cdk-virtual-scroll-viewport\n #vp\n [itemSize]=\"50\"\n class=\"viewport pivot-viewport\"\n (scrolledIndexChange)=\"onPivotScroll($event)\"\n (scroll)=\"onBodyScroll($event)\"\n style=\"height: 100%; overflow: auto;\">\n <table class=\"eru-grid-table pivot-table\" \n [style]=\"'width: auto; min-width: 100%; --table-total-width: ' + getTotalTableWidth() + 'px'\"\n [class.show-column-lines]=\"showColumnLines()\" \n [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\"\n class=\"pivot-row\"\n [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\"\n [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\n [attr.rowspan]=\"getEffectiveRowspan(i, column.name)\"\n [style.width.px]=\"column.field_size\"\n [style.minWidth.px]=\"column.field_size\"\n 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\"\n [style.height.px]=\"50\"\n [attr.xx]=\"i\"> \n <div class=\"cell-content pivot-cell-content\">\n <data-cell\n [fieldSize]=\"column.field_size\"\n [columnDatatype]=\"column.datatype\"\n [columnName]=\"column.name\"\n [value]=\"getEffectiveCellValue(i,column.name, pivotRow)\"\n [column]=\"column\"\n [drillable]=\"column.enableDrilldown || false\"\n [mode]=\"mode()\"\n [isEditable]=\"isEditable()\"\n [id]=\"'pivot_' + i + '_' + column.name\">\n </data-cell>\n </div>\n </td>\n }\n }\n }\n </tr> \n </tbody>\n </table>\n </cdk-virtual-scroll-viewport>\n @if (freezeGrandTotal() && grandTotalPosition() === 'after') {\n <div #gtScroller class=\"header-shell gt-shell\">\n <table class=\"eru-grid-table pivot-table\" \n [style]=\"'width: auto; min-width: 100%; --table-total-width: ' + getTotalTableWidth() + 'px'\"\n [class.show-column-lines]=\"showColumnLines()\" \n [class.show-row-lines]=\"showRowLines()\">\n <!-- Column Groups for consistent width -->\n <ng-container *ngTemplateOutlet=\"pivotColGroup\"></ng-container>\n \n <ng-container *ngTemplateOutlet=\"pivotGrandTotal\"></ng-container>\n \n </table> \n </div>\n }\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\n [itemSize]=\"50\"\n class=\"viewport table-viewport\"\n (scrolledIndexChange)=\"onScroll($event)\"\n >\n <div class=\"table-wrapper\">\n <table class=\"eru-grid-table\" [class.show-column-lines]=\"showColumnLines()\" [class.show-column-lines]=\"showColumnLines()\">\n <thead>\n <tr style=\"visibility:hidden;\">\n <th class=\"checkbox-column\"></th>\n <th *ngFor=\"let column of columns(); trackBy: trackByColumnFn\"\n [style.width.px]=\"column.field_size\"\n [style.minWidth.px]=\"column.field_size\"\n class=\"column-header\">\n {{column.label}}\n </th>\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\n *ngIf=\"groupItem.type === 'header'\"\n 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 <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'\" style=\"background:#fafafa\">\n <th class=\"checkbox-column\" style=\"text-align: center;\">\n <input\n type=\"checkbox\"\n [checked]=\"isGroupSelected(groupItem.group?.id || '')\"\n (click)=\"$event.stopPropagation()\"\n (change)=\"toggleGroupSelection($event, groupItem.group?.id || '')\"\n >\n </th>\n <th *ngFor=\"let column of columns(); trackBy: trackByColumnFn;let i =index\"\n style=\"text-align: center;\"\n [style.width.px]=\"column.field_size\"\n [style.minWidth.px]=\"column.field_size\"\n [resizeColumn]=\"true\"\n [columnConfig]=\"column\"\n [columnDraggable]=\"i\"\n class=\"column-header\">\n <div class=\"column-drag-handle\"></div>\n {{column.label}} {{column.symbol}}\n </th>\n </tr>\n <tr\n *ngIf=\"groupItem.type === 'row' && groupItem.group?.isExpanded\"\n class=\"row-item\"\n [attr.data-row-id]=\"groupItem.row?.entity_id\"\n [style.height.px]=\"30\"\n [style.minHeight.px]=\"30\"\n [style.maxHeight.px]=\"30\"\n >\n <td class=\"checkbox-column\" style=\"text-align: center;\">\n <input\n type=\"checkbox\"\n [checked]=\"isRowSelected(groupItem.row?.entity_id)\"\n (change)=\"toggleRowSelection($event, groupItem.row)\"\n >\n </td>\n <td #cell *ngFor=\"let column of columns(); trackBy: trackByColumnFn\"\n [style.width.px]=\"column.field_size\"\n [style.minWidth.px]=\"column.field_size\"\n class=\"data-cell\"\n [style.height.px]=\"30\"\n [style.minHeight.px]=\"30\"\n [style.maxHeight.px]=\"30\"\n [matTooltipClass]=\"'error-message'\"\n [matTooltip]=\"datacell.error()?'Error: ' + datacell.error():''\"\n matTooltipPosition=\"below\"\n >\n <div class=\"cell-content\">\n <data-cell\n #datacell \n [td]=cell\n [fieldSize]=\"column.field_size\"\n [columnDatatype]=\"column.datatype\"\n [columnName]=\"column.name\"\n [value]=\"groupItem.row?.[column.name] || ''\"\n [column]=\"column\"\n [mode]=\"mode()\"\n [isEditable]=\"isEditable()\"\n [drillable]=\"column.enableDrilldown || false\"\n [id]=\"groupItem.row?.['entity_id'] || '_' ||column.name\"\n ></data-cell>\n </div>\n </td>\n </tr>\n\n <tr\n *ngIf=\"groupItem.type === 'ghost-loading' && groupItem.group?.isExpanded\"\n class=\"ghost-loading-row\"\n [style.height.px]=\"30\"\n [style.minHeight.px]=\"30\"\n [style.maxHeight.px]=\"30\"\n >\n <td class=\"checkbox-column\"></td>\n <td *ngFor=\"let column of columns(); trackBy: trackByColumnFn\"\n [style.width.px]=\"column.field_size\"\n [style.minWidth.px]=\"column.field_size\"\n class=\"ghost-cell-container\"\n >\n <div class=\"ghost-cell\"></div>\n </td>\n </tr>\n\n <tr\n *ngIf=\"groupItem.type === 'row-place-holder'\"\n class=\"group-separator\"\n >\n <td [attr.colspan]=\"columns().length + 1\" 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\" \n [class.pivot-header-level]=\"'level-' + rowIndex\">\n @for (header of headerRow; track trackByHeaderFn($index, header); let colIndex = $index) {\n <th\n [attr.colspan]=\"header.colspan\"\n [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)\"\n [class.sticky-column]=\"isStickyColumn(header.name, colIndex)\"\n [class.expanded]=\"header.isExpanded\"\n [class.collapsed]=\"!header.isExpanded\"\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 <span class=\"header-label\">{{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\"\n [style.minWidth.px]=\"column.field_size\"\n [resizeColumn]=\"gridStore.isFeatureEnabled('columnResizable')\"\n [columnConfig]=\"column\"\n class=\"column-header pivot-column-header\"\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) ? 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 [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 \n 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\"\n [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\n [attr.rowspan]=\"getEffectiveRowspan(i, column.name)\" \n [style.width.px]=\"column.field_size\"\n [style.minWidth.px]=\"column.field_size\"\n 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\"\n [style.height.px]=\"50\"\n [attr.xx]=\"i\"> \n <div class=\"cell-content pivot-cell-content\">\n <data-cell\n [fieldSize]=\"column.field_size\"\n [columnDatatype]=\"column.datatype\"\n [columnName]=\"column.name\"\n [value]=\"getEffectiveCellValue(i,column.name, pivotRow)\"\n [column]=\"column\"\n [drillable]=\"column.enableDrilldown || false\"\n [mode]=\"mode()\"\n [isEditable]=\"isEditable()\"\n [id]=\"'pivot_' + i + '_' + column.name\">\n </data-cell>\n </div>\n </td>\n }\n </tr>\n}\n</tbody>\n</ng-template>\n", 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-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: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{height:calc(100% - 60px);width:100%;overflow-x:auto;overflow-y:auto;background-color:var(--grid-surface);scrollbar-gutter:stable}.pivot-viewport{height:calc(100% - 60px);width:100%;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-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;border:1px solid var(--grid-outline);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)}.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{position:relative;border-left:var(--grid-outline-width, 1px) solid var(--grid-outline, #e0e0e0);border-right:var(--grid-outline-width, 1px) solid var(--grid-outline, #e0e0e0);border-bottom:var(--grid-outline-width, 1px) solid var(--grid-outline, #e0e0e0)}.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}.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;min-height:500px;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;width:calc(100% - var(--scrollbar-width, 17px))!important;bottom:65px;z-index:1;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 .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 .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:400px!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}\n"] }]
|
|
4553
4580
|
}], ctorParameters: () => [{ type: i0.ChangeDetectorRef }], propDecorators: { viewport: [{
|
|
4554
4581
|
type: ViewChild,
|
|
4555
4582
|
args: [CdkVirtualScrollViewport]
|
|
4556
4583
|
}], rowContainer: [{
|
|
4557
4584
|
type: ViewChild,
|
|
4558
4585
|
args: ['rowContainer']
|
|
4586
|
+
}], headerScroller: [{
|
|
4587
|
+
type: ViewChild,
|
|
4588
|
+
args: ['headerScroller', { read: ElementRef }]
|
|
4589
|
+
}], gtScroller: [{
|
|
4590
|
+
type: ViewChild,
|
|
4591
|
+
args: ['gtScroller', { read: ElementRef }]
|
|
4592
|
+
}], vp: [{
|
|
4593
|
+
type: ViewChild,
|
|
4594
|
+
args: ['vp']
|
|
4559
4595
|
}] } });
|
|
4560
4596
|
|
|
4561
4597
|
class ThemeToggleComponent {
|
|
@@ -4608,7 +4644,7 @@ class ThemeToggleComponent {
|
|
|
4608
4644
|
<mat-icon *ngIf="isActiveTheme(theme.value)" class="check-icon">check</mat-icon>
|
|
4609
4645
|
</button>
|
|
4610
4646
|
</mat-menu>
|
|
4611
|
-
`, isInline: true, styles: [".theme-toggle-button{color:var(--grid-on-surface)}.theme-toggle-button:hover{background-color:var(--grid-surface-variant)}.active{background-color:var(--grid-primary-light);color:var(--grid-primary-color)}.check-icon{margin-left:auto;color:var(--grid-primary-color)}mat-menu-item{display:flex;align-items:center;gap:8px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type:
|
|
4647
|
+
`, isInline: true, styles: [".theme-toggle-button{color:var(--grid-on-surface)}.theme-toggle-button:hover{background-color:var(--grid-surface-variant)}.active{background-color:var(--grid-primary-light);color:var(--grid-primary-color)}.check-icon{margin-left:auto;color:var(--grid-primary-color)}mat-menu-item{display:flex;align-items:center;gap:8px}\n"], dependencies: [{ 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: "ngmodule", type: MatButtonModule }, { kind: "component", type: i4.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i3$2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatMenuModule }, { kind: "component", type: i4$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: i4$1.MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i4$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 });
|
|
4612
4648
|
}
|
|
4613
4649
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: ThemeToggleComponent, decorators: [{
|
|
4614
4650
|
type: Component,
|