ms-data-grid 0.0.89 → 0.0.91
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/esm2022/lib/data-grid/data-grid.component.mjs +252 -42
- package/esm2022/lib/services/common.service.mjs +2 -2
- package/esm2022/public-api.mjs +2 -2
- package/fesm2022/ms-data-grid.mjs +252 -42
- package/fesm2022/ms-data-grid.mjs.map +1 -1
- package/lib/data-grid/data-grid.component.d.ts +42 -2
- package/package.json +1 -1
- package/public-api.d.ts +0 -1
- package/esm2022/lib/interfaces/data-grid-config.ts.mjs +0 -2
- package/lib/interfaces/data-grid-config.ts.d.ts +0 -97
|
@@ -347,7 +347,7 @@ class CommonService {
|
|
|
347
347
|
col.query = {
|
|
348
348
|
first_value: null,
|
|
349
349
|
second_value: null,
|
|
350
|
-
first_condition: col.type !== 'date' && col.type !== 'number' ? 'contain' : 'equal',
|
|
350
|
+
first_condition: col.type !== 'date' && col.type !== 'number' && col.type !== 'time' ? 'contain' : 'equal',
|
|
351
351
|
second_condition: null,
|
|
352
352
|
condition: 'none',
|
|
353
353
|
_ids: []
|
|
@@ -1314,6 +1314,7 @@ class DataGridComponent {
|
|
|
1314
1314
|
this.showCheckboxes = true;
|
|
1315
1315
|
this.pageSizeOptions = [10, 25, 50, 75, 100, 150, 200, 250, 300, 500];
|
|
1316
1316
|
this.resetAllFilters = { resetAll: false };
|
|
1317
|
+
this.defaultConfig = null;
|
|
1317
1318
|
this.columnThreedotsMunuConfig = {
|
|
1318
1319
|
showPinleft: true,
|
|
1319
1320
|
showPinright: true,
|
|
@@ -1903,6 +1904,7 @@ class DataGridComponent {
|
|
|
1903
1904
|
// }
|
|
1904
1905
|
this.undoStack = [];
|
|
1905
1906
|
this.redoStack = [];
|
|
1907
|
+
this.pageSizeKeyMap = {};
|
|
1906
1908
|
// Hold expanded IDs (array for multiple, single value for single)
|
|
1907
1909
|
this.expandededDetailRows = '';
|
|
1908
1910
|
this.openIndex = null;
|
|
@@ -1945,6 +1947,7 @@ class DataGridComponent {
|
|
|
1945
1947
|
this.cdr.detectChanges();
|
|
1946
1948
|
});
|
|
1947
1949
|
this.renderCustomCells();
|
|
1950
|
+
this.buildPageSizeKeyMap();
|
|
1948
1951
|
}
|
|
1949
1952
|
createCellInjector(row, col) {
|
|
1950
1953
|
return Injector.create({
|
|
@@ -2166,6 +2169,15 @@ class DataGridComponent {
|
|
|
2166
2169
|
}
|
|
2167
2170
|
this.cdr.detectChanges();
|
|
2168
2171
|
}
|
|
2172
|
+
else if (this.defaultConfig) {
|
|
2173
|
+
this.rowShadingEnabled = this.defaultConfig.rowShadingEnabled;
|
|
2174
|
+
this.showVerticalBorder = this.defaultConfig.showVerticalBorder;
|
|
2175
|
+
this.fontFaimly = this.defaultConfig.fontFaimly;
|
|
2176
|
+
this.headerTextFontsSize = this.defaultConfig.headerTextFontsSize;
|
|
2177
|
+
this.selectedTableLayout = this.defaultConfig.selectedTableLayout;
|
|
2178
|
+
this.bodyTextFontsSize = this.defaultConfig.bodyTextFontsSize;
|
|
2179
|
+
this.globalSearchText = this.defaultConfig.globalSearch;
|
|
2180
|
+
}
|
|
2169
2181
|
else {
|
|
2170
2182
|
this.rowShadingEnabled = false;
|
|
2171
2183
|
this.showVerticalBorder = false;
|
|
@@ -2180,6 +2192,9 @@ class DataGridComponent {
|
|
|
2180
2192
|
this.cdr.detectChanges();
|
|
2181
2193
|
}, 0);
|
|
2182
2194
|
}
|
|
2195
|
+
if (changes['pageSizeOptions'] && changes['pageSizeOptions']?.currentValue) {
|
|
2196
|
+
this.buildPageSizeKeyMap();
|
|
2197
|
+
}
|
|
2183
2198
|
}
|
|
2184
2199
|
async setColumnsColumnDropdownValus() {
|
|
2185
2200
|
if (!this.columns)
|
|
@@ -2350,9 +2365,22 @@ class DataGridComponent {
|
|
|
2350
2365
|
columns: this.cleanColumns(this.columns),
|
|
2351
2366
|
filters: this.cleanFilterdColumns(),
|
|
2352
2367
|
no_of_records: this.paginationConfig.pageSize,
|
|
2368
|
+
table_config: {
|
|
2369
|
+
rowShadingEnabled: this.rowShadingEnabled,
|
|
2370
|
+
showVerticalBorder: this.showVerticalBorder,
|
|
2371
|
+
fontFaimly: this.fontFaimly,
|
|
2372
|
+
headerTextFontsSize: this.headerTextColor,
|
|
2373
|
+
selectedTableLayout: this.selectedTableLayout,
|
|
2374
|
+
bodyTextFontsSize: this.bodyTextFontsSize,
|
|
2375
|
+
globalSearch: this.globalSearchText,
|
|
2376
|
+
filterNames: '',
|
|
2377
|
+
totalCount: 0,
|
|
2378
|
+
activeFilters: true,
|
|
2379
|
+
oddRowsBackgroundColor: '#f1f1f1'
|
|
2380
|
+
},
|
|
2353
2381
|
type: this.tableType,
|
|
2354
2382
|
};
|
|
2355
|
-
this.createUpdateConfigListing.emit(
|
|
2383
|
+
this.createUpdateConfigListing.emit(this.createUpdateColumnConfig);
|
|
2356
2384
|
};
|
|
2357
2385
|
window.addEventListener('mousemove', onMouseMove);
|
|
2358
2386
|
window.addEventListener('mouseup', onMouseUp);
|
|
@@ -2371,6 +2399,27 @@ class DataGridComponent {
|
|
|
2371
2399
|
update(this.columns);
|
|
2372
2400
|
this.cdr.detectChanges();
|
|
2373
2401
|
}
|
|
2402
|
+
get createUpdateColumnConfig() {
|
|
2403
|
+
return {
|
|
2404
|
+
columns: this.cleanColumns(this.columns),
|
|
2405
|
+
filters: this.cleanFilterdColumns(),
|
|
2406
|
+
no_of_records: this.paginationConfig.pageSize,
|
|
2407
|
+
table_config: {
|
|
2408
|
+
rowShadingEnabled: this.rowShadingEnabled,
|
|
2409
|
+
showVerticalBorder: this.showVerticalBorder,
|
|
2410
|
+
fontFaimly: this.fontFaimly,
|
|
2411
|
+
headerTextFontsSize: Number(this.headerTextFontsSize),
|
|
2412
|
+
selectedTableLayout: this.selectedTableLayout,
|
|
2413
|
+
bodyTextFontsSize: Number(this.bodyTextFontsSize),
|
|
2414
|
+
globalSearch: this.globalSearchText,
|
|
2415
|
+
filterNames: '',
|
|
2416
|
+
totalCount: 0,
|
|
2417
|
+
activeFilters: true,
|
|
2418
|
+
oddRowsBackgroundColor: '#f1f1f1'
|
|
2419
|
+
},
|
|
2420
|
+
type: this.tableType,
|
|
2421
|
+
};
|
|
2422
|
+
}
|
|
2374
2423
|
cleanColumns(columns) {
|
|
2375
2424
|
return columns.map((col) => {
|
|
2376
2425
|
const { __typename, _id, column_dropdown_value, filterValue, expandedFilter, query, isRowGrouped, ...rest } = col;
|
|
@@ -2440,7 +2489,7 @@ class DataGridComponent {
|
|
|
2440
2489
|
no_of_records: this.paginationConfig.pageSize,
|
|
2441
2490
|
type: this.tableType,
|
|
2442
2491
|
};
|
|
2443
|
-
this.createUpdateConfigListing.emit(
|
|
2492
|
+
this.createUpdateConfigListing.emit(this.createUpdateColumnConfig);
|
|
2444
2493
|
matchingEls.forEach((el) => {
|
|
2445
2494
|
el.classList.remove('resizing-highlight');
|
|
2446
2495
|
el.classList.remove('resizing-highlight-right');
|
|
@@ -2646,7 +2695,7 @@ class DataGridComponent {
|
|
|
2646
2695
|
no_of_records: this.paginationConfig.pageSize,
|
|
2647
2696
|
type: this.tableType,
|
|
2648
2697
|
};
|
|
2649
|
-
this.createUpdateConfigListing.emit(
|
|
2698
|
+
this.createUpdateConfigListing.emit(this.createUpdateColumnConfig);
|
|
2650
2699
|
}
|
|
2651
2700
|
autosizeColumn(cols) {
|
|
2652
2701
|
this.activeCol = null;
|
|
@@ -2681,7 +2730,7 @@ class DataGridComponent {
|
|
|
2681
2730
|
no_of_records: this.paginationConfig.pageSize,
|
|
2682
2731
|
type: this.tableType,
|
|
2683
2732
|
};
|
|
2684
|
-
this.createUpdateConfigListing.emit(
|
|
2733
|
+
this.createUpdateConfigListing.emit(this.createUpdateColumnConfig);
|
|
2685
2734
|
}, 1000);
|
|
2686
2735
|
this.refreshPreviewColumns();
|
|
2687
2736
|
}
|
|
@@ -2732,7 +2781,7 @@ class DataGridComponent {
|
|
|
2732
2781
|
no_of_records: this.paginationConfig.pageSize,
|
|
2733
2782
|
type: this.tableType,
|
|
2734
2783
|
};
|
|
2735
|
-
this.createUpdateConfigListing.emit(
|
|
2784
|
+
this.createUpdateConfigListing.emit(this.createUpdateColumnConfig);
|
|
2736
2785
|
}, 1000);
|
|
2737
2786
|
}
|
|
2738
2787
|
markColumnAsGrouped(columns, field) {
|
|
@@ -2924,7 +2973,7 @@ class DataGridComponent {
|
|
|
2924
2973
|
no_of_records: this.paginationConfig.pageSize,
|
|
2925
2974
|
type: this.tableType,
|
|
2926
2975
|
};
|
|
2927
|
-
this.createUpdateConfigListing.emit(
|
|
2976
|
+
this.createUpdateConfigListing.emit(this.createUpdateColumnConfig);
|
|
2928
2977
|
setTimeout(() => {
|
|
2929
2978
|
this.updateColumnWidthsAndGroups();
|
|
2930
2979
|
this.refreshPreviewColumns();
|
|
@@ -2979,7 +3028,7 @@ class DataGridComponent {
|
|
|
2979
3028
|
no_of_records: this.paginationConfig.pageSize,
|
|
2980
3029
|
type: this.tableType,
|
|
2981
3030
|
};
|
|
2982
|
-
this.createUpdateConfigListing.emit(
|
|
3031
|
+
this.createUpdateConfigListing.emit(this.createUpdateColumnConfig);
|
|
2983
3032
|
if (this.tableFilterViewId) {
|
|
2984
3033
|
this.savePreset('mouseUp');
|
|
2985
3034
|
}
|
|
@@ -3023,7 +3072,7 @@ class DataGridComponent {
|
|
|
3023
3072
|
no_of_records: this.paginationConfig.pageSize,
|
|
3024
3073
|
type: this.tableType,
|
|
3025
3074
|
};
|
|
3026
|
-
this.createUpdateConfigListing.emit(
|
|
3075
|
+
this.createUpdateConfigListing.emit(this.createUpdateColumnConfig);
|
|
3027
3076
|
}
|
|
3028
3077
|
finally {
|
|
3029
3078
|
this.loading = false;
|
|
@@ -3194,7 +3243,7 @@ class DataGridComponent {
|
|
|
3194
3243
|
no_of_records: this.paginationConfig.pageSize,
|
|
3195
3244
|
type: this.tableType,
|
|
3196
3245
|
};
|
|
3197
|
-
this.createUpdateConfigListing.emit(
|
|
3246
|
+
this.createUpdateConfigListing.emit(this.createUpdateColumnConfig);
|
|
3198
3247
|
}, 400);
|
|
3199
3248
|
}
|
|
3200
3249
|
async refreshHeaders() {
|
|
@@ -3561,7 +3610,7 @@ class DataGridComponent {
|
|
|
3561
3610
|
no_of_records: this.paginationConfig.pageSize,
|
|
3562
3611
|
type: this.tableType,
|
|
3563
3612
|
};
|
|
3564
|
-
this.createUpdateConfigListing.emit(
|
|
3613
|
+
this.createUpdateConfigListing.emit(this.createUpdateColumnConfig);
|
|
3565
3614
|
this.cdr.detectChanges();
|
|
3566
3615
|
}
|
|
3567
3616
|
deepCloneColumns(columns) {
|
|
@@ -3683,7 +3732,7 @@ class DataGridComponent {
|
|
|
3683
3732
|
no_of_records: this.paginationConfig.pageSize,
|
|
3684
3733
|
type: this.tableType,
|
|
3685
3734
|
};
|
|
3686
|
-
this.createUpdateConfigListing.emit(
|
|
3735
|
+
this.createUpdateConfigListing.emit(this.createUpdateColumnConfig);
|
|
3687
3736
|
setTimeout(() => {
|
|
3688
3737
|
this.cdr.detectChanges();
|
|
3689
3738
|
}, 2);
|
|
@@ -3809,6 +3858,7 @@ class DataGridComponent {
|
|
|
3809
3858
|
this.bodyTextFontsSize = this.bodyTextFontsSize || 16;
|
|
3810
3859
|
this.headerTextFontsSize = this.headerTextFontsSize || 16;
|
|
3811
3860
|
}
|
|
3861
|
+
// this.createUpdateConfigListing.emit(this.createUpdateColumnConfig);
|
|
3812
3862
|
}
|
|
3813
3863
|
get startIndexData() {
|
|
3814
3864
|
return (this.paginationConfig.page - 1) * this.paginationConfig.limit;
|
|
@@ -3868,11 +3918,11 @@ class DataGridComponent {
|
|
|
3868
3918
|
}
|
|
3869
3919
|
}, 100);
|
|
3870
3920
|
}
|
|
3871
|
-
else if (['string', 'number', 'date'].includes(col.type)) {
|
|
3872
|
-
this.firstCondition = col.query.first_condition ? col.query.first_condition : ((col.type == 'date' || col.type == 'number') ? 'equal' : 'contain');
|
|
3921
|
+
else if (['string', 'number', 'date', 'time'].includes(col.type)) {
|
|
3922
|
+
this.firstCondition = col.query.first_condition ? col.query.first_condition : ((col.type == 'date' || col.type == 'time' || col.type == 'number') ? 'equal' : 'contain');
|
|
3873
3923
|
this.firstValue = col?.query?.first_value || '';
|
|
3874
3924
|
this.condition = col?.query?.condition || 'none';
|
|
3875
|
-
this.secondCondition = col.query.first_condition ? col.query.first_condition : ((col.type == 'date' || col.type == 'number') ? 'equal' : 'contain');
|
|
3925
|
+
this.secondCondition = col.query.first_condition ? col.query.first_condition : ((col.type == 'date' || col.type == 'time' || col.type == 'number') ? 'equal' : 'contain');
|
|
3876
3926
|
this.secondValue = col?.query?.second_value || '';
|
|
3877
3927
|
setTimeout(() => {
|
|
3878
3928
|
this.filterMenueTextchInput.nativeElement.focus();
|
|
@@ -3900,11 +3950,11 @@ class DataGridComponent {
|
|
|
3900
3950
|
savedIds.forEach((id) => this.currentFilterSelectedIds.add(id));
|
|
3901
3951
|
this.selectedFilterOptions = this.selectedColumnForFilter?.column_dropdown_value?.filter((option) => this.currentFilterSelectedIds.has(option?.id || option?._id || option));
|
|
3902
3952
|
}
|
|
3903
|
-
else if (['string', 'number', 'date'].includes(col.type)) {
|
|
3904
|
-
this.firstCondition = col?.query?.first_condition || (col.type == 'number' || col.type == 'date') ? 'equal' : 'contain';
|
|
3953
|
+
else if (['string', 'number', 'date', 'time'].includes(col.type)) {
|
|
3954
|
+
this.firstCondition = col?.query?.first_condition || (col.type == 'number' || col.type == 'time' || col.type == 'date') ? 'equal' : 'contain';
|
|
3905
3955
|
this.firstValue = col?.query?.first_value || '';
|
|
3906
3956
|
this.condition = col?.query?.condition || 'none';
|
|
3907
|
-
this.secondCondition = col?.query?.second_condition || (col.type == 'number' || col.type == 'date') ? 'equal' : 'contain';
|
|
3957
|
+
this.secondCondition = col?.query?.second_condition || (col.type == 'number' || col.type == 'time' || col.type == 'date') ? 'equal' : 'contain';
|
|
3908
3958
|
this.secondValue = col?.query?.second_value || '';
|
|
3909
3959
|
}
|
|
3910
3960
|
this.cdr.detectChanges();
|
|
@@ -3975,7 +4025,7 @@ class DataGridComponent {
|
|
|
3975
4025
|
}
|
|
3976
4026
|
});
|
|
3977
4027
|
}
|
|
3978
|
-
else if (['string', 'number', 'date'].includes(column.type)) {
|
|
4028
|
+
else if (['string', 'number', 'date', 'time'].includes(column.type)) {
|
|
3979
4029
|
column.query = {
|
|
3980
4030
|
first_condition: this.firstCondition || 'contain',
|
|
3981
4031
|
first_value: this.firstValue || null,
|
|
@@ -4011,7 +4061,7 @@ class DataGridComponent {
|
|
|
4011
4061
|
no_of_records: Number(this.paginationConfig.limit),
|
|
4012
4062
|
type: this.tableType,
|
|
4013
4063
|
};
|
|
4014
|
-
this.createUpdateConfigListing.emit(
|
|
4064
|
+
this.createUpdateConfigListing.emit(this.createUpdateColumnConfig);
|
|
4015
4065
|
const filters = this.cleanFilterdColumns();
|
|
4016
4066
|
setTimeout(() => {
|
|
4017
4067
|
this.commonSevice.mainContainerLeft = this.centerScrollableBody.nativeElement.scrollLeft;
|
|
@@ -4104,14 +4154,14 @@ class DataGridComponent {
|
|
|
4104
4154
|
no_of_records: Number(this.paginationConfig.limit),
|
|
4105
4155
|
type: this.tableType,
|
|
4106
4156
|
};
|
|
4107
|
-
this.createUpdateConfigListing.emit(
|
|
4157
|
+
this.createUpdateConfigListing.emit(this.createUpdateColumnConfig);
|
|
4108
4158
|
const filters = this.cleanFilterdColumns();
|
|
4109
4159
|
setTimeout(() => {
|
|
4110
4160
|
this.commonSevice.mainContainerLeft = this.centerScrollableBody.nativeElement.scrollLeft;
|
|
4111
4161
|
this.filterOptions.emit(filters);
|
|
4112
4162
|
}, 200);
|
|
4113
4163
|
}
|
|
4114
|
-
clearAllFilters() {
|
|
4164
|
+
clearAllFilters(shouldUpdateConfigListing = false) {
|
|
4115
4165
|
this.groupedColumns = [];
|
|
4116
4166
|
this.tableView?.forEach((ele) => { ele.is_temp = false; });
|
|
4117
4167
|
const resetAllRecursively = (columns) => {
|
|
@@ -4136,13 +4186,13 @@ class DataGridComponent {
|
|
|
4136
4186
|
this.filtersConfig = [];
|
|
4137
4187
|
this.refreshPreviewColumns();
|
|
4138
4188
|
this.cdr.detectChanges();
|
|
4139
|
-
this.rowShadingEnabled = false;
|
|
4140
|
-
this.showVerticalBorder = false;
|
|
4141
|
-
this.fontFaimly = 'Inter';
|
|
4142
|
-
this.headerTextFontsSize = 14;
|
|
4143
|
-
this.selectedTableLayout = 'mediumd';
|
|
4144
|
-
this.bodyTextFontsSize = 14;
|
|
4145
|
-
this.globalSearchText = '';
|
|
4189
|
+
// this.rowShadingEnabled = false;
|
|
4190
|
+
// this.showVerticalBorder = false;
|
|
4191
|
+
// this.fontFaimly = 'Inter';
|
|
4192
|
+
// this.headerTextFontsSize = 14;
|
|
4193
|
+
// this.selectedTableLayout = 'mediumd';
|
|
4194
|
+
// this.bodyTextFontsSize = 14;
|
|
4195
|
+
// this.globalSearchText = '';
|
|
4146
4196
|
const event = { eventType: 'reset', data: { tableType: this.tableType } };
|
|
4147
4197
|
const sendData = {
|
|
4148
4198
|
columns: this.cleanColumns(this.columns),
|
|
@@ -4150,13 +4200,17 @@ class DataGridComponent {
|
|
|
4150
4200
|
no_of_records: Number(this.paginationConfig.limit),
|
|
4151
4201
|
type: this.tableType,
|
|
4152
4202
|
};
|
|
4153
|
-
|
|
4203
|
+
if (!shouldUpdateConfigListing) {
|
|
4204
|
+
this.createUpdateConfigListing.emit(this.createUpdateColumnConfig);
|
|
4205
|
+
}
|
|
4154
4206
|
this.commonSevice.mainContainerLeft = this.centerScrollableBody.nativeElement.scrollLeft;
|
|
4155
4207
|
this.commonSevice.mainContainerLeft = this.centerScrollableBody.nativeElement.scrollLeft;
|
|
4156
4208
|
setTimeout(() => {
|
|
4157
4209
|
const filteredColumns = this.cleanFilterdColumns();
|
|
4158
4210
|
this.genericEvent.emit(event);
|
|
4159
|
-
|
|
4211
|
+
if (!shouldUpdateConfigListing) {
|
|
4212
|
+
this.filterOptions.emit(filteredColumns);
|
|
4213
|
+
}
|
|
4160
4214
|
}, 300);
|
|
4161
4215
|
this.cdr.detectChanges();
|
|
4162
4216
|
}
|
|
@@ -4193,7 +4247,7 @@ class DataGridComponent {
|
|
|
4193
4247
|
no_of_records: Number(this.paginationConfig.limit),
|
|
4194
4248
|
type: this.tableType,
|
|
4195
4249
|
};
|
|
4196
|
-
this.createUpdateConfigListing.emit(
|
|
4250
|
+
this.createUpdateConfigListing.emit(this.createUpdateColumnConfig);
|
|
4197
4251
|
this.commonSevice.mainContainerLeft = this.centerScrollableBody.nativeElement.scrollLeft;
|
|
4198
4252
|
setTimeout(() => {
|
|
4199
4253
|
const filteredColumns = this.cleanFilterdColumns();
|
|
@@ -4221,7 +4275,7 @@ class DataGridComponent {
|
|
|
4221
4275
|
no_of_records: Number(this.paginationConfig.limit),
|
|
4222
4276
|
type: this.tableType,
|
|
4223
4277
|
};
|
|
4224
|
-
this.createUpdateConfigListing.emit(
|
|
4278
|
+
this.createUpdateConfigListing.emit(this.createUpdateColumnConfig);
|
|
4225
4279
|
this.commonSevice.mainContainerLeft = this.centerScrollableBody.nativeElement.scrollLeft;
|
|
4226
4280
|
setTimeout(() => {
|
|
4227
4281
|
const filteredColumns = this.cleanFilterdColumns();
|
|
@@ -4414,7 +4468,7 @@ class DataGridComponent {
|
|
|
4414
4468
|
no_of_records: Number(this.paginationConfig.limit),
|
|
4415
4469
|
type: this.tableType,
|
|
4416
4470
|
};
|
|
4417
|
-
this.createUpdateConfigListing.emit(
|
|
4471
|
+
this.createUpdateConfigListing.emit(this.createUpdateColumnConfig);
|
|
4418
4472
|
setTimeout(() => {
|
|
4419
4473
|
const event = {
|
|
4420
4474
|
obj: {
|
|
@@ -4567,7 +4621,7 @@ class DataGridComponent {
|
|
|
4567
4621
|
no_of_records: Number(this.paginationConfig.limit),
|
|
4568
4622
|
type: this.tableType,
|
|
4569
4623
|
};
|
|
4570
|
-
this.createUpdateConfigListing.emit(
|
|
4624
|
+
this.createUpdateConfigListing.emit(this.createUpdateColumnConfig);
|
|
4571
4625
|
setTimeout(() => {
|
|
4572
4626
|
this.genericEvent.emit(event);
|
|
4573
4627
|
}, 500);
|
|
@@ -4778,8 +4832,8 @@ class DataGridComponent {
|
|
|
4778
4832
|
// || text == 'sync' || text == 'unsync' || text == 'backup' || text == 'restore backup' || text == 'migrate' || text == 'import' || text == 'export' || text == 'generate report' || text == 'download report' || text == 'view details'
|
|
4779
4833
|
// || text == 'edit details' || text == 'update details' || text == 'change status' || text == 'reset password' || text == 'send notification' || text == 'schedule' || text == 'reschedule' || text == 'cancel schedule' || text == 'start' || text == 'stop' || text == 'pause' || text == 'resume'
|
|
4780
4834
|
) {
|
|
4781
|
-
this.clearSelectionState(this.tableType);
|
|
4782
|
-
this.selectedRows.clear();
|
|
4835
|
+
// this.clearSelectionState(this.tableType);
|
|
4836
|
+
// this.selectedRows.clear();
|
|
4783
4837
|
}
|
|
4784
4838
|
const idsArray = Array.from(this.selectedRows);
|
|
4785
4839
|
const arrayOfObjectsWithTableType = [];
|
|
@@ -4861,7 +4915,7 @@ class DataGridComponent {
|
|
|
4861
4915
|
no_of_records: Number(this.paginationConfig.limit),
|
|
4862
4916
|
type: this.tableType,
|
|
4863
4917
|
};
|
|
4864
|
-
this.createUpdateConfigListing.emit(
|
|
4918
|
+
this.createUpdateConfigListing.emit(this.createUpdateColumnConfig);
|
|
4865
4919
|
setTimeout(() => {
|
|
4866
4920
|
const filteredColumns = cleanedFilteredColumns;
|
|
4867
4921
|
this.filterOptions.emit(filteredColumns);
|
|
@@ -4883,7 +4937,7 @@ class DataGridComponent {
|
|
|
4883
4937
|
no_of_records: this.paginationConfig.pageSize,
|
|
4884
4938
|
type: this.tableType,
|
|
4885
4939
|
};
|
|
4886
|
-
this.createUpdateConfigListing.emit(
|
|
4940
|
+
this.createUpdateConfigListing.emit(this.createUpdateColumnConfig);
|
|
4887
4941
|
}
|
|
4888
4942
|
cleanFilterdColumns() {
|
|
4889
4943
|
const filteredColumns = this.commonSevice.getFiltersFromColumns(this.columns, this.filtersConfig);
|
|
@@ -4949,6 +5003,7 @@ class DataGridComponent {
|
|
|
4949
5003
|
eventType: 'config'
|
|
4950
5004
|
};
|
|
4951
5005
|
this.genericEvent.emit(event);
|
|
5006
|
+
this.createUpdateConfigListing.emit(this.createUpdateColumnConfig);
|
|
4952
5007
|
}
|
|
4953
5008
|
onGlobalSearch() {
|
|
4954
5009
|
const event = {
|
|
@@ -4961,6 +5016,7 @@ class DataGridComponent {
|
|
|
4961
5016
|
if (this.tableFilterViewId) {
|
|
4962
5017
|
this.savePreset('mouseUp');
|
|
4963
5018
|
}
|
|
5019
|
+
this.createUpdateConfigListing.emit(this.createUpdateColumnConfig);
|
|
4964
5020
|
}
|
|
4965
5021
|
onSearchInput(event) {
|
|
4966
5022
|
const value = event.target.value;
|
|
@@ -5358,13 +5414,138 @@ class DataGridComponent {
|
|
|
5358
5414
|
getSelectedDataForCopy() {
|
|
5359
5415
|
return this.copyService.getSelectedDataForCopy(this.dataSet, this.columns, this.rowSelectedIndexes, this.selectedCells, this.getNestedValue.bind(this));
|
|
5360
5416
|
}
|
|
5417
|
+
buildPageSizeKeyMap() {
|
|
5418
|
+
this.pageSizeKeyMap = {};
|
|
5419
|
+
this.pageSizeOptions.forEach((size, index) => {
|
|
5420
|
+
// Keys: 1–9, then 0 for 10th item
|
|
5421
|
+
const key = index < 9
|
|
5422
|
+
? String(index + 1)
|
|
5423
|
+
: index === 9
|
|
5424
|
+
? '0'
|
|
5425
|
+
: null;
|
|
5426
|
+
if (key) {
|
|
5427
|
+
this.pageSizeKeyMap[key] = size;
|
|
5428
|
+
}
|
|
5429
|
+
});
|
|
5430
|
+
}
|
|
5361
5431
|
onKeyDown(event) {
|
|
5362
5432
|
const target = event.target;
|
|
5363
5433
|
const isFormField = target.tagName === 'INPUT' ||
|
|
5364
5434
|
target.tagName === 'TEXTAREA' ||
|
|
5365
5435
|
target.isContentEditable;
|
|
5366
|
-
if (isFormField)
|
|
5436
|
+
if (isFormField || this.loading)
|
|
5437
|
+
return;
|
|
5438
|
+
if ((event.ctrlKey || event.metaKey) && !event.shiftKey && event.key === 'ArrowRight') {
|
|
5439
|
+
event.preventDefault();
|
|
5440
|
+
this.goToNextPage();
|
|
5441
|
+
return;
|
|
5442
|
+
}
|
|
5443
|
+
// Ctrl + Arrow Left → Previous Page
|
|
5444
|
+
if ((event.ctrlKey || event.metaKey) && !event.shiftKey && event.key === 'ArrowLeft') {
|
|
5445
|
+
event.preventDefault();
|
|
5446
|
+
this.goToPreviousPage();
|
|
5447
|
+
return;
|
|
5448
|
+
}
|
|
5449
|
+
// Ctrl + Shift + Arrow Right → Last Page
|
|
5450
|
+
if ((event.ctrlKey || event.metaKey) && event.shiftKey && event.key === 'ArrowRight') {
|
|
5451
|
+
event.preventDefault();
|
|
5452
|
+
this.goToLastPage();
|
|
5453
|
+
return;
|
|
5454
|
+
}
|
|
5455
|
+
// Ctrl + Shift + Arrow Left → First Page
|
|
5456
|
+
if ((event.ctrlKey || event.metaKey) && event.shiftKey && event.key === 'ArrowLeft') {
|
|
5457
|
+
event.preventDefault();
|
|
5458
|
+
this.goToFirstPage();
|
|
5459
|
+
return;
|
|
5460
|
+
}
|
|
5461
|
+
// Ctrl + Shift + Arrow Right → Last Page
|
|
5462
|
+
const MIN_HEIGHT = 28;
|
|
5463
|
+
if ((event.ctrlKey || event.metaKey) && event.shiftKey && event.key === 'ArrowUp') {
|
|
5464
|
+
event.preventDefault();
|
|
5465
|
+
this.headerRowHeight += 1;
|
|
5466
|
+
this.rowHeight += 1;
|
|
5467
|
+
return;
|
|
5468
|
+
}
|
|
5469
|
+
// Ctrl + Shift + Arrow Right → Last Page
|
|
5470
|
+
if ((event.ctrlKey || event.metaKey) && event.shiftKey && event.key === 'ArrowDown') {
|
|
5471
|
+
event.preventDefault();
|
|
5472
|
+
this.headerRowHeight = Math.max(MIN_HEIGHT, this.headerRowHeight - 1);
|
|
5473
|
+
this.rowHeight = Math.max(MIN_HEIGHT, this.rowHeight - 1);
|
|
5474
|
+
return;
|
|
5475
|
+
}
|
|
5476
|
+
if ((event.ctrlKey || event.metaKey) && event.key === '/') {
|
|
5477
|
+
event.preventDefault();
|
|
5478
|
+
if (this.globalSearchInput) {
|
|
5479
|
+
const inputEl = this.globalSearchInput.nativeElement;
|
|
5480
|
+
inputEl.focus();
|
|
5481
|
+
const originalOutline = inputEl.style.outline;
|
|
5482
|
+
const originalBoxShadow = inputEl.style.boxShadow;
|
|
5483
|
+
inputEl.style.setProperty('outline', '2px solid #4f9cff', 'important');
|
|
5484
|
+
inputEl.style.setProperty('box-shadow', '0 0 8px 2px #4f9cff', 'important');
|
|
5485
|
+
setTimeout(() => {
|
|
5486
|
+
inputEl.style.setProperty('outline', originalOutline || '', 'important');
|
|
5487
|
+
inputEl.style.setProperty('box-shadow', originalBoxShadow || '', 'important');
|
|
5488
|
+
}, 1000);
|
|
5489
|
+
}
|
|
5490
|
+
return;
|
|
5491
|
+
}
|
|
5492
|
+
if (event.ctrlKey && event.altKey && event.key.toLowerCase() === 'r') {
|
|
5493
|
+
event.preventDefault();
|
|
5494
|
+
this.autosizeAllColumns();
|
|
5495
|
+
return;
|
|
5496
|
+
}
|
|
5497
|
+
if (event.altKey && event.key?.toLocaleLowerCase() === 'r') {
|
|
5498
|
+
event.preventDefault();
|
|
5499
|
+
this.autoSizeColumnsByRatio();
|
|
5500
|
+
return;
|
|
5501
|
+
}
|
|
5502
|
+
if ((event.ctrlKey || event.metaKey) && event.shiftKey && event.key.toLowerCase() === 'c') {
|
|
5503
|
+
event.preventDefault();
|
|
5504
|
+
this.downloadCsv('csv');
|
|
5505
|
+
return;
|
|
5506
|
+
}
|
|
5507
|
+
if ((event.ctrlKey || event.metaKey) && event.shiftKey && event.key.toLowerCase() === 'e') {
|
|
5508
|
+
event.preventDefault();
|
|
5509
|
+
this.downloadCsv('xlsx');
|
|
5510
|
+
return;
|
|
5511
|
+
}
|
|
5512
|
+
if ((event.ctrlKey || event.metaKey) && event.shiftKey && event.key.toLowerCase() === 'b') {
|
|
5513
|
+
event.preventDefault();
|
|
5514
|
+
this.showVerticalBorder = !this.showVerticalBorder;
|
|
5515
|
+
this.onFontChange();
|
|
5516
|
+
return;
|
|
5517
|
+
}
|
|
5518
|
+
if ((event.ctrlKey || event.metaKey) && event.shiftKey && event.key.toLowerCase() === 'h') {
|
|
5519
|
+
event.preventDefault();
|
|
5520
|
+
this.rowShadingEnabled = !this.rowShadingEnabled;
|
|
5521
|
+
this.onFontChange();
|
|
5522
|
+
return;
|
|
5523
|
+
}
|
|
5524
|
+
if ((event.ctrlKey || event.metaKey) && event.shiftKey && event.key.toLowerCase() === 's') {
|
|
5525
|
+
event.preventDefault();
|
|
5526
|
+
this.setTableLayout('small');
|
|
5527
|
+
return;
|
|
5528
|
+
}
|
|
5529
|
+
if ((event.ctrlKey || event.metaKey) && event.shiftKey && event.key.toLowerCase() === 'm') {
|
|
5530
|
+
event.preventDefault();
|
|
5531
|
+
this.setTableLayout('medium');
|
|
5367
5532
|
return;
|
|
5533
|
+
}
|
|
5534
|
+
if ((event.ctrlKey || event.metaKey) && event.shiftKey && event.key.toLowerCase() === 'l') {
|
|
5535
|
+
event.preventDefault();
|
|
5536
|
+
this.setTableLayout('large');
|
|
5537
|
+
return;
|
|
5538
|
+
}
|
|
5539
|
+
if (event.altKey) {
|
|
5540
|
+
const newLimit = this.pageSizeKeyMap[event.key];
|
|
5541
|
+
if (newLimit) {
|
|
5542
|
+
event.preventDefault();
|
|
5543
|
+
if (this.paginationConfig.limit !== newLimit) {
|
|
5544
|
+
this.paginationConfig.limit = newLimit;
|
|
5545
|
+
this.onPageSizeChange();
|
|
5546
|
+
}
|
|
5547
|
+
}
|
|
5548
|
+
}
|
|
5368
5549
|
const tableContainer = document.querySelector('.data-grid-body-wrapper');
|
|
5369
5550
|
if (tableContainer && !tableContainer.contains(target))
|
|
5370
5551
|
return;
|
|
@@ -5400,6 +5581,30 @@ class DataGridComponent {
|
|
|
5400
5581
|
this.selectAllCells();
|
|
5401
5582
|
}
|
|
5402
5583
|
}
|
|
5584
|
+
goToNextPage() {
|
|
5585
|
+
const currentPage = this.paginationConfig.page;
|
|
5586
|
+
const totalPages = this.paginationConfig.totalPages;
|
|
5587
|
+
if (currentPage >= totalPages)
|
|
5588
|
+
return;
|
|
5589
|
+
this.goToPage(currentPage + 1);
|
|
5590
|
+
}
|
|
5591
|
+
goToPreviousPage() {
|
|
5592
|
+
const currentPage = this.paginationConfig.page;
|
|
5593
|
+
if (currentPage <= 1)
|
|
5594
|
+
return;
|
|
5595
|
+
this.goToPage(currentPage - 1);
|
|
5596
|
+
}
|
|
5597
|
+
goToFirstPage() {
|
|
5598
|
+
if (this.paginationConfig.page === 1)
|
|
5599
|
+
return;
|
|
5600
|
+
this.goToPage(1);
|
|
5601
|
+
}
|
|
5602
|
+
goToLastPage() {
|
|
5603
|
+
const lastPage = this.paginationConfig.totalPages;
|
|
5604
|
+
if (this.paginationConfig.page === lastPage)
|
|
5605
|
+
return;
|
|
5606
|
+
this.goToPage(lastPage);
|
|
5607
|
+
}
|
|
5403
5608
|
selectAllCells() {
|
|
5404
5609
|
this.selectedCells = [];
|
|
5405
5610
|
this.selectedKeys.clear();
|
|
@@ -6124,7 +6329,7 @@ class DataGridComponent {
|
|
|
6124
6329
|
}, 0);
|
|
6125
6330
|
}
|
|
6126
6331
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DataGridComponent, deps: [{ token: SplitColumnsService }, { token: i0.ChangeDetectorRef }, { token: CommonService }, { token: i0.ElementRef }, { token: i0.NgZone }, { token: CopyServiceService }, { token: i0.Renderer2 }, { token: i4.DomSanitizer }, { token: ExportService }, { token: i6.DatePipe }, { token: FormatCurrencyPipe }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
6127
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: DataGridComponent, selector: "data-grid", inputs: { rowAnimation: "rowAnimation", paginationConfig: "paginationConfig", dataSet: "dataSet", columns: "columns", rowHeight: "rowHeight", headerRowHeight: "headerRowHeight", showVerticalBorder: "showVerticalBorder", evenRowsBackgroundColor: "evenRowsBackgroundColor", oddRowsBackgroundColor: "oddRowsBackgroundColor", headerBackgroundColor: "headerBackgroundColor", checkboxesBackgroundColor: "checkboxesBackgroundColor", showColumnsGrouping: "showColumnsGrouping", rowHoverColor: "rowHoverColor", leftPinnedBackgroundColor: "leftPinnedBackgroundColor", bodyBackgroundColor: "bodyBackgroundColor", rightPinnedBackgroundColor: "rightPinnedBackgroundColor", sidemenuBackgroundColor: "sidemenuBackgroundColor", bodyTextColor: "bodyTextColor", headerTextColor: "headerTextColor", checkboxesColor: "checkboxesColor", headerTextFontsSize: "headerTextFontsSize", bodyTextFontsSize: "bodyTextFontsSize", headerFontWeight: "headerFontWeight", bodyFontWeight: "bodyFontWeight", checkedRowBackgroundColor: "checkedRowBackgroundColor", dropdownsBackgroundColor: "dropdownsBackgroundColor", footerRowBackgroundColor: "footerRowBackgroundColor", footerRowHeight: "footerRowHeight", topGroupedBadgesBackgroundColor: "topGroupedBadgesBackgroundColor", showRowsGrouping: "showRowsGrouping", showFilterRow: "showFilterRow", fontFaimly: "fontFaimly", showSideMenu: "showSideMenu", footerPadding: "footerPadding", topFilterRowHeight: "topFilterRowHeight", rowShadingEnabled: "rowShadingEnabled", showSerialNumber: "showSerialNumber", singleSpaAssetsPath: "singleSpaAssetsPath", filtersConfig: "filtersConfig", loading: "loading", verticalScrollbarWidth: "verticalScrollbarWidth", horizintalScrollbarWidth: "horizintalScrollbarWidth", showCellDetailsBox: "showCellDetailsBox", dateFormat: "dateFormat", tableSearch: "tableSearch", actions: "actions", config: "config", showTaskbar: "showTaskbar", tableName: "tableName", listingType: "listingType", checkboxState: "checkboxState", taskbarActions: "taskbarActions", sortingConfig: "sortingConfig", tableFilterViewId: "tableFilterViewId", selectedTableLayout: "selectedTableLayout", closeDropdown: "closeDropdown", globalSearchText: "globalSearchText", nestedTablerowFontsize: "nestedTablerowFontsize", nestedTableHeaderRowHeight: "nestedTableHeaderRowHeight", nestedTablerowHeight: "nestedTablerowHeight", gridType: "gridType", currencySymbol: "currencySymbol", currencyFormat: "currencyFormat", leftPinnedBoxshadow: "leftPinnedBoxshadow", rightPinnedBoxshadow: "rightPinnedBoxshadow", selectedRowsBackgroundColor: "selectedRowsBackgroundColor", nestedTableHeaderBackgroundColor: "nestedTableHeaderBackgroundColor", nestedTableRowBackgroundColor: "nestedTableRowBackgroundColor", tableView: "tableView", buttons: "buttons", keepMultipleExpandedDetails: "keepMultipleExpandedDetails", showTotalAmountRow: "showTotalAmountRow", enableGlobalSearch: "enableGlobalSearch", tableType: "tableType", enableExport: "enableExport", showFullScreenButton: "showFullScreenButton", enableCut: "enableCut", tabs: "tabs", showCheckboxes: "showCheckboxes", pageSizeOptions: "pageSizeOptions", resetAllFilters: "resetAllFilters", columnThreedotsMunuConfig: "columnThreedotsMunuConfig" }, outputs: { changeLayout: "changeLayout", customCellEvent: "customCellEvent", filterOptions: "filterOptions", genericEvent: "genericEvent", tablePresetConfig: "tablePresetConfig", sortingOrderOptions: "sortingOrderOptions", createUpdateConfigListing: "createUpdateConfigListing" }, host: { listeners: { "document:click": "onDocumentClick($event)", "document:keydown.escape": "onEscape($event)", "window:resize": "onResize($event)", "document:keydown": "onKeyDown($event)", "document:paste": "onPaste($event)" } }, viewQueries: [{ propertyName: "cellText", first: true, predicate: ["cellText"], descendants: true }, { propertyName: "nestedHeader", first: true, predicate: ["nestedHeader"], descendants: true }, { propertyName: "dataGridContainer", first: true, predicate: ["dataGridContainer"], descendants: true }, { propertyName: "taskManagementContainer", first: true, predicate: ["taskManagementContainer"], descendants: true }, { propertyName: "nestedTableContainer", first: true, predicate: ["nestedTableContainer"], descendants: true }, { propertyName: "leftPinnedBody", first: true, predicate: ["leftPinnedBody"], descendants: true }, { propertyName: "centerPinnedBody", first: true, predicate: ["centerPinnedBody"], descendants: true }, { propertyName: "rightPinnedBody", first: true, predicate: ["rightPinnedBody"], descendants: true }, { propertyName: "leftPinnedHeader", first: true, predicate: ["leftPinnedHeader"], descendants: true }, { propertyName: "centerPinnedHeader", first: true, predicate: ["centerPinnedHeader"], descendants: true }, { propertyName: "rightPinnedHeader", first: true, predicate: ["rightPinnedHeader"], descendants: true }, { propertyName: "columnsGroupedBox", first: true, predicate: ["columnsGroupedBox"], descendants: true }, { propertyName: "centerFakeScrollbar", first: true, predicate: ["centerFakeScrollbar"], descendants: true }, { propertyName: "centerScroll", first: true, predicate: ["centerScroll"], descendants: true }, { propertyName: "mainScroll", first: true, predicate: ["mainScroll"], descendants: true }, { propertyName: "fakeScroll", first: true, predicate: ["fakeScroll"], descendants: true }, { propertyName: "horizintalFakeScroll", first: true, predicate: ["horizintalFakeScroll"], descendants: true }, { propertyName: "centerScrollableBody", first: true, predicate: ["centerScrollableBody"], descendants: true }, { propertyName: "filterMenueSearchInput", first: true, predicate: ["filterMenueSearchInput"], descendants: true }, { propertyName: "filterMenueTextchInput", first: true, predicate: ["filterMenueTextchInput"], descendants: true }, { propertyName: "textAreadInput", first: true, predicate: ["textAreadInput"], descendants: true }, { propertyName: "nestedTable", first: true, predicate: ["nestedTable"], descendants: true }, { propertyName: "fullscreenImageTemplate", first: true, predicate: ["fullscreenImageTemplate"], descendants: true }, { propertyName: "cellHosts", predicate: CellHostDirective, descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div class=\"position-relative h-100\">\r\n <div\r\n class=\"d-flex justify-content-between mb-2 align-items-center position-relative\"\r\n >\r\n <div class=\"d-flex gap-2\">\r\n <div class=\"nav nav-tabs\" *ngIf=\"true\">\r\n <div class=\"nav nav-tabs\" id=\"nav-tab\" role=\"tablist\">\r\n <span\r\n *ngFor=\"let tab of tabs; let i = index\"\r\n (click)=\"setActiveTab(tab)\"\r\n class=\"nav-link cursor-pointer\"\r\n [class.active]=\"activeTab == tab\"\r\n >\r\n {{ tab }}\r\n </span>\r\n </div>\r\n </div>\r\n <div class=\"global-search\" [style.width.px]=\"350\">\r\n <span\r\n *ngIf=\"enableGlobalSearch\"\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/search.svg'\"\r\n class=\"data-grid-svg-icon mx-2 position-absolute icon\"\r\n ></span>\r\n <input\r\n *ngIf=\"enableGlobalSearch\"\r\n style=\"height: 36px\"\r\n class=\"form-control\"\r\n placeholder=\"Type to search, then press Enter\"\r\n [(ngModel)]=\"tableSearch\"\r\n (keydown.enter)=\"onGlobalSearch()\"\r\n (input)=\"onSearchInput($event)\"\r\n type=\"search\"\r\n />\r\n </div>\r\n </div>\r\n <div class=\"d-flex gap-2 align-items-center table-right-top-actions\">\r\n <ng-container *ngFor=\"let button of buttons\">\r\n <div\r\n class=\"d-flex align-items-center gap-2 action-buttons-row\"\r\n *ngIf=\"button?.has_permission\"\r\n >\r\n <a\r\n href=\"JavaScript:void(0)\"\r\n (click)=\"onActionButtonClick(button.name)\"\r\n class=\"button button-small btn border border-primary btn-active-primary me-2 p-0 d-flex align-items-center justify-content-center px-3\"\r\n >\r\n <span\r\n *ngIf=\"button.is_showIcon\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/' + button.icon + '.svg'\r\n \"\r\n class=\"svg-icon svg-icon-2\"\r\n ></span>\r\n <span\r\n class=\"label-hidden text-white\"\r\n [class.ms-0]=\"button.is_showIcon\"\r\n >{{ button?.name }}</span\r\n >\r\n </a>\r\n </div>\r\n </ng-container>\r\n <div\r\n *ngIf=\"!showFilterRow\"\r\n class=\"cursor-pointer position-relative action-buttons-row\"\r\n (click)=\"toggleOpenFilter()\"\r\n [class.active]=\"showFilters\"\r\n >\r\n <a\r\n href=\"JavaScript:void(0)\"\r\n class=\"button button-small btn btn-active-primary border border-primary me-2 p-0 d-flex align-items-center justify-content-center px-3\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\"\r\n class=\"svg-icon svg-icon-2\"\r\n ></span>\r\n <span class=\"label-hidden text-white\">Filters</span>\r\n </a>\r\n <span\r\n *ngIf=\"activeFilteredColumns?.length\"\r\n style=\"\r\n width: 7px;\r\n height: 7px;\r\n box-shadow: 0px 0px 3px #0022ff;\r\n background-color: rgb(0, 60, 255);\r\n position: absolute;\r\n right: 16px;\r\n top: 10px;\r\n \"\r\n class=\"rounded-circle d-block\"\r\n ></span>\r\n </div>\r\n <div\r\n class=\"cursor-pointer d-none\"\r\n (click)=\"toggleActions('advance-filter')\"\r\n [class.active]=\"activeTopButton === 'advance-filter'\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/zoom-charge.svg'\"\r\n class=\"data-grid-svg-icon top-icon me-2\"\r\n ></span>\r\n </div>\r\n <div\r\n class=\"cursor-pointer action-buttons-row\"\r\n (click)=\"toggleActions('setting')\"\r\n [class.active]=\"\r\n activeTopButton === 'setting' ||\r\n activeTopButton === 'table-layout' ||\r\n activeTopButton === 'table-presets' ||\r\n activeTopButton === 'show-hide-columns'\r\n \"\r\n >\r\n <!-- <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/settings-2.svg'\"\r\n class=\"data-grid-svg-icon top-icon me-2\"\r\n ></span> -->\r\n <a\r\n href=\"JavaScript:void(0)\"\r\n class=\"button button-small btn btn-active-primary border border-primary me-2 p-0 d-flex align-items-center justify-content-center px-3\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/settings-2.svg'\"\r\n class=\"svg-icon svg-icon-2\"\r\n ></span>\r\n <span class=\"label-hidden text-white\">Setting</span>\r\n </a>\r\n\r\n <div\r\n *ngIf=\"activeTopButton === 'setting'\"\r\n class=\"actions-dropdown mt-1 actions-dropdown-setting\"\r\n style=\"position: absolute\"\r\n >\r\n <div class=\"dropdown-menu show shadow custom-menu\">\r\n <!-- Table Layout -->\r\n <a\r\n class=\"dropdown-item d-flex justify-content-between align-items-center cursor-pointer\"\r\n (click)=\"$event.stopPropagation(); toggleActions('table-layout')\"\r\n >\r\n <span\r\n ><span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/table-2.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n Table Layout</span\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n </a>\r\n <!-- Table Presets -->\r\n <a\r\n (click)=\"$event.stopPropagation(); toggleActions('table-presets')\"\r\n class=\"dropdown-item d-flex justify-content-between align-items-center cursor-pointer\"\r\n >\r\n <span\r\n ><span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/list-details.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n Table Presets</span\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n </a>\r\n\r\n <!-- Columns -->\r\n <a\r\n *ngIf=\"!showSideMenu\"\r\n (click)=\"\r\n $event.stopPropagation(); toggleActions('show-hide-columns')\r\n \"\r\n class=\"dropdown-item d-flex justify-content-between align-items-center cursor-pointer\"\r\n >\r\n <span class=\"align-items-center d-flex\"\r\n ><span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/eye.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n Columns</span\r\n >\r\n <div class=\"d-flex gap-2\">\r\n <span class=\"muted-text\">{{ columnsCount }}</span>\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n </div>\r\n </a>\r\n\r\n <div class=\"dropdown-divider\"></div>\r\n\r\n <!-- Filter -->\r\n <a\r\n class=\"dropdown-item cursor-pointer\"\r\n (click)=\"toggleOpenFilter(); activeTopButton = '';\"\r\n *ngIf=\"!showFilterRow\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2 mt-1 cursor-pointer\"\r\n ></span>\r\n Filter\r\n </a>\r\n\r\n <!-- Download -->\r\n <a\r\n class=\"dropdown-item cursor-pointer\"\r\n (click)=\"downloadCsv('csv')\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/download.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2 cursor-pointer\"\r\n ></span>\r\n CSV Export\r\n </a>\r\n <a\r\n *ngIf=\"enableExport\"\r\n class=\"dropdown-item cursor-pointer\"\r\n (click)=\"downloadCsv('xlsx')\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/download.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2 cursor-pointer\"\r\n ></span>\r\n Excel Export\r\n </a>\r\n <!-- Font Family & Font Size -->\r\n <div class=\"px-2 pb-2 pt-2\">\r\n <div class=\"d-flex gap-2\">\r\n <!-- Font Family -->\r\n <select\r\n class=\"form-select form-select-sm\"\r\n [(ngModel)]=\"fontFaimly\"\r\n (change)=\"onFontChange()\"\r\n >\r\n <option *ngFor=\"let font of fontFamilies\" [value]=\"font\">\r\n {{ font }}\r\n </option>\r\n </select>\r\n\r\n <!-- Font Size -->\r\n <select\r\n class=\"form-select form-select-sm\"\r\n (change)=\"onFontChange()\"\r\n [(ngModel)]=\"bodyTextFontsSize\"\r\n >\r\n <option *ngFor=\"let size of fontSizes\" [value]=\"size\">\r\n {{ size }}\r\n </option>\r\n </select>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Table Layout -->\r\n\r\n <ng-container *ngIf=\"activeTopButton === 'table-layout'\">\r\n <div\r\n *ngTemplateOutlet=\"tableLayout\"\r\n class=\"actions-dropdown mt-1\"\r\n style=\"position: absolute\"\r\n ></div>\r\n </ng-container>\r\n\r\n <!-- Table Presets -->\r\n <ng-container *ngIf=\"activeTopButton === 'table-presets'\">\r\n <div\r\n *ngTemplateOutlet=\"tablePreset\"\r\n class=\"actions-dropdown mt-1\"\r\n style=\"position: absolute\"\r\n ></div>\r\n </ng-container>\r\n\r\n <!-- Table Presets -->\r\n <ng-container *ngIf=\"activeTopButton === 'show-hide-columns'\">\r\n <div\r\n *ngTemplateOutlet=\"showHideColumns\"\r\n class=\"actions-dropdown mt-1\"\r\n style=\"position: absolute\"\r\n ></div>\r\n </ng-container>\r\n </div>\r\n\r\n <div class=\"action-buttons-row\" *ngIf=\"showFullScreenButton\">\r\n <a\r\n *ngIf=\"!isFullScreen\"\r\n class=\"button button-small btn btn-active-primary border border-primary expend d-flex justify-content-center align-items-center\"\r\n (click)=\"toggleFullscreen()\"\r\n data-bs-toggle=\"tooltip\"\r\n data-bs-placement=\"top\"\r\n title=\"Minimise\"\r\n [ngClass]=\"{ minArrow: !isFullScreen, maxArrow: isFullScreen }\"\r\n style=\"transition: color 0.2s\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/expend.svg'\"\r\n class=\"svg-icon svg-icon-2 mb-1\"\r\n ></span>\r\n </a>\r\n <a\r\n *ngIf=\"isFullScreen\"\r\n class=\"button button-small btn btn-active-primary border border-primary expend d-flex justify-content-center align-items-center\"\r\n (click)=\"toggleFullscreen()\"\r\n data-bs-toggle=\"tooltip\"\r\n data-bs-placement=\"top\"\r\n title=\"Maximise\"\r\n [ngClass]=\"{ minArrow: !isFullScreen, maxArrow: isFullScreen }\"\r\n style=\"transition: color 0.2s\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/minimize.svg'\"\r\n class=\"svg-icon svg-icon-2 mb-1\"\r\n ></span>\r\n </a>\r\n </div>\r\n <div>\r\n <!-- Example single danger button -->\r\n\r\n <!-- <button\r\n type=\"button\"\r\n class=\"btn btn-primary btn-sm d-flex gap-2 action-button\"\r\n (click)=\"toggleActions('actions')\"\r\n >\r\n Action\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/Vector.svg'\"\r\n class=\"data-grid-svg-icon\"\r\n ></span>\r\n </button>\r\n <div\r\n *ngIf=\"activeTopButton === 'actions'\"\r\n class=\"actions-dropdown mt-1\"\r\n >\r\n <div class=\"dropdown-menu show\">\r\n <a class=\"dropdown-item\" href=\"#\">Action</a>\r\n <a class=\"dropdown-item\" href=\"#\">Another action</a>\r\n <a class=\"dropdown-item\" href=\"#\">Something else here</a>\r\n <div class=\"dropdown-divider\"></div>\r\n <a class=\"dropdown-item\" href=\"#\">Separated link</a>\r\n </div>\r\n </div> -->\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div\r\n *ngIf=\"showFilters && !showFilterRow\"\r\n class=\"top-filter-row border-top py-2 d-flex justify-content-between align-items-center\"\r\n [style.height.px]=\"topFilterRowHeight\"\r\n >\r\n <!-- LEFT SIDE (Filter tags + Filter button) -->\r\n <div class=\"d-flex gap-2 align-items-center\">\r\n <ng-container>\r\n <div\r\n *ngFor=\"let col of activeFilteredColumns; trackBy: trackByField\"\r\n class=\"filter-tags\"\r\n >\r\n <div\r\n (click)=\"\r\n isActiveFilterOpen = true;\r\n activeTopButton = 'filter-columns';\r\n openFilter(col)\r\n \"\r\n class=\"d-flex justify-content-center align-items-center muted-text add-filter-button active-filters\"\r\n style=\"white-space: nowrap\"\r\n [class.active]=\"\r\n col?.field == selectedColumnForFilter?.field &&\r\n isActiveFilterOpen &&\r\n activeTopButton == 'filter-columns'\r\n \"\r\n >\r\n <span class=\"header-tag mt-0 d-flex align-items-center\">\r\n <span\r\n *ngIf=\"col?.pinned\"\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/pin.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n {{ col.header }}\r\n <span\r\n (click)=\"\r\n $event.stopPropagation(); removeColumnFilterFromColumn(col)\r\n \"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/cross-primary.svg'\r\n \"\r\n class=\"data-grid-svg-icon cross-secondary ms-2 mb-1\"\r\n ></span>\r\n </span>\r\n </div>\r\n\r\n <ng-container\r\n *ngIf=\"\r\n activeTopButton === 'filter-columns' &&\r\n col?.field == selectedColumnForFilter?.field &&\r\n isActiveFilterOpen\r\n \"\r\n >\r\n <div\r\n *ngTemplateOutlet=\"filterColumns; context: { column: col }\"\r\n class=\"actions-dropdown mt-1\"\r\n ></div>\r\n </ng-container>\r\n </div>\r\n </ng-container>\r\n\r\n <!-- Filter Button -->\r\n <div class=\"add-filter-button-menu\">\r\n <div\r\n (click)=\"toggleActions('filter-columns'); isActiveFilterOpen = false\"\r\n class=\"d-flex justify-content-center align-items-center muted-text add-filter-button button-filter\"\r\n style=\"width: 70px\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/plus.svg'\"\r\n class=\"me-2 data-grid-svg-icon\"\r\n ></span>\r\n Filter\r\n </div>\r\n\r\n <ng-container\r\n *ngIf=\"activeTopButton === 'filter-columns' && !isActiveFilterOpen\"\r\n >\r\n <div\r\n *ngTemplateOutlet=\"filterColumns\"\r\n class=\"actions-dropdown mt-1\"\r\n ></div>\r\n </ng-container>\r\n </div>\r\n </div>\r\n\r\n <!-- RIGHT SIDE (Update + Reset) -->\r\n <div class=\"d-flex gap-3 align-items-center\">\r\n <div\r\n (click)=\"savePreset()\"\r\n class=\"text-primary cursor-pointer all-filters-reset-button\"\r\n *ngIf=\"!checkFilterChangesEffect()\"\r\n >\r\n Update View\r\n </div>\r\n\r\n <div\r\n class=\"text-primary cursor-pointer all-filters-reset-button\"\r\n *ngIf=\"!tableFilterViewId && activeFilteredColumns?.length\"\r\n (click)=\"clearAllFilters()\"\r\n >\r\n Reset\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div\r\n [style.height]=\"\r\n showFilters ? 'calc(100% - ' + topFilterRowHeight + 'px)' : '100%'\r\n \"\r\n cdkDropListGroup\r\n class=\"data-grid-table-wrapper overflow-hidden\"\r\n #dataGridContainer\r\n [style.fontFamily]=\"fontFaimly\"\r\n [style.backgroundColor]=\"bodyBackgroundColor\"\r\n id=\"data-grid-main-container\"\r\n >\r\n <div\r\n *ngIf=\"showRowsGrouping\"\r\n [style.height.px]=\"headerRowHeight\"\r\n [cdkDropListData]=\"columns\"\r\n [style.backgroundColor]=\"\r\n topGroupedBadgesBackgroundColor || headerBackgroundColor\r\n \"\r\n cdkDropList\r\n (cdkDropListEntered)=\"enterToTopRowGrouping($event)\"\r\n (cdkDropListExited)=\"exitedFromTheTopRow($event)\"\r\n (cdkDropListDropped)=\"onDropTopGroup($event)\"\r\n [cdkDropListEnterPredicate]=\"canEnterToRowsGrouping\"\r\n id=\"rows-grouping-top-container\"\r\n class=\"border-below d-flex px-4 align-items-center\"\r\n >\r\n <div\r\n class=\"d-flex gap-2 align-items-center\"\r\n [style.color]=\"headerTextColor\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/justify.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n <div *ngIf=\"!draggingInGroupArea && !groupedColumns?.length\">\r\n Drag here to set row groups\r\n </div>\r\n <div\r\n cdkDropListOrientation=\"horizontal\"\r\n cdkDropList\r\n (cdkDropListDropped)=\"onGroupReorder($event)\"\r\n class=\"d-flex\"\r\n >\r\n <div\r\n cdkDrag\r\n [cdkDragLockAxis]=\"'x'\"\r\n *ngFor=\"\r\n let child of groupedColumns;\r\n let i = index;\r\n trackBy: trackByField\r\n \"\r\n class=\"d-flex align-items-center\"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n topGroupingRowPlaceholder;\r\n context: {\r\n $implicit: child,\r\n showChevron:\r\n groupedColumns.length > 1 && i != groupedColumns.length - 1\r\n }\r\n \"\r\n ></ng-container>\r\n <ng-template cdkDragPreview\r\n ><div class=\"p-2 border d-flex gap-2\">\r\n <div>\r\n <span\r\n *ngIf=\"!draggingInGroupArea\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/arrows-move.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n <div>{{ child.header }}</div>\r\n </div>\r\n </ng-template>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n <div\r\n class=\"d-flex overflow-hidden\"\r\n [style.height]=\"\r\n 'calc(100% - ' +\r\n (showRowsGrouping\r\n ? headerRowHeight + footerRowHeight\r\n : footerRowHeight) +\r\n 'px)'\r\n \"\r\n >\r\n <div\r\n class=\"h-100\"\r\n [style.width]=\"\r\n !showSideMenu\r\n ? '100%'\r\n : sideMenuVisible\r\n ? 'calc(100% - 280px)'\r\n : 'calc(100% - 30px)'\r\n \"\r\n >\r\n <div class=\"h-100 transition position-relative w-100\">\r\n <!-- ##################################################################################################################################################################################### -->\r\n <!-- ##################################################################################################################################################################################### -->\r\n <!-- Data Grid Header starts here -->\r\n <!-- ##################################################################################################################################################################################### -->\r\n <!-- ##################################################################################################################################################################################### -->\r\n\r\n <div\r\n class=\"data-grid-header-wrapper w-100\"\r\n [style.color]=\"headerTextColor\"\r\n [style.fontSize.px]=\"headerTextFontsSize\"\r\n [style.backgroundColor]=\"headerBackgroundColor\"\r\n [class.border-below]=\"!hasAnyVisibleColumn\"\r\n [style.height.px]=\"\r\n showColumnsGrouping && showFilterRow\r\n ? headerRowHeight * 3\r\n : showColumnsGrouping || showFilterRow\r\n ? headerRowHeight * 2\r\n : headerRowHeight\r\n \"\r\n >\r\n <!-- ********************************************************************************* -->\r\n <!-- ********************************************************************************* -->\r\n <!-- Data Grid Left Pinned Header starts here -->\r\n <!-- ********************************************************************************* -->\r\n <!-- ********************************************************************************* -->\r\n <div\r\n class=\"data-grid-header left-pinned\"\r\n #leftPinnedHeader\r\n [class.border-right]=\"hasLeftPinnedColumns\"\r\n >\r\n <div\r\n *ngIf=\"showSerialNumber\"\r\n [style.backgroundColor]=\"checkboxesBackgroundColor\"\r\n class=\"select-all-checkbox-cell border-below\"\r\n [style.width.px]=\"55\"\r\n [style.height.px]=\"\r\n showColumnsGrouping && showFilterRow\r\n ? headerRowHeight * 3\r\n : showColumnsGrouping || showFilterRow\r\n ? headerRowHeight * 2\r\n : headerRowHeight\r\n \"\r\n >\r\n S.No\r\n </div>\r\n <div\r\n *ngIf=\"showCheckboxes\"\r\n [style.backgroundColor]=\"checkboxesBackgroundColor\"\r\n class=\"select-all-checkbox-cell border-below\"\r\n [style.height.px]=\"\r\n showColumnsGrouping && showFilterRow\r\n ? headerRowHeight * 3\r\n : showColumnsGrouping || showFilterRow\r\n ? headerRowHeight * 2\r\n : headerRowHeight\r\n \"\r\n >\r\n <input\r\n *ngIf=\"hasAnyVisibleColumn\"\r\n style=\"width: 16px; height: 16px\"\r\n type=\"checkbox\"\r\n [indeterminate]=\"isIndeterminateState(dataSet)\"\r\n [checked]=\"isAllSelected(dataSet)\"\r\n (change)=\"toggleSelectAll(dataSet)\"\r\n />\r\n </div>\r\n <div\r\n [style.backgroundColor]=\"headerBackgroundColor\"\r\n class=\"d-flex\"\r\n cdkDropList\r\n id=\"left-pinned-header\"\r\n cdkDropListOrientation=\"horizontal\"\r\n [cdkDropListData]=\"leftPinnedColumns\"\r\n (cdkDropListEntered)=\"onDropListEnter($event, 'left')\"\r\n (cdkDropListSorted)=\"\r\n onSortGroup($event, 'previewLeftPinnedColumns')\r\n \"\r\n (cdkDropListDropped)=\"onDropGroup()\"\r\n style=\"min-width: 1px\"\r\n >\r\n <div\r\n class=\"dragable-header\"\r\n cdkDrag\r\n [cdkDragData]=\"col\"\r\n *ngFor=\"\r\n let col of leftPinnedColumns;\r\n let i = index;\r\n trackBy: trackByField\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n headerCell;\r\n context: {\r\n $implicit: col,\r\n index: i,\r\n section: 'previewLeftPinnedColumns'\r\n }\r\n \"\r\n ></ng-container>\r\n <ng-template cdkDragPreview\r\n ><div class=\"p-2 border d-flex gap-2\">\r\n <div>\r\n <span\r\n *ngIf=\"!draggingInGroupArea\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath +\r\n 'data-grid/icons/arrows-move.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n <div>{{ col.header }}</div>\r\n </div>\r\n </ng-template>\r\n <ng-template cdkDragPlaceholder>\r\n <div *ngIf=\"!draggingInGroupArea\">\r\n <div\r\n *ngTemplateOutlet=\"\r\n headerCell;\r\n context: {\r\n $implicit: col,\r\n index: i,\r\n section: ''\r\n }\r\n \"\r\n ></div>\r\n </div>\r\n <div\r\n *ngIf=\"draggingInGroupArea\"\r\n class=\"d-flex gap-2 ms-2\"\r\n style=\"opacity: 0.6\"\r\n >\r\n <ng-container\r\n *ngIf=\"col?.children?.length; else singleCol\"\r\n >\r\n <ng-container\r\n *ngFor=\"\r\n let child of col.children;\r\n let i = index;\r\n trackBy: trackByField\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n topGroupingRowPlaceholder;\r\n context: {\r\n $implicit: child,\r\n showChevron:\r\n col.children.length > 1 &&\r\n i != col.children.length - 1\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </ng-container>\r\n\r\n <ng-template #singleCol>\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n topGroupingRowPlaceholder;\r\n context: {\r\n $implicit: col,\r\n showChevron: col?.children?.length > 1\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-template>\r\n </div>\r\n </ng-template>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- ********************************************************************************* -->\r\n <!-- ********************************************************************************* -->\r\n <!-- Data Grid Center Pinned Header starts here -->\r\n <!-- ********************************************************************************* -->\r\n <!-- ********************************************************************************* -->\r\n <div\r\n class=\"data-grid-header center-scrollable\"\r\n #centerPinnedHeader\r\n (scroll)=\"onCenterBodyScroll($event)\"\r\n id=\"center-pinned-header\"\r\n cdkDropList\r\n [cdkDropListConnectedTo]=\"\r\n showRowsGrouping ? ['rows-grouping-top-container'] : []\r\n \"\r\n [cdkDropListData]=\"centerColumns\"\r\n cdkDropListOrientation=\"horizontal\"\r\n [cdkDropListSortingDisabled]=\"\r\n isDisableColumnGrouping && draggingInGroupArea\r\n \"\r\n (cdkDropListEntered)=\"onDropListEnter($event, 'center')\"\r\n (cdkDropListSorted)=\"onSortGroup($event, 'previewCenterColumns')\"\r\n (cdkDropListDropped)=\"onDropGroup()\"\r\n [style.maxWidth]=\"\r\n 'calc(100% - ' +\r\n (rightPinnedHeader.offsetWidth + leftPinnedHeader.offsetWidth) +\r\n 'px)'\r\n \"\r\n >\r\n <div\r\n *ngIf=\"groupedColumns?.length\"\r\n style=\"min-width: 200px\"\r\n class=\"h-100 align-items-center\"\r\n #columnsGroupedBox\r\n id=\"groupBoxHeaderDiv\"\r\n >\r\n <div\r\n class=\"d-flex w-100 justify-content-between align-items-center border-below\"\r\n [style.height.px]=\"\r\n showFilterRow ? headerRowHeight * 2 : headerRowHeight\r\n \"\r\n >\r\n <div class=\"ps-3\">Group</div>\r\n <div class=\"d-flex\">\r\n <div\r\n class=\"three-dots cursor-pointer\"\r\n (click)=\"\r\n openThreeDotsMenu($event, 'group');\r\n isThreeDotsFilterOpen = false\r\n \"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath +\r\n 'data-grid/icons/three-dots-vertical.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n <div\r\n (mousedown)=\"\r\n $event.stopPropagation(); onResizeGroupBox($event)\r\n \"\r\n class=\"resize-handle\"\r\n style=\"margin-right: -2px\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath +\r\n 'data-grid/icons/resize-handle.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div\r\n [style.height.px]=\"headerRowHeight\"\r\n class=\"border-below\"\r\n ></div>\r\n </div>\r\n <span\r\n class=\"d-flex align-items-center justify-content-center cursor-pointer border-below\"\r\n style=\"min-width: 30px; height: 100%\"\r\n *ngIf=\"gridType === 'Assets' || gridType === 'Tasks'\"\r\n >\r\n </span>\r\n <div\r\n class=\"dragable-header\"\r\n (cdkDragStarted)=\"\r\n checkColumnGroupingStatus(col);\r\n dragStartOnGroup(col);\r\n onDragStarted(col)\r\n \"\r\n (cdkDragMoved)=\"onDragMoved($event)\"\r\n (cdkDragEnded)=\"onDragEnded()\"\r\n cdkDrag\r\n [cdkDragData]=\"col\"\r\n *ngFor=\"\r\n let col of centerColumns;\r\n let i = index;\r\n trackBy: trackById\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n headerCell;\r\n context: {\r\n $implicit: col,\r\n index: i,\r\n section: 'previewCenterColumns'\r\n }\r\n \"\r\n >\r\n </ng-container>\r\n <ng-template cdkDragPreview\r\n ><div class=\"p-2 border d-flex gap-2\">\r\n <div>\r\n <span\r\n *ngIf=\"!isOutsideContainer\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath +\r\n (draggingInGroupArea\r\n ? 'data-grid/icons/justify.svg'\r\n : 'data-grid/icons/arrows-move.svg')\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n >\r\n </span>\r\n <span\r\n *ngIf=\"isOutsideContainer\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/eye-cross.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n >\r\n </span>\r\n </div>\r\n <div>{{ col.header }}</div>\r\n </div>\r\n </ng-template>\r\n <ng-template cdkDragPlaceholder>\r\n <div *ngIf=\"!draggingInGroupArea\">\r\n <div\r\n *ngTemplateOutlet=\"\r\n headerCell;\r\n context: {\r\n $implicit: col,\r\n index: i,\r\n section: 'centerColumns'\r\n }\r\n \"\r\n ></div>\r\n </div>\r\n <div\r\n *ngIf=\"draggingInGroupArea && !isOutsideContainer\"\r\n class=\"d-flex gap-2 ms-2\"\r\n style=\"opacity: 0.6\"\r\n >\r\n <ng-container *ngIf=\"col?.children?.length; else singleCol\">\r\n <ng-container\r\n *ngFor=\"\r\n let child of col.children;\r\n let i = index;\r\n trackBy: trackById\r\n \"\r\n >\r\n <ng-container *ngIf=\"child?.is_groupable\">\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n topGroupingRowPlaceholder;\r\n context: {\r\n $implicit: child,\r\n showChevron:\r\n col.children.length > 1 &&\r\n i != col.children.length - 1\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </ng-container>\r\n </ng-container>\r\n\r\n <ng-template #singleCol>\r\n <ng-container *ngIf=\"col?.is_groupable\">\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n topGroupingRowPlaceholder;\r\n context: {\r\n $implicit: col,\r\n showChevron: col?.children?.length > 1\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </ng-template>\r\n </div>\r\n </ng-template>\r\n </div>\r\n </div>\r\n\r\n <!-- ********************************************************************************* -->\r\n <!-- ********************************************************************************* -->\r\n <!-- Data Grid Right Pinned Header starts here -->\r\n <!-- ********************************************************************************* -->\r\n <!-- ********************************************************************************* -->\r\n <div\r\n [style.backgroundColor]=\"headerBackgroundColor\"\r\n cdkDropList\r\n id=\"right-pinned-header\"\r\n [cdkDropListConnectedTo]=\"\r\n showRowsGrouping ? ['rows-grouping-top-container'] : []\r\n \"\r\n cdkDropListOrientation=\"horizontal\"\r\n class=\"data-grid-header right-pinned\"\r\n (cdkDropListSorted)=\"\r\n onSortGroup($event, 'previewRightPinnedColumns')\r\n \"\r\n (cdkDropListEntered)=\"onDropListEnter($event, 'right')\"\r\n (cdkDropListDropped)=\"onDropGroup()\"\r\n #rightPinnedHeader\r\n class=\"right-pinned-header d-flex\"\r\n style=\"min-width: 0.2px\"\r\n >\r\n <div\r\n class=\"dragable-header\"\r\n cdkDrag\r\n [cdkDragData]=\"col\"\r\n *ngFor=\"\r\n let col of rightPinnedColumns;\r\n let i = index;\r\n trackBy: trackById\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n headerCell;\r\n context: {\r\n $implicit: col,\r\n pinnedRight: true,\r\n index: i,\r\n section: 'right'\r\n }\r\n \"\r\n ></ng-container>\r\n <ng-template cdkDragPreview\r\n ><div class=\"p-2 border d-flex gap-2\">\r\n <div>\r\n <span\r\n *ngIf=\"!draggingInGroupArea\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath +\r\n 'data-grid/icons/arrows-move.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n <div>{{ col.header }}</div>\r\n </div>\r\n </ng-template>\r\n <ng-template cdkDragPlaceholder>\r\n <div *ngIf=\"!draggingInGroupArea\">\r\n <div\r\n *ngTemplateOutlet=\"\r\n headerCell;\r\n context: {\r\n $implicit: col,\r\n index: i,\r\n section: 'right'\r\n }\r\n \"\r\n ></div>\r\n </div>\r\n <div\r\n *ngIf=\"draggingInGroupArea\"\r\n class=\"d-flex gap-2 ms-2\"\r\n style=\"opacity: 0.6\"\r\n >\r\n <ng-container *ngIf=\"col?.children?.length; else singleCol\">\r\n <ng-container\r\n *ngFor=\"\r\n let child of col.children;\r\n let i = index;\r\n trackBy: trackById\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n topGroupingRowPlaceholder;\r\n context: {\r\n $implicit: child,\r\n showChevron:\r\n col.children.length > 1 &&\r\n i != col.children.length - 1\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </ng-container>\r\n\r\n <ng-template #singleCol>\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n topGroupingRowPlaceholder;\r\n context: {\r\n $implicit: col,\r\n showChevron: col?.children?.length > 1\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-template>\r\n </div>\r\n </ng-template>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!--########################################################################################################################################################################################################################### -->\r\n <!--########################################################################################################################################################################################################################### -->\r\n <!-- Data Grid Body starts here -->\r\n <!--########################################################################################################################################################################################################################### -->\r\n <!--########################################################################################################################################################################################################################### -->\r\n <div\r\n class=\"h-100 d-flex justify-content-center align-items-center\"\r\n *ngIf=\"!dataSet?.length && !loading && !dataSetLoading\"\r\n >\r\n <!-- <div\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/record-not-found.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></div> -->\r\n <div>No Record Found</div>\r\n </div>\r\n\r\n <div\r\n class=\"position-absolute w-100 h-100 d-flex justify-content-center align-items-center loading-overlay\"\r\n *ngIf=\"loading || dataSetLoading\"\r\n style=\"\r\n z-index: 999;\r\n backdrop-filter: blur(1px);\r\n \"\r\n [style.backgroundColor]=\"bodyBackgroundColor\"\r\n >\r\n <div class=\"spinner-border text-primary\" role=\"status\">\r\n <!-- <span class=\"loader\"></span> -->\r\n <!-- <span class=\"visually-hidden\">Loading...</span> -->\r\n <!-- </div> -->\r\n </div>\r\n </div>\r\n\r\n <div\r\n class=\"data-grid-body-wrapper position-relative d-flex\"\r\n [style.height]=\"bodyWrapperHeight\"\r\n style=\"overflow-y: auto; overflow-x: hidden\"\r\n #mainScroll\r\n (scroll)=\"onMainScroll($event)\"\r\n [style.scrollbarWidth]=\"verticalScrollbarWidth\"\r\n >\r\n <!-- LEFT PINNED -->\r\n <div\r\n [style.height.px]=\"\r\n !groupedColumns.length ? originalDataSet.length * rowHeight : 0\r\n \"\r\n ></div>\r\n <div [class.h-100]=\"originalDataSet.length < 8\">\r\n <div\r\n class=\"data-grid-body left-pinned-body w-100\"\r\n style=\"overflow-y: hidden\"\r\n [class.border-right]=\"hasLeftPinnedColumns\"\r\n [class.transparent-border-right]=\"!hasLeftPinnedColumns\"\r\n [style.transform]=\"'translateY(' + translateY + 'px)'\"\r\n [style.backgroundColor]=\"leftPinnedBackgroundColor\"\r\n [class.h-100]=\"originalDataSet.length < 8\"\r\n *ngIf=\"!loading && !dataSetLoading\"\r\n [@rowDynamic]=\"rowAnimation\"\r\n\r\n \r\n >\r\n <ng-container\r\n *ngFor=\"\r\n let row of visibleRows;\r\n let i = index;\r\n trackBy: trackById\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n rowCell;\r\n context: {\r\n $implicit: row,\r\n columns: previewLeftPinnedColumns,\r\n isEven: (startIndex + i) % 2 === 0,\r\n isOdd: (startIndex + i) % 2 !== 0,\r\n isLeft: true,\r\n section: 'left',\r\n isTotalRow: false\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n <ng-container *ngIf=\"showTotalAmountRow && originalDataSet?.length\">\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n rowCell;\r\n context: {\r\n $implicit: { __virtualIndex: 0 },\r\n columns: previewLeftPinnedColumns,\r\n isEven: false,\r\n isOdd: false,\r\n section: 'left',\r\n isTotalRow: true\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </div>\r\n </div>\r\n\r\n <!-- CENTER -->\r\n <div\r\n class=\"h-100\"\r\n [style.width.px]=\"centerPinnedHeader.clientWidth\"\r\n [style.backgroundColor]=\"bodyBackgroundColor\"\r\n >\r\n <div\r\n class=\"data-grid-body center-scrollable\"\r\n [class.h-100]=\"originalDataSet.length < 8\"\r\n style=\"overflow-y: hidden; overflow-x: auto\"\r\n [style.transform]=\"'translateY(' + translateY + 'px)'\"\r\n [style.backgroundColor]=\"bodyBackgroundColor\"\r\n #centerScrollableBody\r\n (scroll)=\"onCenterBodyScroll($event)\"\r\n [style.boxShadow]=\"leftPinnedBoxshadow\"\r\n >\r\n <div [@rowDynamic]=\"rowAnimation\" *ngIf=\"!loading && !dataSetLoading\">\r\n <ng-container\r\n *ngFor=\"\r\n let row of visibleRows;\r\n let i = index;\r\n trackBy: trackById\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n rowCell;\r\n context: {\r\n $implicit: row,\r\n columns: previewCenterColumns,\r\n isEven: (startIndex + i) % 2 === 0,\r\n isOdd: (startIndex + i) % 2 !== 0,\r\n section: 'center',\r\n isTotalRow: false\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </div>\r\n <ng-container *ngIf=\"showTotalAmountRow && originalDataSet?.length\">\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n rowCell;\r\n context: {\r\n $implicit: { __virtualIndex: 0 },\r\n columns: previewCenterColumns,\r\n isEven: false,\r\n isOdd: false,\r\n section: 'center',\r\n isTotalRow: true\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </div>\r\n </div>\r\n\r\n <!-- RIGHT PINNED -->\r\n <div\r\n class=\"right-pinned-body-wrapper\"\r\n *ngIf=\"hasRightPinnedColumns\"\r\n [class.h-100]=\"originalDataSet.length < 8\"\r\n [style.maxWidth.px]=\"\r\n isScrollbarVisible\r\n ? rightPinnedHeader.offsetWidth - 15\r\n : rightPinnedHeader.offsetWidth\r\n \"\r\n [style.backgroundColor]=\"rightPinnedBackgroundColor\"\r\n >\r\n <div\r\n class=\"data-grid-body right-pinned-body w-100 h-100\"\r\n style=\"overflow-y: hidden\"\r\n [style.transform]=\"'translateY(' + translateY + 'px)'\"\r\n [style.boxShadow]=\"rightPinnedBoxshadow\"\r\n [style.backgroundColor]=\"rightPinnedBackgroundColor\"\r\n *ngIf=\"!loading && !dataSetLoading\"\r\n [@rowDynamic]=\"rowAnimation\"\r\n >\r\n <ng-container\r\n *ngFor=\"\r\n let row of visibleRows;\r\n let i = index;\r\n trackBy: trackById\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n rowCell;\r\n context: {\r\n $implicit: row,\r\n columns: previewRightPinnedColumns,\r\n isEven: (startIndex + i) % 2 === 0,\r\n isOdd: (startIndex + i) % 2 !== 0,\r\n section: 'right',\r\n isTotalRow: false\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n <ng-container *ngIf=\"showTotalAmountRow && originalDataSet?.length\">\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n rowCell;\r\n context: {\r\n $implicit: { __virtualIndex: 0 },\r\n columns: previewRightPinnedColumns,\r\n isEven: false,\r\n isOdd: false,\r\n section: 'right',\r\n isTotalRow: true\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </div>\r\n </div>\r\n\r\n <div\r\n style=\"top: auto; left: auto\"\r\n (click)=\"\r\n $event.stopPropagation();\r\n fullscreenImage = null;\r\n cdr.detectChanges()\r\n \"\r\n [style.width.px]=\"dataGridContainer.offsetWidth\"\r\n [style.height.px]=\"\r\n dataGridContainer.offsetHeight - (footerRowHeight + 100)\r\n \"\r\n class=\"image-modal full-image-modal\"\r\n *ngIf=\"fullscreenImage\"\r\n >\r\n <img\r\n (click)=\"$event.stopPropagation()\"\r\n [src]=\"fullscreenImage\"\r\n alt=\"Fullscreen Image\"\r\n />\r\n </div>\r\n <div\r\n *ngIf=\"selectedRows.size > 0 && showTaskbar\"\r\n class=\"taskbar w-100\"\r\n [style.bottom.px]=\"85\"\r\n >\r\n <div class=\"selected-rows-action-bar\" [@slideUp]>\r\n <span class=\"selected-count\">\r\n {{ selectedRows.size }} selected of\r\n {{\r\n paginationConfig.totalResults ||\r\n config?.paginationParams?.totalItems\r\n }}\r\n Total\r\n </span>\r\n <div class=\"action-buttons d-flex align-items-center\">\r\n <ng-container\r\n *ngFor=\"let action of taskbarActions; let i = index\"\r\n >\r\n <ng-container *ngIf=\"action?.has_permission\">\r\n <span\r\n class=\"action-btn verified btn {{ action }}\"\r\n (click)=\"onVerifyClick(action?.actionName)\"\r\n >{{ action?.actionName }}</span\r\n >\r\n <span\r\n *ngIf=\"\r\n taskbarActions.length > 1 &&\r\n i !== taskbarActions.length - 1 &&\r\n taskbarActions[i + 1]?.has_permission\r\n \"\r\n class=\"\"\r\n >|</span\r\n >\r\n </ng-container>\r\n </ng-container>\r\n <button (click)=\"clearSelectionState(tableType);selectedRows.clear();\" class=\"clear-btn ms-2 mt-2\">\r\n <i class=\"bi bi-x-circle\"></i> Clear Selection\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n <!-- Vertical Fake scroll Bar -->\r\n <!-- <div\r\n (scroll)=\"onMainFakeScroll($event)\"\r\n class=\"fake-scrollbar fake-scrollbar-vertical d-none\"\r\n [style.scrollbarWidth]=\"verticalScrollbarWidth\"\r\n [style.top.px]=\"\r\n showColumnsGrouping && showFilterRow\r\n ? headerRowHeight * 3\r\n : showColumnsGrouping || showFilterRow\r\n ? headerRowHeight * 2\r\n : headerRowHeight\r\n \"\r\n #fakeScroll\r\n [style.height]=\"bodyWrapperHeight\"\r\n style=\"\r\n overflow-y: auto;\r\n overflow-x: hidden;\r\n width: 17px;\r\n position: absolute;\r\n right: 0;\r\n background-color: f1f2f3;\r\n z-index: 10;\r\n \"\r\n >\r\n <div [style.height.px]=\"rowHeight * dataSetLength\"></div>\r\n </div> -->\r\n </div>\r\n\r\n <!-- Horizintal Fake Scrollbars -->\r\n <div\r\n class=\"d-flex justify-content-between\"\r\n *ngIf=\"hasScroll && !shouldRestoreScroll\"\r\n >\r\n <div\r\n [style.scrollbarWidth]=\"horizintalScrollbarWidth\"\r\n class=\"fake-horizintal-scrollbar\"\r\n #fakeScroll\r\n [style.width.px]=\"leftPinnedHeader.offsetWidth\"\r\n style=\"overflow-x: scroll\"\r\n ></div>\r\n <div\r\n [style.scrollbarWidth]=\"horizintalScrollbarWidth\"\r\n (scroll)=\"onCenterBodyScroll($event)\"\r\n class=\"fake-horizintal-scrollbar\"\r\n #horizintalFakeScroll\r\n [style.width.px]=\"centerPinnedHeader.offsetWidth\"\r\n >\r\n <div [style.width.px]=\"centerPinnedHeader.scrollWidth - 10\"></div>\r\n </div>\r\n <div\r\n [style.scrollbarWidth]=\"horizintalScrollbarWidth\"\r\n class=\"fake-horizintal-scrollbar\"\r\n #fakeScroll\r\n [style.width.px]=\"rightPinnedHeader.offsetWidth\"\r\n style=\"overflow-x: scroll\"\r\n ></div>\r\n </div>\r\n </div>\r\n\r\n <!-- Side Menu Implemented Here -->\r\n <div\r\n *ngIf=\"showSideMenu\"\r\n [style.width.px]=\"sideMenuVisible ? 280 : 30\"\r\n class=\"right-menu h-100\"\r\n [style.backgroundColor]=\"sidemenuBackgroundColor\"\r\n >\r\n <div class=\"h-100 d-flex flex-row-reverse\">\r\n <div\r\n style=\"width: 30px\"\r\n class=\"d-flex flex-column align-items-center cursor-pointer\"\r\n [class.border-start]=\"sideMenuVisible\"\r\n >\r\n <div\r\n (click)=\"toggleSideMenu('cols')\"\r\n [class.bg-fff]=\"\r\n currentOpenedSideMenue == 'cols' && sideMenuVisible\r\n \"\r\n [class.border-below]=\"sideMenuVisible\"\r\n class=\"columns-button d-flex flex-column align-items-center\"\r\n >\r\n <div>\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/ui-checks-grid.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n <div class=\"side-menue-text\">Columns</div>\r\n </div>\r\n\r\n <div\r\n (click)=\"toggleSideMenu('filtrs')\"\r\n [class.bg-fff]=\"\r\n currentOpenedSideMenue == 'filtrs' && sideMenuVisible\r\n \"\r\n [class.border-below]=\"\r\n sideMenuVisible && currentOpenedSideMenue == 'filtrs'\r\n \"\r\n class=\"columns-button d-flex flex-column align-items-center\"\r\n >\r\n <div>\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n <div class=\"side-menue-text\">Filter</div>\r\n </div>\r\n </div>\r\n <div\r\n class=\"h-100\"\r\n *ngIf=\"sideMenuVisible\"\r\n [ngStyle]=\"{ width: sideMenuVisible ? '250px' : '' }\"\r\n >\r\n <div class=\"h-100\">\r\n <ng-container\r\n *ngIf=\"currentOpenedSideMenue == 'cols' && sideMenuVisible\"\r\n >\r\n <ng-container *ngTemplateOutlet=\"columnPannel\"></ng-container>\r\n <!-- Column Items -->\r\n <div class=\"column-panel-body px-3\">\r\n <ng-container\r\n *ngFor=\"let col of columns; trackBy: trackByField\"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"columnPanelItem; context: { col: col }\"\r\n ></ng-container>\r\n </ng-container>\r\n </div>\r\n <hr />\r\n\r\n <div class=\"side-menu-row-groups\" style=\"height: 30%\">\r\n <ng-container\r\n *ngTemplateOutlet=\"sideMenuRowGroups\"\r\n ></ng-container>\r\n </div>\r\n </ng-container>\r\n <ng-container\r\n *ngIf=\"currentOpenedSideMenue == 'filtrs' && sideMenuVisible\"\r\n >\r\n <ng-container *ngTemplateOutlet=\"sideFilters\"></ng-container>\r\n </ng-container>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n <div\r\n [style.height.px]=\"footerRowHeight\"\r\n class=\"border-top\"\r\n [style.backgroundColor]=\"footerRowBackgroundColor\"\r\n >\r\n <!-- Rows: <span class=\"fw-500 ms-1\">{{ dataSet.length }}</span> -->\r\n\r\n <div\r\n class=\"pagination-container\"\r\n [style.height.px]=\"footerRowHeight\"\r\n [style.padding.px]=\"footerPadding\"\r\n >\r\n <div class=\"page-size\">\r\n <select\r\n [(ngModel)]=\"paginationConfig.limit\"\r\n (change)=\"onPageSizeChange()\"\r\n >\r\n <option *ngFor=\"let size of pageSizeOptions\" [value]=\"size\">\r\n {{ size }}\r\n </option>\r\n </select>\r\n <span class=\"separator\"> per page </span>\r\n </div>\r\n\r\n <div class=\"page-info\">\r\n Results:\r\n {{ (paginationConfig.page - 1) * paginationConfig.limit + 1 }}-{{\r\n paginationConfig.page * paginationConfig.limit <\r\n paginationConfig.totalResults\r\n ? paginationConfig.page * paginationConfig.limit\r\n : paginationConfig.totalResults\r\n }}\r\n of\r\n {{ paginationConfig.totalResults }}\r\n </div>\r\n\r\n <div class=\"page-buttons\">\r\n <button\r\n (click)=\"goToPage(paginationConfig.page - 1)\"\r\n [disabled]=\"paginationConfig.page === 1\"\r\n >\r\n \u2039\r\n </button>\r\n\r\n <ng-container *ngFor=\"let page of visiblePages\">\r\n <button\r\n *ngIf=\"page !== '...'\"\r\n (click)=\"goToPage(page)\"\r\n [class.active]=\"page === paginationConfig.page\"\r\n >\r\n {{ page }}\r\n </button>\r\n <span *ngIf=\"page === '...'\">...</span>\r\n </ng-container>\r\n\r\n <button\r\n (click)=\"goToPage(paginationConfig.page + 1)\"\r\n [disabled]=\"paginationConfig.page === paginationConfig.totalResults\"\r\n >\r\n \u203A\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<!-- ------------------------------------------------------------------------------------------------------------------------ -->\r\n<!-- ------------------------------------------------------------------------------------------------------------------------ -->\r\n<!-- Header Cell Template -->\r\n<!-- ------------------------------------------------------------------------------------------------------------------------ -->\r\n<!-- ------------------------------------------------------------------------------------------------------------------------ -->\r\n\r\n<ng-template\r\n #headerCell\r\n let-col\r\n let-pinnedRight=\"pinnedRight\"\r\n let-i=\"index\"\r\n let-columnIndex=\"index\"\r\n let-sections=\"section\"\r\n let-calledFromNestedPlaceholder=\"calledFromNestedPlaceholder\"\r\n>\r\n <div>\r\n <!-- Group Header -->\r\n <ng-container *ngIf=\"col.children?.length > 0; else flatHeader\">\r\n <div cdkDroplistGroup class=\"group-column-wrapper\">\r\n <!-- Parent Header -->\r\n <div\r\n *ngIf=\"shouldTheGroupHeaderShow(col)\"\r\n class=\"header-cell group-header\"\r\n [style.height.px]=\"headerRowHeight\"\r\n [style.min-height.px]=\"headerRowHeight\"\r\n [style.max-height.px]=\"headerRowHeight\"\r\n [class.border-right]=\"showVerticalBorder\"\r\n [style.gridColumn]=\"'span ' + col.children.length\"\r\n [style.fontWeight]=\"headerFontWeight\"\r\n [class.flex-row-reverse]=\"pinnedRight\"\r\n [class.justify-content-end]=\"pinnedRight\"\r\n style=\"grid-row: 1\"\r\n >\r\n <div\r\n class=\"group-header-content\"\r\n [title]=\"col.header\"\r\n [class.ms-2]=\"pinnedRight\"\r\n >\r\n {{ col.header }}\r\n </div>\r\n <div\r\n class=\"resize-handle\"\r\n (dblclick)=\"autosizeColumn(col.children)\"\r\n (mousedown)=\"\r\n $event.stopPropagation(); onResizeGroup($event, col, pinnedRight)\r\n \"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/resize-handle.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n </div>\r\n\r\n <!-- Child Headers and Filters -->\r\n\r\n <div\r\n class=\"d-flex\"\r\n cdkDropList\r\n cdkDropListOrientation=\"horizontal\"\r\n [cdkDropListData]=\"col.children\"\r\n (cdkDropListSorted)=\"onChildDroplistSorted($event, sections)\"\r\n (cdkDropListDropped)=\"onChildDroplistDroped($event)\"\r\n [cdkDropListSortingDisabled]=\"false\"\r\n [cdkDropListConnectedTo]=\"\r\n showRowsGrouping ? ['rows-grouping-top-container'] : []\r\n \"\r\n >\r\n <div\r\n cdkDrag\r\n [cdkDragData]=\"child\"\r\n *ngFor=\"let child of col.children; let i = index\"\r\n >\r\n <!-- Child Header -->\r\n <ng-container *ngIf=\"child.is_visible && !child['isRowGrouped']\">\r\n <div\r\n cdkDragHandle\r\n class=\"header-cell one-row-header-cells cursor-pointer\"\r\n [class.border-right]=\"showVerticalBorder\"\r\n [attr.field]=\"child.field\"\r\n [style.width.px]=\"child.width\"\r\n [style.min-width.px]=\"child.width\"\r\n [style.min-height.px]=\"headerRowHeight\"\r\n [style.max-height.px]=\"headerRowHeight\"\r\n [style.fontWeight]=\"headerFontWeight\"\r\n style=\"grid-row: 2\"\r\n [class.filter-applied-on-text]=\"isFilterAppliedOnColumn(child)\"\r\n >\r\n <div\r\n class=\"d-flex justify-content-between h-100 align-items-center w-100\"\r\n >\r\n <div\r\n class=\"d-flex justify-content-between align-items-center w-100\"\r\n [class.flex-row-reverse]=\"pinnedRight\"\r\n >\r\n <div\r\n class=\"text-ellipsis h-100 d-flex align-items-center w-100\"\r\n [title]=\"col.header\"\r\n [class.w-100]=\"pinnedRight\"\r\n >\r\n <div\r\n class=\"text-ellipsis h-100\"\r\n [class.editable-header]=\"child?.is_editable\"\r\n (click)=\"\r\n openThreeDotsMenu($event, child);\r\n openFilteronThreeDotsClick(child)\r\n \"\r\n >\r\n {{ child.header }}\r\n </div>\r\n </div>\r\n\r\n <div\r\n class=\"position-relative d-flex\"\r\n [class.flex-row-reverse]=\"pinnedRight\"\r\n >\r\n <div\r\n [class.me-2]=\"pinnedRight\"\r\n class=\"d-flex align-items-center\"\r\n *ngIf=\"child.pinned\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/pin-blue.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n <div\r\n class=\"three-dots p-1\"\r\n (click)=\"\r\n openThreeDotsMenu($event, child);\r\n isThreeDotsFilterOpen = false\r\n \"\r\n style=\"cursor: pointer\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath +\r\n 'data-grid/icons/three-dots-vertical.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n\r\n <!-- Only show menu if this column is active -->\r\n <div\r\n class=\"position-absolute\"\r\n *ngIf=\"activeCol === child\"\r\n style=\"top: -50%; z-index: 21\"\r\n [style.left.px]=\"\r\n -(!child?.pinned ? centerPinnedHeader.scrollLeft : 0)\r\n \"\r\n [style.top.px]=\"\r\n isThreeDotsFilterOpen\r\n ? showFilterRow || showColumnsGrouping\r\n ? headerRowHeight * 2 - 10\r\n : headerRowHeight - 10\r\n : 0\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n columnMenu;\r\n context: {\r\n col: child,\r\n isNestedTable: false,\r\n section: sections,\r\n columnIndex: columnIndex,\r\n childColIndex: i\r\n }\r\n \"\r\n ></ng-container>\r\n </div>\r\n\r\n <div\r\n class=\"resize-handle\"\r\n (dblclick)=\"autosizeColumn(child)\"\r\n (mousedown)=\"\r\n $event.stopPropagation();\r\n onResizeColumn($event, child)\r\n \"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath +\r\n 'data-grid/icons/resize-handle.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Filter Cell -->\r\n <div\r\n *ngIf=\"showFilterRow\"\r\n [style.backgroundColor]=\"headerBackgroundColor\"\r\n class=\"header-cell filter-cell\"\r\n [class.border-right]=\"showVerticalBorder\"\r\n [attr.field]=\"child.field\"\r\n [style.width.px]=\"child.width\"\r\n [style.min-width.px]=\"child.width\"\r\n [style.height.px]=\"headerRowHeight\"\r\n [style.min-height.px]=\"headerRowHeight\"\r\n [style.max-height.px]=\"headerRowHeight\"\r\n [class.border-right]=\"showVerticalBorder\"\r\n style=\"grid-row: 3\"\r\n >\r\n <div\r\n class=\"header-cell filter-cell\"\r\n [attr.field]=\"col.field\"\r\n [style.width.px]=\"col.width\"\r\n [style.min-width.px]=\"col.width\"\r\n [style.height.px]=\"headerRowHeight\"\r\n [style.min-height.px]=\"headerRowHeight\"\r\n [style.max-height.px]=\"headerRowHeight\"\r\n >\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Filter\"\r\n [(ngModel)]=\"child.filterValue\"\r\n (ngModelChange)=\"onFilterChange(child)\"\r\n (paste)=\"onFilterChange(child); applyDropdownFilter()\"\r\n [readonly]=\"\r\n child?.type == 'dropdown' || child?.type == 'image' || child?.type == 'array'\r\n \"\r\n [class.disabled-search-input]=\"\r\n child?.type == 'dropdown' || child?.type == 'image' || child?.type == 'array'\r\n \"\r\n (click)=\"\r\n $event.stopPropagation();\r\n openFilterFromDisabledSearchedInput(child)\r\n \"\r\n (keydown.enter)=\"applyDropdownFilter()\"\r\n (mousedown)=\"$event.stopPropagation()\"\r\n />\r\n <span\r\n class=\"filter-icon-wrapper\"\r\n (click)=\"$event.stopPropagation(); openFilter(child)\"\r\n [class.filter-applied]=\"isFilterAppliedOnColumn(child)\"\r\n [class.pe-none]=\"child?.type == 'image'\"\r\n ><span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n <span\r\n *ngIf=\"isFilterAppliedOnColumn(child)\"\r\n style=\"\r\n width: 7px;\r\n height: 7px;\r\n box-shadow: 0px 0px 3px #7486ff;\r\n background-color: rgb(0 163 233);\r\n position: absolute;\r\n right: 4px;\r\n top: 12px;\r\n \"\r\n class=\"rounded-circle d-block\"\r\n ></span\r\n ></span>\r\n\r\n <div\r\n class=\"position-absolute filter-row-filter-wrapper\"\r\n *ngIf=\"activeFilterCell?.field == child?.field\"\r\n style=\"top: 100%; right: 0; z-index: 99\"\r\n [style.left.px]=\"\r\n child?.pinned ? 0 : -centerPinnedHeader.scrollLeft\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"filterMenu; context: { col: child }\"\r\n ></ng-container>\r\n </div>\r\n </div>\r\n </div>\r\n </ng-container>\r\n <ng-template cdkDragPreview\r\n ><div class=\"p-2 border d-flex gap-2\">\r\n <div\r\n *ngIf=\"\r\n !draggingInGroupArea ||\r\n (child.is_groupable && draggingInGroupArea)\r\n \"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/arrows-move.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n <div *ngIf=\"draggingInGroupArea && !child.is_groupable\">\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/ban.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n <div>{{ child.header }}</div>\r\n </div>\r\n </ng-template>\r\n <ng-template cdkDragPlaceholder>\r\n <div *ngIf=\"!draggingInGroupArea\" class=\"position-relative\">\r\n <div\r\n *ngTemplateOutlet=\"\r\n childHeaderPlaceholder;\r\n context: {\r\n $implicit: child,\r\n index: i,\r\n sections: sections,\r\n calledFromNestedPlaceholder: true,\r\n }\r\n \"\r\n ></div>\r\n </div>\r\n <div\r\n *ngIf=\"draggingInGroupArea && child?.is_groupable\"\r\n class=\"d-flex gap-2 ms-2\"\r\n style=\"opacity: 0.6\"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n topGroupingRowPlaceholder;\r\n context: {\r\n $implicit: child,\r\n showChevron: false,\r\n pinnedRight: pinnedRight,\r\n sections: sections,\r\n index: i\r\n }\r\n \"\r\n ></ng-container>\r\n </div>\r\n </ng-template>\r\n </div>\r\n </div>\r\n </div>\r\n </ng-container>\r\n\r\n <!-- Flat Header || Single Header Cell-->\r\n <ng-template #flatHeader>\r\n <div\r\n class=\"group-column-wrapper\"\r\n *ngIf=\"col.is_visible && !col['isRowGrouped']\"\r\n >\r\n <!-- Full-height Header Cell (spans 2 rows visually) -->\r\n <div\r\n class=\"header-cell one-row-header-cells\"\r\n [attr.field]=\"col.field\"\r\n [style.width.px]=\"col.width\"\r\n [style.min-width.px]=\"col.width\"\r\n [class.border-right]=\"showVerticalBorder\"\r\n [style.min-height.px]=\"\r\n showColumnsGrouping ? headerRowHeight * 2 : headerRowHeight\r\n \"\r\n [style.height.px]=\"\r\n showColumnsGrouping ? headerRowHeight * 2 : headerRowHeight\r\n \"\r\n [style.fontWeight]=\"headerFontWeight\"\r\n style=\"grid-row: 1 / span 2\"\r\n >\r\n <div\r\n class=\"d-flex justify-content-between h-100 align-items-center w-100\"\r\n >\r\n <div\r\n class=\"d-flex justify-content-between w-100 align-items-center\"\r\n [class.flex-row-reverse]=\"pinnedRight\"\r\n >\r\n <div\r\n class=\"text-ellipsis h-100 d-flex align-items-center w-100\"\r\n [title]=\"col.header\"\r\n >\r\n <div\r\n class=\"text-ellipsis h-100 cursor-pointer\"\r\n [class.editable-header]=\"col?.is_editable\"\r\n [class.filter-applied-on-text]=\"isFilterAppliedOnColumn(col)\"\r\n (click)=\"\r\n openThreeDotsMenu($event, col);\r\n openFilteronThreeDotsClick(col)\r\n \"\r\n >\r\n {{ col.header }}\r\n </div>\r\n </div>\r\n\r\n <div\r\n class=\"position-relative d-flex\"\r\n [class.flex-row-reverse]=\"pinnedRight\"\r\n >\r\n <div\r\n [class.me-2]=\"pinnedRight\"\r\n class=\"d-flex align-items-center\"\r\n *ngIf=\"col?.pinned\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/pin-blue.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n <div\r\n [class.me-2]=\"col.order_by\"\r\n class=\"d-flex align-items-center\"\r\n *ngIf=\"sortingConfig?.field == col.field\"\r\n >\r\n <!-- Ascending Sort Icon -->\r\n <span\r\n *ngIf=\"sortingConfig?.order_by == 'asc'\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/sort-asc.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center mt-1 cursor-pointer\"\r\n (click)=\"sortDesc(col)\"\r\n [class.active]=\"sortingConfig?.order_by === 'asc'\"\r\n ></span>\r\n\r\n <!-- Descending Sort Icon -->\r\n <span\r\n *ngIf=\"sortingConfig?.order_by == 'desc'\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/sort-desc.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center mt-1 cursor-pointer\"\r\n (click)=\"sortAsc(col)\"\r\n [class.active]=\"sortingConfig?.order_by === 'desc'\"\r\n ></span>\r\n </div>\r\n <div\r\n class=\"three-dots p-1\"\r\n (click)=\"\r\n openThreeDotsMenu($event, col);\r\n isThreeDotsFilterOpen = false\r\n \"\r\n style=\"cursor: pointer\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath +\r\n 'data-grid/icons/three-dots-vertical.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n\r\n <!-- Only show menu if this column is active -->\r\n <div\r\n class=\"position-absolute\"\r\n *ngIf=\"activeCol === col\"\r\n style=\"top: -50%; z-index: 21\"\r\n [style.left.px]=\"\r\n -(!col?.pinned ? centerPinnedHeader.scrollLeft : 0)\r\n \"\r\n [style.top.px]=\"\r\n isThreeDotsFilterOpen\r\n ? showFilterRow || showColumnsGrouping\r\n ? headerRowHeight * 2 - 10\r\n : headerRowHeight - 10\r\n : 0\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n columnMenu;\r\n context: {\r\n col: col,\r\n isNestedTable: false,\r\n section: sections,\r\n columnIndex: columnIndex,\r\n childColIndex: 0\r\n },\r\n \"\r\n ></ng-container>\r\n </div>\r\n\r\n <div\r\n class=\"resize-handle\"\r\n [class.w-100]=\"col.pinned == 'right'\"\r\n (dblclick)=\"autosizeColumn(col)\"\r\n (mousedown)=\"\r\n $event.stopPropagation(); onResizeColumn($event, col)\r\n \"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/resize-handle.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Filter Cell -->\r\n <div\r\n *ngIf=\"showFilterRow\"\r\n [style.backgroundColor]=\"headerBackgroundColor\"\r\n class=\"header-cell filter-cell\"\r\n [class.border-right]=\"showVerticalBorder\"\r\n [attr.field]=\"col.field\"\r\n [style.width.px]=\"col.width\"\r\n [style.min-width.px]=\"col.width\"\r\n [style.height.px]=\"headerRowHeight\"\r\n [style.min-height.px]=\"headerRowHeight\"\r\n [style.max-height.px]=\"headerRowHeight\"\r\n >\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Filter\"\r\n [(ngModel)]=\"col.filterValue\"\r\n (ngModelChange)=\"onFilterChange(col)\"\r\n [readonly]=\"col?.type == 'dropdown' || col?.type == 'image' || col?.type == 'array'\"\r\n [class.disabled-search-input]=\"\r\n col?.type == 'dropdown' || col?.type == 'image' || col?.type == 'array'\r\n \"\r\n (paste)=\"onPasteInFilterRowSearch($event, col)\"\r\n (click)=\"\r\n $event.stopPropagation(); openFilterFromDisabledSearchedInput(col)\r\n \"\r\n (keydown.enter)=\"applyDropdownFilter()\"\r\n (mousedown)=\"$event.stopPropagation()\"\r\n />\r\n <span\r\n class=\"filter-icon-wrapper\"\r\n (click)=\"$event.stopPropagation(); openFilter(col)\"\r\n [class.filter-applied]=\"isFilterAppliedOnColumn(col)\"\r\n [class.pe-none]=\"col?.type == 'image'\"\r\n ><span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n <span\r\n *ngIf=\"isFilterAppliedOnColumn(col)\"\r\n style=\"\r\n width: 7px;\r\n height: 7px;\r\n box-shadow: 0px 0px 3px #7486ff;\r\n background-color: rgb(0 163 233);\r\n position: absolute;\r\n right: 4px;\r\n top: 12px;\r\n \"\r\n class=\"rounded-circle d-block\"\r\n ></span\r\n ></span>\r\n\r\n <div\r\n class=\"position-absolute filter-row-filter-wrapper\"\r\n *ngIf=\"activeFilterCell === col\"\r\n style=\"top: 100%; right: 0; z-index: 99\"\r\n [style.left.px]=\"col?.pinned ? 0 : -centerPinnedHeader.scrollLeft\"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"filterMenu; context: { col: col }\"\r\n ></ng-container>\r\n </div>\r\n </div>\r\n </div>\r\n </ng-template>\r\n </div>\r\n</ng-template>\r\n\r\n<!-- -------------------------------------------------------------------------------------------------------------------------------------------------------------------- -->\r\n<!-- -------------------------------------------------------------------------------------------------------------------------------------------------------------------- -->\r\n<!-- Body Cell Template -->\r\n<!-- -------------------------------------------------------------------------------------------------------------------------------------------------------------------- -->\r\n<!-- -------------------------------------------------------------------------------------------------------------------------------------------------------------------- -->\r\n\r\n<ng-template\r\n #rowCell\r\n let-row\r\n let-columns=\"columns\"\r\n let-isEven=\"isEven\"\r\n let-isOdd=\"isOdd\"\r\n let-isLeftSection=\"isLeft\"\r\n let-section=\"section\"\r\n let-rowIndex=\"rowIndex\"\r\n let-isTotalRow=\"isTotalRow\"\r\n>\r\n <!-- Check if row is a group -->\r\n <ng-container\r\n *ngTemplateOutlet=\"groupRowTemplate; context: { $implicit: row, depth: 0 }\"\r\n ></ng-container>\r\n <ng-template #groupRowTemplate let-row let-depth=\"depth\">\r\n <ng-container *ngIf=\"row.isGroup; else regularRow\">\r\n <!-- Group Header -->\r\n <div\r\n class=\"group-header-row d-flex align-items-center\"\r\n [style.height.px]=\"rowHeight\"\r\n [class.border-below]=\"section !== 'center'\"\r\n [style.width]=\"\r\n section === 'center'\r\n ? (centerScrollableBody?.scrollWidth ?? 0) + 'px'\r\n : '100%'\r\n \"\r\n >\r\n <div\r\n *ngIf=\"section == 'left'\"\r\n class=\"h-100 d-flex\"\r\n [style.width.px]=\"leftPinnedHeader.offsetWidth - 1\"\r\n [class.row-selected]=\"rowSelectedIndexes.has(row.__virtualIndex)\"\r\n >\r\n <div\r\n *ngIf=\"showSerialNumber\"\r\n style=\"width: 50px\"\r\n class=\"d-flex align-items-center h-100 border-right justify-content-end pe-2 s-no\"\r\n [style.backgroundColor]=\"checkboxesBackgroundColor\"\r\n [style.width.px]=\"55\"\r\n [style.cursor]=\"\r\n 'url(' +\r\n singleSpaAssetsPath +\r\n 'data-grid/icons/arrow-right.svg), auto'\r\n \"\r\n (mousedown)=\"onRowMouseDown(row.__virtualIndex, $event)\"\r\n (mouseover)=\"onRowMouseOver(row.__virtualIndex, $event)\"\r\n [style.color]=\"checkboxesColor\"\r\n >\r\n {{ getStartIndex() + (row.__virtualIndex - 1) || \"\" }}\r\n </div>\r\n <div\r\n *ngIf=\"showCheckboxes\"\r\n style=\"width: 50px\"\r\n class=\"d-flex align-items-center justify-content-center h-100 border-right\"\r\n [style.backgroundColor]=\"checkboxesBackgroundColor\"\r\n [class.row-selected]=\"rowSelectedIndexes.has(row.__virtualIndex)\"\r\n [class.left-selection-border]=\"\r\n rowSelectedIndexes.has(row.__virtualIndex)\r\n \"\r\n [class.first-row-selected]=\"firstSelectedRow === row.__virtualIndex\"\r\n [class.last-row-selected]=\"lastSelectedRow === row.__virtualIndex\"\r\n [style.color]=\"checkboxesColor\"\r\n >\r\n <input\r\n style=\"width: 16px; height: 16px\"\r\n type=\"checkbox\"\r\n [checked]=\"getGroupCheckedState(row) === true\"\r\n [indeterminate]=\"getGroupCheckedState(row) === undefined\"\r\n (change)=\"selectGroupRow($event, row)\"\r\n />\r\n\r\n </div>\r\n </div>\r\n\r\n <div\r\n *ngIf=\"section == 'center'\"\r\n [style.width.px]=\"centerPinnedHeader.scrollWidth\"\r\n [style.minWidth.px]=\"centerPinnedHeader.scrollWidth\"\r\n class=\"d-flex align-items-center ps-2 h-100 border-below\"\r\n [class.row-selected]=\"rowSelectedIndexes.has(row.__virtualIndex)\"\r\n [class.first-row-selected]=\"firstSelectedRow === row.__virtualIndex\"\r\n [class.last-row-selected]=\"lastSelectedRow === row.__virtualIndex\"\r\n >\r\n <div\r\n class=\"d-flex align-items-center justify-content-between\"\r\n [style.paddingLeft.px]=\"depth > 0 ? depth * 30 : 0\"\r\n >\r\n <span class=\"me-2 filter-icon-wrapper\" (click)=\"toggleExpand(row)\">\r\n <span\r\n class=\"data-grid-svg-icon align-items-center d-flex\"\r\n [inlineSVG]=\"\r\n row.isExpand\r\n ? singleSpaAssetsPath + 'data-grid/icons/chevron-down.svg'\r\n : singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\r\n \"\r\n ></span>\r\n </span>\r\n <strong (click)=\"toggleExpand(row)\" class=\"cursor-pointer\">\r\n {{ row.groupValue }} ({{ countLeafRows(row) }})\r\n </strong>\r\n </div>\r\n </div>\r\n\r\n <div\r\n *ngIf=\"section == 'right'\"\r\n [style.width.px]=\"rightPinnedHeader.offsetWidth\"\r\n [class.row-selected]=\"rowSelectedIndexes.has(row.__virtualIndex)\"\r\n [class.first-row-selected]=\"firstSelectedRow === row.__virtualIndex\"\r\n [class.last-row-selected]=\"lastSelectedRow === row.__virtualIndex\"\r\n ></div>\r\n </div>\r\n\r\n <!-- Recursive Children -->\r\n <div class=\"group-children\" *ngIf=\"row.isExpand\" [@slideToggle]>\r\n <ng-container\r\n *ngFor=\"let child of row.children; let i = index; trackBy: trackById\"\r\n >\r\n <ng-container *ngIf=\"child.isGroup; else dataRow\">\r\n <!-- Recursive call for nested group -->\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n groupRowTemplate;\r\n context: { $implicit: child, depth: depth + 1 }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n\r\n <ng-template #dataRow>\r\n <!-- Regular data row -->\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n rowCell;\r\n context: {\r\n $implicit: child,\r\n columns: columns,\r\n isEven: i % 2 === 0,\r\n isOdd: i % 2 !== 0,\r\n isLeft: isLeftSection,\r\n section: section,\r\n isTotalRow: isTotalRow\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-template>\r\n </ng-container>\r\n </div>\r\n </ng-container>\r\n </ng-template>\r\n\r\n <!-- Regular row (not a group) -->\r\n <ng-template #regularRow>\r\n <div\r\n class=\"d-flex\"\r\n [style.height.px]=\"rowHeight\"\r\n [style.minHeight.px]=\"rowHeight\"\r\n [style.maxHeight.px]=\"rowHeight\"\r\n >\r\n <span\r\n class=\"d-flex align-items-center justify-content-center cursor-pointer border-below\"\r\n style=\"min-width: 30px; height: 100%\"\r\n *ngIf=\"\r\n section == 'center' && (gridType === 'Assets' || gridType === 'Tasks')\r\n \"\r\n [ngStyle]=\"{\r\n 'background-color': rowSelectedIndexes.has(row.__virtualIndex)\r\n ? null\r\n : getBackgroundColor(row, isEven, section)\r\n }\"\r\n [class.selected-cell]=\"rowSelectedIndexes.has(row.__virtualIndex)\"\r\n [class.first-row-selected]=\"firstSelectedRow === row.__virtualIndex\"\r\n [class.last-row-selected]=\"lastSelectedRow === row.__virtualIndex\"\r\n >\r\n <span\r\n (click)=\"toggleDetailRowExpand(row)\"\r\n *ngIf=\"row?.detail?.result?.length || gridType === 'Tasks'\"\r\n class=\"data-grid-svg-icon filter-icon-wrapper\"\r\n [inlineSVG]=\"\r\n isDetailsExpanded(row)\r\n ? singleSpaAssetsPath + 'data-grid/icons/chevron-down.svg'\r\n : singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\r\n \"\r\n ></span>\r\n </span>\r\n <div\r\n [style.min-width.px]=\"\r\n section == 'center' && groupedColumns?.length ? groupBoxPadding : 0\r\n \"\r\n [class.row-selected]=\"rowSelectedIndexes.has(row.__virtualIndex)\"\r\n [class.first-row-selected]=\"firstSelectedRow === row.__virtualIndex\"\r\n [class.last-row-selected]=\"lastSelectedRow === row.__virtualIndex\"\r\n (contextmenu)=\"onRightClick($event, row)\"\r\n [style.height.px]=\"rowHeight\"\r\n class=\"data-grid-row h-100\"\r\n [class.even-row]=\"isEven\"\r\n [class.odd-row]=\"isOdd\"\r\n [class.hovered-row]=\"hoveredRowId === (row._id || row.id)\"\r\n (mouseenter)=\"onRowHover(row)\"\r\n (mouseleave)=\"onRowLeave()\"\r\n [ngStyle]=\"{\r\n 'background-color': getBackgroundColor(row, isEven, section)\r\n }\"\r\n [style.minHeight.px]=\"rowHeight\"\r\n [style.maxHeight.px]=\"rowHeight\"\r\n ></div>\r\n <div\r\n (contextmenu)=\"onRightClick($event, row)\"\r\n [style.height.px]=\"rowHeight\"\r\n class=\"data-grid-row\"\r\n [class.even-row]=\"isEven\"\r\n [class.odd-row]=\"isOdd\"\r\n [class.hovered-row]=\"hoveredRowId === (row._id || row.id)\"\r\n (mouseenter)=\"onRowHover(row)\"\r\n (mouseleave)=\"onRowLeave()\"\r\n [ngStyle]=\"{\r\n 'background-color': getBackgroundColor(row, isEven, section)\r\n }\"\r\n >\r\n <div\r\n [style.backgroundColor]=\"checkboxesBackgroundColor\"\r\n class=\"select-all-checkbox-cell justify-content-end pe-2 s-no\"\r\n [style.width.px]=\"55\"\r\n *ngIf=\"isLeftSection && showSerialNumber\"\r\n [style.cursor]=\"\r\n 'url(' +\r\n singleSpaAssetsPath +\r\n 'data-grid/icons/arrow-right.svg), auto'\r\n \"\r\n (mousedown)=\"onRowMouseDown(row.__virtualIndex, $event)\"\r\n (mouseover)=\"onRowMouseOver(row.__virtualIndex, $event)\"\r\n [style.color]=\"checkboxesColor\"\r\n >\r\n {{ getStartIndex() + (row.__virtualIndex - 1) }}\r\n </div>\r\n <div\r\n class=\"border-below\"\r\n [style.backgroundColor]=\"\r\n rowSelectedIndexes.has(row.__virtualIndex)\r\n ? selectedRowsBackgroundColor\r\n : checkboxesBackgroundColor\r\n \"\r\n class=\"select-all-checkbox-cell\"\r\n *ngIf=\"isLeftSection && showCheckboxes\"\r\n [class.left-selection-border]=\"\r\n rowSelectedIndexes.has(row.__virtualIndex)\r\n \"\r\n [class.first-row-selected]=\"firstSelectedRow === row.__virtualIndex\"\r\n [class.last-row-selected]=\"lastSelectedRow === row.__virtualIndex\"\r\n [style.minHeight.px]=\"rowHeight - 1\"\r\n [style.maxHeight.px]=\"rowHeight\"\r\n >\r\n <input\r\n *ngIf=\"hasAnyVisibleColumn\"\r\n style=\"width: 16px; height: 16px\"\r\n type=\"checkbox\"\r\n [checked]=\"isRowSelected(row)\"\r\n (change)=\"toggleRowSelection(row)\"\r\n />\r\n </div>\r\n\r\n <!-- Render all columns -->\r\n <ng-container\r\n *ngFor=\"\r\n let col of columns;\r\n trackBy: trackByField;\r\n let colIndex = index\r\n \"\r\n >\r\n <ng-container *ngIf=\"col.children?.length > 0; else flatColumn\">\r\n <ng-container\r\n *ngFor=\"\r\n let child of col.children;\r\n trackBy: trackByField;\r\n let subColIndex = index\r\n \"\r\n >\r\n <ng-container *ngIf=\"child?.is_visible && !child?.isRowGrouped\">\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n cellTemplate;\r\n context: {\r\n col: child,\r\n row: row,\r\n rowIndex: rowIndex,\r\n colIndex: colIndex,\r\n subColIndex: subColIndex,\r\n section: section,\r\n isTotalRow: isTotalRow\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </ng-container>\r\n </ng-container>\r\n\r\n <ng-template #flatColumn>\r\n <ng-container *ngIf=\"col?.is_visible && !col?.isRowGrouped\">\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n cellTemplate;\r\n context: {\r\n col: col,\r\n row: row,\r\n rowIndex: rowIndex,\r\n colIndex: colIndex,\r\n subColIndex: null,\r\n section: section,\r\n isTotalRow: isTotalRow\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </ng-template>\r\n </ng-container>\r\n </div>\r\n </div>\r\n\r\n <div\r\n [@slideToggle]\r\n *ngIf=\"section === 'left' && isDetailsExpanded(row)\"\r\n class=\"accordion-details\"\r\n style=\"max-height: 350px; overflow: hidden\"\r\n [style.maxHeight.px]=\"hasHorizontalScroll ? 339 : 341\"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n leftRightNestedPlaceholder;\r\n context: { $implicit: row }\r\n \"\r\n >\r\n </ng-container>\r\n </div>\r\n\r\n <div\r\n [@slideToggle]\r\n *ngIf=\"section === 'center' && isDetailsExpanded(row)\"\r\n class=\"accordion-details center-section\"\r\n style=\"\r\n max-height: 350px;\r\n overflow-y: hidden;\r\n overflow-x: auto;\r\n scrollbar-width: thin;\r\n \"\r\n #nestedTable\r\n [style.width]=\"\r\n hasRightPinnedColumns\r\n ? '100%'\r\n : hasVerticalScroll\r\n ? 'calc(100% - 12px)'\r\n : '100%'\r\n \"\r\n >\r\n <ng-container *ngIf=\"gridType == 'Assets'\">\r\n <ng-container\r\n *ngTemplateOutlet=\"nestedTableTemplate; context: { $implicit: row }\"\r\n ></ng-container>\r\n </ng-container>\r\n <ng-container *ngIf=\"gridType == 'Tasks'\">\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n taskManagementTemplate;\r\n context: { taskDetails: row }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </div>\r\n\r\n <div\r\n [@slideToggle]\r\n *ngIf=\"section === 'right' && isDetailsExpanded(row)\"\r\n class=\"accordion-details\"\r\n style=\"max-height: 350px; overflow: hidden\"\r\n [style.maxHeight.px]=\"hasHorizontalScroll ? 339 : 341\"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n leftRightNestedPlaceholder;\r\n context: { $implicit: row }\r\n \"\r\n >\r\n </ng-container>\r\n </div>\r\n </ng-template>\r\n</ng-template>\r\n\r\n<!-- Actual Cell is Here -->\r\n<ng-template\r\n #cellTemplate\r\n let-col=\"col\"\r\n let-row=\"row\"\r\n let-section=\"section\"\r\n let-subColIndex=\"subColIndex\"\r\n let-rowIndex=\"rowIndex\"\r\n let-colIndex=\"colIndex\"\r\n let-isTotalRow=\"isTotalRow\"\r\n>\r\n <div\r\n #cellContainer\r\n (click)=\"\r\n editingKey = ''; setActiveCell(row, col); collapseAllExpandedCells()\r\n \"\r\n [style.fontWeight]=\"bodyFontWeight\"\r\n [class.border-right]=\"showVerticalBorder\"\r\n class=\"cell overflow-visible position-relative data-grid-cell\"\r\n [attr.field]=\"col.field\"\r\n [style.width.px]=\"col.width\"\r\n [style.min-width.px]=\"col.width\"\r\n [style.fontSize.px]=\"bodyTextFontsSize\"\r\n [style.minHeight.px]=\"rowHeight\"\r\n [style.maxHeight.px]=\"rowHeight\"\r\n [class.active-cell]=\"\r\n isActiveCell(row, col) && !isEditing(row, col) && selectedKeys.size == 1\r\n \"\r\n (dblclick)=\"\r\n $event.stopPropagation();\r\n $event.preventDefault();\r\n enableEdit(row, col, false, cellContainer)\r\n \"\r\n [class.row-selected]=\"rowSelectedIndexes.has(row.__virtualIndex)\"\r\n [class.first-row-selected]=\"firstSelectedRow === row?.__virtualIndex\"\r\n [class.last-row-selected]=\"lastSelectedRow === row?.__virtualIndex\"\r\n tabindex=\"-1\"\r\n (keydown.enter)=\"$event.preventDefault(); enableEdit(row, col)\"\r\n (mousedown)=\"\r\n startSelection(\r\n row.__virtualIndex,\r\n colIndex,\r\n subColIndex ?? 0,\r\n col.field,\r\n $event,\r\n section\r\n )\r\n \"\r\n (mouseenter)=\"\r\n extendSelection(\r\n row.__virtualIndex,\r\n colIndex,\r\n subColIndex ?? 0,\r\n col.field,\r\n $event,\r\n section\r\n )\r\n \"\r\n (mouseup)=\"endSelection()\"\r\n [class.selected-cell]=\"\r\n isSelected(\r\n row.__virtualIndex,\r\n colIndex,\r\n subColIndex ?? 0,\r\n col.field,\r\n section\r\n )\r\n \"\r\n [class.top-border]=\"\r\n isTopBorder(row.__virtualIndex, colIndex, subColIndex, section)\r\n \"\r\n [class.bottom-border]=\"\r\n isBottomBorder(row.__virtualIndex, colIndex, subColIndex, section)\r\n \"\r\n [class.left-border]=\"\r\n isLeftBorder(row.__virtualIndex, colIndex, subColIndex, section)\r\n \"\r\n [class.right-border]=\"\r\n isRightBorder(row.__virtualIndex, colIndex, subColIndex, section)\r\n \"\r\n [class.top-left-corner]=\"\r\n isTopLeftCorner(row.__virtualIndex, colIndex, subColIndex, section)\r\n \"\r\n [class.top-right-corner]=\"\r\n isTopRightCorner(row.__virtualIndex, colIndex, subColIndex, section)\r\n \"\r\n [class.bottom-left-corner]=\"\r\n isBottomLeftCorner(row.__virtualIndex, colIndex, subColIndex, section)\r\n \"\r\n [class.bottom-right-corner]=\"\r\n isBottomRightCorner(row.__virtualIndex, colIndex, subColIndex, section)\r\n \"\r\n >\r\n <!-- (mousedown)=\"startSelection(row.__virtualIndex, colIndex, subColIndex ?? 0, col.field, $event)\"\r\n (mouseenter)=\"extendSelection(row.__virtualIndex, colIndex, subColIndex ?? 0, col.field, $event)\"\r\n (mouseup)=\"endSelection()\"\r\n [class.selected-cell]=\"isSelected(row.__virtualIndex, colIndex, subColIndex ?? 0, col.field)\" -->\r\n <div\r\n class=\"table-cell\"\r\n [class.active-for-editing]=\"\r\n isEditing(row, col) &&\r\n (getNestedValue(row, col.field)?.length === undefined ||\r\n getNestedValue(row, col.field)?.length <= 50)\r\n \"\r\n >\r\n <div\r\n (click)=\"$event.stopPropagation()\"\r\n *ngIf=\"\r\n isEditing(row, col) &&\r\n (getNestedValue(row, col.field)?.length === undefined ||\r\n (getNestedValue(row, col.field)?.length <= 50 &&\r\n !expandedCells.size));\r\n else viewMode\r\n \"\r\n >\r\n\r\n <ng-container *ngIf=\"col.cellEditor; else builtInEditors\">\r\n <ng-container\r\n [cellEditor]=\"col.cellEditor\"\r\n [rowData]=\"row\"\r\n [colData]=\"col\"\r\n [cellValue]=\"getNestedValue(row, col.field)\"\r\n (editorEvent)=\"finishEdit($event)\"\r\n ></ng-container>\r\n </ng-container>\r\n\r\n <ng-template #builtInEditors>\r\n <ng-container [ngSwitch]=\"col?.type\">\r\n <!-- Text Input -->\r\n <input\r\n [style.height.px]=\"rowHeight - 10\"\r\n *ngSwitchCase=\"'input'\"\r\n type=\"text\"\r\n [(ngModel)]=\"row[col.field]\"\r\n (blur)=\"disableEdit(row, col)\"\r\n autofocus\r\n (keydown.enter)=\"blurInput($event, row, col)\"\r\n class=\"form-control form-control-sm\"\r\n (mousedown)=\"$event.stopPropagation()\"\r\n />\r\n\r\n <!-- Number Input -->\r\n <input\r\n [style.height.px]=\"rowHeight - 8\"\r\n *ngSwitchCase=\"'number'\"\r\n #numberInput=\"ngModel\"\r\n #numberRef\r\n (keypress)=\"allowOnlyNumbers($event)\"\r\n type=\"number\"\r\n required\r\n [(ngModel)]=\"row[col.field]\"\r\n (blur)=\"disableEdit(row, col, numberInput)\"\r\n autofocus\r\n (keydown.enter)=\"blurInput($event, row, col)\"\r\n class=\"form-control form-control-sm\"\r\n [ngClass]=\"{\r\n 'is-invalid': numberInput.invalid\r\n }\"\r\n (mousedown)=\"$event.stopPropagation()\"\r\n />\r\n\r\n <!-- Date Input -->\r\n <input\r\n [style.height.px]=\"rowHeight - 8\"\r\n *ngSwitchCase=\"'date'\"\r\n type=\"date\"\r\n [(ngModel)]=\"row[col.field]\"\r\n (blur)=\"disableEdit(row, col, dateInput)\"\r\n autofocus\r\n class=\"form-control form-control-sm\"\r\n #dateInput=\"ngModel\"\r\n (keydown.enter)=\"blurInput($event, row, col)\"\r\n [ngClass]=\"{\r\n 'is-invalid': dateInput.invalid\r\n }\"\r\n (mousedown)=\"$event.stopPropagation()\"\r\n />\r\n\r\n <!-- Dropdown -->\r\n <!-- ng-select like dropdown -->\r\n <div\r\n *ngSwitchCase=\"'dropdown'\"\r\n class=\"dropdown w-100\"\r\n (blur)=\"disableEdit(row, col)\"\r\n >\r\n <!-- Trigger -->\r\n <button\r\n class=\"form-select form-select-sm text-start w-100 text-ellipsis\"\r\n type=\"button\"\r\n data-bs-toggle=\"dropdown\"\r\n aria-expanded=\"false\"\r\n [style.minHeight.px]=\"rowHeight - 10\"\r\n data-bs-display=\"static\"\r\n (mousedown)=\"$event.stopPropagation()\"\r\n >\r\n <ng-container>\r\n {{\r\n getNestedValue(row, col.field)?.value ||\r\n getNestedValue(row, col.field)?.name ||\r\n getNestedValue(row, col.field)\r\n }}\r\n </ng-container>\r\n <ng-template #placeholder> Select options... </ng-template>\r\n </button>\r\n\r\n <!-- Menu -->\r\n <div\r\n class=\"dropdown-menu w-100 p-0 cell-editing-dropdown-menu rounded-3\"\r\n [class.show]=\"isEditing(row, col)\"\r\n >\r\n <!-- Search -->\r\n <div class=\"px-2 py-1 editing-dropdown-search-input\" *ngIf=\"col?.column_dropdown_value?.length > 5\">\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Search...\"\r\n [(ngModel)]=\"editinDropdownSearch\"\r\n (mousedown)=\"$event.stopPropagation()\"\r\n />\r\n </div>\r\n <cdk-virtual-scroll-viewport \r\n itemSize=\"35\" \r\n class=\"dropdown-viewport\"\r\n style=\"height: 120px\"\r\n >\r\n <div\r\n [class.selected]=\"getNestedValue(row, col.field) == option?.value || getNestedValue(row, col.field) == option\"\r\n class=\"px-2 py-1 d-flex align-items-center dropdown-item\"\r\n *cdkVirtualFor=\"\r\n let option of col.column_dropdown_value \r\n | filter : editinDropdownSearch : 'value'\r\n \"\r\n (click)=\"setNestedValue(row, col, option, true); editingKey = null\"\r\n >\r\n <label\r\n \r\n class=\"form-check-label d-flex align-items-center mb-0 cursor-pointer\"\r\n [for]=\"col.field + '-' + (option.value || option)\"\r\n >\r\n {{ option.value || option }}\r\n </label>\r\n </div>\r\n </cdk-virtual-scroll-viewport>\r\n\r\n </div>\r\n </div>\r\n\r\n <input\r\n *ngSwitchCase=\"'email'\"\r\n [style.height.px]=\"rowHeight - 10\"\r\n [style.maxHeight.px]=\"rowHeight - 10\"\r\n #emailModel=\"ngModel\"\r\n #emailInput\r\n type=\"email\"\r\n [(ngModel)]=\"row[col.field]\"\r\n name=\"{{ col.field }}\"\r\n required\r\n pattern=\"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$\"\r\n (blur)=\"disableEdit(row, col, emailModel)\"\r\n (keydown.enter)=\"blurInput($event, row, col)\"\r\n autofocus\r\n class=\"form-control form-control-sm\"\r\n [ngClass]=\"{\r\n 'is-invalid': emailModel.invalid\r\n }\"\r\n (mousedown)=\"$event.stopPropagation()\"\r\n />\r\n <!-- Default fallback -->\r\n <input\r\n *ngSwitchDefault\r\n [style.height.px]=\"rowHeight - 10\"\r\n [style.maxHeight.px]=\"rowHeight - 10\"\r\n #textModel=\"ngModel\"\r\n #textInput\r\n type=\"text\"\r\n (keydown.enter)=\"blurInput($event, row, col)\"\r\n [(ngModel)]=\"row[col.field]\"\r\n name=\"{{ col.field }}\"\r\n required\r\n (blur)=\"disableEdit(row, col, textModel)\"\r\n autofocus\r\n class=\"form-control form-control-sm\"\r\n [ngClass]=\"{\r\n 'is-invalid': textModel.invalid\r\n }\"\r\n (mousedown)=\"$event.stopPropagation()\"\r\n />\r\n </ng-container>\r\n </ng-template>\r\n\r\n </div>\r\n\r\n <!-- Display mode -->\r\n <ng-template #viewMode>\r\n <div\r\n class=\"d-flex justify-content-between align-items-center w-100 overflow-hidden\"\r\n [ngClass]=\"getCellClasses(col, getNestedValue(row, col.field))\"\r\n >\r\n <!-- Field icon (for Tasks grid) -->\r\n <ng-container\r\n *ngIf=\"gridType === 'Tasks' && iconMap[col.field] && !isTotalRow\"\r\n >\r\n <span\r\n class=\"cursor-pointer me-2\"\r\n (click)=\"$event.preventDefault(); $event.stopPropagation()\"\r\n [inlineSVG]=\"iconMap[col.field](row, col)\"\r\n ></span>\r\n </ng-container>\r\n\r\n <!-- \u2705 Custom cell renderer support -->\r\n <ng-container *ngIf=\"col.cellRenderer; else defaultCell\">\r\n <ng-container\r\n [cellRenderInit]=\"col.cellRenderer\"\r\n [rowData]=\"row\"\r\n [colData]=\"col\"\r\n [cellValue]=\"getNestedValue(row, col?.field)\"\r\n (cellEvent)=\"onCellEvent($event)\"\r\n >\r\n </ng-container>\r\n </ng-container>\r\n\r\n <!-- \uD83E\uDDFE Default text-based cell rendering -->\r\n <ng-template #defaultCell>\r\n <div\r\n #cellText\r\n class=\"text-ellipsis flex-grow-1\"\r\n [title]=\"getCellTitle(row, col)\"\r\n >\r\n <!-- Normal cell -->\r\n <ng-container\r\n *ngIf=\"\r\n col?.type !== 'image' &&\r\n col?.field != 'image' &&\r\n col?.field != 'invoice.invoice_image' &&\r\n !isTotalRow\r\n \"\r\n >\r\n <ng-container *ngIf=\"col.is_amount\">{{\r\n currencySymbol\r\n }}</ng-container>\r\n {{getCellTitle(row, col)}}\r\n </ng-container>\r\n\r\n <!-- Total row -->\r\n <ng-container *ngIf=\"isTotalRow\">\r\n {{ getTotalAmount(col) }}\r\n </ng-container>\r\n\r\n <!-- Invoice Image -->\r\n <ng-container *ngIf=\"col.field == 'invoice.invoice_image'\">\r\n <div style=\"display: flex; align-items: center; zoom: 0.7\">\r\n <span\r\n title=\"{{ getNestedValue(row, col.field) || 'Attachment' }}\"\r\n (click)=\"downloadAttchment(getNestedValue(row, col.field))\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath +\r\n 'data-grid/document-icons/' +\r\n getExtention(getNestedValue(row, col.field)) +\r\n '.svg'\r\n \"\r\n ></span>\r\n </div>\r\n </ng-container>\r\n\r\n <!-- Image cell -->\r\n <ng-container *ngIf=\"col?.type == 'image' && !isTotalRow\">\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n defaultImagePlaceholder;\r\n context: { row: row, col: col }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </div>\r\n <span\r\n *ngIf=\"\r\n (!col?.cellRenderer && showCellDetailsBox &&\r\n getNestedValue(row, col.field)?.length > 50 && col?.type !== 'image') ||\r\n (isNestedValueArray(row, col.field) &&\r\n getNestedValue(row, col.field)?.length > 1)\r\n \"\r\n class=\"toggle-icon data-grid-svg-icon ms-2 cursor-pointer\"\r\n [inlineSVG]=\"\r\n isExpanded(row, col)\r\n ? singleSpaAssetsPath + 'data-grid/icons/chevron-down.svg'\r\n : singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\r\n \"\r\n (click)=\"\r\n $event.stopPropagation();\r\n toggleExpandOfLongCellText(row, col, columns, true)\r\n \"\r\n (dblclick)=\"$event.preventDefault(); $event.stopPropagation()\"\r\n ></span>\r\n </ng-template>\r\n <!-- Expand / Collapse icon -->\r\n </div>\r\n\r\n <!-- Expanded text -->\r\n <div\r\n class=\"position-absolute w-100 expanded-box\"\r\n *ngIf=\"isExpanded(row, col)\"\r\n [style.zIndex]=\"getZIndex(row, col)\"\r\n style=\"top: 100%; left: 0\"\r\n [attr.id]=\"(row.id || row._id) + '-' + (col.id || col._id)\"\r\n [class.invisible]=\"!showDetailsBox\"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n fullTextTemplate;\r\n context: {\r\n row: row,\r\n col: col,\r\n isArray: isNestedValueArray(row, col.field)\r\n }\r\n \"\r\n ></ng-container>\r\n </div>\r\n </ng-template>\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<!-- Headers Action List On clicking three dots -->\r\n\r\n<ng-template\r\n #columnMenu\r\n let-col=\"col\"\r\n let-isNestedTable=\"isNestedTable\"\r\n let-columns=\"columns\"\r\n let-section=\"section\"\r\n let-columnIndex=\"columnIndex\"\r\n let-childColIndex=\"childColIndex\"\r\n>\r\n <div\r\n class=\"column-menu three-dots-col-menu\"\r\n [class.visually-hidden]=\"isMenueHidden\"\r\n *ngIf=\"activeCol && !isThreeDotsFilterOpen\"\r\n [style.backgroundColor]=\"dropdownsBackgroundColor\"\r\n (click)=\"$event.stopPropagation()\"\r\n [style.color]=\"headerTextColor\"\r\n >\r\n <!-- Sort Ascending -->\r\n <div class=\"border-below pb-2\" [class.disable-sorting]=\"!col.is_sortable\">\r\n <span class=\"muted-text fs-7\" style=\"margin-left: 12px\">Sort</span>\r\n <div\r\n *ngIf=\"\r\n columnThreedotsMunuConfig?.showAscending &&\r\n (sortingConfig?.field != col.field ||\r\n sortingConfig?.order_by == 'desc')\r\n \"\r\n class=\"column-menu-item\"\r\n (click)=\"sortAsc(activeCol)\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrow-up.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n Sort Ascending\r\n </div>\r\n\r\n <!-- Sort Descending -->\r\n <div\r\n *ngIf=\"\r\n columnThreedotsMunuConfig?.showDescending &&\r\n (sortingConfig?.field != col.field ||\r\n sortingConfig?.order_by == 'asc')\r\n \"\r\n class=\"column-menu-item\"\r\n (click)=\"sortDesc(activeCol)\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrow-down.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n Sort Descending\r\n </div>\r\n\r\n <div\r\n *ngIf=\"\r\n sortingConfig?.field === col.field &&\r\n (sortingConfig?.order_by === 'asc' ||\r\n sortingConfig?.order_by === 'desc')\r\n \"\r\n class=\"column-menu-item\"\r\n (click)=\"resetSort(activeCol)\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/arrow-counterclockwise.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n Reset Sort\r\n </div>\r\n </div>\r\n <div class=\"py-2 border-below three-dots-filter\" [class.disable-sorting]=\"col?.type == 'image' || !col.is_search_able\">\r\n <div\r\n *ngIf=\"columnThreedotsMunuConfig?.showFilter\"\r\n class=\"column-menu-item three-dots-filter\"\r\n (click)=\"openFilteronThreeDotsClick(col)\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n Filter\r\n </div>\r\n </div>\r\n\r\n <div class=\"py-2 border-below\">\r\n <span class=\"muted-text fs-7\" style=\"margin-left: 12px\">Pin</span>\r\n <div\r\n *ngIf=\"columnThreedotsMunuConfig?.showPinleft && col?.pinned !== 'left'\"\r\n class=\"column-menu-item\"\r\n (click)=\"\r\n $event.stopPropagation();\r\n updateColumnPinInSourceByField(\r\n activeCol,\r\n 'left',\r\n isNestedTable,\r\n columns\r\n )\r\n \"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/pin-left.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span\r\n >Pin Left\r\n </div>\r\n\r\n <div\r\n *ngIf=\"\r\n columnThreedotsMunuConfig?.showPinright && col?.pinned !== 'right'\r\n \"\r\n class=\"column-menu-item\"\r\n (click)=\"\r\n $event.stopPropagation();\r\n updateColumnPinInSourceByField(\r\n activeCol,\r\n 'right',\r\n isNestedTable,\r\n columns\r\n )\r\n \"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/pin-right.svg'\"\r\n class=\"data-grid-svg-icon data-grid-svg-icon me-2\"\r\n ></span\r\n >Pin Right\r\n </div>\r\n\r\n <div\r\n *ngIf=\"col?.pinned\"\r\n class=\"column-menu-item\"\r\n (click)=\"\r\n $event.stopPropagation();\r\n updateColumnPinInSourceByField(\r\n activeCol,\r\n null,\r\n isNestedTable,\r\n columns\r\n )\r\n \"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/layout-three-columns.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span\r\n >Unpin\r\n </div>\r\n </div>\r\n\r\n <div\r\n *ngIf=\"columnThreedotsMunuConfig?.showAutosizeThisColumn\"\r\n class=\"column-menu-item\"\r\n (click)=\"autosizeColumn(activeCol)\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/arrows-expand-vertical.svg'\r\n \"\r\n class=\"me-2\"\r\n ></span>\r\n Autosize This Column\r\n </div>\r\n\r\n <!-- Autosize All Columns -->\r\n <div\r\n *ngIf=\"columnThreedotsMunuConfig?.showAutosizeAllColumns\"\r\n class=\"column-menu-item\"\r\n (click)=\"autosizeAllColumns()\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/arrows-angle-expand.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span\r\n >Autosize All Columns\r\n </div>\r\n\r\n <!-- Group By -->\r\n <div\r\n *ngIf=\"showRowsGrouping\"\r\n class=\"column-menu-item\"\r\n (click)=\"groupBy(activeCol)\"\r\n [class.disable-sorting]=\"!col.is_groupable\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/diagram-3.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n Group by {{ col.header }}\r\n </div>\r\n\r\n <!-- Choose Columns -->\r\n <div\r\n *ngIf=\"columnThreedotsMunuConfig?.showChoseColumns\"\r\n class=\"column-menu-item\"\r\n (click)=\"chooseColumns()\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/ui-checks-grid.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n Choose Columns\r\n </div>\r\n\r\n <!-- Reset Columns -->\r\n <div\r\n *ngIf=\"columnThreedotsMunuConfig?.showResetColumns\"\r\n class=\"column-menu-item\"\r\n (click)=\"resetColumns()\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/arrow-counterclockwise.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span\r\n >Reset Columns\r\n </div>\r\n </div>\r\n <div\r\n @slideToggle\r\n *ngIf=\"isThreeDotsFilterOpen && col?.is_search_able\"\r\n class=\"three-dots-col-menu position-relative\"\r\n [style.right.px]=\"getDynamicRight(col, section, columnIndex, childColIndex)\"\r\n [class.visually-hidden]=\"isMenueHidden\"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"filterMenu; context: { col: col }\"\r\n ></ng-container>\r\n </div>\r\n</ng-template>\r\n\r\n<!-- Filter Menue -->\r\n<ng-template #filterMenu let-col=\"col\">\r\n <div\r\n class=\"filter-menu-container filter-menu\"\r\n [style.backgroundColor]=\"dropdownsBackgroundColor\"\r\n >\r\n <!-- Dropdown Type -->\r\n <ng-container *ngIf=\"col?.type === 'dropdown'|| col?.type == 'array'; else textFilter\">\r\n <div class=\"filter-dropdown-section p-1\">\r\n <input\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Search...\"\r\n type=\"search\"\r\n [(ngModel)]=\"addFilterColumnInput\"\r\n />\r\n\r\n <div class=\"form-check mb-1 mt-2 ms-1 select-all-filter\">\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n [checked]=\"isAllSideFilterOptionsSelected(col)\"\r\n (change)=\"toggleSelectAllSideFilters(col, $event)\"\r\n id=\"selectAll_{{ col.field }}\"\r\n />\r\n <label class=\"form-check-label\" for=\"selectAll_{{ col.field }}\">\r\n Select All\r\n </label>\r\n </div>\r\n\r\n <!-- <div class=\"dropdown-options ps-1\">\r\n <div\r\n class=\"form-check mb-1\"\r\n *ngFor=\"\r\n let option of selectedColumnForFilter?.column_dropdown_value\r\n | filter : addFilterColumnInput : 'value';\r\n trackBy: trackById;\r\n let i = index\r\n \"\r\n >\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n [id]=\"i\"\r\n [checked]=\"\r\n currentFilterSelectedIds.has(option?.id ?? option?._id ?? option)\r\n \"\r\n (change)=\"toggleSelectionInFilter(option)\"\r\n />\r\n <label class=\"form-check-label fw-semibold\" [for]=\"i\">\r\n {{ option?.value ?? option?.name ?? option }}\r\n </label>\r\n </div>\r\n </div> -->\r\n <cdk-virtual-scroll-viewport\r\n itemSize=\"32\"\r\n class=\"filter-viewport\"\r\n style=\"height: 120px\"\r\n >\r\n <div\r\n class=\"form-check mb-1 ms-1\"\r\n *cdkVirtualFor=\"\r\n let option of selectedColumnForFilter?.column_dropdown_value\r\n | filter : addFilterColumnInput : 'value';\r\n trackBy: trackById\r\n \"\r\n >\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n [id]=\"option?.id ?? option?._id ?? option\"\r\n [checked]=\"\r\n currentFilterSelectedIds.has(option?.id ?? option?._id ?? option)\r\n \"\r\n (change)=\"toggleSelectionInFilter(option)\"\r\n />\r\n\r\n <label\r\n class=\"form-check-label fw-semibold\"\r\n [for]=\"option?.id ?? option?._id ?? option\"\r\n >\r\n {{ ((option?.value ?? option?.name ?? option) | titlecase ) }}\r\n </label>\r\n </div>\r\n </cdk-virtual-scroll-viewport>\r\n </div>\r\n </ng-container>\r\n\r\n <!-- Text Filter Section -->\r\n <ng-template #textFilter>\r\n <div class=\"filter-text-section\">\r\n <div class=\"form-group mb-2\">\r\n <select\r\n class=\"form-select form-select-sm custom-select\"\r\n [(ngModel)]=\"firstCondition\"\r\n >\r\n <ng-container *ngIf=\"selectedColumnForFilter?.type == 'string'\">\r\n <option value=\"contain\">Contains</option>\r\n <option value=\"does_not_contain\">Does Not Contain</option>\r\n <option value=\"equal\">Equals</option>\r\n <option value=\"before\">Starts With</option>\r\n <option value=\"after\">Ends With</option>\r\n </ng-container>\r\n\r\n <ng-container *ngIf=\"selectedColumnForFilter?.type == 'date'\">\r\n <option value=\"equal\">Equals To</option>\r\n <option value=\"not_equal\">Not Equal</option>\r\n <option value=\"after\">After</option>\r\n <option value=\"before\">Before</option>\r\n </ng-container>\r\n\r\n <ng-container *ngIf=\"selectedColumnForFilter?.type == 'number'\">\r\n <option value=\"equal\">Equals To</option>\r\n <option value=\"before\">Less Then </option>\r\n <option value=\"after\">Greater Then </option>\r\n <option value=\"less_then_equal\">less then Equal to</option>\r\n <option value=\"greater_then_equal\">Greater then Equal to </option>\r\n </ng-container>\r\n </select>\r\n </div>\r\n\r\n <input\r\n [type]=\"col?.type == 'string' ? 'text' : col?.type\"\r\n class=\"form-control form-control-sm mb-3\"\r\n placeholder=\"Value\"\r\n [(ngModel)]=\"firstValue\"\r\n #filterMenueTextchInput\r\n (keydown.enter)=\"applyDropdownFilter()\"\r\n />\r\n\r\n <div class=\"form-group mb-3 d-flex flex-row\">\r\n <div\r\n class=\"form-check form-check-inline m-0 col-4 d-flex align-items-center gap-1\"\r\n >\r\n <input\r\n class=\"form-check-input filter-radio-inputs\"\r\n type=\"radio\"\r\n name=\"condition\"\r\n [(ngModel)]=\"condition\"\r\n value=\"and\"\r\n id=\"and_{{ col.field }}\"\r\n (change)=\"cdr.detectChanges()\"\r\n />\r\n <label class=\"form-check-label mb-0 mt-1\" for=\"and_{{ col.field }}\"\r\n >AND</label\r\n >\r\n </div>\r\n <div\r\n class=\"form-check form-check-inline m-0 col-4 d-flex align-items-center gap-1 gap-1\"\r\n >\r\n <input\r\n class=\"form-check-input filter-radio-inputs\"\r\n type=\"radio\"\r\n name=\"condition\"\r\n [(ngModel)]=\"condition\"\r\n value=\"or\"\r\n id=\"or_{{ col.field }}\"\r\n (change)=\"cdr.detectChanges()\"\r\n />\r\n <label class=\"form-check-label mb-0 mt-1\" for=\"or_{{ col.field }}\"\r\n >OR</label\r\n >\r\n </div>\r\n <div\r\n class=\"form-check form-check-inline m-0 col-4 d-flex align-items-center gap-1 gap-1\"\r\n >\r\n <input\r\n class=\"form-check-input filter-radio-inputs\"\r\n type=\"radio\"\r\n name=\"condition\"\r\n [(ngModel)]=\"condition\"\r\n value=\"none\"\r\n id=\"none_{{ col.field }}\"\r\n (change)=\"cdr.detectChanges()\"\r\n />\r\n <label class=\"form-check-label mb-0 mt-1\" for=\"none_{{ col.field }}\"\r\n >None</label\r\n >\r\n </div>\r\n </div>\r\n <div @slideToggle *ngIf=\"firstValue && condition != 'none'\">\r\n <div class=\"form-group mb-2\">\r\n <select\r\n class=\"form-select form-select-sm custom-select\"\r\n [(ngModel)]=\"secondCondition\"\r\n >\r\n <ng-container *ngIf=\"selectedColumnForFilter?.type == 'string'\">\r\n <option value=\"contain\">Contains</option>\r\n <option value=\"does_not_contain\">Does Not Contain</option>\r\n <option value=\"equal\">Equals</option>\r\n <option value=\"before\">Starts With</option>\r\n <option value=\"after\">Ends With</option>\r\n </ng-container>\r\n\r\n <ng-container *ngIf=\"selectedColumnForFilter?.type == 'date'\">\r\n <option value=\"equal\">Equals To</option>\r\n <option value=\"not_equal\">Not Equal</option>\r\n <option value=\"after\">After</option>\r\n <option value=\"before\">Before</option>\r\n </ng-container>\r\n\r\n <ng-container *ngIf=\"selectedColumnForFilter?.type == 'number'\">\r\n <option value=\"equal\">Equals To</option>\r\n <option value=\"before\">Less Then </option>\r\n <option value=\"after\">Greater Then </option>\r\n <option value=\"less_then_equal\">less then Equal to</option>\r\n <option value=\"greater_then_equal\">Greater then Equal to </option>\r\n </ng-container>\r\n </select>\r\n </div>\r\n\r\n <input\r\n [type]=\"col?.type == 'string' ? 'text' : col?.type\"\r\n class=\"form-control form-control-sm mb-3\"\r\n placeholder=\"Second Value\"\r\n [(ngModel)]=\"secondValue\"\r\n />\r\n </div>\r\n </div>\r\n </ng-template>\r\n\r\n <!-- Actions -->\r\n <div class=\"d-flex gap-2 mt-2\">\r\n <div\r\n class=\"btn btn-sm btn-primary d-flex justify-content-center align-items-center w-100\"\r\n style=\"height: 30px\"\r\n (click)=\"applyDropdownFilter()\"\r\n >\r\n Apply\r\n </div>\r\n <div\r\n class=\"btn btn-sm btn-secondary d-flex justify-content-center align-items-center w-100\"\r\n style=\"height: 30px\"\r\n (click)=\"resetSideFilter(col)\"\r\n >\r\n Reset\r\n </div>\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<!-- Side Menue -->\r\n\r\n<!-- Column Pannel / Pivot Mode / Searching -->\r\n\r\n<ng-template #columnPannel>\r\n <div class=\"column-panel-header\">\r\n <!-- Pivot Toggle -->\r\n <div\r\n class=\"form-check form-switch d-flex align-items-center mb-2 pivot-mode px-5 ms-2 d-none\"\r\n >\r\n <input\r\n class=\"form-check-input me-2\"\r\n type=\"checkbox\"\r\n id=\"pivotToggle\"\r\n [(ngModel)]=\"pivotMode\"\r\n />\r\n <label class=\"form-check-label\" for=\"pivotToggle\">Pivot Mode</label>\r\n </div>\r\n\r\n <!-- Select All & Search -->\r\n <div class=\"d-flex align-items-center mb-2 px-3 mt-3\">\r\n <span class=\"filter-icon-wrapper me-2\" *ngIf=\"showColumnsGrouping\">\r\n <span\r\n class=\"toggle-icon data-grid-svg-icon\"\r\n [inlineSVG]=\"\r\n accordionState === 'all'\r\n ? singleSpaAssetsPath + 'data-grid/icons/chevron-down.svg'\r\n : accordionState === 'some'\r\n ? singleSpaAssetsPath + 'data-grid/icons/dash.svg'\r\n : singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\r\n \"\r\n (click)=\"toggleAllAccordions()\"\r\n ></span>\r\n </span>\r\n <input\r\n type=\"checkbox\"\r\n class=\"form-check-input me-2\"\r\n [checked]=\"allColumnsSelected()\"\r\n (change)=\"toggleAllColumnsVisibility()\"\r\n />\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Search columns...\"\r\n [(ngModel)]=\"columnSearch\"\r\n />\r\n </div>\r\n\r\n <!-- Separator -->\r\n <hr class=\"my-2\" />\r\n </div>\r\n</ng-template>\r\n\r\n<!-- Right Columns Menue -->\r\n\r\n<!-- Column Panel Item Template -->\r\n<ng-template #columnPanelItem let-col=\"col\">\r\n <!-- Group Column -->\r\n <ng-container *ngIf=\"col.children?.length\">\r\n <div class=\"column-group d-flex align-items-center mb-2\">\r\n <span class=\"filter-icon-wrapper me-2\">\r\n <span\r\n class=\"toggle-icon data-grid-svg-icon\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\r\n \"\r\n [class.rotate]=\"col.expanded\"\r\n (click)=\"col.expanded = !col.expanded\"\r\n ></span>\r\n </span>\r\n <input\r\n type=\"checkbox\"\r\n class=\"form-check-input me-2\"\r\n [id]=\"'group_' + col.header\"\r\n [checked]=\"isColumnVisible(col)\"\r\n (change)=\"toggleGroupVisibility(col)\"\r\n />\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/grid-3x2-gap.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center me-2\"\r\n ></span>\r\n <label\r\n class=\"d-flex align-items-center mb-0 w-100\"\r\n [for]=\"'group_' + col.header\"\r\n style=\"cursor: pointer\"\r\n >\r\n <span class=\"text-truncate\">{{ col.header }}</span>\r\n </label>\r\n </div>\r\n <div *ngIf=\"col.expanded\" class=\"ps-4\">\r\n <ng-container *ngFor=\"let child of col.children; trackBy: trackByField\">\r\n <ng-container\r\n *ngTemplateOutlet=\"columnPanelItem; context: { col: child }\"\r\n ></ng-container>\r\n </ng-container>\r\n </div>\r\n </ng-container>\r\n\r\n <!-- Leaf Column -->\r\n <ng-container *ngIf=\"!col.children?.length\">\r\n <div class=\"d-flex align-items-center mb-2\">\r\n <span class=\"me-2\" style=\"width: 1.5rem\"></span>\r\n <input\r\n type=\"checkbox\"\r\n class=\"form-check-input me-2\"\r\n [(ngModel)]=\"col.is_visible\"\r\n [id]=\"'col_' + col.field\"\r\n (change)=\"onSideMenuColumnsVisibilityChange()\"\r\n />\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/grid-3x2-gap.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center me-2\"\r\n ></span>\r\n <label\r\n class=\"d-flex align-items-center mb-0 w-100\"\r\n [for]=\"'col_' + col.field\"\r\n style=\"cursor: pointer\"\r\n >\r\n <span class=\"text-truncate\">{{ col.header }}</span>\r\n </label>\r\n </div>\r\n </ng-container>\r\n</ng-template>\r\n\r\n<!-- Columns Side Filter -->\r\n<ng-template #sideFilters>\r\n <div class=\"py-3 px-2 pe-3 h-100\">\r\n <div class=\"d-flex align-items-center mb-2\">\r\n <span class=\"filter-icon-wrapper me-2\" *ngIf=\"showColumnsGrouping\">\r\n <span\r\n class=\"toggle-icon data-grid-svg-icon\"\r\n [inlineSVG]=\"\r\n filterAccordionState === 'all'\r\n ? singleSpaAssetsPath + 'data-grid/icons/chevron-down.svg'\r\n : filterAccordionState === 'some'\r\n ? singleSpaAssetsPath + 'data-grid/icons/dash.svg'\r\n : singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\r\n \"\r\n (click)=\"toggleAllFilterAccordions()\"\r\n ></span>\r\n </span>\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Search...\"\r\n [(ngModel)]=\"columnSearch\"\r\n />\r\n </div>\r\n <div\r\n class=\"overflow-auto side-filter-columns-wrapper\"\r\n style=\"height: calc(100% - 70px); scrollbar-width: thin\"\r\n >\r\n <ng-container\r\n *ngFor=\"\r\n let col of columns | filter : columnSearch : 'header';\r\n trackBy: trackByField\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"filterPannelItem; context: { col: col }\"\r\n ></ng-container>\r\n </ng-container>\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template #filterPannelItem let-col=\"col\">\r\n <!-- Group Column -->\r\n <ng-container *ngIf=\"col.children?.length\">\r\n <div\r\n class=\"column-group d-flex align-items-center mb-2\"\r\n *ngIf=\"col?.type !== 'image'\"\r\n >\r\n <!-- Chevron toggle -->\r\n <span class=\"filter-icon-wrapper me-2\">\r\n <span\r\n class=\"toggle-icon data-grid-svg-icon\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\r\n \"\r\n [class.rotate]=\"col.expandedFilter\"\r\n (click)=\"col.expandedFilter = !col.expandedFilter\"\r\n ></span>\r\n </span>\r\n\r\n <!-- Group label toggle -->\r\n <label\r\n class=\"d-flex align-items-center mb-0 w-100\"\r\n style=\"cursor: pointer\"\r\n (click)=\"col.expandedFilter = !col.expandedFilter\"\r\n >\r\n <span class=\"fw-bold text-truncate\"\r\n >{{ col.header }}\r\n <span\r\n class=\"text-primary ms-1\"\r\n *ngIf=\"col?.query?._ids?.length || col?.query?._first_value\"\r\n >*</span\r\n >\r\n </span>\r\n </label>\r\n </div>\r\n\r\n <!-- Children columns -->\r\n <div *ngIf=\"col.expandedFilter\" class=\"ps-4\">\r\n <ng-container *ngFor=\"let child of col.children; trackBy: trackByField\">\r\n <ng-container\r\n *ngTemplateOutlet=\"filterPannelItem; context: { col: child }\"\r\n ></ng-container>\r\n </ng-container>\r\n </div>\r\n </ng-container>\r\n\r\n <!-- Leaf Column -->\r\n <ng-container *ngIf=\"!col.children?.length\">\r\n <div class=\"d-flex align-items-center mb-2\" *ngIf=\"col?.type !== 'image'\">\r\n <span\r\n class=\"me-2 filter-icon-wrapper me-2\"\r\n (click)=\"col.expandedFilter = !col.expandedFilter\"\r\n >\r\n <span\r\n class=\"toggle-icon data-grid-svg-icon\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\r\n \"\r\n [class.rotate]=\"col.expandedFilter\"\r\n ></span>\r\n </span>\r\n\r\n <label\r\n class=\"d-flex align-items-center mb-0 w-100\"\r\n style=\"cursor: pointer\"\r\n (click)=\"col.expandedFilter = !col.expandedFilter\"\r\n >\r\n <span class=\"text-truncate fw-bold\">{{ col.header }}</span>\r\n </label>\r\n </div>\r\n\r\n <!-- Show filter when expanded -->\r\n <div *ngIf=\"col.expandedFilter\" class=\"ps-4 pe-3\">\r\n <ng-container\r\n *ngTemplateOutlet=\"sideNestedFilter; context: { col: col }\"\r\n ></ng-container>\r\n </div>\r\n </ng-container>\r\n</ng-template>\r\n\r\n<!-- Side Nested Filters -->\r\n<ng-template #sideNestedFilter let-col=\"col\">\r\n <div class=\"\">\r\n <!-- Dropdown Type -->\r\n <ng-container *ngIf=\"col?.type === 'dropdown' || col?.type == 'array'; else textFilter\">\r\n <div class=\"p-1\">\r\n <!-- Search -->\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm mb-2\"\r\n placeholder=\"Search...\"\r\n [(ngModel)]=\"sideNestedFilterSearch\"\r\n />\r\n\r\n <!-- Select All -->\r\n <div class=\"form-check mb-1 ms-1 select-all-filter\">\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n [checked]=\"\r\n col.query?._ids?.length == col?.column_dropdown_value?.length\r\n \"\r\n (change)=\"toggleSelectAllSideFilters(col, $event)\"\r\n id=\"selectAll_{{ col.field }}\"\r\n />\r\n <label class=\"form-check-label\" for=\"selectAll_{{ col.field }}\">\r\n Select All\r\n </label>\r\n </div>\r\n\r\n <!-- Options -->\r\n <!-- <div class=\"dropdown-options\">\r\n <div\r\n class=\"form-check mb-1 ms-1\"\r\n *ngFor=\"\r\n let option of col?.column_dropdown_value\r\n | filter : sideNestedFilterSearch : 'value'\r\n \"\r\n >\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n [value]=\"option\"\r\n [checked]=\"\r\n col.query?._ids?.includes(option?._id || option?.id || option)\r\n \"\r\n (change)=\"onOptionToggle(col, option)\"\r\n id=\"option_{{ col.field }}_{{\r\n option?.id || option?._id || option\r\n }}\"\r\n />\r\n <label\r\n class=\"form-check-label\"\r\n [for]=\"\r\n 'option_' +\r\n col.field +\r\n '_' +\r\n (option?.id || option?._id || option)\r\n \"\r\n >\r\n {{ option.value || option }}\r\n </label>\r\n </div>\r\n </div> -->\r\n <cdk-virtual-scroll-viewport\r\n itemSize=\"32\"\r\n class=\"dropdown-viewport\"\r\n style=\"height: 120px\"\r\n >\r\n <div\r\n class=\"form-check mb-1 ms-1\"\r\n *cdkVirtualFor=\"\r\n let option of col?.column_dropdown_value\r\n | filter : sideNestedFilterSearch : 'value'\r\n \"\r\n >\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n [value]=\"option\"\r\n [checked]=\"\r\n col.query?._ids?.includes(option?._id || option?.id || option)\r\n \"\r\n (change)=\"onOptionToggle(col, option)\"\r\n id=\"option_{{ col.field }}_{{\r\n option?.id || option?._id || option\r\n }}\"\r\n />\r\n\r\n <label\r\n class=\"form-check-label\"\r\n [for]=\"\r\n 'option_' +\r\n col.field +\r\n '_' +\r\n (option?.id || option?._id || option)\r\n \"\r\n >\r\n {{( (option.value || option) | titlecase ) }}\r\n </label>\r\n </div>\r\n </cdk-virtual-scroll-viewport>\r\n\r\n\r\n <!-- Actions -->\r\n <!-- <div class=\"d-flex gap-2 mt-2\">\r\n <div\r\n class=\"btn btn-sm btn-primary d-flex justify-content-center align-items-center\"\r\n style=\"height: 22px;\"\r\n (click)=\"applySideFilter(col)\"\r\n >\r\n Apply\r\n </div>\r\n <div\r\n class=\"btn btn-sm btn-secondary d-flex justify-content-center align-items-center\" \r\n style=\"height: 22px;\"\r\n (click)=\"resetSideFilter(col)\"\r\n >\r\n Reset\r\n </div>\r\n </div> -->\r\n </div>\r\n </ng-container>\r\n\r\n <!-- Text Filter Section -->\r\n <ng-template #textFilter>\r\n <div class=\"filter-text-section\">\r\n <div class=\"form-group mb-2\">\r\n <select\r\n class=\"form-select form-select-sm\"\r\n [(ngModel)]=\"col.query.first_condition\"\r\n >\r\n <ng-container *ngIf=\"col?.type == 'string'\">\r\n <option value=\"contain\">Contains</option>\r\n <option value=\"does_not_contain\">Does Not Contain</option>\r\n <option value=\"equal\">Equals</option>\r\n <option value=\"before\">Starts With</option>\r\n <option value=\"after\">Ends With</option>\r\n </ng-container>\r\n\r\n <ng-container *ngIf=\"col?.type == 'date'\">\r\n <option value=\"equal\">Equals To</option>\r\n <option value=\"not_equal\">Not Equal</option>\r\n <option value=\"after\">After</option>\r\n <option value=\"before\">Before</option>\r\n </ng-container>\r\n\r\n <ng-container *ngIf=\"col?.type == 'number'\">\r\n <option value=\"equal\">Equals To</option>\r\n <option value=\"before\">Less Then </option>\r\n <option value=\"after\">Greater Then </option>\r\n <option value=\"less_then_equal\">less then Equal to</option>\r\n <option value=\"greater_then_equal\">Greater then Equal to </option>\r\n </ng-container>\r\n </select>\r\n </div>\r\n\r\n <input\r\n [type]=\"col?.type == 'date' ? 'date' : 'text'\"\r\n class=\"form-control form-control-sm mb-3\"\r\n placeholder=\"Value\"\r\n [(ngModel)]=\"col!.query!.first_value\"\r\n />\r\n\r\n <div\r\n class=\"form-group mb-3 d-flex flex-row muted\"\r\n style=\"font-size: 14px\"\r\n >\r\n <div\r\n class=\"form-check form-check-inline m-0 col-4 d-flex align-items-center gap-1\"\r\n >\r\n <input\r\n class=\"form-check-input filter-radio-inputs\"\r\n type=\"radio\"\r\n name=\"condition\"\r\n [(ngModel)]=\"col!.query.condition\"\r\n value=\"and\"\r\n id=\"and_{{ col.field }}\"\r\n />\r\n <label class=\"form-check-label mb-0 mt-1\" for=\"and_{{ col.field }}\"\r\n >AND</label\r\n >\r\n </div>\r\n <div\r\n class=\"form-check form-check-inline m-0 col-4 d-flex align-items-center gap-1\"\r\n >\r\n <input\r\n class=\"form-check-input filter-radio-inputs\"\r\n type=\"radio\"\r\n name=\"condition\"\r\n [(ngModel)]=\"col!.query.condition\"\r\n value=\"or\"\r\n id=\"or_{{ col.field }}\"\r\n />\r\n <label class=\"form-check-label mb-0 mt-1\" for=\"or_{{ col.field }}\"\r\n >OR</label\r\n >\r\n </div>\r\n <div\r\n class=\"form-check form-check-inline m-0 col-4 d-flex align-items-center gap-1\"\r\n >\r\n <input\r\n class=\"form-check-input filter-radio-inputs\"\r\n type=\"radio\"\r\n name=\"condition\"\r\n [(ngModel)]=\"col!.query.condition\"\r\n value=\"none\"\r\n id=\"none_{{ col.field }}\"\r\n />\r\n <label\r\n class=\"nnonem-check-label mb-0 mt-1\"\r\n for=\"none_{{ col.field }}\"\r\n >None</label\r\n >\r\n </div>\r\n </div>\r\n <ng-container\r\n *ngIf=\"col?.query?.first_value && col?.query?.condition !== 'none'\"\r\n >\r\n <div class=\"form-group mb-2\">\r\n <select\r\n class=\"form-select form-select-sm\"\r\n [(ngModel)]=\"col!.query.second_condition\"\r\n >\r\n <ng-container *ngIf=\"col?.type == 'string'\">\r\n <option value=\"contain\">Contains</option>\r\n <option value=\"does_not_contain\">Does Not Contain</option>\r\n <option value=\"equal\">Equals</option>\r\n <option value=\"before\">Starts With</option>\r\n <option value=\"after\">Ends With</option>\r\n </ng-container>\r\n\r\n <ng-container *ngIf=\"col?.type == 'date'\">\r\n <option value=\"equal\">Equals To</option>\r\n <option value=\"not_equal\">Not Equal</option>\r\n <option value=\"after\">After</option>\r\n <option value=\"before\">Before</option>\r\n </ng-container>\r\n\r\n <ng-container *ngIf=\"col?.type == 'number'\">\r\n <option value=\"equal\">Equals To</option>\r\n <option value=\"before\">Less Then </option>\r\n <option value=\"after\">Greater Then </option>\r\n <option value=\"less_then_equal\">less then Equal to</option>\r\n <option value=\"greater_then_equal\">Greater then Equal to </option>\r\n </ng-container>\r\n </select>\r\n </div>\r\n\r\n <input\r\n [type]=\"col?.type == 'date' ? 'date' : 'text'\"\r\n class=\"form-control form-control-sm mb-3\"\r\n placeholder=\"Second Value\"\r\n [(ngModel)]=\"col!.query.second_value\"\r\n />\r\n </ng-container>\r\n <!-- <div class=\"d-flex gap-2\">\r\n <div class=\"btn btn-sm btn-primary d-flex justify-content-center align-items-center\" style=\"height: 22px;\" (click)=\"applyDropdownFilter()\">apply</div>\r\n <div class=\"btn btn-sm btn-secondary d-flex justify-content-center align-items-center\" style=\"height: 22px;\" (click)=\"applyDropdownFilter()\">reset</div>\r\n\r\n </div> -->\r\n </div>\r\n </ng-template>\r\n <div\r\n class=\"d-flex justify-content-center gap-2 border-top\"\r\n style=\"height: 38px\"\r\n >\r\n <button\r\n type=\"button\"\r\n style=\"max-height: 30px\"\r\n class=\"btn btn-outline-secondary btn-light border w-100 d-flex align-items-center justify-content-center mt-1 btn-light\"\r\n (click)=\"$event.stopPropagation(); removeSideFilter(col)\"\r\n >\r\n <span>Clear</span>\r\n </button>\r\n <button\r\n type=\"button\"\r\n style=\"max-height: 30px\"\r\n class=\"btn btn-primary w-100 d-flex align-items-center justify-content-center mt-1\"\r\n (click)=\"applySideFilter(col)\"\r\n [class.disabled]=\"(col?.query.condition !== 'none' && !col?.query?.second_value)\"\r\n [class.pe-none]=\"(col!?.query.condition !== 'none' && !col?.query?.second_value)\"\r\n >\r\n <span style=\"margin-top: -1px\">Apply</span>\r\n </button>\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<!-- Centr Overlay for showing the chose columns -->\r\n\r\n<div *ngIf=\"showColumnPanel\" class=\"custom-modal-overlay\">\r\n <div\r\n class=\"custom-modal-content\"\r\n [style.backgroundColor]=\"dropdownsBackgroundColor\"\r\n (click)=\"$event.stopPropagation()\"\r\n >\r\n <ng-container *ngTemplateOutlet=\"modalColumnPannel\"></ng-container>\r\n </div>\r\n</div>\r\n\r\n<!-- The existing ng-template you provided -->\r\n<ng-template #modalColumnPannel>\r\n <div class=\"column-panel-header\">\r\n <div\r\n class=\"d-flex justify-content-between align-items-center px-2 ps-3 rounded-top-2 moda-header\"\r\n [style.height.px]=\"48\"\r\n >\r\n Choose Columns\r\n <span class=\"filter-icon-wrapper\" (click)=\"closeModalColumnPanel()\"\r\n ><span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/x.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span\r\n ></span>\r\n </div>\r\n <hr class=\"my-0\" />\r\n <div>\r\n <div class=\"d-flex align-items-center px-2 pe-3\" [style.height.px]=\"48\">\r\n <span class=\"filter-icon-wrapper me-2\" *ngIf=\"showColumnsGrouping\">\r\n <span\r\n class=\"toggle-icon data-grid-svg-icon\"\r\n [inlineSVG]=\"\r\n accordionState === 'all'\r\n ? singleSpaAssetsPath + 'data-grid/icons/chevron-down.svg'\r\n : accordionState === 'some'\r\n ? singleSpaAssetsPath + 'data-grid/icons/dash.svg'\r\n : singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\r\n \"\r\n (click)=\"toggleAllAccordions()\"\r\n ></span>\r\n </span>\r\n <input\r\n type=\"checkbox\"\r\n class=\"form-check-input me-2\"\r\n [checked]=\"allColumnsSelected()\"\r\n (change)=\"toggleAllColumnsVisibility()\"\r\n />\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Search columns...\"\r\n [(ngModel)]=\"choseColumnsSearch\"\r\n />\r\n </div>\r\n\r\n <hr class=\"mt-0 mb-1\" />\r\n <div class=\"px-2 overlay-scrollable\">\r\n <ng-container\r\n *ngFor=\"\r\n let col of columns | filter : choseColumnsSearch : 'header';\r\n trackBy: trackByField\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"columnPanelItem; context: { col: col }\"\r\n ></ng-container>\r\n </ng-container>\r\n </div>\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template #sideMenuRowGroups>\r\n <div class=\"d-flex flex-column h-100 d-none\">\r\n <div class=\"px-3 h-100\">\r\n <div class=\"d-flex gap-3 mb-4\">\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/justify.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n <span>Row Groups</span>\r\n </div>\r\n <div class=\"h-50\">\r\n <div\r\n class=\"px-3 py-2 border-dashed h-100 d-flex justify-content-center align-items-center\"\r\n style=\"font-size: 14px\"\r\n >\r\n Drag here to set row Groups\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <hr class=\"mt-4\" />\r\n\r\n <div class=\"px-3 h-100\">\r\n <div class=\"d-flex gap-3 mb-4\">\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/justify.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n <span>Values</span>\r\n </div>\r\n <div class=\"h-50 d-flex\">\r\n <div\r\n class=\"px-3 py-2 border-dashed h-100 d-flex justify-content-center align-items-center\"\r\n style=\"font-size: 14px\"\r\n >\r\n Drag here aggregate\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<!-- *************************************************** -->\r\n<!-- *************************************************** -->\r\n<!-- *************************************************** -->\r\n<!-- Drag Preview Template -->\r\n<!-- *************************************************** -->\r\n<!-- *************************************************** -->\r\n<ng-template #dragPreview let-col>\r\n <div class=\"p-2 border d-flex gap-2\">\r\n <div>\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrows-move.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n <div>{{ col.header }}</div>\r\n </div>\r\n</ng-template>\r\n\r\n<!-- Drag Placeholder Template -->\r\n<ng-template\r\n #dragPlaceholder\r\n let-col\r\n let-i=\"index\"\r\n let-section=\"section\"\r\n let-draggingInGroupArea=\"draggingInGroupArea\"\r\n>\r\n <div *ngIf=\"!draggingInGroupArea\">\r\n <div\r\n *ngTemplateOutlet=\"\r\n headerCell;\r\n context: { $implicit: col, index: i, section: section }\r\n \"\r\n ></div>\r\n </div>\r\n <div *ngIf=\"draggingInGroupArea\">New Placeholder</div>\r\n</ng-template>\r\n\r\n<!-- Top Group Row Placeholder -->\r\n<ng-template #topGroupingRowPlaceholder let-col let-showChevron=\"showChevron\">\r\n <div class=\"d-flex gap-2\">\r\n <div\r\n class=\"d-flex gap-2 top-row-grouping-placeholder\"\r\n [style.backgroundColor]=\"topGroupedBadgesBackgroundColor\"\r\n >\r\n <span\r\n cdkDragHandle\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/grid-3x2-gap.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n <span>{{ col.header }}</span>\r\n <span\r\n (click)=\"ungroupColumn(col)\"\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/x.svg'\"\r\n class=\"cursor-pointer data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n </div>\r\n <div *ngIf=\"showChevron\" style=\"opacity: 0.6; font-size: 14px\">\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template\r\n #childHeaderPlaceholder\r\n let-col\r\n let-pinnedRight=\"pinnedRight\"\r\n let-i=\"index\"\r\n let-sections=\"sections\"\r\n>\r\n <div\r\n class=\"header-cell one-row-header-cells\"\r\n [class.border-right]=\"showVerticalBorder\"\r\n [style.width.px]=\"col.width\"\r\n [style.min-width.px]=\"col.width\"\r\n [style.min-height.px]=\"headerRowHeight\"\r\n [style.max-height.px]=\"headerRowHeight\"\r\n [style.fontWeight]=\"headerFontWeight\"\r\n >\r\n <div class=\"d-flex justify-content-between h-100 align-items-center w-100\">\r\n <div\r\n class=\"d-flex justify-content-between align-items-center w-100\"\r\n [class.flex-row-reverse]=\"pinnedRight\"\r\n >\r\n <div\r\n class=\"text-ellipsis h-100 d-flex align-items-center\"\r\n [title]=\"col.header\"\r\n [class.w-100]=\"pinnedRight\"\r\n >\r\n {{ col.header }}\r\n </div>\r\n\r\n <div\r\n class=\"position-relative d-flex\"\r\n [class.flex-row-reverse]=\"pinnedRight\"\r\n >\r\n <div class=\"three-dots p-1\" style=\"cursor: pointer\">\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/three-dots-vertical.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n\r\n <div class=\"resize-handle\">\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/resize-handle.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n <div\r\n *ngIf=\"showFilterRow\"\r\n [style.backgroundColor]=\"headerBackgroundColor\"\r\n class=\"header-cell filter-cell\"\r\n [class.border-right]=\"showVerticalBorder\"\r\n [style.width.px]=\"col.width\"\r\n [style.min-width.px]=\"col.width\"\r\n [style.height.px]=\"headerRowHeight\"\r\n [style.min-height.px]=\"headerRowHeight\"\r\n [style.max-height.px]=\"headerRowHeight\"\r\n [class.border-right]=\"showVerticalBorder\"\r\n style=\"grid-row: 3\"\r\n >\r\n <div\r\n class=\"header-cell filter-cell\"\r\n [style.backgroundColor]=\"headerBackgroundColor\"\r\n [style.width.px]=\"col.width\"\r\n [style.min-width.px]=\"col.width\"\r\n [style.height.px]=\"headerRowHeight\"\r\n [style.min-height.px]=\"headerRowHeight\"\r\n [style.max-height.px]=\"headerRowHeight\"\r\n >\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Filter\"\r\n [(ngModel)]=\"col.filterValue\"\r\n [readonly]=\"col?.type == 'dropdown' || col?.type == 'image' || col?.type == 'array'\"\r\n [class.disabled-search-input]=\"\r\n col?.type == 'dropdown' || col?.type == 'image' || col?.type == 'array'\r\n \"\r\n />\r\n <span\r\n class=\"filter-icon-wrapper\"\r\n (click)=\"activeFilterCell = col; activeCol = null\"\r\n ><span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span\r\n ></span>\r\n\r\n <div\r\n class=\"position-absolute\"\r\n *ngIf=\"activeFilterCell === col\"\r\n style=\"top: 100%; right: 0; z-index: 10; left: 0\"\r\n ></div>\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template #tableLayout>\r\n <div\r\n (click)=\"$event.stopPropagation()\"\r\n class=\"p-3 shadow actions-dropdown mt-1 dropdown-menu show shadow custom-menu table-layout\"\r\n style=\"width: 320px\"\r\n >\r\n <div class=\"d-flex align-items-center mb-3\">\r\n <button\r\n class=\"btn btn-link p-0\"\r\n style=\"margin-left: -10px\"\r\n (click)=\"toggleActions('setting')\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrow-left.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n </button>\r\n <h6 class=\"mb-0 ms-2\" style=\"font-weight: 500\">Table Layout</h6>\r\n </div>\r\n <hr class=\"my-2\" />\r\n <div class=\"w-100 mb-3 d-flex\" role=\"group\">\r\n <input\r\n type=\"radio\"\r\n class=\"btn-check layout-button-check\"\r\n name=\"layoutSize\"\r\n id=\"small\"\r\n autocomplete=\"off\"\r\n (change)=\"changeTableLayout($event, 'small')\"\r\n [checked]=\"selectedTableLayout == 'small'\"\r\n />\r\n <label\r\n class=\"border d-flex flex-column align-items-center layout-button\"\r\n for=\"small\"\r\n [ngStyle]=\"{\r\n color: selectedTableLayout == 'small' ? '#000' : '#727272'\r\n }\"\r\n >\r\n <div class=\"preview-box border mb-1\" style=\"height: 8px\"></div>\r\n Small\r\n </label>\r\n\r\n <input\r\n type=\"radio\"\r\n class=\"btn-check layout-button-check\"\r\n name=\"layoutSize\"\r\n id=\"medium\"\r\n autocomplete=\"off\"\r\n [checked]=\"selectedTableLayout == 'medium'\"\r\n (change)=\"changeTableLayout($event, 'medium')\"\r\n />\r\n <label\r\n class=\"border mx-3 d-flex flex-column align-items-center layout-button\"\r\n for=\"medium\"\r\n [ngStyle]=\"{\r\n color: selectedTableLayout == 'medium' ? '#000' : '#727272'\r\n }\"\r\n >\r\n <div class=\"preview-box border mb-1\" style=\"height: 12px\"></div>\r\n Medium\r\n </label>\r\n\r\n <input\r\n type=\"radio\"\r\n class=\"btn-check layout-button-check\"\r\n name=\"layoutSize\"\r\n id=\"large\"\r\n autocomplete=\"off\"\r\n (change)=\"changeTableLayout($event, 'large')\"\r\n [checked]=\"selectedTableLayout == 'large'\"\r\n />\r\n <label\r\n class=\"border d-flex flex-column align-items-center layout-button\"\r\n for=\"large\"\r\n [ngStyle]=\"{\r\n color: selectedTableLayout == 'large' ? '#000' : '#727272'\r\n }\"\r\n >\r\n <div class=\"preview-box border mb-1\" style=\"height: 16px\"></div>\r\n Large\r\n </label>\r\n </div>\r\n\r\n <hr class=\"my-2\" />\r\n <div class=\"d-flex justify-content-between align-items-center mb-2\">\r\n <span>Show separators</span>\r\n <div class=\"form-check form-switch m-0\">\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n id=\"separators\"\r\n [(ngModel)]=\"showVerticalBorder\"\r\n (change)=\"onFontChange()\"\r\n />\r\n </div>\r\n </div>\r\n <div class=\"d-flex justify-content-between align-items-center\">\r\n <span>Row shading</span>\r\n <div class=\"form-check form-switch m-0\">\r\n <input\r\n class=\"form-check-input\"\r\n [(ngModel)]=\"rowShadingEnabled\"\r\n (change)=\"toggleRowShading()\"\r\n type=\"checkbox\"\r\n id=\"rowShading\"\r\n />\r\n </div>\r\n </div>\r\n <!-- <div class=\"d-flex justify-content-between align-items-center mb-2\">\r\n <span>Show Side Menu</span>\r\n <div class=\"form-check form-switch m-0\">\r\n <input\r\n class=\"form-check-input\"\r\n [(ngModel)]=\"showSideMenu\"\r\n type=\"checkbox\"\r\n id=\"rowShading\"\r\n />\r\n </div>\r\n </div>\r\n <div class=\"d-flex justify-content-between align-items-center mb-2\">\r\n <span>Show Filter Row</span>\r\n <div class=\"form-check form-switch m-0\">\r\n <input\r\n class=\"form-check-input\"\r\n [(ngModel)]=\"showFilterRow\"\r\n type=\"checkbox\"\r\n id=\"rowShading\"\r\n />\r\n </div>\r\n </div> -->\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template #tablePreset>\r\n <div\r\n *ngIf=\"activeSubButton !== 'save-preset'\"\r\n (click)=\"$event.stopPropagation()\"\r\n class=\"p-3 shadow actions-dropdown mt-1 dropdown-menu show shadow custom-menu table-layout\"\r\n style=\"width: 280px\"\r\n >\r\n <!-- Header -->\r\n <div class=\"d-flex justify-content-between align-items-center mb-3\">\r\n <div class=\"d-flex align-items-center\">\r\n <button\r\n class=\"btn btn-link p-0\"\r\n style=\"margin-left: -10px\"\r\n (click)=\"toggleActions('setting')\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrow-left.svg'\"\r\n class=\"data-grid-svg-icon\"\r\n ></span>\r\n </button>\r\n <h6 class=\"mb-0 ms-2\" style=\"font-weight: 500\">Table Presets</h6>\r\n </div>\r\n <!-- Save Preset Button with Dropdown -->\r\n <div>\r\n <a\r\n class=\"text-decoration-none text-primary\"\r\n type=\"button\"\r\n id=\"savePresetDropdown\"\r\n (click)=\"$event.stopPropagation(); toggleSubActions('save-preset')\"\r\n >\r\n {{ isTablePresetNotChanged ? \"Save preset\" : \"Update Preset\" }}\r\n </a>\r\n </div>\r\n </div>\r\n\r\n <!-- Search -->\r\n <div class=\"mb-3\">\r\n <div class=\"col-12 global-search\">\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/search.svg'\"\r\n class=\"data-grid-svg-icon mx-2 position-absolute icon\"\r\n ></span>\r\n <input\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Search...\"\r\n [(ngModel)]=\"searchTextPresetTable\"\r\n type=\"search\"\r\n />\r\n </div>\r\n </div>\r\n\r\n <!-- Preset List -->\r\n <ng-container\r\n *ngIf=\"\r\n tableView | filter : searchTextPresetTable : 'name' as filteredList\r\n \"\r\n >\r\n <!-- If filteredList exists and none is default -> show fallback -->\r\n <div\r\n class=\" pb-5 overflow-auto\"\r\n [style.maxHeight.px]=\"dataGridContainer.offsetHeight - 250\"\r\n >\r\n <div\r\n class=\"cursor-pointer\"\r\n (click)=\"\r\n clearAllFilters();\r\n openIndex = null;\r\n temp_state.id = '';\r\n activeTopButton = '';\r\n curretaTablePresetForUpdate = null\r\n \"\r\n >\r\n <div class=\"fw-semibold\">Default View</div>\r\n </div>\r\n <div class=\"d-flex justify-content-between\">\r\n <small class=\"text-dark\">Created by system</small>\r\n <span\r\n *ngIf=\"!tableFilterViewId && !hasAnyDefaultView()\"\r\n class=\"badge bg-light text-primary ms-2\"\r\n >Default</span\r\n >\r\n <!-- <span\r\n *ngIf=\"!tableFilterViewId && !hasAnyDefaultView()\"\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/check-blue.svg'\"\r\n class=\"me-2\"\r\n ></span> -->\r\n <div\r\n class=\"dropdown d-flex justify-content-end\"\r\n *ngIf=\"tableFilterViewId\"\r\n ></div>\r\n </div>\r\n\r\n <!-- The list: render each table from filteredList -->\r\n <div\r\n class=\"list-group list-group-flush\"\r\n *ngFor=\"\r\n let table of filteredList;\r\n let i = index;\r\n trackBy: trackByTable\r\n \"\r\n >\r\n <!-- Item -->\r\n <div\r\n (click)=\"\r\n $event.stopPropagation(); openIndex = null; activeTopButton = ''\r\n \"\r\n class=\"list-group-item px-0 d-flex justify-content-between align-items-center\"\r\n >\r\n <div (click)=\"selectFilter(table); openIndex = null\">\r\n <div class=\"fw-semibold\" style=\"cursor: pointer\">\r\n {{ table?.name }}\r\n <!-- {{table?.is_temp}} -->\r\n <span\r\n *ngIf=\"\r\n (table?.is_temp && !temp_state.id) ||\r\n temp_state.id == table.id\r\n \"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/check-blue.svg'\r\n \"\r\n class=\"me-2\"\r\n ></span>\r\n <span\r\n *ngIf=\"table?.is_default\"\r\n class=\"badge bg-light text-primary ms-2\"\r\n >Default</span\r\n >\r\n </div>\r\n <small class=\"text-dark\" *ngIf=\"table?.config?.filterNames\" [title]=\"table?.config?.filterNames\">\r\n {{\r\n table?.config?.filterNames?.length > 25\r\n ? (table?.config?.filterNames | slice:0:25) + '...'\r\n : table?.config?.filterNames\r\n }}\r\n ({{ table?.config?.totalCount }})\r\n </small>\r\n <small class=\"text-dark\" *ngIf=\"!table?.config?.filterNames\">{{ table?.createdAt | date : \"MMM d, y\" }}</small>\r\n </div>\r\n\r\n <div class=\"d-flex align-items-center\">\r\n <span\r\n *ngIf=\"table?.is_default\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/check-blue.svg'\r\n \"\r\n class=\"me-2\"\r\n ></span>\r\n\r\n <div class=\"dropdown\" *ngIf=\"!table?.is_default\">\r\n <div\r\n class=\"dropdown-wrapper\"\r\n (click)=\"$event.stopPropagation()\"\r\n >\r\n <button\r\n type=\"button\"\r\n class=\"btn-icon muted-text\"\r\n (click)=\"toggleMenu(i, $event)\"\r\n aria-haspopup=\"true\"\r\n [attr.aria-expanded]=\"openIndex === i\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath +\r\n 'data-grid/icons/horizontal-dots.svg'\r\n \"\r\n class=\"me-2\"\r\n ></span>\r\n </button>\r\n\r\n <!-- menu -->\r\n <ul\r\n *ngIf=\"openIndex === i\"\r\n class=\"custom-dropdown-menu position-fixed top-auto\"\r\n role=\"menu\"\r\n [style.right.px]=\"'unset'\"\r\n [style.left.px]=\"dataGridContainer.offsetWidth - 200\"\r\n style=\"top: unset; right: unset\"\r\n >\r\n <li role=\"none\">\r\n <button\r\n role=\"menuitem\"\r\n class=\"dropdown-item\"\r\n (click)=\"\r\n actionPreset(table, 'setPreset'); temp_state.id = ''\r\n \"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/star.svg'\r\n \"\r\n class=\"me-2\"\r\n ></span>\r\n Set as default\r\n </button>\r\n </li>\r\n\r\n <li role=\"none\" *ngIf=\"!table.confirmDelete\">\r\n <button\r\n role=\"menuitem\"\r\n class=\"dropdown-item text-danger\"\r\n (click)=\"table.confirmDelete = true\"\r\n >\r\n <span\r\n style=\"margin-top: -4px\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath +\r\n 'data-grid/icons/trash-red.svg'\r\n \"\r\n class=\"me-2\"\r\n ></span>\r\n Delete\r\n </button>\r\n </li>\r\n\r\n <li\r\n role=\"none\"\r\n *ngIf=\"table.confirmDelete\"\r\n class=\"confirm-block\"\r\n >\r\n <div class=\"px-3 py-2 text-center\">\r\n <div class=\"mb-2\">\r\n Are you sure you want to delete <br /><b\r\n >\u201C{{ table?.name }}\u201D</b\r\n >?\r\n </div>\r\n <div class=\"d-flex gap-2\">\r\n <button\r\n class=\"btn btn-sm btn-light me-2\"\r\n (click)=\"table.confirmDelete = false\"\r\n >\r\n Cancel\r\n </button>\r\n <button\r\n class=\"btn btn-sm btn-danger\"\r\n (click)=\"actionPreset(table, 'deletePreset')\"\r\n >\r\n Delete\r\n </button>\r\n </div>\r\n </div>\r\n </li>\r\n </ul>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n <!-- Item End Here -->\r\n </div>\r\n </div>\r\n </ng-container>\r\n </div>\r\n\r\n <div\r\n (click)=\"$event.stopPropagation()\"\r\n *ngIf=\"activeSubButton == 'save-preset'\"\r\n class=\"dropdown-menu p-3 badge mt-4 save-preset-dropdown mt-1\"\r\n aria-labelledby=\"savePresetDropdown\"\r\n style=\"min-width: 250px\"\r\n >\r\n <div class=\"fw-bold fs-14px mb-2\">\r\n {{ isTablePresetNotChanged ? \"Save preset\" : \"Update Preset\" }}\r\n </div>\r\n <div class=\"fs-14px mb-2\" style=\"line-height: 20px\">\r\n This will save the current table adjustments as a preset.\r\n </div>\r\n <!-- Input -->\r\n <div class=\"mb-2\">\r\n <label for=\"presetName\" class=\"form-label fs-12px fw-bold\"\r\n >Preset Name</label\r\n >\r\n <div class=\"col-12 global-search\">\r\n <input\r\n #presetNameCtrl=\"ngModel\"\r\n required\r\n [(ngModel)]=\"presetName\"\r\n [ngClass]=\"{\r\n 'is-invalid':\r\n presetNameCtrl.invalid &&\r\n (presetNameCtrl.dirty || presetNameCtrl.touched)\r\n }\"\r\n class=\"form-control form-control-sm ps-2\"\r\n placeholder=\"Enter preset name\"\r\n type=\"text\"\r\n />\r\n </div>\r\n </div>\r\n\r\n <!-- Checkbox -->\r\n <div class=\"form-check mb-2\">\r\n <input\r\n class=\"form-check-input\"\r\n [(ngModel)]=\"presetFilter\"\r\n type=\"checkbox\"\r\n id=\"saveFilters\"\r\n />\r\n <label class=\"form-check-label mt-1\" for=\"saveFilters\">\r\n Save active filters\r\n </label>\r\n </div>\r\n\r\n <!-- Save Button -->\r\n <div class=\"d-flex justify-content-center gap-2\" style=\"height: 32px\">\r\n <button\r\n type=\"button\"\r\n style=\"height: 32px\"\r\n class=\"btn border w-100 d-flex align-items-center justify-content-center btn-light\"\r\n (click)=\"$event.stopPropagation(); toggleActions('table-presets')\"\r\n style=\"margin-top: -2px\"\r\n >\r\n <span>Cancel</span>\r\n </button>\r\n <button\r\n [disabled]=\"closeDropdown.preset.loading\"\r\n (click)=\"savePreset(presetNameCtrl)\"\r\n type=\"button\"\r\n style=\"height: 32px\"\r\n class=\"btn btn-primary w-100 d-flex align-items-center justify-content-center\"\r\n >\r\n <span style=\"margin-top: -2px\" *ngIf=\"isTablePresetNotChanged\">\r\n <ng-container *ngIf=\"!closeDropdown.preset.loading\"\r\n >Save</ng-container\r\n >\r\n <ng-container *ngIf=\"closeDropdown.preset.loading\"\r\n ><span class=\"spinner-border spinner-border-sm\"></span\r\n ></ng-container>\r\n </span>\r\n <span style=\"white-space: nowrap\" *ngIf=\"!isTablePresetNotChanged\"\r\n >Update Preset</span\r\n >\r\n </button>\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template #showHideColumns>\r\n <div\r\n (click)=\"$event.stopPropagation()\"\r\n class=\"p-3 shadow actions-dropdown mt-1 dropdown-menu show shadow custom-menu table-layout\"\r\n style=\"width: 280px\"\r\n >\r\n <!-- Header -->\r\n <div class=\"d-flex justify-content-between align-items-center mb-3\">\r\n <div class=\"d-flex align-items-center\">\r\n <button\r\n class=\"btn btn-link p-0\"\r\n style=\"margin-left: -10px\"\r\n (click)=\"toggleActions('setting')\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrow-left.svg'\"\r\n class=\"data-grid-svg-icon\"\r\n ></span>\r\n </button>\r\n <h6 class=\"mb-0 ms-2\" style=\"font-weight: 500\">Columns</h6>\r\n </div>\r\n <a\r\n (click)=\"resetColumns()\"\r\n href=\"javascript:void(0)\"\r\n class=\"text-primary text-decoration-none d-none\"\r\n >Reset</a\r\n >\r\n </div>\r\n\r\n <!-- Search -->\r\n <div class=\"mb-3\">\r\n <div class=\"col-12 global-search\">\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/search.svg'\"\r\n class=\"mx-2 position-absolute icon data-grid-svg-icon\"\r\n ></span>\r\n <input\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Search column\"\r\n type=\"search\"\r\n [(ngModel)]=\"topShowHideColumns\"\r\n />\r\n </div>\r\n </div>\r\n <!-- Preset List -->\r\n <div\r\n class=\"list-group list-group-flush\"\r\n style=\"overflow: auto; scrollbar-width: thin\"\r\n [style.maxHeight.px]=\"dataGridContainer.offsetHeight - 220\"\r\n >\r\n <div class=\"muted-text show-hide-table-label d-flex justify-content-between\" *ngIf=\"hasAnyVisibleColumn\">\r\n Show in table\r\n <div class=\"form-check\">\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n id=\"hide_all\"\r\n [checked]=\"allColumnsSelected()\"\r\n (change)=\"toggleAllColumnsVisibility()\"\r\n />\r\n <label class=\"form-check-label fw-semibold\" for=\"hide_all\">\r\n Show/Hide All \r\n </label>\r\n </div>\r\n </div>\r\n <!-- Item -->\r\n <ng-container\r\n *ngFor=\"\r\n let col of columns | filter : topShowHideColumns : 'header';\r\n trackBy: trackByField\r\n \"\r\n >\r\n <div\r\n *ngIf=\"col.is_visible\"\r\n class=\"list-group-item border-0 px-0 d-flex justify-content-between align-items-center\"\r\n >\r\n <div class=\"d-flex gap-1\">\r\n <div>\r\n <span\r\n *ngIf=\"!col?.pinned\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/grip-vertical.svg'\r\n \"\r\n class=\"cursor-grap data-grid-svg-icon\"\r\n (mousedown)=\"$event.preventDefault()\"\r\n ></span>\r\n <span\r\n *ngIf=\"col?.pinned\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/pin-blue.svg'\r\n \"\r\n class=\"cursor-grap data-grid-svg-icon\"\r\n (mousedown)=\"$event.preventDefault()\"\r\n ></span>\r\n </div>\r\n <div class=\"fw-semibold\">\r\n {{ col.header }}\r\n </div>\r\n </div>\r\n <div\r\n *ngIf=\"!col?.query?.first_value && !col?.query?._ids?.length\"\r\n class=\"d-flex align-items-center cursor-pointer\"\r\n (click)=\"toggleColumnVisibility(col, false)\"\r\n [class.disabled]=\"visibleColumns().length <= 2 || col?.is_always_visible\"\r\n [class.pe-none]=\"visibleColumns().length <= 2 || col?.is_always_visible\"\r\n [class.opacity-50]=\"visibleColumns().length <= 2 || col?.is_always_visible\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/eye.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n </div>\r\n <div\r\n *ngIf=\"col?.query?.first_value || col?.query?._ids?.length\"\r\n class=\"d-flex align-items-center\"\r\n style=\"opacity: 0.5\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/eye.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n </div>\r\n </div>\r\n </ng-container>\r\n\r\n <!-- Item End Here -->\r\n\r\n <div\r\n class=\"dropdown-divider\"\r\n *ngIf=\"hasAnyVisibleColumn && hasAnyInVisibleColumn\"\r\n ></div>\r\n\r\n <div\r\n class=\"muted-text show-hide-table-label d-flex justify-content-between\"\r\n *ngIf=\"hasAnyInVisibleColumn\"\r\n >\r\n Hide in table\r\n <div class=\"form-check\">\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n id=\"show_all\"\r\n [checked]=\"allColumnsSelected()\"\r\n (change)=\"toggleAllColumnsVisibility()\"\r\n />\r\n <label class=\"form-check-label fw-semibold\" for=\"show_all\">\r\n Show/Hide All \r\n </label>\r\n </div>\r\n </div>\r\n <div class=\"list-group list-group-flush\">\r\n <ng-container *ngFor=\"let col of columns; trackBy: trackByField\">\r\n <div\r\n *ngIf=\"!col.is_visible\"\r\n class=\"list-group-item border-0 px-0 d-flex justify-content-between align-items-center\"\r\n >\r\n <div class=\"d-flex gap-1\">\r\n <div>\r\n <span\r\n *ngIf=\"!col?.pinned\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/grip-vertical.svg'\r\n \"\r\n class=\"data-grid-svg-icon cursor-grap\"\r\n (mousedown)=\"$event.preventDefault()\"\r\n ></span>\r\n <span\r\n *ngIf=\"col?.pinned\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/pin-blue.svg'\r\n \"\r\n class=\"data-grid-svg-icon cursor-grap\"\r\n (mousedown)=\"$event.preventDefault()\"\r\n ></span>\r\n </div>\r\n <div class=\"fw-semibold\">\r\n {{ col.header }}\r\n </div>\r\n </div>\r\n <div\r\n class=\"d-flex align-items-center cursor-pointer\"\r\n (click)=\"toggleColumnVisibility(col, true)\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/eye-cross.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n </div>\r\n </div>\r\n </ng-container>\r\n </div>\r\n\r\n <!-- Item End Here -->\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template #filterColumns let-col=\"column\">\r\n <div\r\n @slideToggle\r\n *ngIf=\"!isFilterOpen && activeTopButton == 'filter-columns'\"\r\n (click)=\"$event.stopPropagation()\"\r\n class=\"shadow actions-dropdown mt-1 show shadow custom-menu table-layout filter-columns\"\r\n style=\"width: 280px; right: unset; max-width: 230px\"\r\n [style.backgroundColor]=\"checkboxesBackgroundColor\"\r\n >\r\n <div class=\"mb-2 px-3\">\r\n <div class=\"col-12 global-search\">\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/search.svg'\"\r\n class=\"data-grid-svg-icon mx-2 position-absolute icon\"\r\n ></span>\r\n <input\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Filter by\"\r\n type=\"search\"\r\n [(ngModel)]=\"addFilterColumnInput\"\r\n />\r\n </div>\r\n </div>\r\n <div\r\n class=\"list-group list-group-flush\"\r\n style=\"max-height: calc(100vh - 500px); overflow: auto\"\r\n >\r\n <ng-container\r\n *ngFor=\"\r\n let col of columns | filter : addFilterColumnInput : 'header';\r\n trackBy: trackByField\r\n \"\r\n >\r\n <div\r\n (click)=\"openFilter(col)\"\r\n *ngIf=\"\r\n col.is_visible &&\r\n !col?.query?.first_value &&\r\n !col?.query?._ids?.length && col?.type !== 'image' && col.is_search_able\r\n \"\r\n class=\"list-group-item border-0 px-0 d-flex justify-content-between align-items-center dropdown-item cursor-pointer\"\r\n >\r\n <div class=\"d-flex gap-1\">\r\n <div style=\"margin-top: -3px\"></div>\r\n <div class=\"fw-semibold\">\r\n {{ col.header }}\r\n </div>\r\n </div>\r\n </div>\r\n </ng-container>\r\n </div>\r\n </div>\r\n\r\n <!-- Dropdown -->\r\n <div\r\n @slideToggle\r\n *ngIf=\"isFilterOpen && selectedColumnForFilter?.type == 'dropdown' || selectedColumnForFilter?.type == 'array'\"\r\n (click)=\"$event.stopPropagation()\"\r\n class=\"shadow actions-dropdown mt-1 show shadow custom-menu table-layout filter-columns pb-2\"\r\n style=\"width: 280px; right: unset; max-width: 230px\"\r\n [style.backgroundColor]=\"checkboxesBackgroundColor\"\r\n >\r\n <div class=\"px-3 my-2 border-below py-1 pb-2 mb-3 d-flex ps-1\">\r\n <span\r\n (click)=\"toggleActions('filter-columns'); isActiveFilterOpen = false\"\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrow-left.svg'\"\r\n class=\"data-grid-svg-icon me-2 cursor-pointer\"\r\n ></span\r\n ><b>{{ selectedColumnForFilter?.header }}</b>\r\n </div>\r\n <div class=\"mb-2 px-3\">\r\n <div\r\n class=\"col-12 global-search position-relative border rounded d-flex align-items-center flex-wrap px-2 filter-serach-inpt\"\r\n >\r\n <span\r\n *ngFor=\"let selected of selectedFilterOptions\"\r\n class=\"badge d-flex align-items-center gap-1 me-1 mb-1 top-row-filter-dropdown\"\r\n >\r\n {{ selected?.value ? selected.value : selected }}\r\n <span\r\n (click)=\"toggleSelectionInFilter(selected)\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/cross-primary.svg'\r\n \"\r\n class=\"me-2\"\r\n ></span>\r\n </span>\r\n <input\r\n class=\"form-control form-control-sm border-0 flex-grow-1\"\r\n style=\"padding: 0\"\r\n [placeholder]=\"selectedFilterOptions?.length ? '' : 'Filter by'\"\r\n type=\"search\"\r\n [(ngModel)]=\"searchTextForFilterDropDown\"\r\n (keydown.backspace)=\"handleBackspace($event)\"\r\n />\r\n </div>\r\n </div>\r\n <div\r\n class=\"list-group list-group-flush\"\r\n style=\"max-height: calc(100vh - 600px); overflow: auto\"\r\n >\r\n <ng-container\r\n *ngFor=\"\r\n let col of selectedColumnForFilter.column_dropdown_value\r\n | filter : searchTextForFilterDropDown : 'value';\r\n let i = index\r\n \"\r\n >\r\n <div\r\n class=\"list-group-item border-0 px-2 d-flex justify-content-between align-items-center dropdown-item cursor-pointer\"\r\n >\r\n <div class=\"form-check\">\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n [id]=\"i\"\r\n [checked]=\"currentFilterSelectedIds.has(col.id || col._id || col)\"\r\n (change)=\"toggleSelectionInFilter(col)\"\r\n />\r\n <label class=\"form-check-label fw-semibold\" [for]=\"i\">\r\n {{ col?.value || col?.name || col }}\r\n </label>\r\n </div>\r\n </div>\r\n </ng-container>\r\n </div>\r\n <div\r\n class=\"d-flex justify-content-center gap-2 px-2 border-top\"\r\n style=\"height: 38px\"\r\n >\r\n <button\r\n type=\"button\"\r\n style=\"height: 32px\"\r\n class=\"btn btn-outline-secondary btn-light border w-100 d-flex align-items-center justify-content-center mt-1 btn-light\"\r\n (click)=\"$event.stopPropagation(); resetFilterChanges()\"\r\n >\r\n <span>Cancel</span>\r\n </button>\r\n <button\r\n type=\"button\"\r\n style=\"height: 32px\"\r\n class=\"btn btn-primary w-100 d-flex align-items-center justify-content-center mt-1\"\r\n (click)=\"applyDropdownFilter()\"\r\n >\r\n <span style=\"margin-top: -2px\">Save</span>\r\n </button>\r\n </div>\r\n </div>\r\n\r\n <!-- For Text fields and number fields-->\r\n\r\n <div\r\n @slideToggle\r\n *ngIf=\"\r\n isFilterOpen &&\r\n (selectedColumnForFilter?.type == 'string' ||\r\n selectedColumnForFilter?.type == 'number' ||\r\n selectedColumnForFilter?.type == 'date')\r\n \"\r\n (click)=\"$event.stopPropagation()\"\r\n class=\"shadow actions-dropdown mt-1 show shadow custom-menu table-layout filter-columns pb-2\"\r\n style=\"width: 210px; right: unset; max-width: 230px\"\r\n [style.backgroundColor]=\"checkboxesBackgroundColor\"\r\n >\r\n <div class=\"px-3 border-below py-1 pb-2 d-flex ps-1\">\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrow-left.svg'\"\r\n (click)=\"toggleActions('filter-columns'); isActiveFilterOpen = false\"\r\n class=\"data-grid-svg-icon me-2 cursor-pointer\"\r\n ></span\r\n ><b>{{ selectedColumnForFilter?.header }}</b>\r\n </div>\r\n <div class=\"col-12 position-relative p-2 text-filter\">\r\n <div class=\"mb-2\">\r\n <select\r\n class=\"form-select form-select-sm custom-select border\"\r\n [(ngModel)]=\"firstCondition\"\r\n >\r\n <ng-container *ngIf=\"selectedColumnForFilter?.type == 'string'\">\r\n <option value=\"contain\">Contains</option>\r\n <option value=\"does_not_contain\">Does Not Contain</option>\r\n <option value=\"equal\">Equals</option>\r\n <option value=\"before\">Starts With</option>\r\n <option value=\"after\">Ends With</option>\r\n </ng-container>\r\n\r\n <ng-container *ngIf=\"selectedColumnForFilter?.type == 'date'\">\r\n <option value=\"equal\">Equals To</option>\r\n <option value=\"not_equal\">Not Equal</option>\r\n <option value=\"after\">After</option>\r\n <option value=\"before\">Before</option>\r\n </ng-container>\r\n\r\n <ng-container *ngIf=\"selectedColumnForFilter?.type == 'number'\">\r\n <option value=\"equal\">Equals To</option>\r\n <option value=\"before\">Less Then </option>\r\n <option value=\"after\">Greater Then </option>\r\n <option value=\"less_then_equal\">less then Equal to</option>\r\n <option value=\"greater_then_equal\">Greater then Equal to </option>\r\n </ng-container>\r\n </select>\r\n </div>\r\n <div class=\"mb-2\">\r\n <input\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Enter first value\"\r\n type=\"search\"\r\n [type]=\"\r\n selectedColumnForFilter?.type == 'string'\r\n ? 'text'\r\n : selectedColumnForFilter?.type\r\n \"\r\n [(ngModel)]=\"firstValue\"\r\n (keydown.enter)=\"applyDropdownFilter()\"\r\n />\r\n </div>\r\n <div>\r\n <div class=\"d-flex my-3 d-flex flex-row\" style=\"font-size: 14px\">\r\n <div\r\n class=\"form-check form-check-inline col-4 m-0 d-flex align-items-center gap-1\"\r\n >\r\n <input\r\n class=\"form-check-input\"\r\n type=\"radio\"\r\n id=\"logicalAnd\"\r\n name=\"logicalOperator\"\r\n value=\"and\"\r\n [(ngModel)]=\"condition\"\r\n />\r\n <label class=\"form-check-label mb-0 mt-1\" for=\"logicalAnd\"\r\n >AND</label\r\n >\r\n </div>\r\n\r\n <div\r\n class=\"form-check form-check-inline col-4 m-0 d-flex align-items-center gap-1\"\r\n >\r\n <input\r\n class=\"form-check-input\"\r\n type=\"radio\"\r\n id=\"logicalOr\"\r\n name=\"logicalOperator\"\r\n value=\"or\"\r\n [(ngModel)]=\"condition\"\r\n />\r\n <label class=\"form-check-label mb-0 mt-1\" for=\"logicalOr\">OR</label>\r\n </div>\r\n\r\n <div\r\n class=\"form-check form-check-inline col-4 m-0 d-flex align-items-center gap-1\"\r\n >\r\n <input\r\n class=\"form-check-input\"\r\n type=\"radio\"\r\n id=\"logicalNone\"\r\n name=\"logicalOperator\"\r\n value=\"none\"\r\n [(ngModel)]=\"condition\"\r\n />\r\n <label class=\"form-check-label mb-0 mt-1\" for=\"logicalNone\"\r\n >None</label\r\n >\r\n </div>\r\n </div>\r\n\r\n <ng-container *ngIf=\"condition !== 'none' && firstValue\">\r\n <div class=\"mb-2 mt-3\">\r\n <!-- Second condition select -->\r\n <select\r\n class=\"form-select form-select-sm border\"\r\n [(ngModel)]=\"secondCondition\"\r\n >\r\n <ng-container *ngIf=\"selectedColumnForFilter?.type == 'string'\">\r\n <option value=\"contain\">Contains</option>\r\n <option value=\"does_not_contain\">Does Not Contain</option>\r\n <option value=\"equal\">Equals</option>\r\n <option value=\"before\">Starts With</option>\r\n <option value=\"after\">Ends With</option>\r\n </ng-container>\r\n\r\n <ng-container *ngIf=\"selectedColumnForFilter?.type == 'date'\">\r\n <option value=\"equal\">Equals To</option>\r\n <option value=\"not_equal\">Not Equal</option>\r\n <option value=\"after\">After</option>\r\n <option value=\"before\">Before</option>\r\n </ng-container>\r\n <ng-container *ngIf=\"selectedColumnForFilter?.type == 'number'\">\r\n <option value=\"equal\">Equals To</option>\r\n <option value=\"before\">Less Then </option>\r\n <option value=\"after\">Greater Then </option>\r\n <option value=\"less_then_equal\">less then Equal to</option>\r\n <option value=\"greater_then_equal\">Greater then Equal to </option>\r\n </ng-container>\r\n </select>\r\n </div>\r\n\r\n <div class=\"mb-2\">\r\n <!-- Second value input -->\r\n <input\r\n [type]=\"\r\n selectedColumnForFilter?.type == 'string'\r\n ? 'text'\r\n : selectedColumnForFilter?.type\r\n \"\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Enter second value\"\r\n type=\"search\"\r\n [(ngModel)]=\"secondValue\"\r\n (keydown.enter)=\"applyDropdownFilter()\"\r\n />\r\n </div>\r\n </ng-container>\r\n </div>\r\n </div>\r\n\r\n <div\r\n class=\"d-flex justify-content-center gap-2 px-2 border-top\"\r\n style=\"height: 38px\"\r\n >\r\n <button\r\n [disabled]=\"!currentFilterSelectedIds?.size && !firstValue\"\r\n type=\"button\"\r\n style=\"height: 32px\"\r\n class=\"btn btn-outline-secondary btn-light border w-100 d-flex align-items-center justify-content-center mt-1 btn-light\"\r\n (click)=\"$event.stopPropagation(); resetTextFilterChanges()\"\r\n >\r\n <span>Cancel</span>\r\n </button>\r\n <button\r\n [disabled]=\"(currentFilterSelectedIds?.size === 0 && !firstValue) || (condition !== 'none' && !secondValue)\"\r\n type=\"button\"\r\n style=\"height: 32px\"\r\n class=\"btn btn-primary w-100 d-flex align-items-center justify-content-center mt-1\"\r\n (click)=\"applyDropdownFilter()\"\r\n >\r\n <span style=\"margin-top: -2px\">Apply</span>\r\n </button>\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<!-- Edit dropdown here -->\r\n<ng-template let-col>\r\n <div class=\"drop-down-edit\"></div>\r\n</ng-template>\r\n\r\n<ng-template\r\n #fullTextTemplate\r\n let-row=\"row\"\r\n let-col=\"col\"\r\n let-isArray=\"isArray\"\r\n>\r\n <div\r\n class=\"full-text-box\"\r\n (dblclick)=\"$event.stopPropagation(); $event.preventDefault()\"\r\n (click)=\"$event.stopPropagation(); $event.preventDefault()\"\r\n [style.maxHeight.px]=\"dataGridContainer.offsetHeight / 2\"\r\n >\r\n <ng-container *ngIf=\"!isEditing(row, col)\">\r\n <div\r\n *ngIf=\"!isArray\"\r\n class=\"full-text-content\"\r\n [style.maxHeight.px]=\"dataGridContainer.offsetHeight / 2\"\r\n (dblclick)=\"\r\n $event.stopPropagation();\r\n $event.preventDefault();\r\n enableEdit(row, col, true)\r\n \"\r\n (click)=\"$event.stopPropagation(); $event.preventDefault()\"\r\n >\r\n {{\r\n getNestedValue(row, col.field)?.value ||\r\n getNestedValue(row, col.field)?.name ||\r\n getNestedValue(row, col.field)\r\n }}\r\n </div>\r\n <div *ngIf=\"isArray\">\r\n <ul>\r\n <ng-container\r\n *ngFor=\"let item of getNestedValue(row, col.field); let i = index\"\r\n >\r\n <li *ngIf=\"i !== 0\">\r\n <ng-container>\r\n {{\r\n item?.department_name ||\r\n item?.roleName ||\r\n item?.full_name ||\r\n \"-\"\r\n }}\r\n </ng-container>\r\n </li>\r\n </ng-container>\r\n </ul>\r\n </div>\r\n </ng-container>\r\n <ng-container *ngIf=\"isEditing(row, col)\">\r\n <textarea\r\n (dblclick)=\"\r\n $event.stopPropagation();\r\n $event.preventDefault();\r\n enableEdit(row, col, true)\r\n \"\r\n #textModel=\"ngModel\"\r\n rows=\"4\"\r\n #textAreadInput\r\n [(ngModel)]=\"row[col.field]\"\r\n name=\"{{ col.field }}\"\r\n required\r\n (blur)=\"disableEdit(row, col, textModel)\"\r\n (keydown.enter)=\"textAreadInput.blur()\"\r\n autofocus\r\n class=\"form-control\"\r\n [ngClass]=\"{\r\n 'is-invalid': textModel.invalid\r\n }\"\r\n (mousedown)=\"$event.stopPropagation()\"\r\n ></textarea>\r\n </ng-container>\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template #defaultImagePlaceholder let-row=\"row\" let-col=\"col\">\r\n <span\r\n class=\"px-2 d-flex w-100 cell-content image-placeholder\"\r\n [title]=\"row?.full_name || row?.name || 'N/A'\"\r\n >\r\n <ng-container\r\n *ngIf=\"\r\n row?.logo ||\r\n row?.assetImage ||\r\n row?.invoice?.invoice_image ||\r\n row?.invoice_image;\r\n else placeholder\r\n \"\r\n >\r\n <span\r\n (click)=\"fullscreenImage = row?.profile_pictures?.[4]?.path ||\r\n row?.logo ||\r\n row?.assetImage ||\r\n row?.invoice_image\"\r\n class=\"pic\"\r\n [style.width.px]=\"rowHeight - 10\"\r\n [style.height.px]=\"rowHeight - 10\"\r\n [class.assets-pic]=\"gridType == 'Assets'\"\r\n >\r\n <img\r\n [width]=\"rowHeight - 12\"\r\n [height]=\"rowHeight - 12\"\r\n [style.width.px]=\"rowHeight - 10\"\r\n [style.height.px]=\"rowHeight - 10\"\r\n [src]=\"\r\n row?.profile_pictures?.[4]?.path ||\r\n row?.logo ||\r\n row?.assetImage ||\r\n row?.invoice_image\r\n \"\r\n alt=\"icon\"\r\n class=\"option-icon\"\r\n loading=\"lazy\"\r\n />\r\n </span>\r\n </ng-container>\r\n <!-- <div\r\n class=\"fullscreen-overlay\"\r\n *ngIf=\"fullscreenImage\"\r\n (click)=\"fullscreenImage = null\"\r\n >\r\n <img [src]=\"fullscreenImage\" class=\"fullscreen-img\" />\r\n </div> -->\r\n\r\n <ng-template #placeholder>\r\n <span\r\n [ngClass]=\"getDynamicClass(row?.full_name || row?.name)\"\r\n class=\"pic d-flex align-items-center rounded-circle\"\r\n [style.width.px]=\"rowHeight - 12\"\r\n [style.height.px]=\"rowHeight - 12\"\r\n [style.fontSize.px]=\"rowHeight / 3\"\r\n [class.assets-pic]=\"gridType == 'Assets'\"\r\n >\r\n {{ getInitials(row?.full_name) }}\r\n </span>\r\n </ng-template>\r\n </span>\r\n</ng-template>\r\n\r\n<!-- Right Click Menue -->\r\n<div\r\n [class.invisible]=\"!positionedYet\"\r\n class=\"context-menu p-2\"\r\n *ngIf=\"actionHide && actions?.length\"\r\n [ngStyle]=\"{ 'top.px': yPos, 'left.px': xPos }\"\r\n [class.show]=\"isVisible\"\r\n appendTo=\"body\"\r\n>\r\n <ul>\r\n <li\r\n *ngFor=\"let action of actions\"\r\n class=\"rounded d-flex align-items-center\"\r\n (click)=\"onActionClick(action)\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/' + action + '.svg'\"\r\n class=\"data-grid-svg-icon right-click-menu-icons me-2\"\r\n ></span>\r\n <span class=\"text-capitalize fw-500\">{{ action }}</span>\r\n </li>\r\n </ul>\r\n</div>\r\n\r\n<!-- Details Toggle from bottom -->\r\n\r\n<ng-template #nestedTableTemplate let-row>\r\n <div\r\n class=\"nested-table table table-sm w-100 mb-0 center-nested-table w-100\"\r\n style=\"table-layout: fixed !important\"\r\n #nestedTableContainer\r\n >\r\n <thead\r\n #nestedHeader\r\n [style.backgroundColor]=\"nestedTableHeaderBackgroundColor\"\r\n >\r\n <div\r\n cdkDropList\r\n [cdkDropListData]=\"row?.detail.columns\"\r\n cdkDropListOrientation=\"horizontal\"\r\n (cdkDropListDropped)=\"dropColumn($event, row)\"\r\n (cdkDropListSorted)=\"onNestedColSort($event, previewNestedCols)\"\r\n [style.height.px]=\"nestedTableHeaderRowHeight\"\r\n class=\"d-flex tr border-below\"\r\n >\r\n <div\r\n *ngFor=\"let col of row.detail.columns; let i = index\"\r\n [style.width.px]=\"col?.width || 250\"\r\n [style.minWidth.px]=\"col?.width || 250\"\r\n [style.maxWidth.px]=\"col?.width || 250\"\r\n class=\"px-4 th\"\r\n [attr.field]=\"col.field\"\r\n [style.backgroundColor]=\"nestedTableHeaderBackgroundColor\"\r\n cdkDrag\r\n >\r\n <div\r\n class=\"d-flex h-100 justify-content-between position-relative align-items-center\"\r\n >\r\n <div class=\"text-ellipsis\" (click)=\"sortNestedCol(col, row)\">\r\n {{ col.header }}\r\n </div>\r\n <div class=\"d-flex gap-2\">\r\n <span\r\n *ngIf=\"currentSubSortColumn == col.field\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath +\r\n (col?.order_by == 'desc'\r\n ? 'data-grid/icons/sort-desc.svg'\r\n : 'data-grid/icons/sort-asc.svg')\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center ms-2 start-50\"\r\n >\r\n </span>\r\n <!-- <div\r\n class=\"three-dots p-1\"\r\n (click)=\"openThreeDotsMenu($event, col)\"\r\n style=\"cursor: pointer\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath +\r\n 'data-grid/icons/three-dots-vertical.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div> -->\r\n\r\n <!-- Only show menu if this column is active -->\r\n <div\r\n class=\"position-absolute\"\r\n *ngIf=\"activeCol === col\"\r\n style=\"top: -50%; z-index: 21; left: 0\"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n columnMenu;\r\n context: {\r\n col: col,\r\n isNestedTable: true,\r\n columns: row?.detail.columns\r\n }\r\n \"\r\n ></ng-container>\r\n </div>\r\n <div\r\n class=\"resize-handle\"\r\n (click)=\"$event.stopPropagation()\"\r\n (mousedown)=\"\r\n $event.preventDefault();\r\n onResizeColumn($event, col);\r\n $event.stopPropagation()\r\n \"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/resize-handle.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n </div>\r\n </div>\r\n <ng-template cdkDragPreview>\r\n <div class=\"p-2 border d-flex gap-2\">\r\n <div>\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/arrows-move.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n <div>{{ col.header }}</div>\r\n </div>\r\n </ng-template>\r\n </div>\r\n </div>\r\n </thead>\r\n <div\r\n [style.width.px]=\"nestedHeader.offsetWidth - 10\"\r\n [style.minWidth.px]=\"nestedHeader.offsetWidth - 10\"\r\n >\r\n <cdk-virtual-scroll-viewport\r\n [itemSize]=\"nestedTablerowHeight\"\r\n class=\"viewport\"\r\n [style.height.px]=\"\r\n (row?.detail?.result?.length < 5\r\n ? nestedTablerowHeight * row?.detail?.result?.length + 40\r\n : 300) + (hasHorizontalScroll ? -12 : 1)\r\n \"\r\n [style.width.px]=\"nestedHeader.offsetWidth - 10\"\r\n [style.minWidth.px]=\"nestedHeader.offsetWidth - 10\"\r\n >\r\n <div\r\n class=\"cursor-pointer border-below d-flex tr\"\r\n *cdkVirtualFor=\"let d of row?.detail?.result; trackBy: trackById\"\r\n [style.height.px]=\"nestedTablerowHeight\"\r\n [style.width.px]=\"nestedHeader?.offsetWidth\"\r\n [style.minWidth.px]=\"nestedHeader?.offsetWidth\"\r\n [style.backgroundColor]=\"bodyBackgroundColor\"\r\n (contextmenu)=\"onRightClick($event, d)\"\r\n >\r\n <div\r\n class=\"px-4 py-0 td\"\r\n *ngFor=\"let col of previewNestedCols; let j = index\"\r\n [style.fontSize.px]=\"nestedTablerowFontsize\"\r\n [attr.field]=\"col.field\"\r\n [style.width.px]=\"col?.width || 250\"\r\n [style.minWidth.px]=\"col?.width || 250\"\r\n [style.maxWidth.px]=\"col?.width || 250\"\r\n >\r\n <div\r\n [style.height.px]=\"nestedTablerowHeight - 1\"\r\n [style.max-width.px]=\"col?.width\"\r\n class=\"d-flex align-items-center\"\r\n >\r\n <!-- {{ d[col.field] || (col.is_amount ? 0 : \"-\") }} -->\r\n <div\r\n #cellText\r\n class=\"text-ellipsis flex-grow-1\"\r\n [title]=\"\r\n col?.type === 'date'\r\n ? (getNestedValue(d, col.field) | date : dateFormat)\r\n : getNestedValue(d, col.field) || '-'\r\n \"\r\n >\r\n <ng-container *ngIf=\"col?.type !== 'image'\">\r\n <ng-container *ngIf=\"col.is_amount\">{{\r\n currencySymbol\r\n }}</ng-container>\r\n {{\r\n !isNestedValueArray(d, col.field)\r\n ? col?.type === 'date'\r\n ? (isDate(getNestedValue(d, col.field))\r\n ? (getNestedValue(d, col.field) | date: dateFormat)\r\n : (getNestedValue(d, col.field)?.value ||\r\n getNestedValue(d, col.field)?.name ||\r\n getNestedValue(d, col.field) ||\r\n '-'))\r\n : (getNestedValue(d, col.field)?.value ||\r\n getNestedValue(d, col.field)?.name ||\r\n getNestedValue(d, col.field) ||\r\n (col.is_amount ? 0: '-'))\r\n : (getNestedValue(d, col.field)?.[0]?.department_name ||\r\n getNestedValue(d, col.field)?.[0]?.roleName || getNestedValue(d, col.field)?.[0]?.full_name ||\r\n '-')\r\n }}\r\n </ng-container>\r\n <ng-container *ngIf=\"false\">\r\n {{ getTotalAmount(col) }}\r\n </ng-container>\r\n <ng-container *ngIf=\"col?.type == 'image'\">\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n defaultImagePlaceholder;\r\n context: {\r\n row: d,\r\n col: col,\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </cdk-virtual-scroll-viewport>\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template #leftRightNestedPlaceholder let-row>\r\n <table\r\n class=\"nested-table table table-sm w-100 mb-0\"\r\n [style.backgroundColor]=\"bodyBackgroundColor\"\r\n [style.height.px]=\"\r\n gridType == 'Assets'\r\n ? (nestedTableContainer?.nativeElement?.offsetHeight ?? 0) + 12\r\n : (taskManagementContainer?.nativeElement?.offsetHeight ?? 0)\r\n \"\r\n >\r\n <!-- <div class=\"thead\">\r\n <div\r\n class=\"tr d-flex border-below\"\r\n [style.height.px]=\"nestedTableHeaderRowHeight\"\r\n [style.backgroundColor]=\"headerBackgroundColor\"\r\n >\r\n <div class=\"th\" *ngFor=\"let _ of [1, 2, 3, 4, 5]\"></div>\r\n </div>\r\n </div> -->\r\n <!-- <div class=\"tbody\">\r\n <div\r\n class=\"tr border-below\"\r\n [style.height.px]=\"nestedTablerowHeight\"\r\n *ngFor=\"let _ of row?.detail?.result\"\r\n [style.backgroundColor]=\"headerBackgroundColor\"\r\n >\r\n <div class=\"td\" *ngFor=\"let __ of [1, 2, 3, 4, 5]\" class=\"py-0\">\r\n <span\r\n [style.height.px]=\"nestedTablerowHeight\"\r\n [style.max-width.px]=\"nestedTablerowHeight\"\r\n ></span>\r\n </div>\r\n </div>\r\n </div> -->\r\n </table>\r\n</ng-template>\r\n\r\n<ng-template #taskManagementTemplate let-taskDetails=\"taskDetails\">\r\n <div\r\n class=\"p-4\"\r\n #taskManagementContainer\r\n [style.backgroundColor]=\"nestedTableHeaderBackgroundColor\"\r\n [style.fontFaimly]=\"fontFaimly\"\r\n >\r\n <div class=\"d-flex justify-content-between\">\r\n <div class=\"col-4\">\r\n <div class=\"item-title\">Description</div>\r\n <!-- <div class=\"item-content firstDiv\">\r\n {{ taskDetails.description }}\r\n </div> -->\r\n <p\r\n [style.fontSize]=\"bodyTextFontsSize\"\r\n class=\"item-content firstDiv taskDescription pe-4\"\r\n [innerHTML]=\"getSafeComment(taskDetails?.editor_description)\"\r\n (click)=\"openFullImage($event)\"\r\n ></p>\r\n </div>\r\n <div class=\"col-4\">\r\n <div class=\"item-title\">Attachments</div>\r\n <h5 *ngIf=\"taskDetails?.attachments?.length == 0\">\r\n No Attachments found\r\n </h5>\r\n <div\r\n *ngIf=\"taskDetails?.attachments?.length\"\r\n class=\"item-content d-flex flex-wrap\"\r\n style=\"gap: 10px\"\r\n >\r\n <a\r\n *ngFor=\"let attachement of taskDetails?.attachments; let i = index\"\r\n class=\"symbol-label fs-2 fw-semibold text-success cursor-pointer\"\r\n >\r\n <span\r\n title=\"{{ taskDetails?.attachments_name[i] || 'Attachment' }}\"\r\n (click)=\"downloadAttchment(attachement)\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath +\r\n 'data-grid/document-icons/' +\r\n getExtention(attachement) +\r\n '.svg'\r\n \"\r\n >\r\n </span>\r\n </a>\r\n </div>\r\n </div>\r\n <div class=\"col-4\">\r\n <div class=\"item-title\">\r\n Comments ({{ taskDetails?.comments?.length }})\r\n </div>\r\n <h5 *ngIf=\"taskDetails?.comments?.length == 0\">No Comments found</h5>\r\n <div *ngIf=\"taskDetails?.comments?.length\" class=\"item-content\">\r\n <div class=\"comment\" *ngFor=\"let comment of taskDetails.comments\">\r\n <div class=\"d-flex align-items-center pe-3\">\r\n <img\r\n class=\"pic image-input-wrapper\"\r\n [style.width.px]=\"rowHeight - 12\"\r\n [style.height.px]=\"rowHeight - 12\"\r\n *ngIf=\"comment?.comment_by.logo\"\r\n src=\"{{ comment?.comment_by.logo }}\"\r\n alt=\"{{ comment.comment_by.full_name }}\"\r\n />\r\n <!-- <app-default-image-placeholder *ngIf=\"!comment?.comment_by.logo\" title=\"{{ comment.comment_by.full_name }}\" [name]=\"comment.comment_by.full_name\"></app-default-image-placeholder> -->\r\n <span\r\n *ngIf=\"!comment?.comment_by.logo\"\r\n [ngClass]=\"getDynamicClass(comment.comment_by.full_name)\"\r\n class=\"pic d-flex align-items-center rounded-circle\"\r\n [style.width.px]=\"rowHeight - 12\"\r\n [style.height.px]=\"rowHeight - 12\"\r\n [style.fontSize.px]=\"rowHeight / 3\"\r\n title=\"{{ comment.comment_by.full_name }}\"\r\n >\r\n {{ getInitials(comment.comment_by.full_name) }}\r\n </span>\r\n </div>\r\n <div>\r\n <div class=\"comment-author fs-14px\">\r\n {{ comment?.comment_by.full_name }}\r\n </div>\r\n <div\r\n class=\"comment-content forCommentImg\"\r\n [innerHTML]=\"getSafeComment(comment.comment)\"\r\n ></div>\r\n <div class=\"comment-timestamp\">\r\n {{ comment.comment_date | date }}\r\n </div>\r\n <div class=\"comment-timestamp\">\r\n Replies: ({{ comment.replies.length }})\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n</ng-template>\r\n", styles: ["@charset \"UTF-8\";@import\"bootstrap/dist/css/bootstrap.min.css\";.data-grid-table-wrapper{height:100%;width:100%;border:1px solid #d9d9db;border-radius:12px;position:relative}.data-grid-header{position:sticky;top:0}.data-grid-header{display:flex}.header-row{display:grid;width:100%}.header-cell{display:flex;align-items:center;position:relative;width:100%;padding:8px 0 8px 8px;font-weight:700;border-bottom:1px solid #d9d9db;white-space:nowrap;min-width:80px;font-weight:600}.header-cell .filter-applied-on-text{color:#5d9cff!important}.filter-cell{padding:4px!important;display:flex;align-items:center;gap:8px;width:100%}.filter-cell .filter-applied{background-color:#bddef9}.border-right{border-right:1px solid #d9d9db}.merged-grid{display:grid;grid-auto-rows:40px;border-bottom:1px solid #ccc}.span-two-rows{grid-row:span 2;display:flex;justify-content:space-between;align-items:center}.group-header{display:flex;justify-content:space-between;position:relative}.group-header-content{position:sticky;left:10px;overflow:hidden;text-overflow:ellipsis}.resize-handle{width:6px;cursor:e-resize;right:0;top:0;color:#00000026;margin-right:4px}.group-header .resize-handle{top:25%}.h-100{height:100%}.data-grid-body{position:relative;overflow-y:auto;overflow-x:hidden}.cell{padding:8px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;height:100%;display:flex;align-items:center}.data-grid-row{display:flex;width:100%;min-width:max-content;align-items:center;border-bottom:1px solid #d9d9db}.hovered-row{background-color:#ccc}.checkbox-row{border-bottom:#d9d9db}.w-100{width:100%}.data-grid-header-wrapper{display:flex;position:relative;overflow:hidden;-webkit-user-select:none;user-select:none}.data-grid-header{display:flex;position:relative;z-index:1}.left-pinned,.right-pinned{position:sticky;top:0}.right-pinned-header{position:absolute;right:0;border-left:1px solid #d9d9db;z-index:unset}.left-pinned{left:0}.right-pinned{right:0;border-left:1px solid #d9d9db}.center-scrollable{z-index:unset!important;overflow-x:auto;overflow-y:visible;white-space:nowrap;scrollbar-width:none;-ms-overflow-style:none}.center-scrollable::-webkit-scrollbar{display:none}.data-grid-body-wrapper{-webkit-user-select:none;user-select:none;display:flex}.center-scrollable-body{overflow-x:auto;scrollbar-width:none;-ms-overflow-style:none}.center-scrollable-body::-webkit-scrollbar{display:none}.left-pinned-body,.right-pinned-body{position:sticky;top:0;z-index:unset;background:#fff;scrollbar-width:none;-ms-overflow-style:none}.left-pinned-body::-webkit-scrollbar,.right-pinned-body::-webkit-scrollbar{display:none}.left-pinned-body{left:0}.border-end{border-right:1px solid #d9d9db!important}.right-pinned-body{right:0;border-left:1px solid #d9d9db}.fake-scroll-bar{height:14px;overflow:scroll;margin-bottom:10px}.text-ellipsis{overflow:hidden;text-overflow:ellipsis}.select-all-checkbox-cell{width:50px;display:flex;justify-content:center;align-items:center;height:100%;border-right:1px solid #d9d9db}.select-all-checkbox-cell input{width:16px;height:14px}.border-below{border-bottom:1px solid #d9d9db!important}.three-dots{width:22px;height:22px;display:flex;justify-content:center;align-items:center;border-radius:3px;margin-right:8px;cursor:pointer}.three-dots:hover{background-color:#ccc!important}.filter-icon-wrapper{min-height:22px;max-height:22px;min-width:22px;max-width:22px;display:flex;justify-content:center;align-items:center;border-radius:3px;cursor:pointer;transition:background-color .3s ease}.filter-icon-wrapper:hover{background-color:#ccc}.column-menu,.filter-menu{box-shadow:0 0 16px #00000026;border-radius:4px}.column-menu{background:#fff;width:100%;width:240px;border:1px solid #ddd;box-shadow:0 0 16px #00000026;border:1px solid #d9d9db;padding:4px 0;font-size:14px;position:fixed}.column-menu-item{padding:8px 12px;cursor:pointer;display:flex;align-items:center;transition:background-color .2s ease}.column-menu-item:hover{background-color:#deebf7}.pin-parent{position:relative;width:100%!important}.column-submenu{position:absolute;top:0;left:100%;background:#fff;border:1px solid #ddd;width:130px;box-shadow:0 0 16px #00000026;border:1px solid #d9d9db;display:none;padding:4px 0;z-index:10;border-radius:4px}.pin-parent:hover .column-submenu{display:block}.filter-menu-container{position:fixed;width:210px;background:#fff;border:1px solid #ddd;border-radius:4px;padding:12px;box-shadow:0 0 16px #00000026;border:1px solid #d9d9db;z-index:1000;font-size:14px}.filter-menu-header{font-weight:600;margin-bottom:10px}.filter-dropdown-section{max-height:350px;overflow-y:auto}.dropdown-options{overflow-y:auto;scrollbar-width:thin;height:100%}.filter-text-section select,.filter-text-section input{width:100%}.filter-radio-inputs{width:14px!important;height:14px!important}.right-menu{border-left:1px solid #d9d9db;font-size:14px}.border-start{border-left:1px solid #d9d9db!important}.column-panel-item{font-size:.875rem;color:#333}.toggle-icon{cursor:pointer;transition:transform .2s ease}.toggle-icon.rotate{transform:rotate(90deg)}.grab-icon{cursor:grab;color:#6c757d}.text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.cursor-pointer{cursor:pointer}.pivot-mode{height:48px}.chevron-wrapper{width:30px;height:20px;cursor:pointer;border-radius:3px;display:flex;justify-content:center;align-items:center;transition:background-color .3s ease;margin-right:8px}.chevron-wrapper:hover{background-color:#cac7c7}.chevron-wrapper i{font-size:14px}.column-panel-body{height:70%;overflow:auto;scrollbar-width:thin}.side-menue-text{transform:rotate(90deg);position:relative;font-weight:700;margin-top:40px}.columns-button{padding-top:20px;padding-bottom:35px;width:29px}.fake-scroll-content{height:12px}.fake-scrollbar{width:25px}.fake-scrollbar div{min-width:1px}.fake-horizintal-scrollbar div{min-height:1px}.side-filter-columns-wrapper{height:calc(100% - 25px)}.custom-modal-overlay{position:fixed;top:0;left:0;width:100%;height:100%;overflow:hidden;display:flex;justify-content:center;align-items:center;z-index:1050}.custom-modal-overlay .moda-header{background-color:#f8f8f8}.custom-modal-content{background-color:#fff;border-radius:8px;min-width:300px;max-width:400px;box-shadow:0 5px 20px #0000004d}.overlay-scrollable{height:250px;overflow:auto}.footer-row{border-top:1px solid #d9d9db;padding-left:32px}.fake-horizintal-scrollbar{position:relative;bottom:17px;overflow-x:auto;overflow-y:hidden;height:17px}.border-dashed{border:1px dashed #d9d9db}.cdk-drag-preview{box-sizing:border-box!important;border-radius:4px!important;box-shadow:0 5px 5px -3px #0003,0 8px 10px 1px #00000024,0 3px 14px 2px #0000001f!important;background-color:#f3f4f5!important;border:1px solid #d9d9db!important;z-index:9999!important}.data-grid-header-wrapper ::ng-deep .cdk-drag-placeholder{display:block!important;background:#fff!important;opacity:1!important}.cdk-drag-animating{transition:transform .25s cubic-bezier(0,0,.2,1)!important}.top-row-grouping-placeholder{display:flex;align-items:center;border-radius:12px;font-size:14px;padding-inline:6px;border:1px solid #d9d9db}.top-row-grouping-placeholder .bi-x{cursor:pointer;color:#7a7a7a}.top-row-grouping-placeholder .bi-x:hover{color:#111}.right-pinned-body-wrapper{position:absolute;right:0}.actions-dropdown{position:absolute;right:200px;z-index:1050;background-color:#fff;border-radius:8px!important;cursor:default}.bg-fff{background-color:#fff}.actions-dropdown-setting{right:250px}.action-button{background-color:#007cf5!important;border-radius:8px!important;padding:8px 16px!important;font-size:14px;height:32px;align-items:center}.global-search{max-width:380px!important;display:flex!important;align-items:center!important}.global-search span{margin-top:-4px!important}.global-search input{padding-left:28px;border-radius:8px!important}.global-search input:focus{outline:none!important;box-shadow:none!important}.active .top-icon ::ng-deep svg path{stroke:#007cf5!important}.dropdown-menu{background-color:#fff!important;border:1px solid #d9d9db!important;border-radius:8px!important}.custom-menu{width:220px;border-radius:8px;padding:4px 0;background-color:#fff}.custom-menu .dropdown-item{font-size:14px;padding:8px 14px}.custom-menu .dropdown-item:hover{background-color:#f5f5f5;border-radius:6px}.table-layout{right:0;background:#fff;border-radius:8px!important}.actions-dropdown,.table-layout,.custom-menu,.dropdown-menu{background:#fff;border-radius:8px!important;border:1px solid #ccc!important;background-color:#fff}.preview-box{width:40px;height:10px;border-radius:3px;background-color:transparent;transition:background-color .2s ease-in-out}.btn-check:checked+label .preview-box{background-color:var(--bs-primary)}.preview-box{width:40px;height:10px;border-radius:3px;border:2px solid transparent;transition:border-color .2s ease-in-out}#small:checked+label .preview-box{border-color:#007cf5!important;background-color:transparent!important}#medium:checked+label .preview-box{border-color:#007cf5!important;background-color:transparent!important}#large:checked+label .preview-box{border-color:#007cf5!important;background-color:transparent!important}.btn-check:checked+.btn{background-color:transparent!important;border-color:#007cf5!important}.layout-button{padding:8px 28px!important;width:82px;border-radius:8px!important}.show-hide-table-label{position:sticky;top:0;z-index:99;background:#fff}.cursor-grap{cursor:grabbing}.pagination-container{display:flex;align-items:center;gap:12px;font-size:13px;color:#333}.page-size select{padding:3px 6px;border:1px solid #ccc;border-radius:6px;background:#fff;font-size:13px}.page-info{margin-left:10px}.page-buttons{display:flex;gap:4px;margin-left:auto;align-items:center}.page-buttons button{padding:3px 8px;border:1px solid #ccc;background:#fff;border-radius:4px;cursor:pointer;font-size:13px;line-height:1.2}.page-buttons button.active{background:#eee;font-weight:600}.page-buttons button:disabled{opacity:.5;cursor:not-allowed}.page-buttons span{padding:0 6px;color:#666}.page-size .separator{padding:0 8px;border-right:1px solid #ccc;margin-right:8px}.page-size .separator .actions-dropdown{position:fixed;right:200px;z-index:1050;background-color:#fff}.fs-14px{font-size:14px}.fs-12px{font-size:12px!important}.save-preset-dropdown{background:#fff;color:#111!important;right:0;font-weight:400!important;text-align:left!important;max-width:250px!important;text-wrap:auto!important;top:14px;font-size:14px!important}.add-filter-button{height:28px;cursor:pointer;border-radius:4px}.add-filter-button:hover,.button-filter:hover{color:#000!important}.button-filter:hover ::ng-deep svg path{stroke:#000!important}.table-layout .dropdown-item{border-radius:0!important;padding-inline:16px!important;font-size:14px;padding-block:6px!important}.table-layout .dropdown-item:hover{background-color:transparent!important}.filter-serach-inpt{max-height:230px!important;overflow:auto;scrollbar-width:thin;padding-top:4px;background-color:#f7f7f7;border-color:#dedede;border-radius:8px}.filter-serach-inpt .badge{color:#007cf5!important;background-color:#e6f2ff!important;border-radius:8px!important;padding:8px!important;font-weight:500!important;font-size:12px!important;height:24px!important}.filter-serach-inpt .badge ::ng-deep svg{cursor:pointer}.filter-serach-inpt .badge ::ng-deep svg:hover path{stroke:#040081!important}.filter-serach-inpt input{background-color:#f7f7f7;padding:0;height:26px;margin-top:-5px}.text-filter select{border:0}.text-filter select option{font-size:14px;font-weight:500}.text-filter select:focus{border:0}.text-filter input:focus,.text-filter select:focus{box-shadow:none!important}.active-filters{background-color:#f7f7f7;white-space:nowrap;background:#f7f7f7;padding-inline:8px;height:28px;font-size:14px;font-weight:500;border-radius:8px;box-shadow:none}.active-filters .header-tag{white-space:nowrap}.filter-tags .active{background-color:#e6f2ff}.filter-tags .active .header-tag{color:#007cf5!important}.table-cell{cursor:pointer;width:100%}.table-cell input:focus{outline:0!important;border:0!important;width:100%!important;box-shadow:none!important}.active-for-editing{outline:2.5px solid #007cf5!important;border-radius:4px;border:0!important;width:100%!important}.active-cell{outline:none!important;box-shadow:inset 0 0 0 1.5px #007cf5}span[inlineSVG]{width:16px;height:16px;display:inline-block}.cell .dropdown-menu{min-width:unset!important}.cell .dropdown-menu .item{transition:background-color .3s ease;display:flex;align-items:center;-webkit-user-select:none;user-select:none}.cell .dropdown-menu .item:hover{background-color:#f0f8ff}.cell .cell-editin-dropdown{scrollbar-width:thin!important;-webkit-user-select:none;user-select:none}.fw-semibold{font-weight:500!important}:host ::ng-deep .three-dots-col-menu svg,:host ::ng-deep .three-dots-col-menu svg path{stroke:#000!important}.fs-7{font-size:12px!important}.fs-8{font-size:10px!important}.all-filters-reset-button:hover{opacity:.7}.full-text-box{background:#fff;position:relative;display:flex;align-items:center;z-index:1050;border:1px solid #dedede;border-radius:8px;padding:12px 14px;box-shadow:0 2px 8px #00000026;max-height:400px;overflow:auto}.full-text-box ul{max-height:400px}.full-text-content{border-radius:8px;max-height:70vh;overflow:auto;white-space:pre-wrap}.pic{border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:22px}.pic-comb2{background-color:#fbe7bf;color:#fd7f31}.pic-comb1{background-color:#d9ecbf;color:#65b500}.pic-comb4{background-color:#fdd3d7;color:#f64e60}.w-40px{width:40px}.h-40px{height:40px}.pic{border-radius:50%;overflow:hidden}.image-placeholder .pic{font-size:14px;font-weight:600;letter-spacing:.5px}.header-cell{font-weight:600}.header-cell,.cell{box-sizing:border-box}.transparent-border-right{border-right:1px solid transparent!important}.resizing-highlight{position:relative}.resizing-highlight:before{content:\"\";position:absolute;top:-1px;right:-1px;width:2px;height:calc(100% + 2px);background:#7cb9f6;z-index:1000;pointer-events:none}.resizing-highlight-right{position:relative}.resizing-highlight-right:before{content:\"\";position:absolute;top:-1px;left:-1px;width:2px;height:calc(100% + 2px);background:#7cb9f6;z-index:1000;pointer-events:none}.resizing-highlight-right:first-child{width:1px}.editable-header{border-bottom:1px dashed #666}.muted-text{color:#727272!important}.context-menu{position:fixed;display:none;background:#fff;border:1px solid #dcdcdc;box-shadow:#0000003d 0 3px 8px;z-index:1000;width:150px;border-radius:8px;font-weight:600}.context-menu.show{display:block}.context-menu ul{list-style:none;margin:0;padding:0}.context-menu li{padding:10px;cursor:pointer;color:#99a1b7}.context-menu li ::ng-deep svg{width:16px;height:16px;display:inline-block;color:#727272}.context-menu li ::ng-deep svg path{stroke:#727272}.context-menu li:hover{background-color:#f0f0f5!important}.invisible{visibility:hidden!important}.fw-500{font-weight:500!important}.taskbar{position:fixed;display:flex;justify-content:center;z-index:1000}.taskbar .action-btn{transition:opacity text-decoration .3s ease}.taskbar .action-btn:hover{text-decoration:underline;opacity:.8}.taskbar .delete{color:#ea0000}.selected-count,.action-btn,.dropdown-content a{font-weight:500;font-size:14px}.selected-rows-action-bar{background-color:#1a1a1a;color:#fff;padding:4px 24px;border-radius:8px;display:flex;align-items:center;justify-content:space-between;gap:24px;box-shadow:0 -4px 12px #00000026}.selected-rows-action-bar .btn:active,.selected-rows-action-bar .btn:focus{outline:0!important;border:0!important;border-color:transparent!important}.selected-rows-action-bar .action-btn{color:#fff!important}.cell .dropdown-menu,.cell .form-select,.cell input{color:#000!important}.cell input::placeholder{color:#727272!important}.cell .badge{border-radius:50px!important;height:26px;align-items:center}.cell .badge-danger{color:#ea5353!important;border:1px solid #ea5353!important;background-color:#ff00000d!important}.cell .badge-success{background-color:#84ca8130!important;border:1.5px solid rgb(70,227,114)!important;color:#46e372!important}.cell .badge-warning{background-color:#fff3dc!important;color:orange!important;border:1px solid #ffa000!important}.cell .badge-info{color:#00bad1;background-color:#e8fbfd;border:1px solid #00bad1}.cell .badge-secondary{color:#6c757d;background-color:#f1f3f5;border:1px solid #6c757d}.header-tag ::ng-deep svg path{stroke:#727272!important}.cross-secondary:hover ::ng-deep svg path{stroke:#000!important}.disable-sorting{pointer-events:none;opacity:.5}.rows-grouping-top-container ::ng-deep .cdk-drag-placeholder{background-color:transparent!important}input.is-invalid:focus{border:2.5px solid red!important;outline:none}.table-cell input.is-invalid:focus{border:2.5px solid red!important;outline-color:red!important;outline:none!important;box-shadow:none!important}.active-for-editing:has(input.is-invalid:focus){outline:none!important;box-shadow:none!important;border:0!important}.selected-cell,.row-selected{background-color:#c2e0fe}.first-row-selected{border-top:2px solid #2196f3!important}.last-row-selected{border-bottom:2px solid #2196f3!important}.left-selection-border{border-left:2px solid #2196f3!important}.s-no{font-size:14px;font-weight:500}.top-border{border-top:2px solid #2196f3!important}.bottom-border{border-bottom:2px solid #2196f3!important}.left-border{border-left:2px solid #2196f3!important}.border-left{border-left:1px solid #d9d9db}.right-border{border-right:2px solid #2196f3!important}.top-left-corner{border-top-left-radius:4px}.top-right-corner{border-top-right-radius:4px}.bottom-left-corner{border-bottom-left-radius:4px}.bottom-right-corner{border-bottom-right-radius:4px}.flash-bg{animation:flashAnim 1000s ease}@keyframes flashAnim{0%{background-color:#48a2fc}50%{background-color:#c2e0fe}to{background-color:#c2e0fe}}.cut-flash-bg{animation:cut-flash .8s ease}@keyframes cut-flash{0%{background-color:#f006}50%{background-color:#f00c}to{background-color:#c2e0fe}}.accordion-details .center-section .table .tbody .tr:hover .td{background-color:#f0f8ff!important}.editing-dropdown-search-input input:focus{border:1px solid #86b7fe!important}.nested-table .thead{position:sticky;top:0}.dropdown-wrapper{position:relative;display:inline-block}.btn-icon{background:transparent;border:0;padding:.25rem .5rem;cursor:pointer}.custom-dropdown-menu{position:absolute;right:0;top:calc(100% + 6px);min-width:200px;list-style:none;margin:0;padding:.25rem 0;background:#fff!important;border:1px solid rgba(0,0,0,.08);box-shadow:0 6px 18px #00000014;border-radius:.35rem;z-index:1200}.custom-dropdown-menu .dropdown-item{display:block;width:100%;padding:.5rem 1rem;text-align:left;background:transparent;border:none}.custom-dropdown-menu .dropdown-item:hover{background:#00000008}.cell-editing-dropdown-menu .dropdown-item{width:99%}.cell-editing-dropdown-menu .selected{background-color:#f0f8ff}.confirm-block{padding:0}.center-nested-table .tr:hover .td{background-color:#f0f8ff}.table ::ng-deep .cdk-drag-placeholder{background-color:#fff!important}.assets-pic{border-radius:8px!important}.fullscreen-overlay{position:fixed;top:0;left:0;width:100vw;height:100vh;background:#000c;display:flex;align-items:center;justify-content:center;z-index:1000;cursor:zoom-out}.fullscreen-img{max-width:90%;max-height:90%;border-radius:8px;box-shadow:0 0 15px #00000080}.position-sticky{z-index:2}.viewport{display:block!important;overflow:visible!important}.nested-table ::ng-deep .cdk-virtual-scroll-content-wrapper{padding:0!important}.nested-table ::ng-deep .cdk-virtual-scroll-viewport{overflow-x:hidden!important}.disabled-search-input{background-color:#f5f5f5;cursor:pointer!important}.right-click-menu-icons ::ng-deep svg path{stroke-width:2!important}.loader{animation:rotate 1s infinite;height:50px;width:50px}.loader:before,.loader:after{border-radius:50%;content:\"\";display:block;height:20px;width:20px}.loader:before{animation:ball1 1s infinite;background-color:#fff;box-shadow:30px 0 #ff3d00;margin-bottom:10px}.loader:after{animation:ball2 1s infinite;background-color:#ff3d00;box-shadow:30px 0 #fff}@keyframes rotate{0%{transform:rotate(0) scale(.8)}50%{transform:rotate(360deg) scale(1.2)}to{transform:rotate(720deg) scale(.8)}}@keyframes ball1{0%{box-shadow:30px 0 #ff3d00}50%{box-shadow:0 0 #ff3d00;margin-bottom:0;transform:translate(15px,15px)}to{box-shadow:30px 0 #ff3d00;margin-bottom:10px}}@keyframes ball2{0%{box-shadow:30px 0 #fff}50%{box-shadow:0 0 #fff;margin-top:-20px;transform:translate(15px,15px)}to{box-shadow:30px 0 #fff;margin-top:0}}.rows-grouping-top-container ::ng-deep .cdk-drag-placeholder{opacity:.7!important}.action-button{background-color:#6f61cf!important;color:#fff!important;border-radius:6px!important;font-weight:500!important;margin-top:-4px}.action-button:hover{background-color:#6a5fb3!important}.action-buttons-row .button{display:inline-flex;align-items:center;justify-content:center;overflow:hidden;color:#fff;border-radius:6px;height:34px;padding:0 10px;white-space:nowrap;transition:max-width .4s ease,background-color .3s ease;max-width:40px;background-color:transparent;border:1px solid #6F61CF}.action-buttons-row .button .label-hidden{opacity:0;margin-left:8px;transition:opacity .3s ease;pointer-events:none;display:none}.action-buttons-row .button:hover{max-width:200px;background-color:#6f61cf}.action-buttons-row .button:hover .label-hidden{opacity:1;pointer-events:auto;margin-left:8px!important;display:block}.action-buttons-row ::ng-deep .button .svg-icon svg path{stroke:#6f61cf;transition:fill .3s ease,stroke .3s ease}.action-buttons-row ::ng-deep .button:hover .svg-icon svg path{stroke:#fff!important}::ng-deep .nav-tabs .nav-link{border:none!important;border-bottom:2px solid transparent!important;border-radius:0!important;background:transparent!important}::ng-deep .nav-tabs .nav-link:hover,::ng-deep .nav-tabs .nav-link:focus{border:none!important;border-bottom:2px solid transparent!important;outline:none!important;background:transparent!important}::ng-deep .nav-tabs .nav-link.active{border:none!important;border-bottom:2px solid var(--bs-primary)!important;background:transparent!important;color:var(--bs-primary)!important}.open-top{top:-150%!important}.muted{color:#7a7a7a!important}.item-title{font-size:1.2em;font-weight:700;margin-bottom:10px}.item-image{width:100%;border-radius:10px}.comment{display:flex;align-items:center;margin-bottom:10px}.comment-avatar{width:40px;height:40px;border-radius:50%;margin-right:10px}.comment-author{font-weight:700}.comment-content{font-size:.9em;line-height:1.4}.comment-timestamp{font-size:.8em;color:#888;margin-left:auto}.des_low{text-overflow:ellipsis;white-space:nowrap;overflow:hidden;width:242px;display:block;text-transform:capitalize!important}.firstDiv{word-break:break-word;overflow-wrap:break-word;white-space:normal}.container{display:flex;flex-wrap:wrap;margin:20px;gap:20px;background-color:#fff;padding:20px;border-radius:10px}.item{width:calc(33.33% - 20px);background-color:#fff;padding:20px;border-radius:10px;box-shadow:0 2px 5px #0000001a}.forCommentImg{width:70px;border-radius:16px;margin:8px 0;cursor:pointer}.image-modal img{max-width:90%;max-height:90%;border-radius:8px;box-shadow:0 4px 10px #00000080}.full-image-modal{position:fixed;background:#000c;display:flex;justify-content:center;align-items:center;z-index:1000}.full-image-modal .full-image{max-width:90%;max-height:90%;border-radius:8px;box-shadow:0 0 10px #fff3}.item-content{font-size:14px;line-height:1.5;max-height:220px;overflow-y:auto}.image-modal.full-image-modal{position:fixed;width:100vw;height:100vh;background-color:#000c;display:flex;justify-content:center;align-items:center;z-index:9999;overflow:hidden;cursor:zoom-out}.image-modal.full-image-modal img{border-radius:8px;box-shadow:0 4px 20px #0006;object-fit:contain;transition:transform .3s ease}.image-modal.full-image-modal img:hover{transform:scale(1.02)}::ng-deep .custom-overlay-wrapper .custom-overlay{position:fixed;top:0;left:0;width:100vw;height:100vh;background:#000000d9;display:flex;align-items:center;justify-content:center;z-index:9999}::ng-deep .custom-overlay-wrapper .custom-modal{background:#fff;border-radius:12px;box-shadow:0 8px 25px #0003;width:360px;max-width:90%;padding:24px;text-align:center;animation:fadeInScale .25s ease}::ng-deep .custom-overlay-wrapper .custom-modal-body .modal-message{font-size:16px;margin-bottom:20px;color:#333}::ng-deep .custom-overlay-wrapper .modal-actions{display:flex;justify-content:center;gap:12px}::ng-deep .custom-overlay-wrapper .modal-actions button{min-width:90px;padding:8px 14px;border-radius:6px;border:none;font-weight:500;cursor:pointer;transition:background-color .2s ease}::ng-deep .custom-overlay-wrapper .btn-confirm{background-color:#007bff;color:#fff}::ng-deep .custom-overlay-wrapper .btn-confirm:hover{background-color:#0069d9}::ng-deep .custom-overlay-wrapper .btn-cancel{background-color:#e4e4e4;color:#333}::ng-deep .custom-overlay-wrapper .btn-cancel:hover{background-color:#d6d6d6}@keyframes fadeInScale{0%{opacity:0;transform:scale(.95)}to{opacity:1;transform:scale(1)}}.clear-btn{background:linear-gradient(135deg,#f53545,#f53545);border:none;color:#fff;font-size:13px;padding:3px 6px;border-radius:20px;font-weight:500;display:inline-flex;align-items:center;gap:6px;cursor:pointer;transition:all .3s ease;box-shadow:0 2px 6px #ff5f6d66;position:relative;bottom:4px}.clear-btn:hover{transform:translateY(-2px);box-shadow:0 4px 10px #ff5f6d99;background:linear-gradient(135deg,#f53545,#f53545)}.clear-btn i{font-size:16px;vertical-align:middle}.cell-editin-dropdown .deopdown-item{width:100%!important;box-shadow:none!important;border-radius:4px;cursor:pointer;padding-block:8px!important}.cell-editin-dropdown .deopdown-item:hover{background-color:#f1f1f1}\n"], dependencies: [{ kind: "directive", type: i6.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i6.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i6.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i6.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i6.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: i6.NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { kind: "directive", type: i6.NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { kind: "directive", type: i6.NgSwitchDefault, selector: "[ngSwitchDefault]" }, { kind: "directive", type: i8.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i8.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i8.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: i8.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i8.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i8.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i8.RadioControlValueAccessor, selector: "input[type=radio][formControlName],input[type=radio][formControl],input[type=radio][ngModel]", inputs: ["name", "formControlName", "value"] }, { kind: "directive", type: i8.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i8.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i8.PatternValidator, selector: "[pattern][formControlName],[pattern][formControl],[pattern][ngModel]", inputs: ["pattern"] }, { kind: "directive", type: i8.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i9.CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: i9.CdkDropListGroup, selector: "[cdkDropListGroup]", inputs: ["cdkDropListGroupDisabled"], exportAs: ["cdkDropListGroup"] }, { kind: "directive", type: i9.CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "directive", type: i9.CdkDragHandle, selector: "[cdkDragHandle]", inputs: ["cdkDragHandleDisabled"] }, { kind: "directive", type: i9.CdkDragPreview, selector: "ng-template[cdkDragPreview]", inputs: ["data", "matchSize"] }, { kind: "directive", type: i9.CdkDragPlaceholder, selector: "ng-template[cdkDragPlaceholder]", inputs: ["data"] }, { kind: "directive", type: i10.InlineSVGDirective, selector: "[inlineSVG]", inputs: ["inlineSVG", "resolveSVGUrl", "replaceContents", "prepend", "injectComponent", "cacheSVG", "setSVGAttributes", "removeSVGAttributes", "forceEvalStyles", "evalScripts", "fallbackImgUrl", "fallbackSVG", "onSVGLoaded"], outputs: ["onSVGInserted", "onSVGFailed"] }, { kind: "directive", type: i11.CdkFixedSizeVirtualScroll, selector: "cdk-virtual-scroll-viewport[itemSize]", inputs: ["itemSize", "minBufferPx", "maxBufferPx"] }, { kind: "directive", type: i11.CdkVirtualForOf, selector: "[cdkVirtualFor][cdkVirtualForOf]", inputs: ["cdkVirtualForOf", "cdkVirtualForTrackBy", "cdkVirtualForTemplate", "cdkVirtualForTemplateCacheSize"] }, { kind: "component", type: i11.CdkVirtualScrollViewport, selector: "cdk-virtual-scroll-viewport", inputs: ["orientation", "appendOnly"], outputs: ["scrolledIndexChange"] }, { kind: "directive", type: CellRenderInitDirective, selector: "[cellRenderInit]", inputs: ["cellRenderInit", "rowData", "colData", "cellValue"], outputs: ["cellEvent"] }, { kind: "directive", type: CellEditorDirective, selector: "[cellEditor]", inputs: ["cellEditor", "rowData", "colData", "cellValue"], outputs: ["editorEvent"] }, { kind: "pipe", type: i6.SlicePipe, name: "slice" }, { kind: "pipe", type: i6.TitleCasePipe, name: "titlecase" }, { kind: "pipe", type: i6.DatePipe, name: "date" }, { kind: "pipe", type: FilterPipe, name: "filter" }], animations: [
|
|
6332
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: DataGridComponent, selector: "data-grid", inputs: { rowAnimation: "rowAnimation", paginationConfig: "paginationConfig", dataSet: "dataSet", columns: "columns", rowHeight: "rowHeight", headerRowHeight: "headerRowHeight", showVerticalBorder: "showVerticalBorder", evenRowsBackgroundColor: "evenRowsBackgroundColor", oddRowsBackgroundColor: "oddRowsBackgroundColor", headerBackgroundColor: "headerBackgroundColor", checkboxesBackgroundColor: "checkboxesBackgroundColor", showColumnsGrouping: "showColumnsGrouping", rowHoverColor: "rowHoverColor", leftPinnedBackgroundColor: "leftPinnedBackgroundColor", bodyBackgroundColor: "bodyBackgroundColor", rightPinnedBackgroundColor: "rightPinnedBackgroundColor", sidemenuBackgroundColor: "sidemenuBackgroundColor", bodyTextColor: "bodyTextColor", headerTextColor: "headerTextColor", checkboxesColor: "checkboxesColor", headerTextFontsSize: "headerTextFontsSize", bodyTextFontsSize: "bodyTextFontsSize", headerFontWeight: "headerFontWeight", bodyFontWeight: "bodyFontWeight", checkedRowBackgroundColor: "checkedRowBackgroundColor", dropdownsBackgroundColor: "dropdownsBackgroundColor", footerRowBackgroundColor: "footerRowBackgroundColor", footerRowHeight: "footerRowHeight", topGroupedBadgesBackgroundColor: "topGroupedBadgesBackgroundColor", showRowsGrouping: "showRowsGrouping", showFilterRow: "showFilterRow", fontFaimly: "fontFaimly", showSideMenu: "showSideMenu", footerPadding: "footerPadding", topFilterRowHeight: "topFilterRowHeight", rowShadingEnabled: "rowShadingEnabled", showSerialNumber: "showSerialNumber", singleSpaAssetsPath: "singleSpaAssetsPath", filtersConfig: "filtersConfig", loading: "loading", verticalScrollbarWidth: "verticalScrollbarWidth", horizintalScrollbarWidth: "horizintalScrollbarWidth", showCellDetailsBox: "showCellDetailsBox", dateFormat: "dateFormat", tableSearch: "tableSearch", actions: "actions", config: "config", showTaskbar: "showTaskbar", tableName: "tableName", listingType: "listingType", checkboxState: "checkboxState", taskbarActions: "taskbarActions", sortingConfig: "sortingConfig", tableFilterViewId: "tableFilterViewId", selectedTableLayout: "selectedTableLayout", closeDropdown: "closeDropdown", globalSearchText: "globalSearchText", nestedTablerowFontsize: "nestedTablerowFontsize", nestedTableHeaderRowHeight: "nestedTableHeaderRowHeight", nestedTablerowHeight: "nestedTablerowHeight", gridType: "gridType", currencySymbol: "currencySymbol", currencyFormat: "currencyFormat", leftPinnedBoxshadow: "leftPinnedBoxshadow", rightPinnedBoxshadow: "rightPinnedBoxshadow", selectedRowsBackgroundColor: "selectedRowsBackgroundColor", nestedTableHeaderBackgroundColor: "nestedTableHeaderBackgroundColor", nestedTableRowBackgroundColor: "nestedTableRowBackgroundColor", tableView: "tableView", buttons: "buttons", keepMultipleExpandedDetails: "keepMultipleExpandedDetails", showTotalAmountRow: "showTotalAmountRow", enableGlobalSearch: "enableGlobalSearch", tableType: "tableType", enableExport: "enableExport", showFullScreenButton: "showFullScreenButton", enableCut: "enableCut", tabs: "tabs", showCheckboxes: "showCheckboxes", pageSizeOptions: "pageSizeOptions", resetAllFilters: "resetAllFilters", defaultConfig: "defaultConfig", columnThreedotsMunuConfig: "columnThreedotsMunuConfig" }, outputs: { changeLayout: "changeLayout", customCellEvent: "customCellEvent", filterOptions: "filterOptions", genericEvent: "genericEvent", tablePresetConfig: "tablePresetConfig", sortingOrderOptions: "sortingOrderOptions", createUpdateConfigListing: "createUpdateConfigListing" }, host: { listeners: { "document:click": "onDocumentClick($event)", "document:keydown.escape": "onEscape($event)", "window:resize": "onResize($event)", "document:keydown": "onKeyDown($event)", "document:paste": "onPaste($event)" } }, viewQueries: [{ propertyName: "cellText", first: true, predicate: ["cellText"], descendants: true }, { propertyName: "nestedHeader", first: true, predicate: ["nestedHeader"], descendants: true }, { propertyName: "dataGridContainer", first: true, predicate: ["dataGridContainer"], descendants: true }, { propertyName: "taskManagementContainer", first: true, predicate: ["taskManagementContainer"], descendants: true }, { propertyName: "nestedTableContainer", first: true, predicate: ["nestedTableContainer"], descendants: true }, { propertyName: "leftPinnedBody", first: true, predicate: ["leftPinnedBody"], descendants: true }, { propertyName: "centerPinnedBody", first: true, predicate: ["centerPinnedBody"], descendants: true }, { propertyName: "rightPinnedBody", first: true, predicate: ["rightPinnedBody"], descendants: true }, { propertyName: "leftPinnedHeader", first: true, predicate: ["leftPinnedHeader"], descendants: true }, { propertyName: "centerPinnedHeader", first: true, predicate: ["centerPinnedHeader"], descendants: true }, { propertyName: "rightPinnedHeader", first: true, predicate: ["rightPinnedHeader"], descendants: true }, { propertyName: "globalSearchInput", first: true, predicate: ["globalSearchInput"], descendants: true }, { propertyName: "columnsGroupedBox", first: true, predicate: ["columnsGroupedBox"], descendants: true }, { propertyName: "centerFakeScrollbar", first: true, predicate: ["centerFakeScrollbar"], descendants: true }, { propertyName: "centerScroll", first: true, predicate: ["centerScroll"], descendants: true }, { propertyName: "mainScroll", first: true, predicate: ["mainScroll"], descendants: true }, { propertyName: "fakeScroll", first: true, predicate: ["fakeScroll"], descendants: true }, { propertyName: "horizintalFakeScroll", first: true, predicate: ["horizintalFakeScroll"], descendants: true }, { propertyName: "centerScrollableBody", first: true, predicate: ["centerScrollableBody"], descendants: true }, { propertyName: "filterMenueSearchInput", first: true, predicate: ["filterMenueSearchInput"], descendants: true }, { propertyName: "filterMenueTextchInput", first: true, predicate: ["filterMenueTextchInput"], descendants: true }, { propertyName: "textAreadInput", first: true, predicate: ["textAreadInput"], descendants: true }, { propertyName: "nestedTable", first: true, predicate: ["nestedTable"], descendants: true }, { propertyName: "fullscreenImageTemplate", first: true, predicate: ["fullscreenImageTemplate"], descendants: true }, { propertyName: "cellHosts", predicate: CellHostDirective, descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div class=\"position-relative h-100\">\r\n <div\r\n class=\"d-flex justify-content-between mb-2 align-items-center position-relative\"\r\n >\r\n <div class=\"d-flex gap-2\">\r\n <div class=\"nav nav-tabs\" *ngIf=\"true\">\r\n <div class=\"nav nav-tabs\" id=\"nav-tab\" role=\"tablist\">\r\n <span\r\n *ngFor=\"let tab of tabs; let i = index\"\r\n (click)=\"setActiveTab(tab)\"\r\n class=\"nav-link cursor-pointer\"\r\n [class.active]=\"activeTab == tab\"\r\n >\r\n {{ tab }}\r\n </span>\r\n </div>\r\n </div>\r\n <div class=\"global-search\" [style.width.px]=\"350\">\r\n <span\r\n *ngIf=\"enableGlobalSearch\"\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/search.svg'\"\r\n class=\"data-grid-svg-icon mx-2 position-absolute icon\"\r\n ></span>\r\n <input\r\n #globalSearchInput\r\n *ngIf=\"enableGlobalSearch\"\r\n style=\"height: 36px\"\r\n class=\"form-control\"\r\n placeholder=\"Type to search, then press Enter\"\r\n [(ngModel)]=\"tableSearch\"\r\n (keydown.enter)=\"onGlobalSearch()\"\r\n (input)=\"onSearchInput($event)\"\r\n type=\"search\"\r\n />\r\n </div>\r\n </div>\r\n <div class=\"d-flex gap-2 align-items-center table-right-top-actions\">\r\n <ng-container *ngFor=\"let button of buttons\">\r\n <div\r\n class=\"d-flex align-items-center gap-2 action-buttons-row\"\r\n *ngIf=\"button?.has_permission\"\r\n >\r\n <a\r\n href=\"JavaScript:void(0)\"\r\n (click)=\"onActionButtonClick(button.name)\"\r\n class=\"button button-small btn border border-primary btn-active-primary me-2 p-0 d-flex align-items-center justify-content-center px-3\"\r\n >\r\n <span\r\n *ngIf=\"button.is_showIcon\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/' + button.icon + '.svg'\r\n \"\r\n class=\"svg-icon svg-icon-2\"\r\n ></span>\r\n <span\r\n class=\"label-hidden text-white\"\r\n [class.ms-0]=\"button.is_showIcon\"\r\n >{{ button?.name }}</span\r\n >\r\n </a>\r\n </div>\r\n </ng-container>\r\n <div\r\n *ngIf=\"!showFilterRow\"\r\n class=\"cursor-pointer position-relative action-buttons-row\"\r\n (click)=\"toggleOpenFilter()\"\r\n [class.active]=\"showFilters\"\r\n >\r\n <a\r\n href=\"JavaScript:void(0)\"\r\n class=\"button button-small btn btn-active-primary border border-primary me-2 p-0 d-flex align-items-center justify-content-center px-3\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\"\r\n class=\"svg-icon svg-icon-2\"\r\n ></span>\r\n <span class=\"label-hidden text-white\">Filters</span>\r\n </a>\r\n <span\r\n *ngIf=\"activeFilteredColumns?.length\"\r\n style=\"\r\n width: 7px;\r\n height: 7px;\r\n box-shadow: 0px 0px 3px #0022ff;\r\n background-color: rgb(0, 60, 255);\r\n position: absolute;\r\n right: 16px;\r\n top: 10px;\r\n \"\r\n class=\"rounded-circle d-block\"\r\n ></span>\r\n </div>\r\n <div\r\n class=\"cursor-pointer d-none\"\r\n (click)=\"toggleActions('advance-filter')\"\r\n [class.active]=\"activeTopButton === 'advance-filter'\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/zoom-charge.svg'\"\r\n class=\"data-grid-svg-icon top-icon me-2\"\r\n ></span>\r\n </div>\r\n <div\r\n class=\"cursor-pointer action-buttons-row\"\r\n (click)=\"toggleActions('setting')\"\r\n [class.active]=\"\r\n activeTopButton === 'setting' ||\r\n activeTopButton === 'table-layout' ||\r\n activeTopButton === 'table-presets' ||\r\n activeTopButton === 'show-hide-columns'\r\n \"\r\n >\r\n <!-- <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/settings-2.svg'\"\r\n class=\"data-grid-svg-icon top-icon me-2\"\r\n ></span> -->\r\n <a\r\n href=\"JavaScript:void(0)\"\r\n class=\"button button-small btn btn-active-primary border border-primary me-2 p-0 d-flex align-items-center justify-content-center px-3\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/settings-2.svg'\"\r\n class=\"svg-icon svg-icon-2\"\r\n ></span>\r\n <span class=\"label-hidden text-white\">Setting</span>\r\n </a>\r\n\r\n <div\r\n *ngIf=\"activeTopButton === 'setting'\"\r\n class=\"actions-dropdown mt-1 actions-dropdown-setting\"\r\n style=\"position: absolute\"\r\n >\r\n <div class=\"dropdown-menu show shadow custom-menu\">\r\n <!-- Table Layout -->\r\n <a\r\n class=\"dropdown-item d-flex justify-content-between align-items-center cursor-pointer\"\r\n (click)=\"$event.stopPropagation(); toggleActions('table-layout')\"\r\n >\r\n <span\r\n ><span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/table-2.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n Table Layout</span\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n </a>\r\n <!-- Table Presets -->\r\n <a\r\n (click)=\"$event.stopPropagation(); toggleActions('table-presets')\"\r\n class=\"dropdown-item d-flex justify-content-between align-items-center cursor-pointer\"\r\n >\r\n <span\r\n ><span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/list-details.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n Table Presets</span\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n </a>\r\n\r\n <!-- Columns -->\r\n <a\r\n *ngIf=\"!showSideMenu\"\r\n (click)=\"\r\n $event.stopPropagation(); toggleActions('show-hide-columns')\r\n \"\r\n class=\"dropdown-item d-flex justify-content-between align-items-center cursor-pointer\"\r\n >\r\n <span class=\"align-items-center d-flex\"\r\n ><span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/eye.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n Columns</span\r\n >\r\n <div class=\"d-flex gap-2\">\r\n <span class=\"muted-text\">{{ columnsCount }}</span>\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n </div>\r\n </a>\r\n\r\n <div class=\"dropdown-divider\"></div>\r\n\r\n <!-- Filter -->\r\n <a\r\n class=\"dropdown-item cursor-pointer\"\r\n (click)=\"toggleOpenFilter(); activeTopButton = '';\"\r\n *ngIf=\"!showFilterRow\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2 mt-1 cursor-pointer\"\r\n ></span>\r\n Filter\r\n </a>\r\n\r\n <!-- Download -->\r\n <a\r\n class=\"dropdown-item cursor-pointer\"\r\n (click)=\"downloadCsv('csv')\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/download.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2 cursor-pointer\"\r\n ></span>\r\n CSV Export\r\n </a>\r\n <a\r\n *ngIf=\"enableExport\"\r\n class=\"dropdown-item cursor-pointer\"\r\n (click)=\"downloadCsv('xlsx')\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/download.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2 cursor-pointer\"\r\n ></span>\r\n Excel Export\r\n </a>\r\n <!-- Font Family & Font Size -->\r\n <div class=\"px-2 pb-2 pt-2\">\r\n <div class=\"d-flex gap-2\">\r\n <!-- Font Family -->\r\n <select\r\n class=\"form-select form-select-sm\"\r\n [(ngModel)]=\"fontFaimly\"\r\n (change)=\"onFontChange()\"\r\n >\r\n <option *ngFor=\"let font of fontFamilies\" [value]=\"font\">\r\n {{ font }}\r\n </option>\r\n </select>\r\n\r\n <!-- Font Size -->\r\n <select\r\n class=\"form-select form-select-sm\"\r\n (change)=\"onFontChange()\"\r\n [(ngModel)]=\"bodyTextFontsSize\"\r\n >\r\n <option *ngFor=\"let size of fontSizes\" [value]=\"size\">\r\n {{ size }}\r\n </option>\r\n </select>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Table Layout -->\r\n\r\n <ng-container *ngIf=\"activeTopButton === 'table-layout'\">\r\n <div\r\n *ngTemplateOutlet=\"tableLayout\"\r\n class=\"actions-dropdown mt-1\"\r\n style=\"position: absolute\"\r\n ></div>\r\n </ng-container>\r\n\r\n <!-- Table Presets -->\r\n <ng-container *ngIf=\"activeTopButton === 'table-presets'\">\r\n <div\r\n *ngTemplateOutlet=\"tablePreset\"\r\n class=\"actions-dropdown mt-1\"\r\n style=\"position: absolute\"\r\n ></div>\r\n </ng-container>\r\n\r\n <!-- Table Presets -->\r\n <ng-container *ngIf=\"activeTopButton === 'show-hide-columns'\">\r\n <div\r\n *ngTemplateOutlet=\"showHideColumns\"\r\n class=\"actions-dropdown mt-1\"\r\n style=\"position: absolute\"\r\n ></div>\r\n </ng-container>\r\n </div>\r\n\r\n <div class=\"action-buttons-row\" *ngIf=\"showFullScreenButton\">\r\n <a\r\n *ngIf=\"!isFullScreen\"\r\n class=\"button button-small btn btn-active-primary border border-primary expend d-flex justify-content-center align-items-center\"\r\n (click)=\"toggleFullscreen()\"\r\n data-bs-toggle=\"tooltip\"\r\n data-bs-placement=\"top\"\r\n title=\"Minimise\"\r\n [ngClass]=\"{ minArrow: !isFullScreen, maxArrow: isFullScreen }\"\r\n style=\"transition: color 0.2s\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/expend.svg'\"\r\n class=\"svg-icon svg-icon-2 mb-1\"\r\n ></span>\r\n </a>\r\n <a\r\n *ngIf=\"isFullScreen\"\r\n class=\"button button-small btn btn-active-primary border border-primary expend d-flex justify-content-center align-items-center\"\r\n (click)=\"toggleFullscreen()\"\r\n data-bs-toggle=\"tooltip\"\r\n data-bs-placement=\"top\"\r\n title=\"Maximise\"\r\n [ngClass]=\"{ minArrow: !isFullScreen, maxArrow: isFullScreen }\"\r\n style=\"transition: color 0.2s\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/minimize.svg'\"\r\n class=\"svg-icon svg-icon-2 mb-1\"\r\n ></span>\r\n </a>\r\n </div>\r\n <div>\r\n <!-- Example single danger button -->\r\n\r\n <!-- <button\r\n type=\"button\"\r\n class=\"btn btn-primary btn-sm d-flex gap-2 action-button\"\r\n (click)=\"toggleActions('actions')\"\r\n >\r\n Action\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/Vector.svg'\"\r\n class=\"data-grid-svg-icon\"\r\n ></span>\r\n </button>\r\n <div\r\n *ngIf=\"activeTopButton === 'actions'\"\r\n class=\"actions-dropdown mt-1\"\r\n >\r\n <div class=\"dropdown-menu show\">\r\n <a class=\"dropdown-item\" href=\"#\">Action</a>\r\n <a class=\"dropdown-item\" href=\"#\">Another action</a>\r\n <a class=\"dropdown-item\" href=\"#\">Something else here</a>\r\n <div class=\"dropdown-divider\"></div>\r\n <a class=\"dropdown-item\" href=\"#\">Separated link</a>\r\n </div>\r\n </div> -->\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div\r\n *ngIf=\"showFilters && !showFilterRow\"\r\n class=\"top-filter-row border-top py-2 d-flex justify-content-between align-items-center\"\r\n [style.height.px]=\"topFilterRowHeight\"\r\n >\r\n <!-- LEFT SIDE (Filter tags + Filter button) -->\r\n <div class=\"d-flex gap-2 align-items-center\">\r\n <ng-container>\r\n <div\r\n *ngFor=\"let col of activeFilteredColumns; trackBy: trackByField\"\r\n class=\"filter-tags\"\r\n >\r\n <div\r\n (click)=\"\r\n isActiveFilterOpen = true;\r\n activeTopButton = 'filter-columns';\r\n openFilter(col)\r\n \"\r\n class=\"d-flex justify-content-center align-items-center muted-text add-filter-button active-filters\"\r\n style=\"white-space: nowrap\"\r\n [class.active]=\"\r\n col?.field == selectedColumnForFilter?.field &&\r\n isActiveFilterOpen &&\r\n activeTopButton == 'filter-columns'\r\n \"\r\n >\r\n <span class=\"header-tag mt-0 d-flex align-items-center\">\r\n <span\r\n *ngIf=\"col?.pinned\"\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/pin.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n {{ col.header }}\r\n <span\r\n (click)=\"\r\n $event.stopPropagation(); removeColumnFilterFromColumn(col)\r\n \"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/cross-primary.svg'\r\n \"\r\n class=\"data-grid-svg-icon cross-secondary ms-2 mb-1\"\r\n ></span>\r\n </span>\r\n </div>\r\n\r\n <ng-container\r\n *ngIf=\"\r\n activeTopButton === 'filter-columns' &&\r\n col?.field == selectedColumnForFilter?.field &&\r\n isActiveFilterOpen\r\n \"\r\n >\r\n <div\r\n *ngTemplateOutlet=\"filterColumns; context: { column: col }\"\r\n class=\"actions-dropdown mt-1\"\r\n ></div>\r\n </ng-container>\r\n </div>\r\n </ng-container>\r\n\r\n <!-- Filter Button -->\r\n <div class=\"add-filter-button-menu\">\r\n <div\r\n (click)=\"toggleActions('filter-columns'); isActiveFilterOpen = false\"\r\n class=\"d-flex justify-content-center align-items-center muted-text add-filter-button button-filter\"\r\n style=\"width: 70px\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/plus.svg'\"\r\n class=\"me-2 data-grid-svg-icon\"\r\n ></span>\r\n Filter\r\n </div>\r\n\r\n <ng-container\r\n *ngIf=\"activeTopButton === 'filter-columns' && !isActiveFilterOpen\"\r\n >\r\n <div\r\n *ngTemplateOutlet=\"filterColumns\"\r\n class=\"actions-dropdown mt-1\"\r\n ></div>\r\n </ng-container>\r\n </div>\r\n </div>\r\n\r\n <!-- RIGHT SIDE (Update + Reset) -->\r\n <div class=\"d-flex gap-3 align-items-center\">\r\n <div\r\n (click)=\"savePreset()\"\r\n class=\"text-primary cursor-pointer all-filters-reset-button\"\r\n *ngIf=\"!checkFilterChangesEffect()\"\r\n >\r\n Update View\r\n </div>\r\n\r\n <div\r\n class=\"text-primary cursor-pointer all-filters-reset-button\"\r\n *ngIf=\"!tableFilterViewId && activeFilteredColumns?.length\"\r\n (click)=\"clearAllFilters()\"\r\n >\r\n Reset\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div\r\n [style.height]=\"\r\n showFilters ? 'calc(100% - ' + topFilterRowHeight + 'px)' : '100%'\r\n \"\r\n cdkDropListGroup\r\n class=\"data-grid-table-wrapper overflow-hidden\"\r\n #dataGridContainer\r\n [style.fontFamily]=\"fontFaimly\"\r\n [style.backgroundColor]=\"bodyBackgroundColor\"\r\n id=\"data-grid-main-container\"\r\n >\r\n <div\r\n *ngIf=\"showRowsGrouping\"\r\n [style.height.px]=\"headerRowHeight\"\r\n [cdkDropListData]=\"columns\"\r\n [style.backgroundColor]=\"\r\n topGroupedBadgesBackgroundColor || headerBackgroundColor\r\n \"\r\n cdkDropList\r\n (cdkDropListEntered)=\"enterToTopRowGrouping($event)\"\r\n (cdkDropListExited)=\"exitedFromTheTopRow($event)\"\r\n (cdkDropListDropped)=\"onDropTopGroup($event)\"\r\n [cdkDropListEnterPredicate]=\"canEnterToRowsGrouping\"\r\n id=\"rows-grouping-top-container\"\r\n class=\"border-below d-flex px-4 align-items-center\"\r\n >\r\n <div\r\n class=\"d-flex gap-2 align-items-center\"\r\n [style.color]=\"headerTextColor\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/justify.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n <div *ngIf=\"!draggingInGroupArea && !groupedColumns?.length\">\r\n Drag here to set row groups\r\n </div>\r\n <div\r\n cdkDropListOrientation=\"horizontal\"\r\n cdkDropList\r\n (cdkDropListDropped)=\"onGroupReorder($event)\"\r\n class=\"d-flex\"\r\n >\r\n <div\r\n cdkDrag\r\n [cdkDragLockAxis]=\"'x'\"\r\n *ngFor=\"\r\n let child of groupedColumns;\r\n let i = index;\r\n trackBy: trackByField\r\n \"\r\n class=\"d-flex align-items-center\"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n topGroupingRowPlaceholder;\r\n context: {\r\n $implicit: child,\r\n showChevron:\r\n groupedColumns.length > 1 && i != groupedColumns.length - 1\r\n }\r\n \"\r\n ></ng-container>\r\n <ng-template cdkDragPreview\r\n ><div class=\"p-2 border d-flex gap-2\">\r\n <div>\r\n <span\r\n *ngIf=\"!draggingInGroupArea\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/arrows-move.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n <div>{{ child.header }}</div>\r\n </div>\r\n </ng-template>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n <div\r\n class=\"d-flex overflow-hidden\"\r\n [style.height]=\"\r\n 'calc(100% - ' +\r\n (showRowsGrouping\r\n ? headerRowHeight + footerRowHeight\r\n : footerRowHeight) +\r\n 'px)'\r\n \"\r\n >\r\n <div\r\n class=\"h-100\"\r\n [style.width]=\"\r\n !showSideMenu\r\n ? '100%'\r\n : sideMenuVisible\r\n ? 'calc(100% - 280px)'\r\n : 'calc(100% - 30px)'\r\n \"\r\n >\r\n <div class=\"h-100 transition position-relative w-100\">\r\n <!-- ##################################################################################################################################################################################### -->\r\n <!-- ##################################################################################################################################################################################### -->\r\n <!-- Data Grid Header starts here -->\r\n <!-- ##################################################################################################################################################################################### -->\r\n <!-- ##################################################################################################################################################################################### -->\r\n\r\n <div\r\n class=\"data-grid-header-wrapper w-100\"\r\n [style.color]=\"headerTextColor\"\r\n [style.fontSize.px]=\"headerTextFontsSize\"\r\n [style.backgroundColor]=\"headerBackgroundColor\"\r\n [class.border-below]=\"!hasAnyVisibleColumn\"\r\n [style.height.px]=\"\r\n showColumnsGrouping && showFilterRow\r\n ? headerRowHeight * 3\r\n : showColumnsGrouping || showFilterRow\r\n ? headerRowHeight * 2\r\n : headerRowHeight\r\n \"\r\n >\r\n <!-- ********************************************************************************* -->\r\n <!-- ********************************************************************************* -->\r\n <!-- Data Grid Left Pinned Header starts here -->\r\n <!-- ********************************************************************************* -->\r\n <!-- ********************************************************************************* -->\r\n <div\r\n class=\"data-grid-header left-pinned\"\r\n #leftPinnedHeader\r\n [class.border-right]=\"hasLeftPinnedColumns\"\r\n >\r\n <div\r\n *ngIf=\"showSerialNumber\"\r\n [style.backgroundColor]=\"checkboxesBackgroundColor\"\r\n class=\"select-all-checkbox-cell border-below\"\r\n [style.width.px]=\"55\"\r\n [style.height.px]=\"\r\n showColumnsGrouping && showFilterRow\r\n ? headerRowHeight * 3\r\n : showColumnsGrouping || showFilterRow\r\n ? headerRowHeight * 2\r\n : headerRowHeight\r\n \"\r\n >\r\n S.No\r\n </div>\r\n <div\r\n *ngIf=\"showCheckboxes\"\r\n [style.backgroundColor]=\"checkboxesBackgroundColor\"\r\n class=\"select-all-checkbox-cell border-below\"\r\n [style.height.px]=\"\r\n showColumnsGrouping && showFilterRow\r\n ? headerRowHeight * 3\r\n : showColumnsGrouping || showFilterRow\r\n ? headerRowHeight * 2\r\n : headerRowHeight\r\n \"\r\n >\r\n <input\r\n *ngIf=\"hasAnyVisibleColumn\"\r\n style=\"width: 16px; height: 16px\"\r\n type=\"checkbox\"\r\n [indeterminate]=\"isIndeterminateState(dataSet)\"\r\n [checked]=\"isAllSelected(dataSet)\"\r\n (change)=\"toggleSelectAll(dataSet)\"\r\n />\r\n </div>\r\n <div\r\n [style.backgroundColor]=\"headerBackgroundColor\"\r\n class=\"d-flex\"\r\n cdkDropList\r\n id=\"left-pinned-header\"\r\n cdkDropListOrientation=\"horizontal\"\r\n [cdkDropListData]=\"leftPinnedColumns\"\r\n (cdkDropListEntered)=\"onDropListEnter($event, 'left')\"\r\n (cdkDropListSorted)=\"\r\n onSortGroup($event, 'previewLeftPinnedColumns')\r\n \"\r\n (cdkDropListDropped)=\"onDropGroup()\"\r\n style=\"min-width: 1px\"\r\n >\r\n <div\r\n class=\"dragable-header\"\r\n cdkDrag\r\n [cdkDragData]=\"col\"\r\n *ngFor=\"\r\n let col of leftPinnedColumns;\r\n let i = index;\r\n trackBy: trackByField\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n headerCell;\r\n context: {\r\n $implicit: col,\r\n index: i,\r\n section: 'previewLeftPinnedColumns'\r\n }\r\n \"\r\n ></ng-container>\r\n <ng-template cdkDragPreview\r\n ><div class=\"p-2 border d-flex gap-2\">\r\n <div>\r\n <span\r\n *ngIf=\"!draggingInGroupArea\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath +\r\n 'data-grid/icons/arrows-move.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n <div>{{ col.header }}</div>\r\n </div>\r\n </ng-template>\r\n <ng-template cdkDragPlaceholder>\r\n <div *ngIf=\"!draggingInGroupArea\">\r\n <div\r\n *ngTemplateOutlet=\"\r\n headerCell;\r\n context: {\r\n $implicit: col,\r\n index: i,\r\n section: ''\r\n }\r\n \"\r\n ></div>\r\n </div>\r\n <div\r\n *ngIf=\"draggingInGroupArea\"\r\n class=\"d-flex gap-2 ms-2\"\r\n style=\"opacity: 0.6\"\r\n >\r\n <ng-container\r\n *ngIf=\"col?.children?.length; else singleCol\"\r\n >\r\n <ng-container\r\n *ngFor=\"\r\n let child of col.children;\r\n let i = index;\r\n trackBy: trackByField\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n topGroupingRowPlaceholder;\r\n context: {\r\n $implicit: child,\r\n showChevron:\r\n col.children.length > 1 &&\r\n i != col.children.length - 1\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </ng-container>\r\n\r\n <ng-template #singleCol>\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n topGroupingRowPlaceholder;\r\n context: {\r\n $implicit: col,\r\n showChevron: col?.children?.length > 1\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-template>\r\n </div>\r\n </ng-template>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- ********************************************************************************* -->\r\n <!-- ********************************************************************************* -->\r\n <!-- Data Grid Center Pinned Header starts here -->\r\n <!-- ********************************************************************************* -->\r\n <!-- ********************************************************************************* -->\r\n <div\r\n class=\"data-grid-header center-scrollable\"\r\n #centerPinnedHeader\r\n (scroll)=\"onCenterBodyScroll($event)\"\r\n id=\"center-pinned-header\"\r\n cdkDropList\r\n [cdkDropListConnectedTo]=\"\r\n showRowsGrouping ? ['rows-grouping-top-container'] : []\r\n \"\r\n [cdkDropListData]=\"centerColumns\"\r\n cdkDropListOrientation=\"horizontal\"\r\n [cdkDropListSortingDisabled]=\"\r\n isDisableColumnGrouping && draggingInGroupArea\r\n \"\r\n (cdkDropListEntered)=\"onDropListEnter($event, 'center')\"\r\n (cdkDropListSorted)=\"onSortGroup($event, 'previewCenterColumns')\"\r\n (cdkDropListDropped)=\"onDropGroup()\"\r\n [style.maxWidth]=\"\r\n 'calc(100% - ' +\r\n (rightPinnedHeader.offsetWidth + leftPinnedHeader.offsetWidth) +\r\n 'px)'\r\n \"\r\n >\r\n <div\r\n *ngIf=\"groupedColumns?.length\"\r\n style=\"min-width: 200px\"\r\n class=\"h-100 align-items-center\"\r\n #columnsGroupedBox\r\n id=\"groupBoxHeaderDiv\"\r\n >\r\n <div\r\n class=\"d-flex w-100 justify-content-between align-items-center border-below\"\r\n [style.height.px]=\"\r\n showFilterRow ? headerRowHeight * 2 : headerRowHeight\r\n \"\r\n >\r\n <div class=\"ps-3\">Group</div>\r\n <div class=\"d-flex\">\r\n <div\r\n class=\"three-dots cursor-pointer\"\r\n (click)=\"\r\n openThreeDotsMenu($event, 'group');\r\n isThreeDotsFilterOpen = false\r\n \"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath +\r\n 'data-grid/icons/three-dots-vertical.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n <div\r\n (mousedown)=\"\r\n $event.stopPropagation(); onResizeGroupBox($event)\r\n \"\r\n class=\"resize-handle\"\r\n style=\"margin-right: -2px\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath +\r\n 'data-grid/icons/resize-handle.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div\r\n [style.height.px]=\"headerRowHeight\"\r\n class=\"border-below\"\r\n ></div>\r\n </div>\r\n <span\r\n class=\"d-flex align-items-center justify-content-center cursor-pointer border-below\"\r\n style=\"min-width: 30px; height: 100%\"\r\n *ngIf=\"gridType === 'Assets' || gridType === 'Tasks'\"\r\n >\r\n </span>\r\n <div\r\n class=\"dragable-header\"\r\n (cdkDragStarted)=\"\r\n checkColumnGroupingStatus(col);\r\n dragStartOnGroup(col);\r\n onDragStarted(col)\r\n \"\r\n (cdkDragMoved)=\"onDragMoved($event)\"\r\n (cdkDragEnded)=\"onDragEnded()\"\r\n cdkDrag\r\n [cdkDragData]=\"col\"\r\n *ngFor=\"\r\n let col of centerColumns;\r\n let i = index;\r\n trackBy: trackById\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n headerCell;\r\n context: {\r\n $implicit: col,\r\n index: i,\r\n section: 'previewCenterColumns'\r\n }\r\n \"\r\n >\r\n </ng-container>\r\n <ng-template cdkDragPreview\r\n ><div class=\"p-2 border d-flex gap-2\">\r\n <div>\r\n <span\r\n *ngIf=\"!isOutsideContainer\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath +\r\n (draggingInGroupArea\r\n ? 'data-grid/icons/justify.svg'\r\n : 'data-grid/icons/arrows-move.svg')\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n >\r\n </span>\r\n <span\r\n *ngIf=\"isOutsideContainer\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/eye-cross.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n >\r\n </span>\r\n </div>\r\n <div>{{ col.header }}</div>\r\n </div>\r\n </ng-template>\r\n <ng-template cdkDragPlaceholder>\r\n <div *ngIf=\"!draggingInGroupArea\">\r\n <div\r\n *ngTemplateOutlet=\"\r\n headerCell;\r\n context: {\r\n $implicit: col,\r\n index: i,\r\n section: 'centerColumns'\r\n }\r\n \"\r\n ></div>\r\n </div>\r\n <div\r\n *ngIf=\"draggingInGroupArea && !isOutsideContainer\"\r\n class=\"d-flex gap-2 ms-2\"\r\n style=\"opacity: 0.6\"\r\n >\r\n <ng-container *ngIf=\"col?.children?.length; else singleCol\">\r\n <ng-container\r\n *ngFor=\"\r\n let child of col.children;\r\n let i = index;\r\n trackBy: trackById\r\n \"\r\n >\r\n <ng-container *ngIf=\"child?.is_groupable\">\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n topGroupingRowPlaceholder;\r\n context: {\r\n $implicit: child,\r\n showChevron:\r\n col.children.length > 1 &&\r\n i != col.children.length - 1\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </ng-container>\r\n </ng-container>\r\n\r\n <ng-template #singleCol>\r\n <ng-container *ngIf=\"col?.is_groupable\">\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n topGroupingRowPlaceholder;\r\n context: {\r\n $implicit: col,\r\n showChevron: col?.children?.length > 1\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </ng-template>\r\n </div>\r\n </ng-template>\r\n </div>\r\n </div>\r\n\r\n <!-- ********************************************************************************* -->\r\n <!-- ********************************************************************************* -->\r\n <!-- Data Grid Right Pinned Header starts here -->\r\n <!-- ********************************************************************************* -->\r\n <!-- ********************************************************************************* -->\r\n <div\r\n [style.backgroundColor]=\"headerBackgroundColor\"\r\n cdkDropList\r\n id=\"right-pinned-header\"\r\n [cdkDropListConnectedTo]=\"\r\n showRowsGrouping ? ['rows-grouping-top-container'] : []\r\n \"\r\n cdkDropListOrientation=\"horizontal\"\r\n class=\"data-grid-header right-pinned\"\r\n (cdkDropListSorted)=\"\r\n onSortGroup($event, 'previewRightPinnedColumns')\r\n \"\r\n (cdkDropListEntered)=\"onDropListEnter($event, 'right')\"\r\n (cdkDropListDropped)=\"onDropGroup()\"\r\n #rightPinnedHeader\r\n class=\"right-pinned-header d-flex\"\r\n style=\"min-width: 0.2px\"\r\n >\r\n <div\r\n class=\"dragable-header\"\r\n cdkDrag\r\n [cdkDragData]=\"col\"\r\n *ngFor=\"\r\n let col of rightPinnedColumns;\r\n let i = index;\r\n trackBy: trackById\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n headerCell;\r\n context: {\r\n $implicit: col,\r\n pinnedRight: true,\r\n index: i,\r\n section: 'right'\r\n }\r\n \"\r\n ></ng-container>\r\n <ng-template cdkDragPreview\r\n ><div class=\"p-2 border d-flex gap-2\">\r\n <div>\r\n <span\r\n *ngIf=\"!draggingInGroupArea\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath +\r\n 'data-grid/icons/arrows-move.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n <div>{{ col.header }}</div>\r\n </div>\r\n </ng-template>\r\n <ng-template cdkDragPlaceholder>\r\n <div *ngIf=\"!draggingInGroupArea\">\r\n <div\r\n *ngTemplateOutlet=\"\r\n headerCell;\r\n context: {\r\n $implicit: col,\r\n index: i,\r\n section: 'right'\r\n }\r\n \"\r\n ></div>\r\n </div>\r\n <div\r\n *ngIf=\"draggingInGroupArea\"\r\n class=\"d-flex gap-2 ms-2\"\r\n style=\"opacity: 0.6\"\r\n >\r\n <ng-container *ngIf=\"col?.children?.length; else singleCol\">\r\n <ng-container\r\n *ngFor=\"\r\n let child of col.children;\r\n let i = index;\r\n trackBy: trackById\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n topGroupingRowPlaceholder;\r\n context: {\r\n $implicit: child,\r\n showChevron:\r\n col.children.length > 1 &&\r\n i != col.children.length - 1\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </ng-container>\r\n\r\n <ng-template #singleCol>\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n topGroupingRowPlaceholder;\r\n context: {\r\n $implicit: col,\r\n showChevron: col?.children?.length > 1\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-template>\r\n </div>\r\n </ng-template>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!--########################################################################################################################################################################################################################### -->\r\n <!--########################################################################################################################################################################################################################### -->\r\n <!-- Data Grid Body starts here -->\r\n <!--########################################################################################################################################################################################################################### -->\r\n <!--########################################################################################################################################################################################################################### -->\r\n <div\r\n class=\"h-100 d-flex justify-content-center align-items-center\"\r\n *ngIf=\"!dataSet?.length && !loading && !dataSetLoading\"\r\n >\r\n <!-- <div\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/record-not-found.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></div> -->\r\n <div>No Record Found</div>\r\n </div>\r\n\r\n <div\r\n class=\"position-absolute w-100 h-100 d-flex justify-content-center align-items-center loading-overlay\"\r\n *ngIf=\"loading || dataSetLoading\"\r\n style=\"\r\n z-index: 999;\r\n backdrop-filter: blur(1px);\r\n \"\r\n [style.backgroundColor]=\"bodyBackgroundColor\"\r\n >\r\n <div class=\"spinner-border text-primary\" role=\"status\">\r\n <!-- <span class=\"loader\"></span> -->\r\n <!-- <span class=\"visually-hidden\">Loading...</span> -->\r\n <!-- </div> -->\r\n </div>\r\n </div>\r\n\r\n <div\r\n class=\"data-grid-body-wrapper position-relative d-flex\"\r\n [style.height]=\"bodyWrapperHeight\"\r\n style=\"overflow-y: auto; overflow-x: hidden\"\r\n #mainScroll\r\n (scroll)=\"onMainScroll($event)\"\r\n [style.scrollbarWidth]=\"verticalScrollbarWidth\"\r\n >\r\n <!-- LEFT PINNED -->\r\n <div\r\n [style.height.px]=\"\r\n !groupedColumns.length ? originalDataSet.length * rowHeight : 0\r\n \"\r\n ></div>\r\n <div [class.h-100]=\"originalDataSet.length < 8\">\r\n <div\r\n class=\"data-grid-body left-pinned-body w-100\"\r\n style=\"overflow-y: hidden\"\r\n [class.border-right]=\"hasLeftPinnedColumns\"\r\n [class.transparent-border-right]=\"!hasLeftPinnedColumns\"\r\n [style.transform]=\"'translateY(' + translateY + 'px)'\"\r\n [style.backgroundColor]=\"leftPinnedBackgroundColor\"\r\n [class.h-100]=\"originalDataSet.length < 8\"\r\n *ngIf=\"!loading && !dataSetLoading\"\r\n [@rowDynamic]=\"rowAnimation\"\r\n\r\n \r\n >\r\n <ng-container\r\n *ngFor=\"\r\n let row of visibleRows;\r\n let i = index;\r\n trackBy: trackById\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n rowCell;\r\n context: {\r\n $implicit: row,\r\n columns: previewLeftPinnedColumns,\r\n isEven: (startIndex + i) % 2 === 0,\r\n isOdd: (startIndex + i) % 2 !== 0,\r\n isLeft: true,\r\n section: 'left',\r\n isTotalRow: false\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n <ng-container *ngIf=\"showTotalAmountRow && originalDataSet?.length\">\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n rowCell;\r\n context: {\r\n $implicit: { __virtualIndex: 0 },\r\n columns: previewLeftPinnedColumns,\r\n isEven: false,\r\n isOdd: false,\r\n section: 'left',\r\n isTotalRow: true\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </div>\r\n </div>\r\n\r\n <!-- CENTER -->\r\n <div\r\n class=\"h-100\"\r\n [style.width.px]=\"centerPinnedHeader.clientWidth\"\r\n [style.backgroundColor]=\"bodyBackgroundColor\"\r\n >\r\n <div\r\n class=\"data-grid-body center-scrollable\"\r\n [class.h-100]=\"originalDataSet.length < 8\"\r\n style=\"overflow-y: hidden; overflow-x: auto\"\r\n [style.transform]=\"'translateY(' + translateY + 'px)'\"\r\n [style.backgroundColor]=\"bodyBackgroundColor\"\r\n #centerScrollableBody\r\n (scroll)=\"onCenterBodyScroll($event)\"\r\n [style.boxShadow]=\"leftPinnedBoxshadow\"\r\n >\r\n <div [@rowDynamic]=\"rowAnimation\" *ngIf=\"!loading && !dataSetLoading\">\r\n <ng-container\r\n *ngFor=\"\r\n let row of visibleRows;\r\n let i = index;\r\n trackBy: trackById\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n rowCell;\r\n context: {\r\n $implicit: row,\r\n columns: previewCenterColumns,\r\n isEven: (startIndex + i) % 2 === 0,\r\n isOdd: (startIndex + i) % 2 !== 0,\r\n section: 'center',\r\n isTotalRow: false\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </div>\r\n <ng-container *ngIf=\"showTotalAmountRow && originalDataSet?.length\">\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n rowCell;\r\n context: {\r\n $implicit: { __virtualIndex: 0 },\r\n columns: previewCenterColumns,\r\n isEven: false,\r\n isOdd: false,\r\n section: 'center',\r\n isTotalRow: true\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </div>\r\n </div>\r\n\r\n <!-- RIGHT PINNED -->\r\n <div\r\n class=\"right-pinned-body-wrapper\"\r\n *ngIf=\"hasRightPinnedColumns\"\r\n [class.h-100]=\"originalDataSet.length < 8\"\r\n [style.maxWidth.px]=\"\r\n isScrollbarVisible\r\n ? rightPinnedHeader.offsetWidth - 15\r\n : rightPinnedHeader.offsetWidth\r\n \"\r\n [style.backgroundColor]=\"rightPinnedBackgroundColor\"\r\n >\r\n <div\r\n class=\"data-grid-body right-pinned-body w-100 h-100\"\r\n style=\"overflow-y: hidden\"\r\n [style.transform]=\"'translateY(' + translateY + 'px)'\"\r\n [style.boxShadow]=\"rightPinnedBoxshadow\"\r\n [style.backgroundColor]=\"rightPinnedBackgroundColor\"\r\n *ngIf=\"!loading && !dataSetLoading\"\r\n [@rowDynamic]=\"rowAnimation\"\r\n >\r\n <ng-container\r\n *ngFor=\"\r\n let row of visibleRows;\r\n let i = index;\r\n trackBy: trackById\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n rowCell;\r\n context: {\r\n $implicit: row,\r\n columns: previewRightPinnedColumns,\r\n isEven: (startIndex + i) % 2 === 0,\r\n isOdd: (startIndex + i) % 2 !== 0,\r\n section: 'right',\r\n isTotalRow: false\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n <ng-container *ngIf=\"showTotalAmountRow && originalDataSet?.length\">\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n rowCell;\r\n context: {\r\n $implicit: { __virtualIndex: 0 },\r\n columns: previewRightPinnedColumns,\r\n isEven: false,\r\n isOdd: false,\r\n section: 'right',\r\n isTotalRow: true\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </div>\r\n </div>\r\n\r\n <div\r\n style=\"top: auto; left: auto\"\r\n (click)=\"\r\n $event.stopPropagation();\r\n fullscreenImage = null;\r\n cdr.detectChanges()\r\n \"\r\n [style.width.px]=\"dataGridContainer.offsetWidth\"\r\n [style.height.px]=\"\r\n dataGridContainer.offsetHeight - (footerRowHeight + 100)\r\n \"\r\n class=\"image-modal full-image-modal\"\r\n *ngIf=\"fullscreenImage\"\r\n >\r\n <img\r\n (click)=\"$event.stopPropagation()\"\r\n [src]=\"fullscreenImage\"\r\n alt=\"Fullscreen Image\"\r\n />\r\n </div>\r\n <div\r\n *ngIf=\"selectedRows.size > 0 && showTaskbar\"\r\n class=\"taskbar w-100\"\r\n [style.bottom.px]=\"85\"\r\n >\r\n <div class=\"selected-rows-action-bar\" [@slideUp]>\r\n <span class=\"selected-count\">\r\n {{ selectedRows.size }} selected of\r\n {{\r\n paginationConfig.totalResults ||\r\n config?.paginationParams?.totalItems\r\n }}\r\n Total\r\n </span>\r\n <div class=\"action-buttons d-flex align-items-center\">\r\n <ng-container\r\n *ngFor=\"let action of taskbarActions; let i = index\"\r\n >\r\n <ng-container *ngIf=\"action?.has_permission\">\r\n <span\r\n class=\"action-btn verified btn {{ action }}\"\r\n (click)=\"onVerifyClick(action?.actionName)\"\r\n >{{ action?.actionName }}</span\r\n >\r\n <span\r\n *ngIf=\"\r\n taskbarActions.length > 1 &&\r\n i !== taskbarActions.length - 1 &&\r\n taskbarActions[i + 1]?.has_permission\r\n \"\r\n class=\"\"\r\n >|</span\r\n >\r\n </ng-container>\r\n </ng-container>\r\n <button (click)=\"clearSelectionState(tableType);selectedRows.clear();\" class=\"clear-btn ms-2 mt-2\">\r\n <i class=\"bi bi-x-circle\"></i> Clear Selection\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n <!-- Vertical Fake scroll Bar -->\r\n <!-- <div\r\n (scroll)=\"onMainFakeScroll($event)\"\r\n class=\"fake-scrollbar fake-scrollbar-vertical d-none\"\r\n [style.scrollbarWidth]=\"verticalScrollbarWidth\"\r\n [style.top.px]=\"\r\n showColumnsGrouping && showFilterRow\r\n ? headerRowHeight * 3\r\n : showColumnsGrouping || showFilterRow\r\n ? headerRowHeight * 2\r\n : headerRowHeight\r\n \"\r\n #fakeScroll\r\n [style.height]=\"bodyWrapperHeight\"\r\n style=\"\r\n overflow-y: auto;\r\n overflow-x: hidden;\r\n width: 17px;\r\n position: absolute;\r\n right: 0;\r\n background-color: f1f2f3;\r\n z-index: 10;\r\n \"\r\n >\r\n <div [style.height.px]=\"rowHeight * dataSetLength\"></div>\r\n </div> -->\r\n </div>\r\n\r\n <!-- Horizintal Fake Scrollbars -->\r\n <div\r\n class=\"d-flex justify-content-between\"\r\n *ngIf=\"hasScroll && !shouldRestoreScroll\"\r\n >\r\n <div\r\n [style.scrollbarWidth]=\"horizintalScrollbarWidth\"\r\n class=\"fake-horizintal-scrollbar\"\r\n #fakeScroll\r\n [style.width.px]=\"leftPinnedHeader.offsetWidth\"\r\n style=\"overflow-x: scroll\"\r\n ></div>\r\n <div\r\n [style.scrollbarWidth]=\"horizintalScrollbarWidth\"\r\n (scroll)=\"onCenterBodyScroll($event)\"\r\n class=\"fake-horizintal-scrollbar\"\r\n #horizintalFakeScroll\r\n [style.width.px]=\"centerPinnedHeader.offsetWidth\"\r\n >\r\n <div [style.width.px]=\"centerPinnedHeader.scrollWidth - 10\"></div>\r\n </div>\r\n <div\r\n [style.scrollbarWidth]=\"horizintalScrollbarWidth\"\r\n class=\"fake-horizintal-scrollbar\"\r\n #fakeScroll\r\n [style.width.px]=\"rightPinnedHeader.offsetWidth\"\r\n style=\"overflow-x: scroll\"\r\n ></div>\r\n </div>\r\n </div>\r\n\r\n <!-- Side Menu Implemented Here -->\r\n <div\r\n *ngIf=\"showSideMenu\"\r\n [style.width.px]=\"sideMenuVisible ? 280 : 30\"\r\n class=\"right-menu h-100\"\r\n [style.backgroundColor]=\"sidemenuBackgroundColor\"\r\n >\r\n <div class=\"h-100 d-flex flex-row-reverse\">\r\n <div\r\n style=\"width: 30px\"\r\n class=\"d-flex flex-column align-items-center cursor-pointer\"\r\n [class.border-start]=\"sideMenuVisible\"\r\n >\r\n <div\r\n (click)=\"toggleSideMenu('cols')\"\r\n [class.bg-fff]=\"\r\n currentOpenedSideMenue == 'cols' && sideMenuVisible\r\n \"\r\n [class.border-below]=\"sideMenuVisible\"\r\n class=\"columns-button d-flex flex-column align-items-center\"\r\n >\r\n <div>\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/ui-checks-grid.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n <div class=\"side-menue-text\">Columns</div>\r\n </div>\r\n\r\n <div\r\n (click)=\"toggleSideMenu('filtrs')\"\r\n [class.bg-fff]=\"\r\n currentOpenedSideMenue == 'filtrs' && sideMenuVisible\r\n \"\r\n [class.border-below]=\"\r\n sideMenuVisible && currentOpenedSideMenue == 'filtrs'\r\n \"\r\n class=\"columns-button d-flex flex-column align-items-center\"\r\n >\r\n <div>\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n <div class=\"side-menue-text\">Filter</div>\r\n </div>\r\n </div>\r\n <div\r\n class=\"h-100\"\r\n *ngIf=\"sideMenuVisible\"\r\n [ngStyle]=\"{ width: sideMenuVisible ? '250px' : '' }\"\r\n >\r\n <div class=\"h-100\">\r\n <ng-container\r\n *ngIf=\"currentOpenedSideMenue == 'cols' && sideMenuVisible\"\r\n >\r\n <ng-container *ngTemplateOutlet=\"columnPannel\"></ng-container>\r\n <!-- Column Items -->\r\n <div class=\"column-panel-body px-3\">\r\n <ng-container\r\n *ngFor=\"let col of columns; trackBy: trackByField\"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"columnPanelItem; context: { col: col }\"\r\n ></ng-container>\r\n </ng-container>\r\n </div>\r\n <hr />\r\n\r\n <div class=\"side-menu-row-groups\" style=\"height: 30%\">\r\n <ng-container\r\n *ngTemplateOutlet=\"sideMenuRowGroups\"\r\n ></ng-container>\r\n </div>\r\n </ng-container>\r\n <ng-container\r\n *ngIf=\"currentOpenedSideMenue == 'filtrs' && sideMenuVisible\"\r\n >\r\n <ng-container *ngTemplateOutlet=\"sideFilters\"></ng-container>\r\n </ng-container>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n <div\r\n [style.height.px]=\"footerRowHeight\"\r\n class=\"border-top\"\r\n [style.backgroundColor]=\"footerRowBackgroundColor\"\r\n >\r\n <!-- Rows: <span class=\"fw-500 ms-1\">{{ dataSet.length }}</span> -->\r\n\r\n <div\r\n class=\"pagination-container\"\r\n [style.height.px]=\"footerRowHeight\"\r\n [style.padding.px]=\"footerPadding\"\r\n >\r\n <div class=\"page-size\">\r\n <select\r\n [(ngModel)]=\"paginationConfig.limit\"\r\n (change)=\"onPageSizeChange()\"\r\n >\r\n <option *ngFor=\"let size of pageSizeOptions\" [value]=\"size\">\r\n {{ size }}\r\n </option>\r\n </select>\r\n <span class=\"separator\"> per page </span>\r\n </div>\r\n\r\n <div class=\"page-info\">\r\n Results:\r\n {{ (paginationConfig.page - 1) * paginationConfig.limit + 1 }}-{{\r\n paginationConfig.page * paginationConfig.limit <\r\n paginationConfig.totalResults\r\n ? paginationConfig.page * paginationConfig.limit\r\n : paginationConfig.totalResults\r\n }}\r\n of\r\n {{ paginationConfig.totalResults }}\r\n </div>\r\n\r\n <div class=\"page-buttons\">\r\n <button\r\n (click)=\"goToPage(paginationConfig.page - 1)\"\r\n [disabled]=\"paginationConfig.page === 1\"\r\n >\r\n \u2039\r\n </button>\r\n\r\n <ng-container *ngFor=\"let page of visiblePages\">\r\n <button\r\n *ngIf=\"page !== '...'\"\r\n (click)=\"goToPage(page)\"\r\n [class.active]=\"page === paginationConfig.page\"\r\n >\r\n {{ page }}\r\n </button>\r\n <span *ngIf=\"page === '...'\">...</span>\r\n </ng-container>\r\n\r\n <button\r\n (click)=\"goToPage(paginationConfig.page + 1)\"\r\n [disabled]=\"paginationConfig.page === paginationConfig.totalResults\"\r\n >\r\n \u203A\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<!-- ------------------------------------------------------------------------------------------------------------------------ -->\r\n<!-- ------------------------------------------------------------------------------------------------------------------------ -->\r\n<!-- Header Cell Template -->\r\n<!-- ------------------------------------------------------------------------------------------------------------------------ -->\r\n<!-- ------------------------------------------------------------------------------------------------------------------------ -->\r\n\r\n<ng-template\r\n #headerCell\r\n let-col\r\n let-pinnedRight=\"pinnedRight\"\r\n let-i=\"index\"\r\n let-columnIndex=\"index\"\r\n let-sections=\"section\"\r\n let-calledFromNestedPlaceholder=\"calledFromNestedPlaceholder\"\r\n>\r\n <div>\r\n <!-- Group Header -->\r\n <ng-container *ngIf=\"col.children?.length > 0; else flatHeader\">\r\n <div cdkDroplistGroup class=\"group-column-wrapper\">\r\n <!-- Parent Header -->\r\n <div\r\n *ngIf=\"shouldTheGroupHeaderShow(col)\"\r\n class=\"header-cell group-header\"\r\n [style.height.px]=\"headerRowHeight\"\r\n [style.min-height.px]=\"headerRowHeight\"\r\n [style.max-height.px]=\"headerRowHeight\"\r\n [class.border-right]=\"showVerticalBorder\"\r\n [style.gridColumn]=\"'span ' + col.children.length\"\r\n [style.fontWeight]=\"headerFontWeight\"\r\n [class.flex-row-reverse]=\"pinnedRight\"\r\n [class.justify-content-end]=\"pinnedRight\"\r\n style=\"grid-row: 1\"\r\n >\r\n <div\r\n class=\"group-header-content\"\r\n [title]=\"col.header\"\r\n [class.ms-2]=\"pinnedRight\"\r\n >\r\n {{ col.header }}\r\n </div>\r\n <div\r\n class=\"resize-handle\"\r\n (dblclick)=\"autosizeColumn(col.children)\"\r\n (mousedown)=\"\r\n $event.stopPropagation(); onResizeGroup($event, col, pinnedRight)\r\n \"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/resize-handle.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n </div>\r\n\r\n <!-- Child Headers and Filters -->\r\n\r\n <div\r\n class=\"d-flex\"\r\n cdkDropList\r\n cdkDropListOrientation=\"horizontal\"\r\n [cdkDropListData]=\"col.children\"\r\n (cdkDropListSorted)=\"onChildDroplistSorted($event, sections)\"\r\n (cdkDropListDropped)=\"onChildDroplistDroped($event)\"\r\n [cdkDropListSortingDisabled]=\"false\"\r\n [cdkDropListConnectedTo]=\"\r\n showRowsGrouping ? ['rows-grouping-top-container'] : []\r\n \"\r\n >\r\n <div\r\n cdkDrag\r\n [cdkDragData]=\"child\"\r\n *ngFor=\"let child of col.children; let i = index\"\r\n >\r\n <!-- Child Header -->\r\n <ng-container *ngIf=\"child.is_visible && !child['isRowGrouped']\">\r\n <div\r\n cdkDragHandle\r\n class=\"header-cell one-row-header-cells cursor-pointer\"\r\n [class.border-right]=\"showVerticalBorder\"\r\n [attr.field]=\"child.field\"\r\n [style.width.px]=\"child.width\"\r\n [style.min-width.px]=\"child.width\"\r\n [style.min-height.px]=\"headerRowHeight\"\r\n [style.max-height.px]=\"headerRowHeight\"\r\n [style.fontWeight]=\"headerFontWeight\"\r\n style=\"grid-row: 2\"\r\n [class.filter-applied-on-text]=\"isFilterAppliedOnColumn(child)\"\r\n >\r\n <div\r\n class=\"d-flex justify-content-between h-100 align-items-center w-100\"\r\n >\r\n <div\r\n class=\"d-flex justify-content-between align-items-center w-100\"\r\n [class.flex-row-reverse]=\"pinnedRight\"\r\n >\r\n <div\r\n class=\"text-ellipsis h-100 d-flex align-items-center w-100\"\r\n [title]=\"col.header\"\r\n [class.w-100]=\"pinnedRight\"\r\n >\r\n <div\r\n class=\"text-ellipsis h-100\"\r\n [class.editable-header]=\"child?.is_editable\"\r\n (click)=\"\r\n openThreeDotsMenu($event, child);\r\n openFilteronThreeDotsClick(child)\r\n \"\r\n >\r\n {{ child.header }}\r\n </div>\r\n </div>\r\n\r\n <div\r\n class=\"position-relative d-flex\"\r\n [class.flex-row-reverse]=\"pinnedRight\"\r\n >\r\n <div\r\n [class.me-2]=\"pinnedRight\"\r\n class=\"d-flex align-items-center\"\r\n *ngIf=\"child.pinned\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/pin-blue.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n <div\r\n class=\"three-dots p-1\"\r\n (click)=\"\r\n openThreeDotsMenu($event, child);\r\n isThreeDotsFilterOpen = false\r\n \"\r\n style=\"cursor: pointer\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath +\r\n 'data-grid/icons/three-dots-vertical.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n\r\n <!-- Only show menu if this column is active -->\r\n <div\r\n class=\"position-absolute\"\r\n *ngIf=\"activeCol === child\"\r\n style=\"top: -50%; z-index: 21\"\r\n [style.left.px]=\"\r\n -(!child?.pinned ? centerPinnedHeader.scrollLeft : 0)\r\n \"\r\n [style.top.px]=\"\r\n isThreeDotsFilterOpen\r\n ? showFilterRow || showColumnsGrouping\r\n ? headerRowHeight * 2 - 10\r\n : headerRowHeight - 10\r\n : 0\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n columnMenu;\r\n context: {\r\n col: child,\r\n isNestedTable: false,\r\n section: sections,\r\n columnIndex: columnIndex,\r\n childColIndex: i\r\n }\r\n \"\r\n ></ng-container>\r\n </div>\r\n\r\n <div\r\n class=\"resize-handle\"\r\n (dblclick)=\"autosizeColumn(child)\"\r\n (mousedown)=\"\r\n $event.stopPropagation();\r\n onResizeColumn($event, child)\r\n \"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath +\r\n 'data-grid/icons/resize-handle.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Filter Cell -->\r\n <div\r\n *ngIf=\"showFilterRow\"\r\n [style.backgroundColor]=\"headerBackgroundColor\"\r\n class=\"header-cell filter-cell\"\r\n [class.border-right]=\"showVerticalBorder\"\r\n [attr.field]=\"child.field\"\r\n [style.width.px]=\"child.width\"\r\n [style.min-width.px]=\"child.width\"\r\n [style.height.px]=\"headerRowHeight\"\r\n [style.min-height.px]=\"headerRowHeight\"\r\n [style.max-height.px]=\"headerRowHeight\"\r\n [class.border-right]=\"showVerticalBorder\"\r\n style=\"grid-row: 3\"\r\n >\r\n <div\r\n class=\"header-cell filter-cell\"\r\n [attr.field]=\"col.field\"\r\n [style.width.px]=\"col.width\"\r\n [style.min-width.px]=\"col.width\"\r\n [style.height.px]=\"headerRowHeight\"\r\n [style.min-height.px]=\"headerRowHeight\"\r\n [style.max-height.px]=\"headerRowHeight\"\r\n >\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Filter\"\r\n [(ngModel)]=\"child.filterValue\"\r\n (ngModelChange)=\"onFilterChange(child)\"\r\n (paste)=\"onFilterChange(child); applyDropdownFilter()\"\r\n [readonly]=\"\r\n child?.type == 'dropdown' || child?.type == 'image' || child?.type == 'array'\r\n \"\r\n [class.disabled-search-input]=\"\r\n child?.type == 'dropdown' || child?.type == 'image' || child?.type == 'array'\r\n \"\r\n (click)=\"\r\n $event.stopPropagation();\r\n openFilterFromDisabledSearchedInput(child)\r\n \"\r\n (keydown.enter)=\"applyDropdownFilter()\"\r\n (mousedown)=\"$event.stopPropagation()\"\r\n />\r\n <span\r\n class=\"filter-icon-wrapper\"\r\n (click)=\"$event.stopPropagation(); openFilter(child)\"\r\n [class.filter-applied]=\"isFilterAppliedOnColumn(child)\"\r\n [class.pe-none]=\"child?.type == 'image'\"\r\n ><span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n <span\r\n *ngIf=\"isFilterAppliedOnColumn(child)\"\r\n style=\"\r\n width: 7px;\r\n height: 7px;\r\n box-shadow: 0px 0px 3px #7486ff;\r\n background-color: rgb(0 163 233);\r\n position: absolute;\r\n right: 4px;\r\n top: 12px;\r\n \"\r\n class=\"rounded-circle d-block\"\r\n ></span\r\n ></span>\r\n\r\n <div\r\n class=\"position-absolute filter-row-filter-wrapper\"\r\n *ngIf=\"activeFilterCell?.field == child?.field\"\r\n style=\"top: 100%; right: 0; z-index: 99\"\r\n [style.left.px]=\"\r\n child?.pinned ? 0 : -centerPinnedHeader.scrollLeft\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"filterMenu; context: { col: child }\"\r\n ></ng-container>\r\n </div>\r\n </div>\r\n </div>\r\n </ng-container>\r\n <ng-template cdkDragPreview\r\n ><div class=\"p-2 border d-flex gap-2\">\r\n <div\r\n *ngIf=\"\r\n !draggingInGroupArea ||\r\n (child.is_groupable && draggingInGroupArea)\r\n \"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/arrows-move.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n <div *ngIf=\"draggingInGroupArea && !child.is_groupable\">\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/ban.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n <div>{{ child.header }}</div>\r\n </div>\r\n </ng-template>\r\n <ng-template cdkDragPlaceholder>\r\n <div *ngIf=\"!draggingInGroupArea\" class=\"position-relative\">\r\n <div\r\n *ngTemplateOutlet=\"\r\n childHeaderPlaceholder;\r\n context: {\r\n $implicit: child,\r\n index: i,\r\n sections: sections,\r\n calledFromNestedPlaceholder: true,\r\n }\r\n \"\r\n ></div>\r\n </div>\r\n <div\r\n *ngIf=\"draggingInGroupArea && child?.is_groupable\"\r\n class=\"d-flex gap-2 ms-2\"\r\n style=\"opacity: 0.6\"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n topGroupingRowPlaceholder;\r\n context: {\r\n $implicit: child,\r\n showChevron: false,\r\n pinnedRight: pinnedRight,\r\n sections: sections,\r\n index: i\r\n }\r\n \"\r\n ></ng-container>\r\n </div>\r\n </ng-template>\r\n </div>\r\n </div>\r\n </div>\r\n </ng-container>\r\n\r\n <!-- Flat Header || Single Header Cell-->\r\n <ng-template #flatHeader>\r\n <div\r\n class=\"group-column-wrapper\"\r\n *ngIf=\"col.is_visible && !col['isRowGrouped']\"\r\n >\r\n <!-- Full-height Header Cell (spans 2 rows visually) -->\r\n <div\r\n class=\"header-cell one-row-header-cells\"\r\n [attr.field]=\"col.field\"\r\n [style.width.px]=\"col.width\"\r\n [style.min-width.px]=\"col.width\"\r\n [class.border-right]=\"showVerticalBorder\"\r\n [style.min-height.px]=\"\r\n showColumnsGrouping ? headerRowHeight * 2 : headerRowHeight\r\n \"\r\n [style.height.px]=\"\r\n showColumnsGrouping ? headerRowHeight * 2 : headerRowHeight\r\n \"\r\n [style.fontWeight]=\"headerFontWeight\"\r\n style=\"grid-row: 1 / span 2\"\r\n >\r\n <div\r\n class=\"d-flex justify-content-between h-100 align-items-center w-100\"\r\n >\r\n <div\r\n class=\"d-flex justify-content-between w-100 align-items-center\"\r\n [class.flex-row-reverse]=\"pinnedRight\"\r\n >\r\n <div\r\n class=\"text-ellipsis h-100 d-flex align-items-center w-100\"\r\n [title]=\"col.header\"\r\n >\r\n <div\r\n class=\"text-ellipsis h-100 cursor-pointer\"\r\n [class.editable-header]=\"col?.is_editable\"\r\n [class.filter-applied-on-text]=\"isFilterAppliedOnColumn(col)\"\r\n (click)=\"\r\n openThreeDotsMenu($event, col);\r\n openFilteronThreeDotsClick(col)\r\n \"\r\n >\r\n {{ col.header }}\r\n </div>\r\n </div>\r\n\r\n <div\r\n class=\"position-relative d-flex\"\r\n [class.flex-row-reverse]=\"pinnedRight\"\r\n >\r\n <div\r\n [class.me-2]=\"pinnedRight\"\r\n class=\"d-flex align-items-center\"\r\n *ngIf=\"col?.pinned\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/pin-blue.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n <div\r\n [class.me-2]=\"col.order_by\"\r\n class=\"d-flex align-items-center\"\r\n *ngIf=\"sortingConfig?.field == col.field\"\r\n >\r\n <!-- Ascending Sort Icon -->\r\n <span\r\n *ngIf=\"sortingConfig?.order_by == 'asc'\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/sort-asc.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center mt-1 cursor-pointer\"\r\n (click)=\"sortDesc(col)\"\r\n [class.active]=\"sortingConfig?.order_by === 'asc'\"\r\n ></span>\r\n\r\n <!-- Descending Sort Icon -->\r\n <span\r\n *ngIf=\"sortingConfig?.order_by == 'desc'\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/sort-desc.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center mt-1 cursor-pointer\"\r\n (click)=\"sortAsc(col)\"\r\n [class.active]=\"sortingConfig?.order_by === 'desc'\"\r\n ></span>\r\n </div>\r\n <div\r\n class=\"three-dots p-1\"\r\n (click)=\"\r\n openThreeDotsMenu($event, col);\r\n isThreeDotsFilterOpen = false\r\n \"\r\n style=\"cursor: pointer\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath +\r\n 'data-grid/icons/three-dots-vertical.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n\r\n <!-- Only show menu if this column is active -->\r\n <div\r\n class=\"position-absolute\"\r\n *ngIf=\"activeCol === col\"\r\n style=\"top: -50%; z-index: 21\"\r\n [style.left.px]=\"\r\n -(!col?.pinned ? centerPinnedHeader.scrollLeft : 0)\r\n \"\r\n [style.top.px]=\"\r\n isThreeDotsFilterOpen\r\n ? showFilterRow || showColumnsGrouping\r\n ? headerRowHeight * 2 - 10\r\n : headerRowHeight - 10\r\n : 0\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n columnMenu;\r\n context: {\r\n col: col,\r\n isNestedTable: false,\r\n section: sections,\r\n columnIndex: columnIndex,\r\n childColIndex: 0\r\n },\r\n \"\r\n ></ng-container>\r\n </div>\r\n\r\n <div\r\n class=\"resize-handle\"\r\n [class.w-100]=\"col.pinned == 'right'\"\r\n (dblclick)=\"autosizeColumn(col)\"\r\n (mousedown)=\"\r\n $event.stopPropagation(); onResizeColumn($event, col)\r\n \"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/resize-handle.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Filter Cell -->\r\n <div\r\n *ngIf=\"showFilterRow\"\r\n [style.backgroundColor]=\"headerBackgroundColor\"\r\n class=\"header-cell filter-cell\"\r\n [class.border-right]=\"showVerticalBorder\"\r\n [attr.field]=\"col.field\"\r\n [style.width.px]=\"col.width\"\r\n [style.min-width.px]=\"col.width\"\r\n [style.height.px]=\"headerRowHeight\"\r\n [style.min-height.px]=\"headerRowHeight\"\r\n [style.max-height.px]=\"headerRowHeight\"\r\n >\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Filter\"\r\n [(ngModel)]=\"col.filterValue\"\r\n (ngModelChange)=\"onFilterChange(col)\"\r\n [readonly]=\"col?.type == 'dropdown' || col?.type == 'image' || col?.type == 'array'\"\r\n [class.disabled-search-input]=\"\r\n col?.type == 'dropdown' || col?.type == 'image' || col?.type == 'array'\r\n \"\r\n (paste)=\"onPasteInFilterRowSearch($event, col)\"\r\n (click)=\"\r\n $event.stopPropagation(); openFilterFromDisabledSearchedInput(col)\r\n \"\r\n (keydown.enter)=\"applyDropdownFilter()\"\r\n (mousedown)=\"$event.stopPropagation()\"\r\n />\r\n <span\r\n class=\"filter-icon-wrapper\"\r\n (click)=\"$event.stopPropagation(); openFilter(col)\"\r\n [class.filter-applied]=\"isFilterAppliedOnColumn(col)\"\r\n [class.pe-none]=\"col?.type == 'image'\"\r\n ><span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n <span\r\n *ngIf=\"isFilterAppliedOnColumn(col)\"\r\n style=\"\r\n width: 7px;\r\n height: 7px;\r\n box-shadow: 0px 0px 3px #7486ff;\r\n background-color: rgb(0 163 233);\r\n position: absolute;\r\n right: 4px;\r\n top: 12px;\r\n \"\r\n class=\"rounded-circle d-block\"\r\n ></span\r\n ></span>\r\n\r\n <div\r\n class=\"position-absolute filter-row-filter-wrapper\"\r\n *ngIf=\"activeFilterCell === col\"\r\n style=\"top: 100%; right: 0; z-index: 99\"\r\n [style.left.px]=\"col?.pinned ? 0 : -centerPinnedHeader.scrollLeft\"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"filterMenu; context: { col: col }\"\r\n ></ng-container>\r\n </div>\r\n </div>\r\n </div>\r\n </ng-template>\r\n </div>\r\n</ng-template>\r\n\r\n<!-- -------------------------------------------------------------------------------------------------------------------------------------------------------------------- -->\r\n<!-- -------------------------------------------------------------------------------------------------------------------------------------------------------------------- -->\r\n<!-- Body Cell Template -->\r\n<!-- -------------------------------------------------------------------------------------------------------------------------------------------------------------------- -->\r\n<!-- -------------------------------------------------------------------------------------------------------------------------------------------------------------------- -->\r\n\r\n<ng-template\r\n #rowCell\r\n let-row\r\n let-columns=\"columns\"\r\n let-isEven=\"isEven\"\r\n let-isOdd=\"isOdd\"\r\n let-isLeftSection=\"isLeft\"\r\n let-section=\"section\"\r\n let-rowIndex=\"rowIndex\"\r\n let-isTotalRow=\"isTotalRow\"\r\n>\r\n <!-- Check if row is a group -->\r\n <ng-container\r\n *ngTemplateOutlet=\"groupRowTemplate; context: { $implicit: row, depth: 0 }\"\r\n ></ng-container>\r\n <ng-template #groupRowTemplate let-row let-depth=\"depth\">\r\n <ng-container *ngIf=\"row.isGroup; else regularRow\">\r\n <!-- Group Header -->\r\n <div\r\n class=\"group-header-row d-flex align-items-center\"\r\n [style.height.px]=\"rowHeight\"\r\n [class.border-below]=\"section !== 'center'\"\r\n [style.width]=\"\r\n section === 'center'\r\n ? (centerScrollableBody?.scrollWidth ?? 0) + 'px'\r\n : '100%'\r\n \"\r\n >\r\n <div\r\n *ngIf=\"section == 'left'\"\r\n class=\"h-100 d-flex\"\r\n [style.width.px]=\"leftPinnedHeader.offsetWidth - 1\"\r\n [class.row-selected]=\"rowSelectedIndexes.has(row.__virtualIndex)\"\r\n >\r\n <div\r\n *ngIf=\"showSerialNumber\"\r\n style=\"width: 50px\"\r\n class=\"d-flex align-items-center h-100 border-right justify-content-end pe-2 s-no\"\r\n [style.backgroundColor]=\"checkboxesBackgroundColor\"\r\n [style.width.px]=\"55\"\r\n [style.cursor]=\"\r\n 'url(' +\r\n singleSpaAssetsPath +\r\n 'data-grid/icons/arrow-right.svg), auto'\r\n \"\r\n (mousedown)=\"onRowMouseDown(row.__virtualIndex, $event)\"\r\n (mouseover)=\"onRowMouseOver(row.__virtualIndex, $event)\"\r\n [style.color]=\"checkboxesColor\"\r\n >\r\n {{ getStartIndex() + (row.__virtualIndex - 1) || \"\" }}\r\n </div>\r\n <div\r\n *ngIf=\"showCheckboxes\"\r\n style=\"width: 50px\"\r\n class=\"d-flex align-items-center justify-content-center h-100 border-right\"\r\n [style.backgroundColor]=\"checkboxesBackgroundColor\"\r\n [class.row-selected]=\"rowSelectedIndexes.has(row.__virtualIndex)\"\r\n [class.left-selection-border]=\"\r\n rowSelectedIndexes.has(row.__virtualIndex)\r\n \"\r\n [class.first-row-selected]=\"firstSelectedRow === row.__virtualIndex\"\r\n [class.last-row-selected]=\"lastSelectedRow === row.__virtualIndex\"\r\n [style.color]=\"checkboxesColor\"\r\n >\r\n <input\r\n style=\"width: 16px; height: 16px\"\r\n type=\"checkbox\"\r\n [checked]=\"getGroupCheckedState(row) === true\"\r\n [indeterminate]=\"getGroupCheckedState(row) === undefined\"\r\n (change)=\"selectGroupRow($event, row)\"\r\n />\r\n\r\n </div>\r\n </div>\r\n\r\n <div\r\n *ngIf=\"section == 'center'\"\r\n [style.width.px]=\"centerPinnedHeader.scrollWidth\"\r\n [style.minWidth.px]=\"centerPinnedHeader.scrollWidth\"\r\n class=\"d-flex align-items-center ps-2 h-100 border-below\"\r\n [class.row-selected]=\"rowSelectedIndexes.has(row.__virtualIndex)\"\r\n [class.first-row-selected]=\"firstSelectedRow === row.__virtualIndex\"\r\n [class.last-row-selected]=\"lastSelectedRow === row.__virtualIndex\"\r\n >\r\n <div\r\n class=\"d-flex align-items-center justify-content-between\"\r\n [style.paddingLeft.px]=\"depth > 0 ? depth * 30 : 0\"\r\n >\r\n <span class=\"me-2 filter-icon-wrapper\" (click)=\"toggleExpand(row)\">\r\n <span\r\n class=\"data-grid-svg-icon align-items-center d-flex\"\r\n [inlineSVG]=\"\r\n row.isExpand\r\n ? singleSpaAssetsPath + 'data-grid/icons/chevron-down.svg'\r\n : singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\r\n \"\r\n ></span>\r\n </span>\r\n <strong (click)=\"toggleExpand(row)\" class=\"cursor-pointer\">\r\n {{ row.groupValue }} ({{ countLeafRows(row) }})\r\n </strong>\r\n </div>\r\n </div>\r\n\r\n <div\r\n *ngIf=\"section == 'right'\"\r\n [style.width.px]=\"rightPinnedHeader.offsetWidth\"\r\n [class.row-selected]=\"rowSelectedIndexes.has(row.__virtualIndex)\"\r\n [class.first-row-selected]=\"firstSelectedRow === row.__virtualIndex\"\r\n [class.last-row-selected]=\"lastSelectedRow === row.__virtualIndex\"\r\n ></div>\r\n </div>\r\n\r\n <!-- Recursive Children -->\r\n <div class=\"group-children\" *ngIf=\"row.isExpand\" [@slideToggle]>\r\n <ng-container\r\n *ngFor=\"let child of row.children; let i = index; trackBy: trackById\"\r\n >\r\n <ng-container *ngIf=\"child.isGroup; else dataRow\">\r\n <!-- Recursive call for nested group -->\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n groupRowTemplate;\r\n context: { $implicit: child, depth: depth + 1 }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n\r\n <ng-template #dataRow>\r\n <!-- Regular data row -->\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n rowCell;\r\n context: {\r\n $implicit: child,\r\n columns: columns,\r\n isEven: i % 2 === 0,\r\n isOdd: i % 2 !== 0,\r\n isLeft: isLeftSection,\r\n section: section,\r\n isTotalRow: isTotalRow\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-template>\r\n </ng-container>\r\n </div>\r\n </ng-container>\r\n </ng-template>\r\n\r\n <!-- Regular row (not a group) -->\r\n <ng-template #regularRow>\r\n <div\r\n class=\"d-flex\"\r\n [style.height.px]=\"rowHeight\"\r\n [style.minHeight.px]=\"rowHeight\"\r\n [style.maxHeight.px]=\"rowHeight\"\r\n >\r\n <span\r\n class=\"d-flex align-items-center justify-content-center cursor-pointer border-below\"\r\n style=\"min-width: 30px; height: 100%\"\r\n *ngIf=\"\r\n section == 'center' && (gridType === 'Assets' || gridType === 'Tasks')\r\n \"\r\n [ngStyle]=\"{\r\n 'background-color': rowSelectedIndexes.has(row.__virtualIndex)\r\n ? null\r\n : getBackgroundColor(row, isEven, section)\r\n }\"\r\n [class.selected-cell]=\"rowSelectedIndexes.has(row.__virtualIndex)\"\r\n [class.first-row-selected]=\"firstSelectedRow === row.__virtualIndex\"\r\n [class.last-row-selected]=\"lastSelectedRow === row.__virtualIndex\"\r\n >\r\n <span\r\n (click)=\"toggleDetailRowExpand(row)\"\r\n *ngIf=\"row?.detail?.result?.length || gridType === 'Tasks'\"\r\n class=\"data-grid-svg-icon filter-icon-wrapper\"\r\n [inlineSVG]=\"\r\n isDetailsExpanded(row)\r\n ? singleSpaAssetsPath + 'data-grid/icons/chevron-down.svg'\r\n : singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\r\n \"\r\n ></span>\r\n </span>\r\n <div\r\n [style.min-width.px]=\"\r\n section == 'center' && groupedColumns?.length ? groupBoxPadding : 0\r\n \"\r\n [class.row-selected]=\"rowSelectedIndexes.has(row.__virtualIndex)\"\r\n [class.first-row-selected]=\"firstSelectedRow === row.__virtualIndex\"\r\n [class.last-row-selected]=\"lastSelectedRow === row.__virtualIndex\"\r\n (contextmenu)=\"onRightClick($event, row)\"\r\n [style.height.px]=\"rowHeight\"\r\n class=\"data-grid-row h-100\"\r\n [class.even-row]=\"isEven\"\r\n [class.odd-row]=\"isOdd\"\r\n [class.hovered-row]=\"hoveredRowId === (row._id || row.id)\"\r\n (mouseenter)=\"onRowHover(row)\"\r\n (mouseleave)=\"onRowLeave()\"\r\n [ngStyle]=\"{\r\n 'background-color': getBackgroundColor(row, isEven, section)\r\n }\"\r\n [style.minHeight.px]=\"rowHeight\"\r\n [style.maxHeight.px]=\"rowHeight\"\r\n ></div>\r\n <div\r\n (contextmenu)=\"onRightClick($event, row)\"\r\n [style.height.px]=\"rowHeight\"\r\n class=\"data-grid-row\"\r\n [class.even-row]=\"isEven\"\r\n [class.odd-row]=\"isOdd\"\r\n [class.hovered-row]=\"hoveredRowId === (row._id || row.id)\"\r\n (mouseenter)=\"onRowHover(row)\"\r\n (mouseleave)=\"onRowLeave()\"\r\n [ngStyle]=\"{\r\n 'background-color': getBackgroundColor(row, isEven, section)\r\n }\"\r\n >\r\n <div\r\n [style.backgroundColor]=\"checkboxesBackgroundColor\"\r\n class=\"select-all-checkbox-cell justify-content-end pe-2 s-no\"\r\n [style.width.px]=\"55\"\r\n *ngIf=\"isLeftSection && showSerialNumber\"\r\n [style.cursor]=\"\r\n 'url(' +\r\n singleSpaAssetsPath +\r\n 'data-grid/icons/arrow-right.svg), auto'\r\n \"\r\n (mousedown)=\"onRowMouseDown(row.__virtualIndex, $event)\"\r\n (mouseover)=\"onRowMouseOver(row.__virtualIndex, $event)\"\r\n [style.color]=\"checkboxesColor\"\r\n >\r\n {{ getStartIndex() + (row.__virtualIndex - 1) }}\r\n </div>\r\n <div\r\n [style.backgroundColor]=\"\r\n rowSelectedIndexes.has(row.__virtualIndex)\r\n ? selectedRowsBackgroundColor\r\n : checkboxesBackgroundColor\r\n \"\r\n class=\"select-all-checkbox-cell\"\r\n *ngIf=\"isLeftSection && showCheckboxes\"\r\n [class.left-selection-border]=\"\r\n rowSelectedIndexes.has(row.__virtualIndex)\r\n \"\r\n [class.first-row-selected]=\"firstSelectedRow === row.__virtualIndex\"\r\n [class.last-row-selected]=\"lastSelectedRow === row.__virtualIndex\"\r\n [style.minHeight.px]=\"rowHeight - 1\"\r\n [style.maxHeight.px]=\"rowHeight\"\r\n >\r\n <input\r\n *ngIf=\"hasAnyVisibleColumn\"\r\n style=\"width: 16px; height: 16px\"\r\n type=\"checkbox\"\r\n [checked]=\"isRowSelected(row)\"\r\n (change)=\"toggleRowSelection(row)\"\r\n />\r\n </div>\r\n\r\n <!-- Render all columns -->\r\n <ng-container\r\n *ngFor=\"\r\n let col of columns;\r\n trackBy: trackByField;\r\n let colIndex = index\r\n \"\r\n >\r\n <ng-container *ngIf=\"col.children?.length > 0; else flatColumn\">\r\n <ng-container\r\n *ngFor=\"\r\n let child of col.children;\r\n trackBy: trackByField;\r\n let subColIndex = index\r\n \"\r\n >\r\n <ng-container *ngIf=\"child?.is_visible && !child?.isRowGrouped\">\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n cellTemplate;\r\n context: {\r\n col: child,\r\n row: row,\r\n rowIndex: rowIndex,\r\n colIndex: colIndex,\r\n subColIndex: subColIndex,\r\n section: section,\r\n isTotalRow: isTotalRow\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </ng-container>\r\n </ng-container>\r\n\r\n <ng-template #flatColumn>\r\n <ng-container *ngIf=\"col?.is_visible && !col?.isRowGrouped\">\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n cellTemplate;\r\n context: {\r\n col: col,\r\n row: row,\r\n rowIndex: rowIndex,\r\n colIndex: colIndex,\r\n subColIndex: null,\r\n section: section,\r\n isTotalRow: isTotalRow\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </ng-template>\r\n </ng-container>\r\n </div>\r\n </div>\r\n\r\n <div\r\n [@slideToggle]\r\n *ngIf=\"section === 'left' && isDetailsExpanded(row)\"\r\n class=\"accordion-details\"\r\n style=\"max-height: 350px; overflow: hidden\"\r\n [style.maxHeight.px]=\"hasHorizontalScroll ? 339 : 341\"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n leftRightNestedPlaceholder;\r\n context: { $implicit: row }\r\n \"\r\n >\r\n </ng-container>\r\n </div>\r\n\r\n <div\r\n [@slideToggle]\r\n *ngIf=\"section === 'center' && isDetailsExpanded(row)\"\r\n class=\"accordion-details center-section\"\r\n style=\"\r\n max-height: 350px;\r\n overflow-y: hidden;\r\n overflow-x: auto;\r\n scrollbar-width: thin;\r\n \"\r\n #nestedTable\r\n [style.width]=\"\r\n hasRightPinnedColumns\r\n ? '100%'\r\n : hasVerticalScroll\r\n ? 'calc(100% - 12px)'\r\n : '100%'\r\n \"\r\n >\r\n <ng-container *ngIf=\"gridType == 'Assets'\">\r\n <ng-container\r\n *ngTemplateOutlet=\"nestedTableTemplate; context: { $implicit: row }\"\r\n ></ng-container>\r\n </ng-container>\r\n <ng-container *ngIf=\"gridType == 'Tasks'\">\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n taskManagementTemplate;\r\n context: { taskDetails: row }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </div>\r\n\r\n <div\r\n [@slideToggle]\r\n *ngIf=\"section === 'right' && isDetailsExpanded(row)\"\r\n class=\"accordion-details\"\r\n style=\"max-height: 350px; overflow: hidden\"\r\n [style.maxHeight.px]=\"hasHorizontalScroll ? 339 : 341\"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n leftRightNestedPlaceholder;\r\n context: { $implicit: row }\r\n \"\r\n >\r\n </ng-container>\r\n </div>\r\n </ng-template>\r\n</ng-template>\r\n\r\n<!-- Actual Cell is Here -->\r\n<ng-template\r\n #cellTemplate\r\n let-col=\"col\"\r\n let-row=\"row\"\r\n let-section=\"section\"\r\n let-subColIndex=\"subColIndex\"\r\n let-rowIndex=\"rowIndex\"\r\n let-colIndex=\"colIndex\"\r\n let-isTotalRow=\"isTotalRow\"\r\n>\r\n <div\r\n #cellContainer\r\n (click)=\"\r\n editingKey = ''; setActiveCell(row, col); collapseAllExpandedCells()\r\n \"\r\n [style.fontWeight]=\"bodyFontWeight\"\r\n [class.border-right]=\"showVerticalBorder\"\r\n class=\"cell overflow-visible position-relative data-grid-cell\"\r\n [attr.field]=\"col.field\"\r\n [style.width.px]=\"col.width\"\r\n [style.min-width.px]=\"col.width\"\r\n [style.fontSize.px]=\"bodyTextFontsSize\"\r\n [style.minHeight.px]=\"rowHeight\"\r\n [style.maxHeight.px]=\"rowHeight\"\r\n [class.active-cell]=\"\r\n isActiveCell(row, col) && !isEditing(row, col) && selectedKeys.size == 1\r\n \"\r\n (dblclick)=\"\r\n $event.stopPropagation();\r\n $event.preventDefault();\r\n enableEdit(row, col, false, cellContainer)\r\n \"\r\n [class.row-selected]=\"rowSelectedIndexes.has(row.__virtualIndex)\"\r\n [class.first-row-selected]=\"firstSelectedRow === row?.__virtualIndex\"\r\n [class.last-row-selected]=\"lastSelectedRow === row?.__virtualIndex\"\r\n tabindex=\"-1\"\r\n (keydown.enter)=\"$event.preventDefault(); enableEdit(row, col)\"\r\n (mousedown)=\"\r\n startSelection(\r\n row.__virtualIndex,\r\n colIndex,\r\n subColIndex ?? 0,\r\n col.field,\r\n $event,\r\n section\r\n )\r\n \"\r\n (mouseenter)=\"\r\n extendSelection(\r\n row.__virtualIndex,\r\n colIndex,\r\n subColIndex ?? 0,\r\n col.field,\r\n $event,\r\n section\r\n )\r\n \"\r\n (mouseup)=\"endSelection()\"\r\n [class.selected-cell]=\"\r\n isSelected(\r\n row.__virtualIndex,\r\n colIndex,\r\n subColIndex ?? 0,\r\n col.field,\r\n section\r\n )\r\n \"\r\n [class.top-border]=\"\r\n isTopBorder(row.__virtualIndex, colIndex, subColIndex, section)\r\n \"\r\n [class.bottom-border]=\"\r\n isBottomBorder(row.__virtualIndex, colIndex, subColIndex, section)\r\n \"\r\n [class.left-border]=\"\r\n isLeftBorder(row.__virtualIndex, colIndex, subColIndex, section)\r\n \"\r\n [class.right-border]=\"\r\n isRightBorder(row.__virtualIndex, colIndex, subColIndex, section)\r\n \"\r\n [class.top-left-corner]=\"\r\n isTopLeftCorner(row.__virtualIndex, colIndex, subColIndex, section)\r\n \"\r\n [class.top-right-corner]=\"\r\n isTopRightCorner(row.__virtualIndex, colIndex, subColIndex, section)\r\n \"\r\n [class.bottom-left-corner]=\"\r\n isBottomLeftCorner(row.__virtualIndex, colIndex, subColIndex, section)\r\n \"\r\n [class.bottom-right-corner]=\"\r\n isBottomRightCorner(row.__virtualIndex, colIndex, subColIndex, section)\r\n \"\r\n >\r\n <!-- (mousedown)=\"startSelection(row.__virtualIndex, colIndex, subColIndex ?? 0, col.field, $event)\"\r\n (mouseenter)=\"extendSelection(row.__virtualIndex, colIndex, subColIndex ?? 0, col.field, $event)\"\r\n (mouseup)=\"endSelection()\"\r\n [class.selected-cell]=\"isSelected(row.__virtualIndex, colIndex, subColIndex ?? 0, col.field)\" -->\r\n <div\r\n class=\"table-cell\"\r\n [class.active-for-editing]=\"\r\n isEditing(row, col) &&\r\n (getNestedValue(row, col.field)?.length === undefined ||\r\n getNestedValue(row, col.field)?.length <= 50)\r\n \"\r\n >\r\n <div\r\n (click)=\"$event.stopPropagation()\"\r\n *ngIf=\"\r\n isEditing(row, col) &&\r\n (getNestedValue(row, col.field)?.length === undefined ||\r\n (getNestedValue(row, col.field)?.length <= 50 &&\r\n !expandedCells.size));\r\n else viewMode\r\n \"\r\n >\r\n\r\n <ng-container *ngIf=\"col.cellEditor; else builtInEditors\">\r\n <ng-container\r\n [cellEditor]=\"col.cellEditor\"\r\n [rowData]=\"row\"\r\n [colData]=\"col\"\r\n [cellValue]=\"getNestedValue(row, col.field)\"\r\n (editorEvent)=\"finishEdit($event)\"\r\n ></ng-container>\r\n </ng-container>\r\n\r\n <ng-template #builtInEditors>\r\n <ng-container [ngSwitch]=\"col?.type\">\r\n <!-- Text Input -->\r\n <input\r\n [style.height.px]=\"rowHeight - 10\"\r\n *ngSwitchCase=\"'input'\"\r\n type=\"text\"\r\n [(ngModel)]=\"row[col.field]\"\r\n (blur)=\"disableEdit(row, col)\"\r\n autofocus\r\n (keydown.enter)=\"blurInput($event, row, col)\"\r\n class=\"form-control form-control-sm\"\r\n (mousedown)=\"$event.stopPropagation()\"\r\n />\r\n\r\n <!-- Number Input -->\r\n <input\r\n [style.height.px]=\"rowHeight - 8\"\r\n *ngSwitchCase=\"'number'\"\r\n #numberInput=\"ngModel\"\r\n #numberRef\r\n (keypress)=\"allowOnlyNumbers($event)\"\r\n type=\"number\"\r\n required\r\n [(ngModel)]=\"row[col.field]\"\r\n (blur)=\"disableEdit(row, col, numberInput)\"\r\n autofocus\r\n (keydown.enter)=\"blurInput($event, row, col)\"\r\n class=\"form-control form-control-sm\"\r\n [ngClass]=\"{\r\n 'is-invalid': numberInput.invalid\r\n }\"\r\n (mousedown)=\"$event.stopPropagation()\"\r\n />\r\n\r\n <!-- Date Input -->\r\n <input\r\n [style.height.px]=\"rowHeight - 8\"\r\n *ngSwitchCase=\"'date'\"\r\n type=\"date\"\r\n [(ngModel)]=\"row[col.field]\"\r\n (blur)=\"disableEdit(row, col, dateInput)\"\r\n autofocus\r\n class=\"form-control form-control-sm\"\r\n #dateInput=\"ngModel\"\r\n (keydown.enter)=\"blurInput($event, row, col)\"\r\n [ngClass]=\"{\r\n 'is-invalid': dateInput.invalid\r\n }\"\r\n (mousedown)=\"$event.stopPropagation()\"\r\n />\r\n\r\n <!-- Dropdown -->\r\n <!-- ng-select like dropdown -->\r\n <div\r\n *ngSwitchCase=\"'dropdown'\"\r\n class=\"dropdown w-100\"\r\n (blur)=\"disableEdit(row, col)\"\r\n >\r\n <!-- Trigger -->\r\n <button\r\n class=\"form-select form-select-sm text-start w-100 text-ellipsis\"\r\n type=\"button\"\r\n data-bs-toggle=\"dropdown\"\r\n aria-expanded=\"false\"\r\n [style.minHeight.px]=\"rowHeight - 10\"\r\n data-bs-display=\"static\"\r\n (mousedown)=\"$event.stopPropagation()\"\r\n >\r\n <ng-container>\r\n {{\r\n getNestedValue(row, col.field)?.value ||\r\n getNestedValue(row, col.field)?.name ||\r\n getNestedValue(row, col.field)\r\n }}\r\n </ng-container>\r\n <ng-template #placeholder> Select options... </ng-template>\r\n </button>\r\n\r\n <!-- Menu -->\r\n <div\r\n class=\"dropdown-menu w-100 p-0 cell-editing-dropdown-menu rounded-3\"\r\n [class.show]=\"isEditing(row, col)\"\r\n >\r\n <!-- Search -->\r\n <div class=\"px-2 py-1 editing-dropdown-search-input\" *ngIf=\"col?.column_dropdown_value?.length > 5\">\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Search...\"\r\n [(ngModel)]=\"editinDropdownSearch\"\r\n (mousedown)=\"$event.stopPropagation()\"\r\n />\r\n </div>\r\n <cdk-virtual-scroll-viewport \r\n itemSize=\"35\" \r\n class=\"dropdown-viewport\"\r\n style=\"height: 120px\"\r\n >\r\n <div\r\n [class.selected]=\"getNestedValue(row, col.field) == option?.value || getNestedValue(row, col.field) == option\"\r\n class=\"px-2 py-1 d-flex align-items-center dropdown-item\"\r\n *cdkVirtualFor=\"\r\n let option of col.column_dropdown_value \r\n | filter : editinDropdownSearch : 'value'\r\n \"\r\n (click)=\"setNestedValue(row, col, option, true); editingKey = null\"\r\n >\r\n <label\r\n \r\n class=\"form-check-label d-flex align-items-center mb-0 cursor-pointer\"\r\n [for]=\"col.field + '-' + (option.value || option)\"\r\n >\r\n {{ option.value || option }}\r\n </label>\r\n </div>\r\n </cdk-virtual-scroll-viewport>\r\n\r\n </div>\r\n </div>\r\n\r\n <input\r\n *ngSwitchCase=\"'email'\"\r\n [style.height.px]=\"rowHeight - 10\"\r\n [style.maxHeight.px]=\"rowHeight - 10\"\r\n #emailModel=\"ngModel\"\r\n #emailInput\r\n type=\"email\"\r\n [(ngModel)]=\"row[col.field]\"\r\n name=\"{{ col.field }}\"\r\n required\r\n pattern=\"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$\"\r\n (blur)=\"disableEdit(row, col, emailModel)\"\r\n (keydown.enter)=\"blurInput($event, row, col)\"\r\n autofocus\r\n class=\"form-control form-control-sm\"\r\n [ngClass]=\"{\r\n 'is-invalid': emailModel.invalid\r\n }\"\r\n (mousedown)=\"$event.stopPropagation()\"\r\n />\r\n <!-- Default fallback -->\r\n <input\r\n *ngSwitchDefault\r\n [style.height.px]=\"rowHeight - 10\"\r\n [style.maxHeight.px]=\"rowHeight - 10\"\r\n #textModel=\"ngModel\"\r\n #textInput\r\n type=\"text\"\r\n (keydown.enter)=\"blurInput($event, row, col)\"\r\n [(ngModel)]=\"row[col.field]\"\r\n name=\"{{ col.field }}\"\r\n required\r\n (blur)=\"disableEdit(row, col, textModel)\"\r\n autofocus\r\n class=\"form-control form-control-sm\"\r\n [ngClass]=\"{\r\n 'is-invalid': textModel.invalid\r\n }\"\r\n (mousedown)=\"$event.stopPropagation()\"\r\n />\r\n </ng-container>\r\n </ng-template>\r\n\r\n </div>\r\n\r\n <!-- Display mode -->\r\n <ng-template #viewMode>\r\n <div\r\n class=\"d-flex justify-content-between align-items-center w-100 overflow-hidden\"\r\n [ngClass]=\"getCellClasses(col, getNestedValue(row, col.field))\"\r\n >\r\n <!-- Field icon (for Tasks grid) -->\r\n <ng-container\r\n *ngIf=\"gridType === 'Tasks' && iconMap[col.field] && !isTotalRow\"\r\n >\r\n <span\r\n class=\"cursor-pointer me-2\"\r\n (click)=\"$event.preventDefault(); $event.stopPropagation()\"\r\n [inlineSVG]=\"iconMap[col.field](row, col)\"\r\n ></span>\r\n </ng-container>\r\n\r\n <!-- \u2705 Custom cell renderer support -->\r\n <ng-container *ngIf=\"col.cellRenderer; else defaultCell\">\r\n <ng-container\r\n [cellRenderInit]=\"col.cellRenderer\"\r\n [rowData]=\"row\"\r\n [colData]=\"col\"\r\n [cellValue]=\"getNestedValue(row, col?.field)\"\r\n (cellEvent)=\"onCellEvent($event)\"\r\n >\r\n </ng-container>\r\n </ng-container>\r\n\r\n <!-- \uD83E\uDDFE Default text-based cell rendering -->\r\n <ng-template #defaultCell>\r\n <div\r\n #cellText\r\n class=\"text-ellipsis flex-grow-1\"\r\n [title]=\"getCellTitle(row, col)\"\r\n >\r\n <!-- Normal cell -->\r\n <ng-container\r\n *ngIf=\"\r\n col?.type !== 'image' &&\r\n col?.field != 'image' &&\r\n col?.field != 'invoice.invoice_image' &&\r\n !isTotalRow\r\n \"\r\n >\r\n <ng-container *ngIf=\"col.is_amount\">{{\r\n currencySymbol\r\n }}</ng-container>\r\n {{getCellTitle(row, col)}}\r\n </ng-container>\r\n\r\n <!-- Total row -->\r\n <ng-container *ngIf=\"isTotalRow\">\r\n {{ getTotalAmount(col) }}\r\n </ng-container>\r\n\r\n <!-- Invoice Image -->\r\n <ng-container *ngIf=\"col.field == 'invoice.invoice_image'\">\r\n <div style=\"display: flex; align-items: center; zoom: 0.7\">\r\n <span\r\n title=\"{{ getNestedValue(row, col.field) || 'Attachment' }}\"\r\n (click)=\"downloadAttchment(getNestedValue(row, col.field))\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath +\r\n 'data-grid/document-icons/' +\r\n getExtention(getNestedValue(row, col.field)) +\r\n '.svg'\r\n \"\r\n ></span>\r\n </div>\r\n </ng-container>\r\n\r\n <!-- Image cell -->\r\n <ng-container *ngIf=\"col?.type == 'image' && !isTotalRow\">\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n defaultImagePlaceholder;\r\n context: { row: row, col: col }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </div>\r\n <span\r\n *ngIf=\"\r\n (!col?.cellRenderer && showCellDetailsBox &&\r\n getNestedValue(row, col.field)?.length > 50 && col?.type !== 'image') ||\r\n (isNestedValueArray(row, col.field) &&\r\n getNestedValue(row, col.field)?.length > 1)\r\n \"\r\n class=\"toggle-icon data-grid-svg-icon ms-2 cursor-pointer\"\r\n [inlineSVG]=\"\r\n isExpanded(row, col)\r\n ? singleSpaAssetsPath + 'data-grid/icons/chevron-down.svg'\r\n : singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\r\n \"\r\n (click)=\"\r\n $event.stopPropagation();\r\n toggleExpandOfLongCellText(row, col, columns, true)\r\n \"\r\n (dblclick)=\"$event.preventDefault(); $event.stopPropagation()\"\r\n ></span>\r\n </ng-template>\r\n <!-- Expand / Collapse icon -->\r\n </div>\r\n\r\n <!-- Expanded text -->\r\n <div\r\n class=\"position-absolute w-100 expanded-box\"\r\n *ngIf=\"isExpanded(row, col)\"\r\n [style.zIndex]=\"getZIndex(row, col)\"\r\n style=\"top: 100%; left: 0\"\r\n [attr.id]=\"(row.id || row._id) + '-' + (col.id || col._id)\"\r\n [class.invisible]=\"!showDetailsBox\"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n fullTextTemplate;\r\n context: {\r\n row: row,\r\n col: col,\r\n isArray: isNestedValueArray(row, col.field)\r\n }\r\n \"\r\n ></ng-container>\r\n </div>\r\n </ng-template>\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<!-- Headers Action List On clicking three dots -->\r\n\r\n<ng-template\r\n #columnMenu\r\n let-col=\"col\"\r\n let-isNestedTable=\"isNestedTable\"\r\n let-columns=\"columns\"\r\n let-section=\"section\"\r\n let-columnIndex=\"columnIndex\"\r\n let-childColIndex=\"childColIndex\"\r\n>\r\n <div\r\n class=\"column-menu three-dots-col-menu\"\r\n [class.visually-hidden]=\"isMenueHidden\"\r\n *ngIf=\"activeCol && !isThreeDotsFilterOpen\"\r\n [style.backgroundColor]=\"dropdownsBackgroundColor\"\r\n (click)=\"$event.stopPropagation()\"\r\n [style.color]=\"headerTextColor\"\r\n >\r\n <!-- Sort Ascending -->\r\n <div class=\"border-below pb-2\" [class.disable-sorting]=\"!col.is_sortable\">\r\n <span class=\"muted-text fs-7\" style=\"margin-left: 12px\">Sort</span>\r\n <div\r\n *ngIf=\"\r\n columnThreedotsMunuConfig?.showAscending &&\r\n (sortingConfig?.field != col.field ||\r\n sortingConfig?.order_by == 'desc')\r\n \"\r\n class=\"column-menu-item\"\r\n (click)=\"sortAsc(activeCol)\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrow-up.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n Sort Ascending\r\n </div>\r\n\r\n <!-- Sort Descending -->\r\n <div\r\n *ngIf=\"\r\n columnThreedotsMunuConfig?.showDescending &&\r\n (sortingConfig?.field != col.field ||\r\n sortingConfig?.order_by == 'asc')\r\n \"\r\n class=\"column-menu-item\"\r\n (click)=\"sortDesc(activeCol)\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrow-down.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n Sort Descending\r\n </div>\r\n\r\n <div\r\n *ngIf=\"\r\n sortingConfig?.field === col.field &&\r\n (sortingConfig?.order_by === 'asc' ||\r\n sortingConfig?.order_by === 'desc')\r\n \"\r\n class=\"column-menu-item\"\r\n (click)=\"resetSort(activeCol)\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/arrow-counterclockwise.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n Reset Sort\r\n </div>\r\n </div>\r\n <div class=\"py-2 border-below three-dots-filter\" [class.disable-sorting]=\"col?.type == 'image' || !col.is_search_able\">\r\n <div\r\n *ngIf=\"columnThreedotsMunuConfig?.showFilter\"\r\n class=\"column-menu-item three-dots-filter\"\r\n (click)=\"openFilteronThreeDotsClick(col)\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n Filter\r\n </div>\r\n </div>\r\n\r\n <div class=\"py-2 border-below\">\r\n <span class=\"muted-text fs-7\" style=\"margin-left: 12px\">Pin</span>\r\n <div\r\n *ngIf=\"columnThreedotsMunuConfig?.showPinleft && col?.pinned !== 'left'\"\r\n class=\"column-menu-item\"\r\n (click)=\"\r\n $event.stopPropagation();\r\n updateColumnPinInSourceByField(\r\n activeCol,\r\n 'left',\r\n isNestedTable,\r\n columns\r\n )\r\n \"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/pin-left.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span\r\n >Pin Left\r\n </div>\r\n\r\n <div\r\n *ngIf=\"\r\n columnThreedotsMunuConfig?.showPinright && col?.pinned !== 'right'\r\n \"\r\n class=\"column-menu-item\"\r\n (click)=\"\r\n $event.stopPropagation();\r\n updateColumnPinInSourceByField(\r\n activeCol,\r\n 'right',\r\n isNestedTable,\r\n columns\r\n )\r\n \"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/pin-right.svg'\"\r\n class=\"data-grid-svg-icon data-grid-svg-icon me-2\"\r\n ></span\r\n >Pin Right\r\n </div>\r\n\r\n <div\r\n *ngIf=\"col?.pinned\"\r\n class=\"column-menu-item\"\r\n (click)=\"\r\n $event.stopPropagation();\r\n updateColumnPinInSourceByField(\r\n activeCol,\r\n null,\r\n isNestedTable,\r\n columns\r\n )\r\n \"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/layout-three-columns.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span\r\n >Unpin\r\n </div>\r\n </div>\r\n\r\n <div\r\n *ngIf=\"columnThreedotsMunuConfig?.showAutosizeThisColumn\"\r\n class=\"column-menu-item\"\r\n (click)=\"autosizeColumn(activeCol)\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/arrows-expand-vertical.svg'\r\n \"\r\n class=\"me-2\"\r\n ></span>\r\n Autosize This Column\r\n </div>\r\n\r\n <!-- Autosize All Columns -->\r\n <div\r\n *ngIf=\"columnThreedotsMunuConfig?.showAutosizeAllColumns\"\r\n class=\"column-menu-item\"\r\n (click)=\"autosizeAllColumns()\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/arrows-angle-expand.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span\r\n >Autosize All Columns\r\n </div>\r\n\r\n <!-- Group By -->\r\n <div\r\n *ngIf=\"showRowsGrouping\"\r\n class=\"column-menu-item\"\r\n (click)=\"groupBy(activeCol)\"\r\n [class.disable-sorting]=\"!col.is_groupable\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/diagram-3.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n Group by {{ col.header }}\r\n </div>\r\n\r\n <!-- Choose Columns -->\r\n <div\r\n *ngIf=\"columnThreedotsMunuConfig?.showChoseColumns\"\r\n class=\"column-menu-item\"\r\n (click)=\"chooseColumns()\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/ui-checks-grid.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n Choose Columns\r\n </div>\r\n\r\n <!-- Reset Columns -->\r\n <div\r\n *ngIf=\"columnThreedotsMunuConfig?.showResetColumns\"\r\n class=\"column-menu-item\"\r\n (click)=\"resetColumns()\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/arrow-counterclockwise.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span\r\n >Reset Columns\r\n </div>\r\n </div>\r\n <div\r\n @slideToggle\r\n *ngIf=\"isThreeDotsFilterOpen && col?.is_search_able\"\r\n class=\"three-dots-col-menu position-relative\"\r\n [style.right.px]=\"getDynamicRight(col, section, columnIndex, childColIndex)\"\r\n [class.visually-hidden]=\"isMenueHidden\"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"filterMenu; context: { col: col }\"\r\n ></ng-container>\r\n </div>\r\n</ng-template>\r\n\r\n<!-- Filter Menue -->\r\n<ng-template #filterMenu let-col=\"col\">\r\n <div\r\n class=\"filter-menu-container filter-menu\"\r\n [style.backgroundColor]=\"dropdownsBackgroundColor\"\r\n >\r\n <!-- Dropdown Type -->\r\n <ng-container *ngIf=\"col?.type === 'dropdown' || col?.type === 'array'; else textFilter\">\r\n <div class=\"filter-dropdown-section p-1\">\r\n\r\n <!-- Search input -->\r\n <input\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Search...\"\r\n type=\"search\"\r\n [(ngModel)]=\"addFilterColumnInput\"\r\n />\r\n\r\n <!-- Filter + Result Handling -->\r\n <ng-container\r\n *ngIf=\"\r\n (selectedColumnForFilter?.column_dropdown_value\r\n | filter : addFilterColumnInput : 'value') as filteredOptions\r\n \"\r\n >\r\n\r\n <!-- DATA FOUND -->\r\n <ng-container *ngIf=\"filteredOptions.length; else noDataFound\">\r\n\r\n <!-- Select All (only when data exists) -->\r\n <div class=\"form-check mb-1 mt-2 ms-1 select-all-filter\">\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n [checked]=\"\r\n (currentFilterSelectedIds?.size ?? 0) ===\r\n (selectedColumnForFilter?.column_dropdown_value?.length ?? 0)\r\n \"\r\n [indeterminate]=\"\r\n (currentFilterSelectedIds?.size ?? 0) > 0 &&\r\n (currentFilterSelectedIds?.size ?? 0) <\r\n (selectedColumnForFilter?.column_dropdown_value?.length ?? 0)\r\n \"\r\n (change)=\"toggleSelectAllSideFilters(col, $event)\"\r\n id=\"selectAll_{{ col.field }}\"\r\n />\r\n\r\n <label class=\"form-check-label\" for=\"selectAll_{{ col.field }}\">\r\n Select All\r\n </label>\r\n </div>\r\n\r\n <!-- Virtual Scroll -->\r\n <cdk-virtual-scroll-viewport\r\n itemSize=\"32\"\r\n class=\"filter-viewport\"\r\n style=\"height: 120px\"\r\n >\r\n <div\r\n class=\"form-check mb-1 ms-1\"\r\n *cdkVirtualFor=\"let option of filteredOptions; trackBy: trackById\"\r\n >\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n [id]=\"option?.id ?? option?._id ?? option\"\r\n [checked]=\"\r\n currentFilterSelectedIds.has(option?.id ?? option?._id ?? option)\r\n \"\r\n (change)=\"toggleSelectionInFilter(option)\"\r\n />\r\n\r\n <label\r\n class=\"form-check-label fw-semibold\"\r\n [for]=\"option?.id ?? option?._id ?? option\"\r\n >\r\n {{ (option?.value ?? option?.name ?? option) | titlecase }}\r\n </label>\r\n </div>\r\n </cdk-virtual-scroll-viewport>\r\n\r\n </ng-container>\r\n\r\n <!-- NO DATA FOUND -->\r\n <ng-template #noDataFound>\r\n <div\r\n class=\"text-center text-muted mt-2\"\r\n *ngIf=\"addFilterColumnInput\"\r\n >\r\n No Record Found\r\n </div>\r\n </ng-template>\r\n\r\n </ng-container>\r\n </div>\r\n</ng-container>\r\n\r\n\r\n <!-- Text Filter Section -->\r\n <ng-template #textFilter>\r\n <div class=\"filter-text-section\">\r\n <div class=\"form-group mb-2\">\r\n <select\r\n class=\"form-select form-select-sm custom-select\"\r\n [(ngModel)]=\"firstCondition\"\r\n >\r\n <ng-container *ngIf=\"selectedColumnForFilter?.type == 'string'\">\r\n <option value=\"contain\">Contains</option>\r\n <option value=\"does_not_contain\">Does Not Contain</option>\r\n <option value=\"equal\">Equals</option>\r\n <option value=\"before\">Starts With</option>\r\n <option value=\"after\">Ends With</option>\r\n </ng-container>\r\n\r\n <ng-container *ngIf=\"selectedColumnForFilter?.type == 'date' || selectedColumnForFilter?.type == 'time'\">\r\n <option value=\"equal\">Equals To</option>\r\n <option value=\"not_equal\">Not Equal</option>\r\n <option value=\"after\">After</option>\r\n <option value=\"before\">Before</option>\r\n </ng-container>\r\n\r\n <ng-container *ngIf=\"selectedColumnForFilter?.type == 'number'\">\r\n <option value=\"equal\">Equals To</option>\r\n <option value=\"before\">Less Then </option>\r\n <option value=\"after\">Greater Then </option>\r\n <option value=\"less_then_equal\">less then Equal to</option>\r\n <option value=\"greater_then_equal\">Greater then Equal to </option>\r\n </ng-container>\r\n </select>\r\n </div>\r\n\r\n <input\r\n [type]=\"col?.type == 'string' ? 'text' : col?.type\"\r\n class=\"form-control form-control-sm mb-3\"\r\n placeholder=\"Value\"\r\n [(ngModel)]=\"firstValue\"\r\n #filterMenueTextchInput\r\n (keydown.enter)=\"applyDropdownFilter()\"\r\n />\r\n\r\n <div class=\"form-group mb-3 d-flex flex-row\">\r\n <div\r\n class=\"form-check form-check-inline m-0 col-4 d-flex align-items-center gap-1\"\r\n >\r\n <input\r\n class=\"form-check-input filter-radio-inputs\"\r\n type=\"radio\"\r\n name=\"condition\"\r\n [(ngModel)]=\"condition\"\r\n value=\"and\"\r\n id=\"and_{{ col.field }}\"\r\n (change)=\"cdr.detectChanges()\"\r\n />\r\n <label class=\"form-check-label mb-0 mt-1\" for=\"and_{{ col.field }}\"\r\n >AND</label\r\n >\r\n </div>\r\n <div\r\n class=\"form-check form-check-inline m-0 col-4 d-flex align-items-center gap-1 gap-1\"\r\n >\r\n <input\r\n class=\"form-check-input filter-radio-inputs\"\r\n type=\"radio\"\r\n name=\"condition\"\r\n [(ngModel)]=\"condition\"\r\n value=\"or\"\r\n id=\"or_{{ col.field }}\"\r\n (change)=\"cdr.detectChanges()\"\r\n />\r\n <label class=\"form-check-label mb-0 mt-1\" for=\"or_{{ col.field }}\"\r\n >OR</label\r\n >\r\n </div>\r\n <div\r\n class=\"form-check form-check-inline m-0 col-4 d-flex align-items-center gap-1 gap-1\"\r\n >\r\n <input\r\n class=\"form-check-input filter-radio-inputs\"\r\n type=\"radio\"\r\n name=\"condition\"\r\n [(ngModel)]=\"condition\"\r\n value=\"none\"\r\n id=\"none_{{ col.field }}\"\r\n (change)=\"cdr.detectChanges()\"\r\n />\r\n <label class=\"form-check-label mb-0 mt-1\" for=\"none_{{ col.field }}\"\r\n >None</label\r\n >\r\n </div>\r\n </div>\r\n <div @slideToggle *ngIf=\"firstValue && condition != 'none'\">\r\n <div class=\"form-group mb-2\">\r\n <select\r\n class=\"form-select form-select-sm custom-select\"\r\n [(ngModel)]=\"secondCondition\"\r\n >\r\n <ng-container *ngIf=\"selectedColumnForFilter?.type == 'string'\">\r\n <option value=\"contain\">Contains</option>\r\n <option value=\"does_not_contain\">Does Not Contain</option>\r\n <option value=\"equal\">Equals</option>\r\n <option value=\"before\">Starts With</option>\r\n <option value=\"after\">Ends With</option>\r\n </ng-container>\r\n\r\n <ng-container *ngIf=\"selectedColumnForFilter?.type == 'date' || selectedColumnForFilter?.type == 'time'\">\r\n <option value=\"equal\">Equals To</option>\r\n <option value=\"not_equal\">Not Equal</option>\r\n <option value=\"after\">After</option>\r\n <option value=\"before\">Before</option>\r\n </ng-container>\r\n\r\n <ng-container *ngIf=\"selectedColumnForFilter?.type == 'number'\">\r\n <option value=\"equal\">Equals To</option>\r\n <option value=\"before\">Less Then </option>\r\n <option value=\"after\">Greater Then </option>\r\n <option value=\"less_then_equal\">less then Equal to</option>\r\n <option value=\"greater_then_equal\">Greater then Equal to </option>\r\n </ng-container>\r\n </select>\r\n </div>\r\n\r\n <input\r\n [type]=\"col?.type == 'string' ? 'text' : col?.type\"\r\n class=\"form-control form-control-sm mb-3\"\r\n placeholder=\"Second Value\"\r\n [(ngModel)]=\"secondValue\"\r\n />\r\n </div>\r\n </div>\r\n </ng-template>\r\n\r\n <!-- Actions -->\r\n <div class=\"d-flex gap-2 mt-2\">\r\n <div\r\n class=\"btn btn-sm btn-primary d-flex justify-content-center align-items-center w-100\"\r\n style=\"height: 30px\"\r\n (click)=\"applyDropdownFilter()\"\r\n >\r\n Apply\r\n </div>\r\n <div\r\n class=\"btn btn-sm btn-secondary d-flex justify-content-center align-items-center w-100\"\r\n style=\"height: 30px\"\r\n (click)=\"resetSideFilter(col)\"\r\n >\r\n Reset\r\n </div>\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<!-- Side Menue -->\r\n\r\n<!-- Column Pannel / Pivot Mode / Searching -->\r\n\r\n<ng-template #columnPannel>\r\n <div class=\"column-panel-header\">\r\n <!-- Pivot Toggle -->\r\n <div\r\n class=\"form-check form-switch d-flex align-items-center mb-2 pivot-mode px-5 ms-2 d-none\"\r\n >\r\n <input\r\n class=\"form-check-input me-2\"\r\n type=\"checkbox\"\r\n id=\"pivotToggle\"\r\n [(ngModel)]=\"pivotMode\"\r\n />\r\n <label class=\"form-check-label\" for=\"pivotToggle\">Pivot Mode</label>\r\n </div>\r\n\r\n <!-- Select All & Search -->\r\n <div class=\"d-flex align-items-center mb-2 px-3 mt-3\">\r\n <span class=\"filter-icon-wrapper me-2\" *ngIf=\"showColumnsGrouping\">\r\n <span\r\n class=\"toggle-icon data-grid-svg-icon\"\r\n [inlineSVG]=\"\r\n accordionState === 'all'\r\n ? singleSpaAssetsPath + 'data-grid/icons/chevron-down.svg'\r\n : accordionState === 'some'\r\n ? singleSpaAssetsPath + 'data-grid/icons/dash.svg'\r\n : singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\r\n \"\r\n (click)=\"toggleAllAccordions()\"\r\n ></span>\r\n </span>\r\n <input\r\n type=\"checkbox\"\r\n class=\"form-check-input me-2\"\r\n [checked]=\"allColumnsSelected()\"\r\n (change)=\"toggleAllColumnsVisibility()\"\r\n />\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Search columns...\"\r\n [(ngModel)]=\"columnSearch\"\r\n />\r\n </div>\r\n\r\n <!-- Separator -->\r\n <hr class=\"my-2\" />\r\n </div>\r\n</ng-template>\r\n\r\n<!-- Right Columns Menue -->\r\n\r\n<!-- Column Panel Item Template -->\r\n<ng-template #columnPanelItem let-col=\"col\">\r\n <!-- Group Column -->\r\n <ng-container *ngIf=\"col.children?.length\">\r\n <div class=\"column-group d-flex align-items-center mb-2\">\r\n <span class=\"filter-icon-wrapper me-2\">\r\n <span\r\n class=\"toggle-icon data-grid-svg-icon\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\r\n \"\r\n [class.rotate]=\"col.expanded\"\r\n (click)=\"col.expanded = !col.expanded\"\r\n ></span>\r\n </span>\r\n <input\r\n type=\"checkbox\"\r\n class=\"form-check-input me-2\"\r\n [id]=\"'group_' + col.header\"\r\n [checked]=\"isColumnVisible(col)\"\r\n (change)=\"toggleGroupVisibility(col)\"\r\n />\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/grid-3x2-gap.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center me-2\"\r\n ></span>\r\n <label\r\n class=\"d-flex align-items-center mb-0 w-100\"\r\n [for]=\"'group_' + col.header\"\r\n style=\"cursor: pointer\"\r\n >\r\n <span class=\"text-truncate\">{{ col.header }}</span>\r\n </label>\r\n </div>\r\n <div *ngIf=\"col.expanded\" class=\"ps-4\">\r\n <ng-container *ngFor=\"let child of col.children; trackBy: trackByField\">\r\n <ng-container\r\n *ngTemplateOutlet=\"columnPanelItem; context: { col: child }\"\r\n ></ng-container>\r\n </ng-container>\r\n </div>\r\n </ng-container>\r\n\r\n <!-- Leaf Column -->\r\n <ng-container *ngIf=\"!col.children?.length\">\r\n <div class=\"d-flex align-items-center mb-2\">\r\n <span class=\"me-2\" style=\"width: 1.5rem\"></span>\r\n <input\r\n type=\"checkbox\"\r\n class=\"form-check-input me-2\"\r\n [(ngModel)]=\"col.is_visible\"\r\n [id]=\"'col_' + col.field\"\r\n (change)=\"onSideMenuColumnsVisibilityChange()\"\r\n />\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/grid-3x2-gap.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center me-2\"\r\n ></span>\r\n <label\r\n class=\"d-flex align-items-center mb-0 w-100\"\r\n [for]=\"'col_' + col.field\"\r\n style=\"cursor: pointer\"\r\n >\r\n <span class=\"text-truncate\">{{ col.header }}</span>\r\n </label>\r\n </div>\r\n </ng-container>\r\n</ng-template>\r\n\r\n<!-- Columns Side Filter -->\r\n<ng-template #sideFilters>\r\n <div class=\"py-3 px-2 pe-3 h-100\">\r\n <div class=\"d-flex align-items-center mb-2\">\r\n <span class=\"filter-icon-wrapper me-2\" *ngIf=\"showColumnsGrouping\">\r\n <span\r\n class=\"toggle-icon data-grid-svg-icon\"\r\n [inlineSVG]=\"\r\n filterAccordionState === 'all'\r\n ? singleSpaAssetsPath + 'data-grid/icons/chevron-down.svg'\r\n : filterAccordionState === 'some'\r\n ? singleSpaAssetsPath + 'data-grid/icons/dash.svg'\r\n : singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\r\n \"\r\n (click)=\"toggleAllFilterAccordions()\"\r\n ></span>\r\n </span>\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Search...\"\r\n [(ngModel)]=\"columnSearch\"\r\n />\r\n </div>\r\n <div\r\n class=\"overflow-auto side-filter-columns-wrapper\"\r\n style=\"height: calc(100% - 70px); scrollbar-width: thin\"\r\n >\r\n <ng-container\r\n *ngFor=\"\r\n let col of columns | filter : columnSearch : 'header';\r\n trackBy: trackByField\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"filterPannelItem; context: { col: col }\"\r\n ></ng-container>\r\n </ng-container>\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template #filterPannelItem let-col=\"col\">\r\n <!-- Group Column -->\r\n <ng-container *ngIf=\"col.children?.length\">\r\n <div\r\n class=\"column-group d-flex align-items-center mb-2\"\r\n *ngIf=\"col?.type !== 'image'\"\r\n >\r\n <!-- Chevron toggle -->\r\n <span class=\"filter-icon-wrapper me-2\">\r\n <span\r\n class=\"toggle-icon data-grid-svg-icon\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\r\n \"\r\n [class.rotate]=\"col.expandedFilter\"\r\n (click)=\"col.expandedFilter = !col.expandedFilter\"\r\n ></span>\r\n </span>\r\n\r\n <!-- Group label toggle -->\r\n <label\r\n class=\"d-flex align-items-center mb-0 w-100\"\r\n style=\"cursor: pointer\"\r\n (click)=\"col.expandedFilter = !col.expandedFilter\"\r\n >\r\n <span class=\"fw-bold text-truncate\"\r\n >{{ col.header }}\r\n <span\r\n class=\"text-primary ms-1\"\r\n *ngIf=\"col?.query?._ids?.length || col?.query?._first_value\"\r\n >*</span\r\n >\r\n </span>\r\n </label>\r\n </div>\r\n\r\n <!-- Children columns -->\r\n <div *ngIf=\"col.expandedFilter\" class=\"ps-4\">\r\n <ng-container *ngFor=\"let child of col.children; trackBy: trackByField\">\r\n <ng-container\r\n *ngTemplateOutlet=\"filterPannelItem; context: { col: child }\"\r\n ></ng-container>\r\n </ng-container>\r\n </div>\r\n </ng-container>\r\n\r\n <!-- Leaf Column -->\r\n <ng-container *ngIf=\"!col.children?.length\">\r\n <div class=\"d-flex align-items-center mb-2\" *ngIf=\"col?.type !== 'image'\">\r\n <span\r\n class=\"me-2 filter-icon-wrapper me-2\"\r\n (click)=\"col.expandedFilter = !col.expandedFilter\"\r\n >\r\n <span\r\n class=\"toggle-icon data-grid-svg-icon\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\r\n \"\r\n [class.rotate]=\"col.expandedFilter\"\r\n ></span>\r\n </span>\r\n\r\n <label\r\n class=\"d-flex align-items-center mb-0 w-100\"\r\n style=\"cursor: pointer\"\r\n (click)=\"col.expandedFilter = !col.expandedFilter\"\r\n >\r\n <span class=\"text-truncate fw-bold\">{{ col.header }}</span>\r\n </label>\r\n </div>\r\n\r\n <!-- Show filter when expanded -->\r\n <div [@slideToggle] *ngIf=\"col.expandedFilter\" class=\"ps-4 pe-3\">\r\n <ng-container\r\n *ngTemplateOutlet=\"sideNestedFilter; context: { col: col }\"\r\n ></ng-container>\r\n </div>\r\n </ng-container>\r\n</ng-template>\r\n\r\n<!-- Side Nested Filters -->\r\n<ng-template #sideNestedFilter let-col=\"col\">\r\n <div class=\"\">\r\n\r\n <ng-container *ngIf=\"col?.type === 'dropdown' || col?.type == 'array'; else textFilter\">\r\n <div class=\"p-1\">\r\n\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm mb-2\"\r\n placeholder=\"Search...\"\r\n [(ngModel)]=\"sideNestedFilterSearch\"\r\n />\r\n\r\n <ng-container\r\n *ngIf=\"\r\n (col?.column_dropdown_value\r\n | filter : sideNestedFilterSearch : 'value') as filteredOptions\r\n \"\r\n >\r\n <ng-container *ngIf=\"filteredOptions.length; else noDataFound\">\r\n <div class=\"form-check mb-1 ms-1 select-all-filter\">\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n [checked]=\"\r\n col.query?._ids?.length == col?.column_dropdown_value?.length\r\n \"\r\n (change)=\"toggleSelectAllSideFilters(col, $event)\"\r\n [indeterminate]=\"(col.query?._ids?.length !== col?.column_dropdown_value?.length && col.query?._ids?.length)\"\r\n id=\"selectAll_{{ col.field }}\"\r\n />\r\n <label class=\"form-check-label\" for=\"selectAll_{{ col.field }}\">\r\n Select All\r\n </label>\r\n </div>\r\n <cdk-virtual-scroll-viewport\r\n itemSize=\"32\"\r\n class=\"dropdown-viewport\"\r\n style=\"height: 120px\"\r\n >\r\n <div\r\n class=\"form-check mb-1 ms-1\"\r\n *cdkVirtualFor=\"let option of filteredOptions\"\r\n >\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n [value]=\"option\"\r\n [checked]=\"\r\n col.query?._ids?.includes(option?._id || option?.id || option)\r\n \"\r\n (change)=\"onOptionToggle(col, option)\"\r\n id=\"option_{{ col.field }}_{{\r\n option?.id || option?._id || option\r\n }}\"\r\n />\r\n\r\n <label\r\n class=\"form-check-label\"\r\n [for]=\"\r\n 'option_' +\r\n col.field +\r\n '_' +\r\n (option?.id || option?._id || option)\r\n \"\r\n >\r\n {{ (option.value || option) | titlecase }}\r\n </label>\r\n </div>\r\n </cdk-virtual-scroll-viewport>\r\n\r\n </ng-container>\r\n <ng-template #noDataFound>\r\n <div\r\n class=\"text-center text-muted mt-2\"\r\n *ngIf=\"sideNestedFilterSearch\"\r\n >\r\n No Record Found\r\n </div>\r\n </ng-template>\r\n\r\n </ng-container>\r\n\r\n </div>\r\n </ng-container>\r\n\r\n\r\n <!-- Text Filter Section -->\r\n <ng-template #textFilter>\r\n <div class=\"filter-text-section\">\r\n <div class=\"form-group mb-2\">\r\n <select\r\n class=\"form-select form-select-sm\"\r\n [(ngModel)]=\"col.query.first_condition\"\r\n >\r\n <ng-container *ngIf=\"col?.type == 'string'\">\r\n <option value=\"contain\">Contains</option>\r\n <option value=\"does_not_contain\">Does Not Contain</option>\r\n <option value=\"equal\">Equals</option>\r\n <option value=\"before\">Starts With</option>\r\n <option value=\"after\">Ends With</option>\r\n </ng-container>\r\n\r\n <ng-container *ngIf=\"col?.type == 'date' || col?.type == 'time'\">\r\n <option value=\"equal\">Equals To</option>\r\n <option value=\"not_equal\">Not Equal</option>\r\n <option value=\"after\">After</option>\r\n <option value=\"before\">Before</option>FV\r\n </ng-container>\r\n\r\n <ng-container *ngIf=\"col?.type == 'number'\">\r\n <option value=\"equal\">Equals To</option>\r\n <option value=\"before\">Less Then </option>\r\n <option value=\"after\">Greater Then </option>\r\n <option value=\"less_then_equal\">less then Equal to</option>\r\n <option value=\"greater_then_equal\">Greater then Equal to </option>FV\r\n </ng-container>\r\n </select>\r\n </div>\r\n\r\n <input\r\n [type]=\"col?.type == 'date' ? 'date' : (col?.type == 'number' ? 'number': 'text')\"\r\n class=\"form-control form-control-sm mb-3\"\r\n placeholder=\"Value\"\r\n [(ngModel)]=\"col!.query!.first_value\"\r\n />\r\n\r\n <div\r\n class=\"form-group mb-3 d-flex flex-row muted\"\r\n style=\"font-size: 14px\"\r\n >\r\n <div\r\n class=\"form-check form-check-inline m-0 col-4 d-flex align-items-center gap-1\"\r\n >\r\n <input\r\n class=\"form-check-input filter-radio-inputs\"\r\n type=\"radio\"\r\n name=\"condition\"\r\n [(ngModel)]=\"col!.query.condition\"\r\n value=\"and\"\r\n id=\"and_{{ col.field }}\"\r\n />\r\n <label class=\"form-check-label mb-0 mt-1\" for=\"and_{{ col.field }}\"\r\n >AND</label\r\n >\r\n </div>\r\n <div\r\n class=\"form-check form-check-inline m-0 col-4 d-flex align-items-center gap-1\"\r\n >\r\n <input\r\n class=\"form-check-input filter-radio-inputs\"\r\n type=\"radio\"\r\n name=\"condition\"\r\n [(ngModel)]=\"col!.query.condition\"\r\n value=\"or\"\r\n id=\"or_{{ col.field }}\"\r\n />\r\n <label class=\"form-check-label mb-0 mt-1\" for=\"or_{{ col.field }}\"\r\n >OR</label\r\n >\r\n </div>\r\n <div\r\n class=\"form-check form-check-inline m-0 col-4 d-flex align-items-center gap-1\"\r\n >\r\n <input\r\n class=\"form-check-input filter-radio-inputs\"\r\n type=\"radio\"\r\n name=\"condition\"\r\n [(ngModel)]=\"col!.query.condition\"\r\n value=\"none\"\r\n id=\"none_{{ col.field }}\"\r\n />\r\n <label\r\n class=\"nnonem-check-label mb-0 mt-1\"\r\n for=\"none_{{ col.field }}\"\r\n >None</label\r\n >\r\n </div>\r\n </div>\r\n <ng-container\r\n *ngIf=\"col?.query?.first_value && col?.query?.condition !== 'none'\"\r\n >\r\n <div class=\"form-group mb-2\">\r\n <select\r\n class=\"form-select form-select-sm\"\r\n [(ngModel)]=\"col!.query.second_condition\"\r\n >\r\n <ng-container *ngIf=\"col?.type == 'string'\">\r\n <option value=\"contain\">Contains</option>\r\n <option value=\"does_not_contain\">Does Not Contain</option>\r\n <option value=\"equal\">Equals</option>\r\n <option value=\"before\">Starts With</option>\r\n <option value=\"after\">Ends With</option>\r\n </ng-container>\r\n\r\n <ng-container *ngIf=\"col?.type == 'date' || col?.type == 'time'\">\r\n <option value=\"equal\">Equals To</option>\r\n <option value=\"not_equal\">Not Equal</option>\r\n <option value=\"after\">After</option>\r\n <option value=\"before\">Before</option>\r\n </ng-container>\r\n\r\n <ng-container *ngIf=\"col?.type == 'number'\">\r\n <option value=\"equal\">Equals To</option>\r\n <option value=\"before\">Less Then </option>\r\n <option value=\"after\">Greater Then </option>\r\n <option value=\"less_then_equal\">less then Equal to</option>\r\n <option value=\"greater_then_equal\">Greater then Equal to </option>\r\n </ng-container>\r\n </select>\r\n </div>\r\n\r\n <input\r\n [type]=\"col?.type == 'date' ? 'date' : 'text'\"\r\n class=\"form-control form-control-sm mb-3\"\r\n placeholder=\"Second Value\"\r\n [(ngModel)]=\"col!.query.second_value\"\r\n />\r\n </ng-container>\r\n <!-- <div class=\"d-flex gap-2\">\r\n <div class=\"btn btn-sm btn-primary d-flex justify-content-center align-items-center\" style=\"height: 22px;\" (click)=\"applyDropdownFilter()\">apply</div>\r\n <div class=\"btn btn-sm btn-secondary d-flex justify-content-center align-items-center\" style=\"height: 22px;\" (click)=\"applyDropdownFilter()\">reset</div>\r\n\r\n </div> -->\r\n </div>\r\n </ng-template>\r\n <div\r\n class=\"d-flex justify-content-center gap-2 border-top\"\r\n style=\"height: 38px\"\r\n >\r\n <button\r\n type=\"button\"\r\n style=\"max-height: 30px\"\r\n class=\"btn btn-outline-secondary btn-light border w-100 d-flex align-items-center justify-content-center mt-1 btn-light\"\r\n (click)=\"$event.stopPropagation(); removeSideFilter(col)\"\r\n >\r\n <span>Clear</span>\r\n </button>\r\n <button\r\n type=\"button\"\r\n style=\"max-height: 30px\"\r\n class=\"btn btn-primary w-100 d-flex align-items-center justify-content-center mt-1\"\r\n (click)=\"applySideFilter(col)\"\r\n [class.disabled]=\"(col?.query.condition !== 'none' && !col?.query?.second_value)\"\r\n [class.pe-none]=\"(col!?.query.condition !== 'none' && !col?.query?.second_value)\"\r\n >\r\n <span style=\"margin-top: -1px\">Apply</span>\r\n </button>\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<!-- Centr Overlay for showing the chose columns -->\r\n\r\n<div *ngIf=\"showColumnPanel\" class=\"custom-modal-overlay\">\r\n <div\r\n class=\"custom-modal-content\"\r\n [style.backgroundColor]=\"dropdownsBackgroundColor\"\r\n (click)=\"$event.stopPropagation()\"\r\n >\r\n <ng-container *ngTemplateOutlet=\"modalColumnPannel\"></ng-container>\r\n </div>\r\n</div>\r\n\r\n<!-- The existing ng-template you provided -->\r\n<ng-template #modalColumnPannel>\r\n <div class=\"column-panel-header\">\r\n <div\r\n class=\"d-flex justify-content-between align-items-center px-2 ps-3 rounded-top-2 moda-header\"\r\n [style.height.px]=\"48\"\r\n >\r\n Choose Columns\r\n <span class=\"filter-icon-wrapper\" (click)=\"closeModalColumnPanel()\"\r\n ><span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/x.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span\r\n ></span>\r\n </div>\r\n <hr class=\"my-0\" />\r\n <div>\r\n <div class=\"d-flex align-items-center px-2 pe-3\" [style.height.px]=\"48\">\r\n <span class=\"filter-icon-wrapper me-2\" *ngIf=\"showColumnsGrouping\">\r\n <span\r\n class=\"toggle-icon data-grid-svg-icon\"\r\n [inlineSVG]=\"\r\n accordionState === 'all'\r\n ? singleSpaAssetsPath + 'data-grid/icons/chevron-down.svg'\r\n : accordionState === 'some'\r\n ? singleSpaAssetsPath + 'data-grid/icons/dash.svg'\r\n : singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\r\n \"\r\n (click)=\"toggleAllAccordions()\"\r\n ></span>\r\n </span>\r\n <input\r\n type=\"checkbox\"\r\n class=\"form-check-input me-2\"\r\n [checked]=\"allColumnsSelected()\"\r\n (change)=\"toggleAllColumnsVisibility()\"\r\n />\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Search columns...\"\r\n [(ngModel)]=\"choseColumnsSearch\"\r\n />\r\n </div>\r\n\r\n <hr class=\"mt-0 mb-1\" />\r\n <div class=\"px-2 overlay-scrollable\">\r\n <ng-container\r\n *ngFor=\"\r\n let col of columns | filter : choseColumnsSearch : 'header';\r\n trackBy: trackByField\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"columnPanelItem; context: { col: col }\"\r\n ></ng-container>\r\n </ng-container>\r\n </div>\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template #sideMenuRowGroups>\r\n <div class=\"d-flex flex-column h-100 d-none\">\r\n <div class=\"px-3 h-100\">\r\n <div class=\"d-flex gap-3 mb-4\">\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/justify.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n <span>Row Groups</span>\r\n </div>\r\n <div class=\"h-50\">\r\n <div\r\n class=\"px-3 py-2 border-dashed h-100 d-flex justify-content-center align-items-center\"\r\n style=\"font-size: 14px\"\r\n >\r\n Drag here to set row Groups\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <hr class=\"mt-4\" />\r\n\r\n <div class=\"px-3 h-100\">\r\n <div class=\"d-flex gap-3 mb-4\">\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/justify.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n <span>Values</span>\r\n </div>\r\n <div class=\"h-50 d-flex\">\r\n <div\r\n class=\"px-3 py-2 border-dashed h-100 d-flex justify-content-center align-items-center\"\r\n style=\"font-size: 14px\"\r\n >\r\n Drag here aggregate\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<!-- *************************************************** -->\r\n<!-- *************************************************** -->\r\n<!-- *************************************************** -->\r\n<!-- Drag Preview Template -->\r\n<!-- *************************************************** -->\r\n<!-- *************************************************** -->\r\n<ng-template #dragPreview let-col>\r\n <div class=\"p-2 border d-flex gap-2\">\r\n <div>\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrows-move.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n <div>{{ col.header }}</div>\r\n </div>\r\n</ng-template>\r\n\r\n<!-- Drag Placeholder Template -->\r\n<ng-template\r\n #dragPlaceholder\r\n let-col\r\n let-i=\"index\"\r\n let-section=\"section\"\r\n let-draggingInGroupArea=\"draggingInGroupArea\"\r\n>\r\n <div *ngIf=\"!draggingInGroupArea\">\r\n <div\r\n *ngTemplateOutlet=\"\r\n headerCell;\r\n context: { $implicit: col, index: i, section: section }\r\n \"\r\n ></div>\r\n </div>\r\n <div *ngIf=\"draggingInGroupArea\">New Placeholder</div>\r\n</ng-template>\r\n\r\n<!-- Top Group Row Placeholder -->\r\n<ng-template #topGroupingRowPlaceholder let-col let-showChevron=\"showChevron\">\r\n <div class=\"d-flex gap-2\">\r\n <div\r\n class=\"d-flex gap-2 top-row-grouping-placeholder\"\r\n [style.backgroundColor]=\"topGroupedBadgesBackgroundColor\"\r\n >\r\n <span\r\n cdkDragHandle\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/grid-3x2-gap.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n <span>{{ col.header }}</span>\r\n <span\r\n (click)=\"ungroupColumn(col)\"\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/x.svg'\"\r\n class=\"cursor-pointer data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n </div>\r\n <div *ngIf=\"showChevron\" style=\"opacity: 0.6; font-size: 14px\">\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template\r\n #childHeaderPlaceholder\r\n let-col\r\n let-pinnedRight=\"pinnedRight\"\r\n let-i=\"index\"\r\n let-sections=\"sections\"\r\n>\r\n <div\r\n class=\"header-cell one-row-header-cells\"\r\n [class.border-right]=\"showVerticalBorder\"\r\n [style.width.px]=\"col.width\"\r\n [style.min-width.px]=\"col.width\"\r\n [style.min-height.px]=\"headerRowHeight\"\r\n [style.max-height.px]=\"headerRowHeight\"\r\n [style.fontWeight]=\"headerFontWeight\"\r\n >\r\n <div class=\"d-flex justify-content-between h-100 align-items-center w-100\">\r\n <div\r\n class=\"d-flex justify-content-between align-items-center w-100\"\r\n [class.flex-row-reverse]=\"pinnedRight\"\r\n >\r\n <div\r\n class=\"text-ellipsis h-100 d-flex align-items-center\"\r\n [title]=\"col.header\"\r\n [class.w-100]=\"pinnedRight\"\r\n >\r\n {{ col.header }}\r\n </div>\r\n\r\n <div\r\n class=\"position-relative d-flex\"\r\n [class.flex-row-reverse]=\"pinnedRight\"\r\n >\r\n <div class=\"three-dots p-1\" style=\"cursor: pointer\">\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/three-dots-vertical.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n\r\n <div class=\"resize-handle\">\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/resize-handle.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n <div\r\n *ngIf=\"showFilterRow\"\r\n [style.backgroundColor]=\"headerBackgroundColor\"\r\n class=\"header-cell filter-cell\"\r\n [class.border-right]=\"showVerticalBorder\"\r\n [style.width.px]=\"col.width\"\r\n [style.min-width.px]=\"col.width\"\r\n [style.height.px]=\"headerRowHeight\"\r\n [style.min-height.px]=\"headerRowHeight\"\r\n [style.max-height.px]=\"headerRowHeight\"\r\n [class.border-right]=\"showVerticalBorder\"\r\n style=\"grid-row: 3\"\r\n >\r\n <div\r\n class=\"header-cell filter-cell\"\r\n [style.backgroundColor]=\"headerBackgroundColor\"\r\n [style.width.px]=\"col.width\"\r\n [style.min-width.px]=\"col.width\"\r\n [style.height.px]=\"headerRowHeight\"\r\n [style.min-height.px]=\"headerRowHeight\"\r\n [style.max-height.px]=\"headerRowHeight\"\r\n >\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Filter\"\r\n [(ngModel)]=\"col.filterValue\"\r\n [readonly]=\"col?.type == 'dropdown' || col?.type == 'image' || col?.type == 'array'\"\r\n [class.disabled-search-input]=\"\r\n col?.type == 'dropdown' || col?.type == 'image' || col?.type == 'array'\r\n \"\r\n />\r\n <span\r\n class=\"filter-icon-wrapper\"\r\n (click)=\"activeFilterCell = col; activeCol = null\"\r\n ><span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span\r\n ></span>\r\n\r\n <div\r\n class=\"position-absolute\"\r\n *ngIf=\"activeFilterCell === col\"\r\n style=\"top: 100%; right: 0; z-index: 10; left: 0\"\r\n ></div>\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template #tableLayout>\r\n <div\r\n (click)=\"$event.stopPropagation()\"\r\n class=\"p-3 shadow actions-dropdown mt-1 dropdown-menu show shadow custom-menu table-layout\"\r\n style=\"width: 320px\"\r\n >\r\n <div class=\"d-flex align-items-center mb-3\">\r\n <button\r\n class=\"btn btn-link p-0\"\r\n style=\"margin-left: -10px\"\r\n (click)=\"toggleActions('setting')\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrow-left.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n </button>\r\n <h6 class=\"mb-0 ms-2\" style=\"font-weight: 500\">Table Layout</h6>\r\n </div>\r\n <hr class=\"my-2\" />\r\n <div class=\"w-100 mb-3 d-flex\" role=\"group\">\r\n <input\r\n type=\"radio\"\r\n class=\"btn-check layout-button-check\"\r\n name=\"layoutSize\"\r\n id=\"small\"\r\n autocomplete=\"off\"\r\n (change)=\"changeTableLayout($event, 'small')\"\r\n [checked]=\"selectedTableLayout == 'small'\"\r\n />\r\n <label\r\n class=\"border d-flex flex-column align-items-center layout-button\"\r\n for=\"small\"\r\n [ngStyle]=\"{\r\n color: selectedTableLayout == 'small' ? '#000' : '#727272'\r\n }\"\r\n >\r\n <div class=\"preview-box border mb-1\" style=\"height: 8px\"></div>\r\n Small\r\n </label>\r\n\r\n <input\r\n type=\"radio\"\r\n class=\"btn-check layout-button-check\"\r\n name=\"layoutSize\"\r\n id=\"medium\"\r\n autocomplete=\"off\"\r\n [checked]=\"selectedTableLayout == 'medium'\"\r\n (change)=\"changeTableLayout($event, 'medium')\"\r\n />\r\n <label\r\n class=\"border mx-3 d-flex flex-column align-items-center layout-button\"\r\n for=\"medium\"\r\n [ngStyle]=\"{\r\n color: selectedTableLayout == 'medium' ? '#000' : '#727272'\r\n }\"\r\n >\r\n <div class=\"preview-box border mb-1\" style=\"height: 12px\"></div>\r\n Medium\r\n </label>\r\n\r\n <input\r\n type=\"radio\"\r\n class=\"btn-check layout-button-check\"\r\n name=\"layoutSize\"\r\n id=\"large\"\r\n autocomplete=\"off\"\r\n (change)=\"changeTableLayout($event, 'large')\"\r\n [checked]=\"selectedTableLayout == 'large'\"\r\n />\r\n <label\r\n class=\"border d-flex flex-column align-items-center layout-button\"\r\n for=\"large\"\r\n [ngStyle]=\"{\r\n color: selectedTableLayout == 'large' ? '#000' : '#727272'\r\n }\"\r\n >\r\n <div class=\"preview-box border mb-1\" style=\"height: 16px\"></div>\r\n Large\r\n </label>\r\n </div>\r\n\r\n <hr class=\"my-2\" />\r\n <div class=\"d-flex justify-content-between align-items-center mb-2\">\r\n <span>Show separators</span>\r\n <div class=\"form-check form-switch m-0\">\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n id=\"separators\"\r\n [(ngModel)]=\"showVerticalBorder\"\r\n (change)=\"onFontChange()\"\r\n />\r\n </div>\r\n </div>\r\n <div class=\"d-flex justify-content-between align-items-center\">\r\n <span>Row shading</span>\r\n <div class=\"form-check form-switch m-0\">\r\n <input\r\n class=\"form-check-input\"\r\n [(ngModel)]=\"rowShadingEnabled\"\r\n (change)=\"toggleRowShading()\"\r\n type=\"checkbox\"\r\n id=\"rowShading\"\r\n />\r\n </div>\r\n </div>\r\n <!-- <div class=\"d-flex justify-content-between align-items-center mb-2\">\r\n <span>Show Side Menu</span>\r\n <div class=\"form-check form-switch m-0\">\r\n <input\r\n class=\"form-check-input\"\r\n [(ngModel)]=\"showSideMenu\"\r\n type=\"checkbox\"\r\n id=\"rowShading\"\r\n />\r\n </div>\r\n </div>\r\n <div class=\"d-flex justify-content-between align-items-center mb-2\">\r\n <span>Show Filter Row</span>\r\n <div class=\"form-check form-switch m-0\">\r\n <input\r\n class=\"form-check-input\"\r\n [(ngModel)]=\"showFilterRow\"\r\n type=\"checkbox\"\r\n id=\"rowShading\"\r\n />\r\n </div>\r\n </div> -->\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template #tablePreset>\r\n <div\r\n *ngIf=\"activeSubButton !== 'save-preset'\"\r\n (click)=\"$event.stopPropagation()\"\r\n class=\"p-3 shadow actions-dropdown mt-1 dropdown-menu show shadow custom-menu table-layout\"\r\n style=\"width: 280px\"\r\n >\r\n <!-- Header -->\r\n <div class=\"d-flex justify-content-between align-items-center mb-3\">\r\n <div class=\"d-flex align-items-center\">\r\n <button\r\n class=\"btn btn-link p-0\"\r\n style=\"margin-left: -10px\"\r\n (click)=\"toggleActions('setting')\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrow-left.svg'\"\r\n class=\"data-grid-svg-icon\"\r\n ></span>\r\n </button>\r\n <h6 class=\"mb-0 ms-2\" style=\"font-weight: 500\">Table Presets</h6>\r\n </div>\r\n <!-- Save Preset Button with Dropdown -->\r\n <div>\r\n <a\r\n class=\"text-decoration-none text-primary\"\r\n type=\"button\"\r\n id=\"savePresetDropdown\"\r\n (click)=\"$event.stopPropagation(); toggleSubActions('save-preset')\"\r\n >\r\n {{ isTablePresetNotChanged ? \"Save preset\" : \"Update Preset\" }}\r\n </a>\r\n </div>\r\n </div>\r\n\r\n <!-- Search -->\r\n <div class=\"mb-3\">\r\n <div class=\"col-12 global-search\">\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/search.svg'\"\r\n class=\"data-grid-svg-icon mx-2 position-absolute icon\"\r\n ></span>\r\n <input\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Search...\"\r\n [(ngModel)]=\"searchTextPresetTable\"\r\n type=\"search\"\r\n />\r\n </div>\r\n </div>\r\n\r\n <!-- Preset List -->\r\n <ng-container\r\n *ngIf=\"\r\n tableView | filter : searchTextPresetTable : 'name' as filteredList\r\n \"\r\n >\r\n <!-- If filteredList exists and none is default -> show fallback -->\r\n <div\r\n class=\" pb-5 overflow-auto\"\r\n [style.maxHeight.px]=\"dataGridContainer.offsetHeight - 250\"\r\n >\r\n <div\r\n class=\"cursor-pointer\"\r\n (click)=\"\r\n clearAllFilters(true);\r\n openIndex = null;\r\n temp_state.id = '';\r\n activeTopButton = '';\r\n curretaTablePresetForUpdate = null\r\n \"\r\n >\r\n <div class=\"fw-semibold\">Default View</div>\r\n </div>\r\n <div class=\"d-flex justify-content-between\">\r\n <small class=\"text-dark\">Created by system</small>\r\n <span\r\n *ngIf=\"!tableFilterViewId && !hasAnyDefaultView()\"\r\n class=\"badge bg-light text-primary ms-2\"\r\n >Default</span\r\n >\r\n <!-- <span\r\n *ngIf=\"!tableFilterViewId && !hasAnyDefaultView()\"\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/check-blue.svg'\"\r\n class=\"me-2\"\r\n ></span> -->\r\n <div\r\n class=\"dropdown d-flex justify-content-end\"\r\n *ngIf=\"tableFilterViewId\"\r\n ></div>\r\n </div>\r\n\r\n <!-- The list: render each table from filteredList -->\r\n <div\r\n class=\"list-group list-group-flush\"\r\n *ngFor=\"\r\n let table of filteredList;\r\n let i = index;\r\n trackBy: trackByTable\r\n \"\r\n >\r\n <!-- Item -->\r\n <div\r\n (click)=\"\r\n $event.stopPropagation(); openIndex = null; activeTopButton = ''\r\n \"\r\n class=\"list-group-item px-0 d-flex justify-content-between align-items-center\"\r\n >\r\n <div (click)=\"selectFilter(table); openIndex = null\">\r\n <div class=\"fw-semibold\" style=\"cursor: pointer\">\r\n {{ table?.name }}\r\n <!-- {{table?.is_temp}} -->\r\n <span\r\n *ngIf=\"\r\n (table?.is_temp && !temp_state.id) ||\r\n temp_state.id == table.id\r\n \"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/check-blue.svg'\r\n \"\r\n class=\"me-2\"\r\n ></span>\r\n <span\r\n *ngIf=\"table?.is_default\"\r\n class=\"badge bg-light text-primary ms-2\"\r\n >Default</span\r\n >\r\n </div>\r\n <small class=\"text-dark\" *ngIf=\"table?.config?.filterNames\" [title]=\"table?.config?.filterNames\">\r\n {{\r\n table?.config?.filterNames?.length > 25\r\n ? (table?.config?.filterNames | slice:0:25) + '...'\r\n : table?.config?.filterNames\r\n }}\r\n ({{ table?.config?.totalCount }})\r\n </small>\r\n <small class=\"text-dark\" *ngIf=\"!table?.config?.filterNames\">{{ table?.createdAt | date : \"MMM d, y\" }}</small>\r\n </div>\r\n\r\n <div class=\"d-flex align-items-center\">\r\n <span\r\n *ngIf=\"table?.is_default\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/check-blue.svg'\r\n \"\r\n class=\"me-2\"\r\n ></span>\r\n\r\n <div class=\"dropdown\" *ngIf=\"!table?.is_default\">\r\n <div\r\n class=\"dropdown-wrapper\"\r\n (click)=\"$event.stopPropagation()\"\r\n >\r\n <button\r\n type=\"button\"\r\n class=\"btn-icon muted-text\"\r\n (click)=\"toggleMenu(i, $event)\"\r\n aria-haspopup=\"true\"\r\n [attr.aria-expanded]=\"openIndex === i\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath +\r\n 'data-grid/icons/horizontal-dots.svg'\r\n \"\r\n class=\"me-2\"\r\n ></span>\r\n </button>\r\n\r\n <!-- menu -->\r\n <ul\r\n *ngIf=\"openIndex === i\"\r\n class=\"custom-dropdown-menu position-fixed top-auto\"\r\n role=\"menu\"\r\n [style.right.px]=\"'unset'\"\r\n [style.left.px]=\"dataGridContainer.offsetWidth - 200\"\r\n style=\"top: unset; right: unset\"\r\n >\r\n <li role=\"none\">\r\n <button\r\n role=\"menuitem\"\r\n class=\"dropdown-item\"\r\n (click)=\"\r\n actionPreset(table, 'setPreset'); temp_state.id = ''\r\n \"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/star.svg'\r\n \"\r\n class=\"me-2\"\r\n ></span>\r\n Set as default\r\n </button>\r\n </li>\r\n\r\n <li role=\"none\" *ngIf=\"!table.confirmDelete\">\r\n <button\r\n role=\"menuitem\"\r\n class=\"dropdown-item text-danger\"\r\n (click)=\"table.confirmDelete = true\"\r\n >\r\n <span\r\n style=\"margin-top: -4px\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath +\r\n 'data-grid/icons/trash-red.svg'\r\n \"\r\n class=\"me-2\"\r\n ></span>\r\n Delete\r\n </button>\r\n </li>\r\n\r\n <li\r\n role=\"none\"\r\n *ngIf=\"table.confirmDelete\"\r\n class=\"confirm-block\"\r\n >\r\n <div class=\"px-3 py-2 text-center\">\r\n <div class=\"mb-2\">\r\n Are you sure you want to delete <br /><b\r\n >\u201C{{ table?.name }}\u201D</b\r\n >?\r\n </div>\r\n <div class=\"d-flex gap-2\">\r\n <button\r\n class=\"btn btn-sm btn-light me-2\"\r\n (click)=\"table.confirmDelete = false\"\r\n >\r\n Cancel\r\n </button>\r\n <button\r\n class=\"btn btn-sm btn-danger\"\r\n (click)=\"actionPreset(table, 'deletePreset')\"\r\n >\r\n Delete\r\n </button>\r\n </div>\r\n </div>\r\n </li>\r\n </ul>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n <!-- Item End Here -->\r\n </div>\r\n </div>\r\n </ng-container>\r\n </div>\r\n\r\n <div\r\n (click)=\"$event.stopPropagation()\"\r\n *ngIf=\"activeSubButton == 'save-preset'\"\r\n class=\"dropdown-menu p-3 badge mt-4 save-preset-dropdown mt-1\"\r\n aria-labelledby=\"savePresetDropdown\"\r\n style=\"min-width: 250px\"\r\n >\r\n <div class=\"fw-bold fs-14px mb-2\">\r\n {{ isTablePresetNotChanged ? \"Save preset\" : \"Update Preset\" }}\r\n </div>\r\n <div class=\"fs-14px mb-2\" style=\"line-height: 20px\">\r\n This will save the current table adjustments as a preset.\r\n </div>\r\n <!-- Input -->\r\n <div class=\"mb-2\">\r\n <label for=\"presetName\" class=\"form-label fs-12px fw-bold\"\r\n >Preset Name</label\r\n >\r\n <div class=\"col-12 global-search\">\r\n <input\r\n #presetNameCtrl=\"ngModel\"\r\n required\r\n [(ngModel)]=\"presetName\"\r\n [ngClass]=\"{\r\n 'is-invalid':\r\n presetNameCtrl.invalid &&\r\n (presetNameCtrl.dirty || presetNameCtrl.touched)\r\n }\"\r\n class=\"form-control form-control-sm ps-2\"\r\n placeholder=\"Enter preset name\"\r\n type=\"text\"\r\n />\r\n </div>\r\n </div>\r\n\r\n <!-- Checkbox -->\r\n <div class=\"form-check mb-2\">\r\n <input\r\n class=\"form-check-input\"\r\n [(ngModel)]=\"presetFilter\"\r\n type=\"checkbox\"\r\n id=\"saveFilters\"\r\n />\r\n <label class=\"form-check-label mt-1\" for=\"saveFilters\">\r\n Save active filters\r\n </label>\r\n </div>\r\n\r\n <!-- Save Button -->\r\n <div class=\"d-flex justify-content-center gap-2\" style=\"height: 32px\">\r\n <button\r\n type=\"button\"\r\n style=\"height: 32px\"\r\n class=\"btn border w-100 d-flex align-items-center justify-content-center btn-light\"\r\n (click)=\"$event.stopPropagation(); toggleActions('table-presets')\"\r\n style=\"margin-top: -2px\"\r\n >\r\n <span>Cancel</span>\r\n </button>\r\n <button\r\n [disabled]=\"closeDropdown.preset.loading\"\r\n (click)=\"savePreset(presetNameCtrl)\"\r\n type=\"button\"\r\n style=\"height: 32px\"\r\n class=\"btn btn-primary w-100 d-flex align-items-center justify-content-center\"\r\n >\r\n <span style=\"margin-top: -2px\" *ngIf=\"isTablePresetNotChanged\">\r\n <ng-container *ngIf=\"!closeDropdown.preset.loading\"\r\n >Save</ng-container\r\n >\r\n <ng-container *ngIf=\"closeDropdown.preset.loading\"\r\n ><span class=\"spinner-border spinner-border-sm\"></span\r\n ></ng-container>\r\n </span>\r\n <span style=\"white-space: nowrap\" *ngIf=\"!isTablePresetNotChanged\"\r\n >Update Preset</span\r\n >\r\n </button>\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template #showHideColumns>\r\n <div\r\n (click)=\"$event.stopPropagation()\"\r\n class=\"p-3 shadow actions-dropdown mt-1 dropdown-menu show shadow custom-menu table-layout\"\r\n style=\"width: 280px\"\r\n >\r\n <!-- Header -->\r\n <div class=\"d-flex justify-content-between align-items-center mb-3\">\r\n <div class=\"d-flex align-items-center\">\r\n <button\r\n class=\"btn btn-link p-0\"\r\n style=\"margin-left: -10px\"\r\n (click)=\"toggleActions('setting')\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrow-left.svg'\"\r\n class=\"data-grid-svg-icon\"\r\n ></span>\r\n </button>\r\n <h6 class=\"mb-0 ms-2\" style=\"font-weight: 500\">Columns</h6>\r\n </div>\r\n <a\r\n (click)=\"resetColumns()\"\r\n href=\"javascript:void(0)\"\r\n class=\"text-primary text-decoration-none d-none\"\r\n >Reset</a\r\n >\r\n </div>\r\n\r\n <!-- Search -->\r\n <div class=\"mb-3\">\r\n <div class=\"col-12 global-search\">\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/search.svg'\"\r\n class=\"mx-2 position-absolute icon data-grid-svg-icon\"\r\n ></span>\r\n <input\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Search column\"\r\n type=\"search\"\r\n [(ngModel)]=\"topShowHideColumns\"\r\n />\r\n </div>\r\n </div>\r\n <!-- Preset List -->\r\n <div\r\n class=\"list-group list-group-flush\"\r\n style=\"overflow: auto; scrollbar-width: thin\"\r\n [style.maxHeight.px]=\"dataGridContainer.offsetHeight - 220\"\r\n >\r\n <div class=\"muted-text show-hide-table-label d-flex justify-content-between\" *ngIf=\"hasAnyVisibleColumn\">\r\n Show in table\r\n <div class=\"form-check\">\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n id=\"hide_all\"\r\n [checked]=\"allColumnsSelected()\"\r\n (change)=\"toggleAllColumnsVisibility()\"\r\n />\r\n <label class=\"form-check-label fw-semibold\" for=\"hide_all\">\r\n Show/Hide All \r\n </label>\r\n </div>\r\n </div>\r\n <!-- Item -->\r\n <ng-container\r\n *ngFor=\"\r\n let col of columns | filter : topShowHideColumns : 'header';\r\n trackBy: trackByField\r\n \"\r\n >\r\n <div\r\n *ngIf=\"col.is_visible\"\r\n class=\"list-group-item border-0 px-0 d-flex justify-content-between align-items-center\"\r\n >\r\n <div class=\"d-flex gap-1\">\r\n <div>\r\n <span\r\n *ngIf=\"!col?.pinned\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/grip-vertical.svg'\r\n \"\r\n class=\"cursor-grap data-grid-svg-icon\"\r\n (mousedown)=\"$event.preventDefault()\"\r\n ></span>\r\n <span\r\n *ngIf=\"col?.pinned\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/pin-blue.svg'\r\n \"\r\n class=\"cursor-grap data-grid-svg-icon\"\r\n (mousedown)=\"$event.preventDefault()\"\r\n ></span>\r\n </div>\r\n <div class=\"fw-semibold\">\r\n {{ col.header }}\r\n </div>\r\n </div>\r\n <div\r\n *ngIf=\"!col?.query?.first_value && !col?.query?._ids?.length\"\r\n class=\"d-flex align-items-center cursor-pointer\"\r\n (click)=\"toggleColumnVisibility(col, false)\"\r\n [class.disabled]=\"visibleColumns().length <= 2 || col?.is_always_visible\"\r\n [class.pe-none]=\"visibleColumns().length <= 2 || col?.is_always_visible\"\r\n [class.opacity-50]=\"visibleColumns().length <= 2 || col?.is_always_visible\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/eye.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n </div>\r\n <div\r\n *ngIf=\"col?.query?.first_value || col?.query?._ids?.length\"\r\n class=\"d-flex align-items-center\"\r\n style=\"opacity: 0.5\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/eye.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n </div>\r\n </div>\r\n </ng-container>\r\n\r\n <!-- Item End Here -->\r\n\r\n <div\r\n class=\"dropdown-divider\"\r\n *ngIf=\"hasAnyVisibleColumn && hasAnyInVisibleColumn\"\r\n ></div>\r\n\r\n <div\r\n class=\"muted-text show-hide-table-label d-flex justify-content-between\"\r\n *ngIf=\"hasAnyInVisibleColumn\"\r\n >\r\n Hide in table\r\n <div class=\"form-check\">\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n id=\"show_all\"\r\n [checked]=\"allColumnsSelected()\"\r\n (change)=\"toggleAllColumnsVisibility()\"\r\n />\r\n <label class=\"form-check-label fw-semibold\" for=\"show_all\">\r\n Show/Hide All \r\n </label>\r\n </div>\r\n </div>\r\n <div class=\"list-group list-group-flush\">\r\n <ng-container *ngFor=\"let col of columns | filter : topShowHideColumns : 'header'; trackBy: trackByField\">\r\n <div\r\n *ngIf=\"!col.is_visible\"\r\n class=\"list-group-item border-0 px-0 d-flex justify-content-between align-items-center\"\r\n >\r\n <div class=\"d-flex gap-1\">\r\n <div>\r\n <span\r\n *ngIf=\"!col?.pinned\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/grip-vertical.svg'\r\n \"\r\n class=\"data-grid-svg-icon cursor-grap\"\r\n (mousedown)=\"$event.preventDefault()\"\r\n ></span>\r\n <span\r\n *ngIf=\"col?.pinned\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/pin-blue.svg'\r\n \"\r\n class=\"data-grid-svg-icon cursor-grap\"\r\n (mousedown)=\"$event.preventDefault()\"\r\n ></span>\r\n </div>\r\n <div class=\"fw-semibold\">\r\n {{ col.header }}\r\n </div>\r\n </div>\r\n <div\r\n class=\"d-flex align-items-center cursor-pointer\"\r\n (click)=\"toggleColumnVisibility(col, true)\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/eye-cross.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n </div>\r\n </div>\r\n </ng-container>\r\n </div>\r\n\r\n <!-- Item End Here -->\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template #filterColumns let-col=\"column\">\r\n <div\r\n @slideToggle\r\n *ngIf=\"!isFilterOpen && activeTopButton == 'filter-columns'\"\r\n (click)=\"$event.stopPropagation()\"\r\n class=\"shadow actions-dropdown mt-1 show shadow custom-menu table-layout filter-columns\"\r\n style=\"width: 280px; right: unset; max-width: 230px\"\r\n [style.backgroundColor]=\"checkboxesBackgroundColor\"\r\n >\r\n <div class=\"mb-2 px-3\">\r\n <div class=\"col-12 global-search\">\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/search.svg'\"\r\n class=\"data-grid-svg-icon mx-2 position-absolute icon\"\r\n ></span>\r\n <input\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Filter by\"\r\n type=\"search\"\r\n [(ngModel)]=\"addFilterColumnInput\"\r\n />\r\n </div>\r\n </div>\r\n <div\r\n class=\"list-group list-group-flush\"\r\n style=\"max-height: calc(100vh - 500px); overflow: auto\"\r\n >\r\n <ng-container\r\n *ngFor=\"\r\n let col of columns | filter : addFilterColumnInput : 'header';\r\n trackBy: trackByField\r\n \"\r\n >\r\n <div\r\n (click)=\"openFilter(col)\"\r\n *ngIf=\"\r\n col.is_visible &&\r\n !col?.query?.first_value &&\r\n !col?.query?._ids?.length && col?.type !== 'image' && col.is_search_able\r\n \"\r\n class=\"list-group-item border-0 px-0 d-flex justify-content-between align-items-center dropdown-item cursor-pointer\"\r\n >\r\n <div class=\"d-flex gap-1\">\r\n <div style=\"margin-top: -3px\"></div>\r\n <div class=\"fw-semibold\">\r\n {{ col.header }}\r\n </div>\r\n </div>\r\n </div>\r\n </ng-container>\r\n </div>\r\n </div>\r\n\r\n <!-- Dropdown -->\r\n <div\r\n @slideToggle\r\n *ngIf=\"isFilterOpen && selectedColumnForFilter?.type == 'dropdown' || selectedColumnForFilter?.type == 'array'\"\r\n (click)=\"$event.stopPropagation()\"\r\n class=\"shadow actions-dropdown mt-1 show shadow custom-menu table-layout filter-columns pb-2\"\r\n style=\"width: 280px; right: unset; max-width: 230px\"\r\n [style.backgroundColor]=\"checkboxesBackgroundColor\"\r\n >\r\n <div class=\"px-3 my-2 border-below py-1 pb-2 mb-3 d-flex ps-1\">\r\n <span\r\n (click)=\"toggleActions('filter-columns'); isActiveFilterOpen = false\"\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrow-left.svg'\"\r\n class=\"data-grid-svg-icon me-2 cursor-pointer\"\r\n ></span\r\n ><b>{{ selectedColumnForFilter?.header }}</b>\r\n </div>\r\n <div class=\"mb-2 px-3\">\r\n <div\r\n class=\"col-12 global-search position-relative border rounded d-flex align-items-center flex-wrap px-2 filter-serach-inpt\"\r\n >\r\n <span\r\n *ngFor=\"let selected of selectedFilterOptions\"\r\n class=\"badge d-flex align-items-center gap-1 me-1 mb-1 top-row-filter-dropdown\"\r\n >\r\n {{ selected?.value ? selected.value : selected }}\r\n <span\r\n (click)=\"toggleSelectionInFilter(selected)\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/cross-primary.svg'\r\n \"\r\n class=\"me-2\"\r\n ></span>\r\n </span>\r\n <input\r\n class=\"form-control form-control-sm border-0 flex-grow-1\"\r\n style=\"padding: 0\"\r\n [placeholder]=\"selectedFilterOptions?.length ? '' : 'Filter by'\"\r\n type=\"search\"\r\n [(ngModel)]=\"searchTextForFilterDropDown\"\r\n (keydown.backspace)=\"handleBackspace($event)\"\r\n />\r\n </div>\r\n </div>\r\n <div\r\n class=\"list-group list-group-flush\"\r\n style=\"max-height: calc(100vh - 600px); overflow: auto\"\r\n >\r\n <ng-container\r\n *ngFor=\"\r\n let col of selectedColumnForFilter.column_dropdown_value\r\n | filter : searchTextForFilterDropDown : 'value';\r\n let i = index\r\n \"\r\n >\r\n <div\r\n class=\"list-group-item border-0 px-2 d-flex justify-content-between align-items-center dropdown-item cursor-pointer\"\r\n >\r\n <div class=\"form-check\">\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n [id]=\"i\"\r\n [checked]=\"currentFilterSelectedIds.has(col.id || col._id || col)\"\r\n (change)=\"toggleSelectionInFilter(col)\"\r\n />\r\n <label class=\"form-check-label fw-semibold\" [for]=\"i\">\r\n {{ col?.value || col?.name || col }}\r\n </label>\r\n </div>\r\n </div>\r\n </ng-container>\r\n </div>\r\n <div\r\n class=\"d-flex justify-content-center gap-2 px-2 border-top\"\r\n style=\"height: 38px\"\r\n >\r\n <button\r\n type=\"button\"\r\n style=\"height: 32px\"\r\n class=\"btn btn-outline-secondary btn-light border w-100 d-flex align-items-center justify-content-center mt-1 btn-light\"\r\n (click)=\"$event.stopPropagation(); resetFilterChanges()\"\r\n >\r\n <span>Cancel</span>\r\n </button>\r\n <button\r\n type=\"button\"\r\n style=\"height: 32px\"\r\n class=\"btn btn-primary w-100 d-flex align-items-center justify-content-center mt-1\"\r\n (click)=\"applyDropdownFilter()\"\r\n >\r\n <span style=\"margin-top: -2px\">Save</span>\r\n </button>\r\n </div>\r\n </div>\r\n\r\n <!-- For Text fields and number fields-->\r\n\r\n <div\r\n @slideToggle\r\n *ngIf=\"\r\n isFilterOpen &&\r\n (selectedColumnForFilter?.type == 'string' ||\r\n selectedColumnForFilter?.type == 'number' ||\r\n selectedColumnForFilter?.type == 'time' ||\r\n selectedColumnForFilter?.type == 'date')\r\n \"\r\n (click)=\"$event.stopPropagation()\"\r\n class=\"shadow actions-dropdown mt-1 show shadow custom-menu table-layout filter-columns pb-2\"\r\n style=\"width: 210px; right: unset; max-width: 230px\"\r\n [style.backgroundColor]=\"checkboxesBackgroundColor\"\r\n >\r\n <div class=\"px-3 border-below py-1 pb-2 d-flex ps-1\">\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrow-left.svg'\"\r\n (click)=\"toggleActions('filter-columns'); isActiveFilterOpen = false\"\r\n class=\"data-grid-svg-icon me-2 cursor-pointer\"\r\n ></span\r\n ><b>{{ selectedColumnForFilter?.header }}</b>\r\n </div>\r\n <div class=\"col-12 position-relative p-2 text-filter\">\r\n <div class=\"mb-2\">\r\n <select\r\n class=\"form-select form-select-sm custom-select border\"\r\n [(ngModel)]=\"firstCondition\"\r\n >\r\n <ng-container *ngIf=\"selectedColumnForFilter?.type == 'string'\">\r\n <option value=\"contain\">Contains</option>\r\n <option value=\"does_not_contain\">Does Not Contain</option>\r\n <option value=\"equal\">Equals</option>\r\n <option value=\"before\">Starts With</option>\r\n <option value=\"after\">Ends With</option>\r\n </ng-container>\r\n\r\n <ng-container *ngIf=\"selectedColumnForFilter?.type == 'date' || selectedColumnForFilter?.type == 'time'\">\r\n <option value=\"equal\">Equals To</option>\r\n <option value=\"not_equal\">Not Equal</option>\r\n <option value=\"after\">After</option>\r\n <option value=\"before\">Before</option>\r\n </ng-container>\r\n\r\n <ng-container *ngIf=\"selectedColumnForFilter?.type == 'number'\">\r\n <option value=\"equal\">Equals To</option>\r\n <option value=\"before\">Less Then </option>\r\n <option value=\"after\">Greater Then </option>\r\n <option value=\"less_then_equal\">less then Equal to</option>\r\n <option value=\"greater_then_equal\">Greater then Equal to </option>\r\n </ng-container>\r\n </select>\r\n </div>\r\n <div class=\"mb-2\">\r\n <input\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Enter first value\"\r\n type=\"search\"\r\n [type]=\"\r\n selectedColumnForFilter?.type == 'string'\r\n ? 'text'\r\n : selectedColumnForFilter?.type\r\n \"\r\n [(ngModel)]=\"firstValue\"\r\n (keydown.enter)=\"applyDropdownFilter()\"\r\n />\r\n </div>\r\n <div>\r\n <div class=\"d-flex my-3 d-flex flex-row\" style=\"font-size: 14px\">\r\n <div\r\n class=\"form-check form-check-inline col-4 m-0 d-flex align-items-center gap-1\"\r\n >\r\n <input\r\n class=\"form-check-input\"\r\n type=\"radio\"\r\n id=\"logicalAnd\"\r\n name=\"logicalOperator\"\r\n value=\"and\"\r\n [(ngModel)]=\"condition\"\r\n />\r\n <label class=\"form-check-label mb-0 mt-1\" for=\"logicalAnd\"\r\n >AND</label\r\n >\r\n </div>\r\n\r\n <div\r\n class=\"form-check form-check-inline col-4 m-0 d-flex align-items-center gap-1\"\r\n >\r\n <input\r\n class=\"form-check-input\"\r\n type=\"radio\"\r\n id=\"logicalOr\"\r\n name=\"logicalOperator\"\r\n value=\"or\"\r\n [(ngModel)]=\"condition\"\r\n />\r\n <label class=\"form-check-label mb-0 mt-1\" for=\"logicalOr\">OR</label>\r\n </div>\r\n\r\n <div\r\n class=\"form-check form-check-inline col-4 m-0 d-flex align-items-center gap-1\"\r\n >\r\n <input\r\n class=\"form-check-input\"\r\n type=\"radio\"\r\n id=\"logicalNone\"\r\n name=\"logicalOperator\"\r\n value=\"none\"\r\n [(ngModel)]=\"condition\"\r\n />\r\n <label class=\"form-check-label mb-0 mt-1\" for=\"logicalNone\"\r\n >None</label\r\n >\r\n </div>\r\n </div>\r\n\r\n <ng-container *ngIf=\"condition !== 'none' && firstValue\">\r\n <div class=\"mb-2 mt-3\">\r\n <!-- Second condition select -->\r\n <select\r\n class=\"form-select form-select-sm border\"\r\n [(ngModel)]=\"secondCondition\"\r\n >\r\n <ng-container *ngIf=\"selectedColumnForFilter?.type == 'string'\">\r\n <option value=\"contain\">Contains</option>\r\n <option value=\"does_not_contain\">Does Not Contain</option>\r\n <option value=\"equal\">Equals</option>\r\n <option value=\"before\">Starts With</option>\r\n <option value=\"after\">Ends With</option>\r\n </ng-container>\r\n\r\n <ng-container *ngIf=\"selectedColumnForFilter?.type == 'date' || selectedColumnForFilter?.type == 'time'\">\r\n <option value=\"equal\">Equals To</option>\r\n <option value=\"not_equal\">Not Equal</option>\r\n <option value=\"after\">After</option>\r\n <option value=\"before\">Before</option>\r\n </ng-container>\r\n <ng-container *ngIf=\"selectedColumnForFilter?.type == 'number'\">\r\n <option value=\"equal\">Equals To</option>\r\n <option value=\"before\">Less Then </option>\r\n <option value=\"after\">Greater Then </option>\r\n <option value=\"less_then_equal\">less then Equal to</option>\r\n <option value=\"greater_then_equal\">Greater then Equal to </option>\r\n </ng-container>\r\n </select>\r\n </div>\r\n\r\n <div class=\"mb-2\">\r\n <!-- Second value input -->\r\n <input\r\n [type]=\"\r\n selectedColumnForFilter?.type == 'string'\r\n ? 'text'\r\n : selectedColumnForFilter?.type\r\n \"\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Enter second value\"\r\n type=\"search\"\r\n [(ngModel)]=\"secondValue\"\r\n (keydown.enter)=\"applyDropdownFilter()\"\r\n />\r\n </div>\r\n </ng-container>\r\n </div>\r\n </div>\r\n\r\n <div\r\n class=\"d-flex justify-content-center gap-2 px-2 border-top\"\r\n style=\"height: 38px\"\r\n >\r\n <button\r\n [disabled]=\"!currentFilterSelectedIds?.size && !firstValue\"\r\n type=\"button\"\r\n style=\"height: 32px\"\r\n class=\"btn btn-outline-secondary btn-light border w-100 d-flex align-items-center justify-content-center mt-1 btn-light\"\r\n (click)=\"$event.stopPropagation(); resetTextFilterChanges()\"\r\n >\r\n <span>Cancel</span>\r\n </button>\r\n <button\r\n [disabled]=\"(currentFilterSelectedIds?.size === 0 && !firstValue) || (condition !== 'none' && !secondValue)\"\r\n type=\"button\"\r\n style=\"height: 32px\"\r\n class=\"btn btn-primary w-100 d-flex align-items-center justify-content-center mt-1\"\r\n (click)=\"applyDropdownFilter()\"\r\n >\r\n <span style=\"margin-top: -2px\">Apply</span>\r\n </button>\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<!-- Edit dropdown here -->\r\n<ng-template let-col>\r\n <div class=\"drop-down-edit\"></div>\r\n</ng-template>\r\n\r\n<ng-template\r\n #fullTextTemplate\r\n let-row=\"row\"\r\n let-col=\"col\"\r\n let-isArray=\"isArray\"\r\n>\r\n <div\r\n class=\"full-text-box\"\r\n (dblclick)=\"$event.stopPropagation(); $event.preventDefault()\"\r\n (click)=\"$event.stopPropagation(); $event.preventDefault()\"\r\n [style.maxHeight.px]=\"dataGridContainer.offsetHeight / 2\"\r\n >\r\n <ng-container *ngIf=\"!isEditing(row, col)\">\r\n <div\r\n *ngIf=\"!isArray\"\r\n class=\"full-text-content\"\r\n [style.maxHeight.px]=\"dataGridContainer.offsetHeight / 2\"\r\n (dblclick)=\"\r\n $event.stopPropagation();\r\n $event.preventDefault();\r\n enableEdit(row, col, true)\r\n \"\r\n (click)=\"$event.stopPropagation(); $event.preventDefault()\"\r\n >\r\n {{\r\n getNestedValue(row, col.field)?.value ||\r\n getNestedValue(row, col.field)?.name ||\r\n getNestedValue(row, col.field)\r\n }}\r\n </div>\r\n <div *ngIf=\"isArray\">\r\n <ul>\r\n <ng-container\r\n *ngFor=\"let item of getNestedValue(row, col.field); let i = index\"\r\n >\r\n <li *ngIf=\"i !== 0\">\r\n <ng-container>\r\n {{\r\n item?.department_name ||\r\n item?.roleName ||\r\n item?.full_name ||\r\n \"-\"\r\n }}\r\n </ng-container>\r\n </li>\r\n </ng-container>\r\n </ul>\r\n </div>\r\n </ng-container>\r\n <ng-container *ngIf=\"isEditing(row, col)\">\r\n <textarea\r\n (dblclick)=\"\r\n $event.stopPropagation();\r\n $event.preventDefault();\r\n enableEdit(row, col, true)\r\n \"\r\n #textModel=\"ngModel\"\r\n rows=\"4\"\r\n #textAreadInput\r\n [(ngModel)]=\"row[col.field]\"\r\n name=\"{{ col.field }}\"\r\n required\r\n (blur)=\"disableEdit(row, col, textModel)\"\r\n (keydown.enter)=\"textAreadInput.blur()\"\r\n autofocus\r\n class=\"form-control\"\r\n [ngClass]=\"{\r\n 'is-invalid': textModel.invalid\r\n }\"\r\n (mousedown)=\"$event.stopPropagation()\"\r\n ></textarea>\r\n </ng-container>\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template #defaultImagePlaceholder let-row=\"row\" let-col=\"col\">\r\n <span\r\n class=\"px-2 d-flex w-100 cell-content image-placeholder\"\r\n [title]=\"row?.full_name || row?.name || 'N/A'\"\r\n >\r\n <ng-container\r\n *ngIf=\"\r\n row?.logo ||\r\n row?.assetImage ||\r\n row?.invoice?.invoice_image ||\r\n row?.invoice_image;\r\n else placeholder\r\n \"\r\n >\r\n <span\r\n (click)=\"fullscreenImage = row?.profile_pictures?.[4]?.path ||\r\n row?.logo ||\r\n row?.assetImage ||\r\n row?.invoice_image\"\r\n class=\"pic\"\r\n [style.width.px]=\"rowHeight - 10\"\r\n [style.height.px]=\"rowHeight - 10\"\r\n [class.assets-pic]=\"gridType == 'Assets'\"\r\n >\r\n <img\r\n [width]=\"rowHeight - 12\"\r\n [height]=\"rowHeight - 12\"\r\n [style.width.px]=\"rowHeight - 10\"\r\n [style.height.px]=\"rowHeight - 10\"\r\n [src]=\"\r\n row?.profile_pictures?.[4]?.path ||\r\n row?.logo ||\r\n row?.assetImage ||\r\n row?.invoice_image\r\n \"\r\n alt=\"icon\"\r\n class=\"option-icon\"\r\n loading=\"lazy\"\r\n />\r\n </span>\r\n </ng-container>\r\n <!-- <div\r\n class=\"fullscreen-overlay\"\r\n *ngIf=\"fullscreenImage\"\r\n (click)=\"fullscreenImage = null\"\r\n >\r\n <img [src]=\"fullscreenImage\" class=\"fullscreen-img\" />\r\n </div> -->\r\n\r\n <ng-template #placeholder>\r\n <span\r\n [ngClass]=\"getDynamicClass(row?.full_name || row?.name)\"\r\n class=\"pic d-flex align-items-center rounded-circle\"\r\n [style.width.px]=\"rowHeight - 12\"\r\n [style.height.px]=\"rowHeight - 12\"\r\n [style.fontSize.px]=\"rowHeight / 3\"\r\n [class.assets-pic]=\"gridType == 'Assets'\"\r\n >\r\n {{ getInitials(row?.full_name) }}\r\n </span>\r\n </ng-template>\r\n </span>\r\n</ng-template>\r\n\r\n<!-- Right Click Menue -->\r\n<div\r\n [class.invisible]=\"!positionedYet\"\r\n class=\"context-menu p-2\"\r\n *ngIf=\"actionHide && actions?.length\"\r\n [ngStyle]=\"{ 'top.px': yPos, 'left.px': xPos }\"\r\n [class.show]=\"isVisible\"\r\n appendTo=\"body\"\r\n>\r\n <ul>\r\n <li\r\n *ngFor=\"let action of actions\"\r\n class=\"rounded d-flex align-items-center\"\r\n (click)=\"onActionClick(action)\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/' + action + '.svg'\"\r\n class=\"data-grid-svg-icon right-click-menu-icons me-2\"\r\n ></span>\r\n <span class=\"text-capitalize fw-500\">{{ action }}</span>\r\n </li>\r\n </ul>\r\n</div>\r\n\r\n<!-- Details Toggle from bottom -->\r\n\r\n<ng-template #nestedTableTemplate let-row>\r\n <div\r\n class=\"nested-table table table-sm w-100 mb-0 center-nested-table w-100\"\r\n style=\"table-layout: fixed !important\"\r\n #nestedTableContainer\r\n >\r\n <thead\r\n #nestedHeader\r\n [style.backgroundColor]=\"nestedTableHeaderBackgroundColor\"\r\n >\r\n <div\r\n cdkDropList\r\n [cdkDropListData]=\"row?.detail.columns\"\r\n cdkDropListOrientation=\"horizontal\"\r\n (cdkDropListDropped)=\"dropColumn($event, row)\"\r\n (cdkDropListSorted)=\"onNestedColSort($event, previewNestedCols)\"\r\n [style.height.px]=\"nestedTableHeaderRowHeight\"\r\n class=\"d-flex tr border-below\"\r\n >\r\n <div\r\n *ngFor=\"let col of row.detail.columns; let i = index\"\r\n [style.width.px]=\"col?.width || 250\"\r\n [style.minWidth.px]=\"col?.width || 250\"\r\n [style.maxWidth.px]=\"col?.width || 250\"\r\n class=\"px-4 th\"\r\n [attr.field]=\"col.field\"\r\n [style.backgroundColor]=\"nestedTableHeaderBackgroundColor\"\r\n cdkDrag\r\n >\r\n <div\r\n class=\"d-flex h-100 justify-content-between position-relative align-items-center\"\r\n >\r\n <div class=\"text-ellipsis\" (click)=\"sortNestedCol(col, row)\">\r\n {{ col.header }}\r\n </div>\r\n <div class=\"d-flex gap-2\">\r\n <span\r\n *ngIf=\"currentSubSortColumn == col.field\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath +\r\n (col?.order_by == 'desc'\r\n ? 'data-grid/icons/sort-desc.svg'\r\n : 'data-grid/icons/sort-asc.svg')\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center ms-2 start-50\"\r\n >\r\n </span>\r\n <!-- <div\r\n class=\"three-dots p-1\"\r\n (click)=\"openThreeDotsMenu($event, col)\"\r\n style=\"cursor: pointer\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath +\r\n 'data-grid/icons/three-dots-vertical.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div> -->\r\n\r\n <!-- Only show menu if this column is active -->\r\n <div\r\n class=\"position-absolute\"\r\n *ngIf=\"activeCol === col\"\r\n style=\"top: -50%; z-index: 21; left: 0\"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n columnMenu;\r\n context: {\r\n col: col,\r\n isNestedTable: true,\r\n columns: row?.detail.columns\r\n }\r\n \"\r\n ></ng-container>\r\n </div>\r\n <div\r\n class=\"resize-handle\"\r\n (click)=\"$event.stopPropagation()\"\r\n (mousedown)=\"\r\n $event.preventDefault();\r\n onResizeColumn($event, col);\r\n $event.stopPropagation()\r\n \"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/resize-handle.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n </div>\r\n </div>\r\n <ng-template cdkDragPreview>\r\n <div class=\"p-2 border d-flex gap-2\">\r\n <div>\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/arrows-move.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n <div>{{ col.header }}</div>\r\n </div>\r\n </ng-template>\r\n </div>\r\n </div>\r\n </thead>\r\n <div\r\n [style.width.px]=\"nestedHeader.offsetWidth - 10\"\r\n [style.minWidth.px]=\"nestedHeader.offsetWidth - 10\"\r\n >\r\n <cdk-virtual-scroll-viewport\r\n [itemSize]=\"nestedTablerowHeight\"\r\n class=\"viewport\"\r\n [style.height.px]=\"\r\n (row?.detail?.result?.length < 5\r\n ? nestedTablerowHeight * row?.detail?.result?.length + 40\r\n : 300) + (hasHorizontalScroll ? -12 : 1)\r\n \"\r\n [style.width.px]=\"nestedHeader.offsetWidth - 10\"\r\n [style.minWidth.px]=\"nestedHeader.offsetWidth - 10\"\r\n >\r\n <div\r\n class=\"cursor-pointer border-below d-flex tr\"\r\n *cdkVirtualFor=\"let d of row?.detail?.result; trackBy: trackById\"\r\n [style.height.px]=\"nestedTablerowHeight\"\r\n [style.width.px]=\"nestedHeader?.offsetWidth\"\r\n [style.minWidth.px]=\"nestedHeader?.offsetWidth\"\r\n [style.backgroundColor]=\"bodyBackgroundColor\"\r\n (contextmenu)=\"onRightClick($event, d)\"\r\n >\r\n <div\r\n class=\"px-4 py-0 td\"\r\n *ngFor=\"let col of previewNestedCols; let j = index\"\r\n [style.fontSize.px]=\"nestedTablerowFontsize\"\r\n [attr.field]=\"col.field\"\r\n [style.width.px]=\"col?.width || 250\"\r\n [style.minWidth.px]=\"col?.width || 250\"\r\n [style.maxWidth.px]=\"col?.width || 250\"\r\n >\r\n <div\r\n [style.height.px]=\"nestedTablerowHeight - 1\"\r\n [style.max-width.px]=\"col?.width\"\r\n class=\"d-flex align-items-center\"\r\n >\r\n <!-- {{ d[col.field] || (col.is_amount ? 0 : \"-\") }} -->\r\n <div\r\n #cellText\r\n class=\"text-ellipsis flex-grow-1\"\r\n [title]=\"\r\n col?.type === 'date'\r\n ? (getNestedValue(d, col.field) | date : dateFormat)\r\n : getNestedValue(d, col.field) || '-'\r\n \"\r\n >\r\n <ng-container *ngIf=\"col?.type !== 'image'\">\r\n <ng-container *ngIf=\"col.is_amount\">{{\r\n currencySymbol\r\n }}</ng-container>\r\n {{\r\n !isNestedValueArray(d, col.field)\r\n ? col?.type === 'date'\r\n ? (isDate(getNestedValue(d, col.field))\r\n ? (getNestedValue(d, col.field) | date: dateFormat)\r\n : (getNestedValue(d, col.field)?.value ||\r\n getNestedValue(d, col.field)?.name ||\r\n getNestedValue(d, col.field) ||\r\n '-'))\r\n : (getNestedValue(d, col.field)?.value ||\r\n getNestedValue(d, col.field)?.name ||\r\n getNestedValue(d, col.field) ||\r\n (col.is_amount ? 0: '-'))\r\n : (getNestedValue(d, col.field)?.[0]?.department_name ||\r\n getNestedValue(d, col.field)?.[0]?.roleName || getNestedValue(d, col.field)?.[0]?.full_name ||\r\n '-')\r\n }}\r\n </ng-container>\r\n <ng-container *ngIf=\"false\">\r\n {{ getTotalAmount(col) }}\r\n </ng-container>\r\n <ng-container *ngIf=\"col?.type == 'image'\">\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n defaultImagePlaceholder;\r\n context: {\r\n row: d,\r\n col: col,\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </cdk-virtual-scroll-viewport>\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template #leftRightNestedPlaceholder let-row>\r\n <table\r\n class=\"nested-table table table-sm w-100 mb-0\"\r\n [style.backgroundColor]=\"bodyBackgroundColor\"\r\n [style.height.px]=\"\r\n gridType == 'Assets'\r\n ? (nestedTableContainer?.nativeElement?.offsetHeight ?? 0) + 12\r\n : (taskManagementContainer?.nativeElement?.offsetHeight ?? 0)\r\n \"\r\n >\r\n <!-- <div class=\"thead\">\r\n <div\r\n class=\"tr d-flex border-below\"\r\n [style.height.px]=\"nestedTableHeaderRowHeight\"\r\n [style.backgroundColor]=\"headerBackgroundColor\"\r\n >\r\n <div class=\"th\" *ngFor=\"let _ of [1, 2, 3, 4, 5]\"></div>\r\n </div>\r\n </div> -->\r\n <!-- <div class=\"tbody\">\r\n <div\r\n class=\"tr border-below\"\r\n [style.height.px]=\"nestedTablerowHeight\"\r\n *ngFor=\"let _ of row?.detail?.result\"\r\n [style.backgroundColor]=\"headerBackgroundColor\"\r\n >\r\n <div class=\"td\" *ngFor=\"let __ of [1, 2, 3, 4, 5]\" class=\"py-0\">\r\n <span\r\n [style.height.px]=\"nestedTablerowHeight\"\r\n [style.max-width.px]=\"nestedTablerowHeight\"\r\n ></span>\r\n </div>\r\n </div>\r\n </div> -->\r\n </table>\r\n</ng-template>\r\n\r\n<ng-template #taskManagementTemplate let-taskDetails=\"taskDetails\">\r\n <div\r\n class=\"p-4\"\r\n #taskManagementContainer\r\n [style.backgroundColor]=\"nestedTableHeaderBackgroundColor\"\r\n [style.fontFaimly]=\"fontFaimly\"\r\n >\r\n <div class=\"d-flex justify-content-between\">\r\n <div class=\"col-4\">\r\n <div class=\"item-title\">Description</div>\r\n <!-- <div class=\"item-content firstDiv\">\r\n {{ taskDetails.description }}\r\n </div> -->\r\n <p\r\n [style.fontSize]=\"bodyTextFontsSize\"\r\n class=\"item-content firstDiv taskDescription pe-4\"\r\n [innerHTML]=\"getSafeComment(taskDetails?.editor_description)\"\r\n (click)=\"openFullImage($event)\"\r\n ></p>\r\n </div>\r\n <div class=\"col-4\">\r\n <div class=\"item-title\">Attachments</div>\r\n <h5 *ngIf=\"taskDetails?.attachments?.length == 0\">\r\n No Attachments found\r\n </h5>\r\n <div\r\n *ngIf=\"taskDetails?.attachments?.length\"\r\n class=\"item-content d-flex flex-wrap\"\r\n style=\"gap: 10px\"\r\n >\r\n <a\r\n *ngFor=\"let attachement of taskDetails?.attachments; let i = index\"\r\n class=\"symbol-label fs-2 fw-semibold text-success cursor-pointer\"\r\n >\r\n <span\r\n title=\"{{ taskDetails?.attachments_name[i] || 'Attachment' }}\"\r\n (click)=\"downloadAttchment(attachement)\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath +\r\n 'data-grid/document-icons/' +\r\n getExtention(attachement) +\r\n '.svg'\r\n \"\r\n >\r\n </span>\r\n </a>\r\n </div>\r\n </div>\r\n <div class=\"col-4\">\r\n <div class=\"item-title\">\r\n Comments ({{ taskDetails?.comments?.length }})\r\n </div>\r\n <h5 *ngIf=\"taskDetails?.comments?.length == 0\">No Comments found</h5>\r\n <div *ngIf=\"taskDetails?.comments?.length\" class=\"item-content\">\r\n <div class=\"comment\" *ngFor=\"let comment of taskDetails.comments\">\r\n <div class=\"d-flex align-items-center pe-3\">\r\n <img\r\n class=\"pic image-input-wrapper\"\r\n [style.width.px]=\"rowHeight - 12\"\r\n [style.height.px]=\"rowHeight - 12\"\r\n *ngIf=\"comment?.comment_by.logo\"\r\n src=\"{{ comment?.comment_by.logo }}\"\r\n alt=\"{{ comment.comment_by.full_name }}\"\r\n />\r\n <!-- <app-default-image-placeholder *ngIf=\"!comment?.comment_by.logo\" title=\"{{ comment.comment_by.full_name }}\" [name]=\"comment.comment_by.full_name\"></app-default-image-placeholder> -->\r\n <span\r\n *ngIf=\"!comment?.comment_by.logo\"\r\n [ngClass]=\"getDynamicClass(comment.comment_by.full_name)\"\r\n class=\"pic d-flex align-items-center rounded-circle\"\r\n [style.width.px]=\"rowHeight - 12\"\r\n [style.height.px]=\"rowHeight - 12\"\r\n [style.fontSize.px]=\"rowHeight / 3\"\r\n title=\"{{ comment.comment_by.full_name }}\"\r\n >\r\n {{ getInitials(comment.comment_by.full_name) }}\r\n </span>\r\n </div>\r\n <div>\r\n <div class=\"comment-author fs-14px\">\r\n {{ comment?.comment_by.full_name }}\r\n </div>\r\n <div\r\n class=\"comment-content forCommentImg\"\r\n [innerHTML]=\"getSafeComment(comment.comment)\"\r\n ></div>\r\n <div class=\"comment-timestamp\">\r\n {{ comment.comment_date | date }}\r\n </div>\r\n <div class=\"comment-timestamp\">\r\n Replies: ({{ comment.replies.length }})\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n</ng-template>\r\n", styles: ["@charset \"UTF-8\";@import\"bootstrap/dist/css/bootstrap.min.css\";.data-grid-table-wrapper{height:100%;width:100%;border:1px solid #d9d9db;border-radius:12px;position:relative}.data-grid-header{position:sticky;top:0}.data-grid-header{display:flex}.header-row{display:grid;width:100%}.header-cell{display:flex;align-items:center;position:relative;width:100%;padding:8px 0 8px 8px;font-weight:700;border-bottom:1px solid #d9d9db;white-space:nowrap;min-width:80px;font-weight:600}.header-cell .filter-applied-on-text{color:#5d9cff!important}.filter-cell{padding:4px!important;display:flex;align-items:center;gap:8px;width:100%}.filter-cell .filter-applied{background-color:#bddef9}.border-right{border-right:1px solid #d9d9db}.merged-grid{display:grid;grid-auto-rows:40px;border-bottom:1px solid #ccc}.span-two-rows{grid-row:span 2;display:flex;justify-content:space-between;align-items:center}.group-header{display:flex;justify-content:space-between;position:relative}.group-header-content{position:sticky;left:10px;overflow:hidden;text-overflow:ellipsis}.resize-handle{width:6px;cursor:e-resize;right:0;top:0;color:#00000026;margin-right:4px}.group-header .resize-handle{top:25%}.h-100{height:100%}.data-grid-body{position:relative;overflow-y:auto;overflow-x:hidden}.cell{padding:8px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;height:100%;display:flex;align-items:center}.data-grid-row{display:flex;width:100%;min-width:max-content;align-items:center;border-bottom:1px solid #d9d9db}.hovered-row{background-color:#ccc}.checkbox-row{border-bottom:#d9d9db}.w-100{width:100%}.data-grid-header-wrapper{display:flex;position:relative;overflow:hidden;-webkit-user-select:none;user-select:none}.data-grid-header{display:flex;position:relative;z-index:1}.left-pinned,.right-pinned{position:sticky;top:0}.right-pinned-header{position:absolute;right:0;border-left:1px solid #d9d9db;z-index:unset}.left-pinned{left:0}.right-pinned{right:0;border-left:1px solid #d9d9db}.center-scrollable{z-index:unset!important;overflow-x:auto;overflow-y:visible;white-space:nowrap;scrollbar-width:none;-ms-overflow-style:none}.center-scrollable::-webkit-scrollbar{display:none}.data-grid-body-wrapper{-webkit-user-select:none;user-select:none;display:flex}.center-scrollable-body{overflow-x:auto;scrollbar-width:none;-ms-overflow-style:none}.center-scrollable-body::-webkit-scrollbar{display:none}.left-pinned-body,.right-pinned-body{position:sticky;top:0;z-index:unset;background:#fff;scrollbar-width:none;-ms-overflow-style:none}.left-pinned-body::-webkit-scrollbar,.right-pinned-body::-webkit-scrollbar{display:none}.left-pinned-body{left:0}.border-end{border-right:1px solid #d9d9db!important}.right-pinned-body{right:0;border-left:1px solid #d9d9db}.fake-scroll-bar{height:14px;overflow:scroll;margin-bottom:10px}.text-ellipsis{overflow:hidden;text-overflow:ellipsis}.select-all-checkbox-cell{width:50px;display:flex;justify-content:center;align-items:center;height:100%;border-right:1px solid #d9d9db}.select-all-checkbox-cell input{width:16px;height:14px}.border-below{border-bottom:1px solid #d9d9db!important}.three-dots{width:22px;height:22px;display:flex;justify-content:center;align-items:center;border-radius:3px;margin-right:8px;cursor:pointer}.three-dots:hover{background-color:#ccc!important}.filter-icon-wrapper{min-height:22px;max-height:22px;min-width:22px;max-width:22px;display:flex;justify-content:center;align-items:center;border-radius:3px;cursor:pointer;transition:background-color .3s ease}.filter-icon-wrapper:hover{background-color:#ccc}.column-menu,.filter-menu{box-shadow:0 0 16px #00000026;border-radius:4px}.column-menu{background:#fff;width:100%;width:240px;border:1px solid #ddd;box-shadow:0 0 16px #00000026;border:1px solid #d9d9db;padding:4px 0;font-size:14px;position:fixed}.column-menu-item{padding:8px 12px;cursor:pointer;display:flex;align-items:center;transition:background-color .2s ease}.column-menu-item:hover{background-color:#deebf7}.pin-parent{position:relative;width:100%!important}.column-submenu{position:absolute;top:0;left:100%;background:#fff;border:1px solid #ddd;width:130px;box-shadow:0 0 16px #00000026;border:1px solid #d9d9db;display:none;padding:4px 0;z-index:10;border-radius:4px}.pin-parent:hover .column-submenu{display:block}.filter-menu-container{position:fixed;width:210px;background:#fff;border:1px solid #ddd;border-radius:4px;padding:12px;box-shadow:0 0 16px #00000026;border:1px solid #d9d9db;z-index:1000;font-size:14px}.filter-menu-header{font-weight:600;margin-bottom:10px}.filter-dropdown-section{max-height:350px;overflow-y:auto}.dropdown-options{overflow-y:auto;scrollbar-width:thin;height:100%}.filter-text-section select,.filter-text-section input{width:100%}.filter-radio-inputs{width:14px!important;height:14px!important}.right-menu{border-left:1px solid #d9d9db;font-size:14px}.border-start{border-left:1px solid #d9d9db!important}.column-panel-item{font-size:.875rem;color:#333}.toggle-icon{cursor:pointer;transition:transform .2s ease}.toggle-icon.rotate{transform:rotate(90deg)}.grab-icon{cursor:grab;color:#6c757d}.text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.cursor-pointer{cursor:pointer}.pivot-mode{height:48px}.chevron-wrapper{width:30px;height:20px;cursor:pointer;border-radius:3px;display:flex;justify-content:center;align-items:center;transition:background-color .3s ease;margin-right:8px}.chevron-wrapper:hover{background-color:#cac7c7}.chevron-wrapper i{font-size:14px}.column-panel-body{height:70%;overflow:auto;scrollbar-width:thin}.side-menue-text{transform:rotate(90deg);position:relative;font-weight:700;margin-top:40px}.columns-button{padding-top:20px;padding-bottom:35px;width:29px}.fake-scroll-content{height:12px}.fake-scrollbar{width:25px}.fake-scrollbar div{min-width:1px}.fake-horizintal-scrollbar div{min-height:1px}.side-filter-columns-wrapper{height:calc(100% - 25px)}.custom-modal-overlay{position:fixed;top:0;left:0;width:100%;height:100%;overflow:hidden;display:flex;justify-content:center;align-items:center;z-index:1050}.custom-modal-overlay .moda-header{background-color:#f8f8f8}.custom-modal-content{background-color:#fff;border-radius:8px;min-width:300px;max-width:400px;box-shadow:0 5px 20px #0000004d}.overlay-scrollable{height:250px;overflow:auto}.footer-row{border-top:1px solid #d9d9db;padding-left:32px}.fake-horizintal-scrollbar{position:relative;bottom:17px;overflow-x:auto;overflow-y:hidden;height:17px}.border-dashed{border:1px dashed #d9d9db}.cdk-drag-preview{box-sizing:border-box!important;border-radius:4px!important;box-shadow:0 5px 5px -3px #0003,0 8px 10px 1px #00000024,0 3px 14px 2px #0000001f!important;background-color:#f3f4f5!important;border:1px solid #d9d9db!important;z-index:9999!important}.data-grid-header-wrapper ::ng-deep .cdk-drag-placeholder{display:block!important;background:#fff!important;opacity:1!important}.cdk-drag-animating{transition:transform .25s cubic-bezier(0,0,.2,1)!important}.top-row-grouping-placeholder{display:flex;align-items:center;border-radius:12px;font-size:14px;padding-inline:6px;border:1px solid #d9d9db}.top-row-grouping-placeholder .bi-x{cursor:pointer;color:#7a7a7a}.top-row-grouping-placeholder .bi-x:hover{color:#111}.right-pinned-body-wrapper{position:absolute;right:0}.actions-dropdown{position:absolute;right:200px;z-index:1050;background-color:#fff;border-radius:8px!important;cursor:default}.bg-fff{background-color:#fff}.actions-dropdown-setting{right:250px}.action-button{background-color:#007cf5!important;border-radius:8px!important;padding:8px 16px!important;font-size:14px;height:32px;align-items:center}.global-search{max-width:380px!important;display:flex!important;align-items:center!important}.global-search span{margin-top:-4px!important}.global-search input{padding-left:28px;border-radius:8px!important}.global-search input:focus{outline:none!important;box-shadow:none!important}.active .top-icon ::ng-deep svg path{stroke:#007cf5!important}.dropdown-menu{background-color:#fff!important;border:1px solid #d9d9db!important;border-radius:8px!important}.custom-menu{width:220px;border-radius:8px;padding:4px 0;background-color:#fff}.custom-menu .dropdown-item{font-size:14px;padding:8px 14px}.custom-menu .dropdown-item:hover{background-color:#f5f5f5;border-radius:6px}.table-layout{right:0;background:#fff;border-radius:8px!important}.actions-dropdown,.table-layout,.custom-menu,.dropdown-menu{background:#fff;border-radius:8px!important;border:1px solid #ccc!important;background-color:#fff}.preview-box{width:40px;height:10px;border-radius:3px;background-color:transparent;transition:background-color .2s ease-in-out}.btn-check:checked+label .preview-box{background-color:var(--bs-primary)}.preview-box{width:40px;height:10px;border-radius:3px;border:2px solid transparent;transition:border-color .2s ease-in-out}#small:checked+label .preview-box{border-color:#007cf5!important;background-color:transparent!important}#medium:checked+label .preview-box{border-color:#007cf5!important;background-color:transparent!important}#large:checked+label .preview-box{border-color:#007cf5!important;background-color:transparent!important}.btn-check:checked+.btn{background-color:transparent!important;border-color:#007cf5!important}.layout-button{padding:8px 28px!important;width:82px;border-radius:8px!important}.show-hide-table-label{position:sticky;top:0;z-index:99;background:#fff}.cursor-grap{cursor:grabbing}.pagination-container{display:flex;align-items:center;gap:12px;font-size:13px;color:#333}.page-size select{padding:3px 6px;border:1px solid #ccc;border-radius:6px;background:#fff;font-size:13px}.page-info{margin-left:10px}.page-buttons{display:flex;gap:4px;margin-left:auto;align-items:center}.page-buttons button{padding:3px 8px;border:1px solid #ccc;background:#fff;border-radius:4px;cursor:pointer;font-size:13px;line-height:1.2}.page-buttons button.active{background:#eee;font-weight:600}.page-buttons button:disabled{opacity:.5;cursor:not-allowed}.page-buttons span{padding:0 6px;color:#666}.page-size .separator{padding:0 8px;border-right:1px solid #ccc;margin-right:8px}.page-size .separator .actions-dropdown{position:fixed;right:200px;z-index:1050;background-color:#fff}.fs-14px{font-size:14px}.fs-12px{font-size:12px!important}.save-preset-dropdown{background:#fff;color:#111!important;right:0;font-weight:400!important;text-align:left!important;max-width:250px!important;text-wrap:auto!important;top:14px;font-size:14px!important}.add-filter-button{height:28px;cursor:pointer;border-radius:4px}.add-filter-button:hover,.button-filter:hover{color:#000!important}.button-filter:hover ::ng-deep svg path{stroke:#000!important}.table-layout .dropdown-item{border-radius:0!important;padding-inline:16px!important;font-size:14px;padding-block:6px!important}.table-layout .dropdown-item:hover{background-color:transparent!important}.filter-serach-inpt{max-height:230px!important;overflow:auto;scrollbar-width:thin;padding-top:4px;background-color:#f7f7f7;border-color:#dedede;border-radius:8px}.filter-serach-inpt .badge{color:#007cf5!important;background-color:#e6f2ff!important;border-radius:8px!important;padding:8px!important;font-weight:500!important;font-size:12px!important;height:24px!important}.filter-serach-inpt .badge ::ng-deep svg{cursor:pointer}.filter-serach-inpt .badge ::ng-deep svg:hover path{stroke:#040081!important}.filter-serach-inpt input{background-color:#f7f7f7;padding:0;height:26px;margin-top:-5px}.text-filter select{border:0}.text-filter select option{font-size:14px;font-weight:500}.text-filter select:focus{border:0}.text-filter input:focus,.text-filter select:focus{box-shadow:none!important}.active-filters{background-color:#f7f7f7;white-space:nowrap;background:#f7f7f7;padding-inline:8px;height:28px;font-size:14px;font-weight:500;border-radius:8px;box-shadow:none}.active-filters .header-tag{white-space:nowrap}.filter-tags .active{background-color:#e6f2ff}.filter-tags .active .header-tag{color:#007cf5!important}.table-cell{cursor:pointer;width:100%}.table-cell input:focus{outline:0!important;border:0!important;width:100%!important;box-shadow:none!important}.active-for-editing{outline:2.5px solid #007cf5!important;border-radius:4px;border:0!important;width:100%!important}.active-cell{outline:none!important;box-shadow:inset 0 0 0 1.5px #007cf5}span[inlineSVG]{width:16px;height:16px;display:inline-block}.cell .dropdown-menu{min-width:unset!important}.cell .dropdown-menu .item{transition:background-color .3s ease;display:flex;align-items:center;-webkit-user-select:none;user-select:none}.cell .dropdown-menu .item:hover{background-color:#f0f8ff}.cell .cell-editin-dropdown{scrollbar-width:thin!important;-webkit-user-select:none;user-select:none}.fw-semibold{font-weight:500!important}:host ::ng-deep .three-dots-col-menu svg,:host ::ng-deep .three-dots-col-menu svg path{stroke:#000!important}.fs-7{font-size:12px!important}.fs-8{font-size:10px!important}.all-filters-reset-button:hover{opacity:.7}.full-text-box{background:#fff;position:relative;display:flex;align-items:center;z-index:1050;border:1px solid #dedede;border-radius:8px;padding:12px 14px;box-shadow:0 2px 8px #00000026;max-height:400px;overflow:auto}.full-text-box ul{max-height:400px}.full-text-content{border-radius:8px;max-height:70vh;overflow:auto;white-space:pre-wrap}.pic{border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:22px}.pic-comb2{background-color:#fbe7bf;color:#fd7f31}.pic-comb1{background-color:#d9ecbf;color:#65b500}.pic-comb4{background-color:#fdd3d7;color:#f64e60}.w-40px{width:40px}.h-40px{height:40px}.pic{border-radius:50%;overflow:hidden}.image-placeholder .pic{font-size:14px;font-weight:600;letter-spacing:.5px}.header-cell{font-weight:600}.header-cell,.cell{box-sizing:border-box}.transparent-border-right{border-right:1px solid transparent!important}.resizing-highlight{position:relative}.resizing-highlight:before{content:\"\";position:absolute;top:-1px;right:-1px;width:2px;height:calc(100% + 2px);background:#7cb9f6;z-index:1000;pointer-events:none}.resizing-highlight-right{position:relative}.resizing-highlight-right:before{content:\"\";position:absolute;top:-1px;left:-1px;width:2px;height:calc(100% + 2px);background:#7cb9f6;z-index:1000;pointer-events:none}.resizing-highlight-right:first-child{width:1px}.editable-header{border-bottom:1px dashed #666}.muted-text{color:#727272!important}.context-menu{position:fixed;display:none;background:#fff;border:1px solid #dcdcdc;box-shadow:#0000003d 0 3px 8px;z-index:1000;width:150px;border-radius:8px;font-weight:600}.context-menu.show{display:block}.context-menu ul{list-style:none;margin:0;padding:0}.context-menu li{padding:10px;cursor:pointer;color:#99a1b7}.context-menu li ::ng-deep svg{width:16px;height:16px;display:inline-block;color:#727272}.context-menu li ::ng-deep svg path{stroke:#727272}.context-menu li:hover{background-color:#f0f0f5!important}.invisible{visibility:hidden!important}.fw-500{font-weight:500!important}.taskbar{position:fixed;display:flex;justify-content:center;z-index:1000}.taskbar .action-btn{transition:opacity text-decoration .3s ease}.taskbar .action-btn:hover{text-decoration:underline;opacity:.8}.taskbar .delete{color:#ea0000}.selected-count,.action-btn,.dropdown-content a{font-weight:500;font-size:14px}.selected-rows-action-bar{background-color:#1a1a1a;color:#fff;padding:4px 24px;border-radius:8px;display:flex;align-items:center;justify-content:space-between;gap:24px;box-shadow:0 -4px 12px #00000026}.selected-rows-action-bar .btn:active,.selected-rows-action-bar .btn:focus{outline:0!important;border:0!important;border-color:transparent!important}.selected-rows-action-bar .action-btn{color:#fff!important}.cell .dropdown-menu,.cell .form-select,.cell input{color:#000!important}.cell input::placeholder{color:#727272!important}.cell .badge{border-radius:50px!important;height:26px;align-items:center}.cell .badge-danger{color:#ea5353!important;border:1px solid #ea5353!important;background-color:#ff00000d!important}.cell .badge-success{background-color:#84ca8130!important;border:1.5px solid rgb(70,227,114)!important;color:#46e372!important}.cell .badge-warning{background-color:#fff3dc!important;color:orange!important;border:1px solid #ffa000!important}.cell .badge-info{color:#00bad1;background-color:#e8fbfd;border:1px solid #00bad1}.cell .badge-secondary{color:#6c757d;background-color:#f1f3f5;border:1px solid #6c757d}.header-tag ::ng-deep svg path{stroke:#727272!important}.cross-secondary:hover ::ng-deep svg path{stroke:#000!important}.disable-sorting{pointer-events:none;opacity:.5}.rows-grouping-top-container ::ng-deep .cdk-drag-placeholder{background-color:transparent!important}input.is-invalid:focus{border:2.5px solid red!important;outline:none}.table-cell input.is-invalid:focus{border:2.5px solid red!important;outline-color:red!important;outline:none!important;box-shadow:none!important}.active-for-editing:has(input.is-invalid:focus){outline:none!important;box-shadow:none!important;border:0!important}.selected-cell,.row-selected{background-color:#c2e0fe}.first-row-selected{border-top:2px solid #2196f3!important}.last-row-selected{border-bottom:2px solid #2196f3!important}.left-selection-border{border-left:2px solid #2196f3!important}.s-no{font-size:14px;font-weight:500}.top-border{border-top:2px solid #2196f3!important}.bottom-border{border-bottom:2px solid #2196f3!important}.left-border{border-left:2px solid #2196f3!important}.border-left{border-left:1px solid #d9d9db}.right-border{border-right:2px solid #2196f3!important}.top-left-corner{border-top-left-radius:4px}.top-right-corner{border-top-right-radius:4px}.bottom-left-corner{border-bottom-left-radius:4px}.bottom-right-corner{border-bottom-right-radius:4px}.flash-bg{animation:flashAnim 1000s ease}@keyframes flashAnim{0%{background-color:#48a2fc}50%{background-color:#c2e0fe}to{background-color:#c2e0fe}}.cut-flash-bg{animation:cut-flash .8s ease}@keyframes cut-flash{0%{background-color:#f006}50%{background-color:#f00c}to{background-color:#c2e0fe}}.accordion-details .center-section .table .tbody .tr:hover .td{background-color:#f0f8ff!important}.editing-dropdown-search-input input:focus{border:1px solid #86b7fe!important}.nested-table .thead{position:sticky;top:0}.dropdown-wrapper{position:relative;display:inline-block}.btn-icon{background:transparent;border:0;padding:.25rem .5rem;cursor:pointer}.custom-dropdown-menu{position:absolute;right:0;top:calc(100% + 6px);min-width:200px;list-style:none;margin:0;padding:.25rem 0;background:#fff!important;border:1px solid rgba(0,0,0,.08);box-shadow:0 6px 18px #00000014;border-radius:.35rem;z-index:1200}.custom-dropdown-menu .dropdown-item{display:block;width:100%;padding:.5rem 1rem;text-align:left;background:transparent;border:none}.custom-dropdown-menu .dropdown-item:hover{background:#00000008}.cell-editing-dropdown-menu .dropdown-item{width:99%}.cell-editing-dropdown-menu .selected{background-color:#f0f8ff}.confirm-block{padding:0}.center-nested-table .tr:hover .td{background-color:#f0f8ff}.table ::ng-deep .cdk-drag-placeholder{background-color:#fff!important}.assets-pic{border-radius:8px!important}.fullscreen-overlay{position:fixed;top:0;left:0;width:100vw;height:100vh;background:#000c;display:flex;align-items:center;justify-content:center;z-index:1000;cursor:zoom-out}.fullscreen-img{max-width:90%;max-height:90%;border-radius:8px;box-shadow:0 0 15px #00000080}.position-sticky{z-index:2}.viewport{display:block!important;overflow:visible!important}.nested-table ::ng-deep .cdk-virtual-scroll-content-wrapper{padding:0!important}.nested-table ::ng-deep .cdk-virtual-scroll-viewport{overflow-x:hidden!important}.disabled-search-input{background-color:#f5f5f5;cursor:pointer!important}.right-click-menu-icons ::ng-deep svg path{stroke-width:2!important}.loader{animation:rotate 1s infinite;height:50px;width:50px}.loader:before,.loader:after{border-radius:50%;content:\"\";display:block;height:20px;width:20px}.loader:before{animation:ball1 1s infinite;background-color:#fff;box-shadow:30px 0 #ff3d00;margin-bottom:10px}.loader:after{animation:ball2 1s infinite;background-color:#ff3d00;box-shadow:30px 0 #fff}@keyframes rotate{0%{transform:rotate(0) scale(.8)}50%{transform:rotate(360deg) scale(1.2)}to{transform:rotate(720deg) scale(.8)}}@keyframes ball1{0%{box-shadow:30px 0 #ff3d00}50%{box-shadow:0 0 #ff3d00;margin-bottom:0;transform:translate(15px,15px)}to{box-shadow:30px 0 #ff3d00;margin-bottom:10px}}@keyframes ball2{0%{box-shadow:30px 0 #fff}50%{box-shadow:0 0 #fff;margin-top:-20px;transform:translate(15px,15px)}to{box-shadow:30px 0 #fff;margin-top:0}}.rows-grouping-top-container ::ng-deep .cdk-drag-placeholder{opacity:.7!important}.action-button{background-color:#6f61cf!important;color:#fff!important;border-radius:6px!important;font-weight:500!important;margin-top:-4px}.action-button:hover{background-color:#6a5fb3!important}.action-buttons-row .button{display:inline-flex;align-items:center;justify-content:center;overflow:hidden;color:#fff;border-radius:6px;height:34px;padding:0 10px;white-space:nowrap;transition:max-width .4s ease,background-color .3s ease;max-width:40px;background-color:transparent;border:1px solid #6F61CF}.action-buttons-row .button .label-hidden{opacity:0;margin-left:8px;transition:opacity .3s ease;pointer-events:none;display:none}.action-buttons-row .button:hover{max-width:200px;background-color:#6f61cf}.action-buttons-row .button:hover .label-hidden{opacity:1;pointer-events:auto;margin-left:8px!important;display:block}.action-buttons-row ::ng-deep .button .svg-icon svg path{stroke:#6f61cf;transition:fill .3s ease,stroke .3s ease}.action-buttons-row ::ng-deep .button:hover .svg-icon svg path{stroke:#fff!important}::ng-deep .nav-tabs .nav-link{border:none!important;border-bottom:2px solid transparent!important;border-radius:0!important;background:transparent!important}::ng-deep .nav-tabs .nav-link:hover,::ng-deep .nav-tabs .nav-link:focus{border:none!important;border-bottom:2px solid transparent!important;outline:none!important;background:transparent!important}::ng-deep .nav-tabs .nav-link.active{border:none!important;border-bottom:2px solid var(--bs-primary)!important;background:transparent!important;color:var(--bs-primary)!important}.open-top{top:-150%!important}.muted{color:#7a7a7a!important}.item-title{font-size:1.2em;font-weight:700;margin-bottom:10px}.item-image{width:100%;border-radius:10px}.comment{display:flex;align-items:center;margin-bottom:10px}.comment-avatar{width:40px;height:40px;border-radius:50%;margin-right:10px}.comment-author{font-weight:700}.comment-content{font-size:.9em;line-height:1.4}.comment-timestamp{font-size:.8em;color:#888;margin-left:auto}.des_low{text-overflow:ellipsis;white-space:nowrap;overflow:hidden;width:242px;display:block;text-transform:capitalize!important}.firstDiv{word-break:break-word;overflow-wrap:break-word;white-space:normal}.container{display:flex;flex-wrap:wrap;margin:20px;gap:20px;background-color:#fff;padding:20px;border-radius:10px}.item{width:calc(33.33% - 20px);background-color:#fff;padding:20px;border-radius:10px;box-shadow:0 2px 5px #0000001a}.forCommentImg{width:70px;border-radius:16px;margin:8px 0;cursor:pointer}.image-modal img{max-width:90%;max-height:90%;border-radius:8px;box-shadow:0 4px 10px #00000080}.full-image-modal{position:fixed;background:#000c;display:flex;justify-content:center;align-items:center;z-index:1000}.full-image-modal .full-image{max-width:90%;max-height:90%;border-radius:8px;box-shadow:0 0 10px #fff3}.item-content{font-size:14px;line-height:1.5;max-height:220px;overflow-y:auto}.image-modal.full-image-modal{position:fixed;width:100vw;height:100vh;background-color:#000c;display:flex;justify-content:center;align-items:center;z-index:9999;overflow:hidden;cursor:zoom-out}.image-modal.full-image-modal img{border-radius:8px;box-shadow:0 4px 20px #0006;object-fit:contain;transition:transform .3s ease}.image-modal.full-image-modal img:hover{transform:scale(1.02)}::ng-deep .custom-overlay-wrapper .custom-overlay{position:fixed;top:0;left:0;width:100vw;height:100vh;background:#000000d9;display:flex;align-items:center;justify-content:center;z-index:9999}::ng-deep .custom-overlay-wrapper .custom-modal{background:#fff;border-radius:12px;box-shadow:0 8px 25px #0003;width:360px;max-width:90%;padding:24px;text-align:center;animation:fadeInScale .25s ease}::ng-deep .custom-overlay-wrapper .custom-modal-body .modal-message{font-size:16px;margin-bottom:20px;color:#333}::ng-deep .custom-overlay-wrapper .modal-actions{display:flex;justify-content:center;gap:12px}::ng-deep .custom-overlay-wrapper .modal-actions button{min-width:90px;padding:8px 14px;border-radius:6px;border:none;font-weight:500;cursor:pointer;transition:background-color .2s ease}::ng-deep .custom-overlay-wrapper .btn-confirm{background-color:#007bff;color:#fff}::ng-deep .custom-overlay-wrapper .btn-confirm:hover{background-color:#0069d9}::ng-deep .custom-overlay-wrapper .btn-cancel{background-color:#e4e4e4;color:#333}::ng-deep .custom-overlay-wrapper .btn-cancel:hover{background-color:#d6d6d6}@keyframes fadeInScale{0%{opacity:0;transform:scale(.95)}to{opacity:1;transform:scale(1)}}.clear-btn{background:linear-gradient(135deg,#f53545,#f53545);border:none;color:#fff;font-size:13px;padding:3px 6px;border-radius:20px;font-weight:500;display:inline-flex;align-items:center;gap:6px;cursor:pointer;transition:all .3s ease;box-shadow:0 2px 6px #ff5f6d66;position:relative;bottom:4px}.clear-btn:hover{transform:translateY(-2px);box-shadow:0 4px 10px #ff5f6d99;background:linear-gradient(135deg,#f53545,#f53545)}.clear-btn i{font-size:16px;vertical-align:middle}.cell-editin-dropdown .deopdown-item{width:100%!important;box-shadow:none!important;border-radius:4px;cursor:pointer;padding-block:8px!important}.cell-editin-dropdown .deopdown-item:hover{background-color:#f1f1f1}\n"], dependencies: [{ kind: "directive", type: i6.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i6.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i6.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i6.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i6.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: i6.NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { kind: "directive", type: i6.NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { kind: "directive", type: i6.NgSwitchDefault, selector: "[ngSwitchDefault]" }, { kind: "directive", type: i8.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i8.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i8.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: i8.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i8.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i8.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i8.RadioControlValueAccessor, selector: "input[type=radio][formControlName],input[type=radio][formControl],input[type=radio][ngModel]", inputs: ["name", "formControlName", "value"] }, { kind: "directive", type: i8.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i8.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i8.PatternValidator, selector: "[pattern][formControlName],[pattern][formControl],[pattern][ngModel]", inputs: ["pattern"] }, { kind: "directive", type: i8.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i9.CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: i9.CdkDropListGroup, selector: "[cdkDropListGroup]", inputs: ["cdkDropListGroupDisabled"], exportAs: ["cdkDropListGroup"] }, { kind: "directive", type: i9.CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "directive", type: i9.CdkDragHandle, selector: "[cdkDragHandle]", inputs: ["cdkDragHandleDisabled"] }, { kind: "directive", type: i9.CdkDragPreview, selector: "ng-template[cdkDragPreview]", inputs: ["data", "matchSize"] }, { kind: "directive", type: i9.CdkDragPlaceholder, selector: "ng-template[cdkDragPlaceholder]", inputs: ["data"] }, { kind: "directive", type: i10.InlineSVGDirective, selector: "[inlineSVG]", inputs: ["inlineSVG", "resolveSVGUrl", "replaceContents", "prepend", "injectComponent", "cacheSVG", "setSVGAttributes", "removeSVGAttributes", "forceEvalStyles", "evalScripts", "fallbackImgUrl", "fallbackSVG", "onSVGLoaded"], outputs: ["onSVGInserted", "onSVGFailed"] }, { kind: "directive", type: i11.CdkFixedSizeVirtualScroll, selector: "cdk-virtual-scroll-viewport[itemSize]", inputs: ["itemSize", "minBufferPx", "maxBufferPx"] }, { kind: "directive", type: i11.CdkVirtualForOf, selector: "[cdkVirtualFor][cdkVirtualForOf]", inputs: ["cdkVirtualForOf", "cdkVirtualForTrackBy", "cdkVirtualForTemplate", "cdkVirtualForTemplateCacheSize"] }, { kind: "component", type: i11.CdkVirtualScrollViewport, selector: "cdk-virtual-scroll-viewport", inputs: ["orientation", "appendOnly"], outputs: ["scrolledIndexChange"] }, { kind: "directive", type: CellRenderInitDirective, selector: "[cellRenderInit]", inputs: ["cellRenderInit", "rowData", "colData", "cellValue"], outputs: ["cellEvent"] }, { kind: "directive", type: CellEditorDirective, selector: "[cellEditor]", inputs: ["cellEditor", "rowData", "colData", "cellValue"], outputs: ["editorEvent"] }, { kind: "pipe", type: i6.SlicePipe, name: "slice" }, { kind: "pipe", type: i6.TitleCasePipe, name: "titlecase" }, { kind: "pipe", type: i6.DatePipe, name: "date" }, { kind: "pipe", type: FilterPipe, name: "filter" }], animations: [
|
|
6128
6333
|
trigger('accordionToggle', [
|
|
6129
6334
|
state('collapsed', style({ height: '0px', overflow: 'unset' })),
|
|
6130
6335
|
state('expanded', style({ height: '*', overflow: 'unset' })),
|
|
@@ -6340,7 +6545,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
|
|
|
6340
6545
|
], { optional: true })
|
|
6341
6546
|
]),
|
|
6342
6547
|
])
|
|
6343
|
-
], template: "<div class=\"position-relative h-100\">\r\n <div\r\n class=\"d-flex justify-content-between mb-2 align-items-center position-relative\"\r\n >\r\n <div class=\"d-flex gap-2\">\r\n <div class=\"nav nav-tabs\" *ngIf=\"true\">\r\n <div class=\"nav nav-tabs\" id=\"nav-tab\" role=\"tablist\">\r\n <span\r\n *ngFor=\"let tab of tabs; let i = index\"\r\n (click)=\"setActiveTab(tab)\"\r\n class=\"nav-link cursor-pointer\"\r\n [class.active]=\"activeTab == tab\"\r\n >\r\n {{ tab }}\r\n </span>\r\n </div>\r\n </div>\r\n <div class=\"global-search\" [style.width.px]=\"350\">\r\n <span\r\n *ngIf=\"enableGlobalSearch\"\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/search.svg'\"\r\n class=\"data-grid-svg-icon mx-2 position-absolute icon\"\r\n ></span>\r\n <input\r\n *ngIf=\"enableGlobalSearch\"\r\n style=\"height: 36px\"\r\n class=\"form-control\"\r\n placeholder=\"Type to search, then press Enter\"\r\n [(ngModel)]=\"tableSearch\"\r\n (keydown.enter)=\"onGlobalSearch()\"\r\n (input)=\"onSearchInput($event)\"\r\n type=\"search\"\r\n />\r\n </div>\r\n </div>\r\n <div class=\"d-flex gap-2 align-items-center table-right-top-actions\">\r\n <ng-container *ngFor=\"let button of buttons\">\r\n <div\r\n class=\"d-flex align-items-center gap-2 action-buttons-row\"\r\n *ngIf=\"button?.has_permission\"\r\n >\r\n <a\r\n href=\"JavaScript:void(0)\"\r\n (click)=\"onActionButtonClick(button.name)\"\r\n class=\"button button-small btn border border-primary btn-active-primary me-2 p-0 d-flex align-items-center justify-content-center px-3\"\r\n >\r\n <span\r\n *ngIf=\"button.is_showIcon\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/' + button.icon + '.svg'\r\n \"\r\n class=\"svg-icon svg-icon-2\"\r\n ></span>\r\n <span\r\n class=\"label-hidden text-white\"\r\n [class.ms-0]=\"button.is_showIcon\"\r\n >{{ button?.name }}</span\r\n >\r\n </a>\r\n </div>\r\n </ng-container>\r\n <div\r\n *ngIf=\"!showFilterRow\"\r\n class=\"cursor-pointer position-relative action-buttons-row\"\r\n (click)=\"toggleOpenFilter()\"\r\n [class.active]=\"showFilters\"\r\n >\r\n <a\r\n href=\"JavaScript:void(0)\"\r\n class=\"button button-small btn btn-active-primary border border-primary me-2 p-0 d-flex align-items-center justify-content-center px-3\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\"\r\n class=\"svg-icon svg-icon-2\"\r\n ></span>\r\n <span class=\"label-hidden text-white\">Filters</span>\r\n </a>\r\n <span\r\n *ngIf=\"activeFilteredColumns?.length\"\r\n style=\"\r\n width: 7px;\r\n height: 7px;\r\n box-shadow: 0px 0px 3px #0022ff;\r\n background-color: rgb(0, 60, 255);\r\n position: absolute;\r\n right: 16px;\r\n top: 10px;\r\n \"\r\n class=\"rounded-circle d-block\"\r\n ></span>\r\n </div>\r\n <div\r\n class=\"cursor-pointer d-none\"\r\n (click)=\"toggleActions('advance-filter')\"\r\n [class.active]=\"activeTopButton === 'advance-filter'\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/zoom-charge.svg'\"\r\n class=\"data-grid-svg-icon top-icon me-2\"\r\n ></span>\r\n </div>\r\n <div\r\n class=\"cursor-pointer action-buttons-row\"\r\n (click)=\"toggleActions('setting')\"\r\n [class.active]=\"\r\n activeTopButton === 'setting' ||\r\n activeTopButton === 'table-layout' ||\r\n activeTopButton === 'table-presets' ||\r\n activeTopButton === 'show-hide-columns'\r\n \"\r\n >\r\n <!-- <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/settings-2.svg'\"\r\n class=\"data-grid-svg-icon top-icon me-2\"\r\n ></span> -->\r\n <a\r\n href=\"JavaScript:void(0)\"\r\n class=\"button button-small btn btn-active-primary border border-primary me-2 p-0 d-flex align-items-center justify-content-center px-3\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/settings-2.svg'\"\r\n class=\"svg-icon svg-icon-2\"\r\n ></span>\r\n <span class=\"label-hidden text-white\">Setting</span>\r\n </a>\r\n\r\n <div\r\n *ngIf=\"activeTopButton === 'setting'\"\r\n class=\"actions-dropdown mt-1 actions-dropdown-setting\"\r\n style=\"position: absolute\"\r\n >\r\n <div class=\"dropdown-menu show shadow custom-menu\">\r\n <!-- Table Layout -->\r\n <a\r\n class=\"dropdown-item d-flex justify-content-between align-items-center cursor-pointer\"\r\n (click)=\"$event.stopPropagation(); toggleActions('table-layout')\"\r\n >\r\n <span\r\n ><span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/table-2.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n Table Layout</span\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n </a>\r\n <!-- Table Presets -->\r\n <a\r\n (click)=\"$event.stopPropagation(); toggleActions('table-presets')\"\r\n class=\"dropdown-item d-flex justify-content-between align-items-center cursor-pointer\"\r\n >\r\n <span\r\n ><span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/list-details.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n Table Presets</span\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n </a>\r\n\r\n <!-- Columns -->\r\n <a\r\n *ngIf=\"!showSideMenu\"\r\n (click)=\"\r\n $event.stopPropagation(); toggleActions('show-hide-columns')\r\n \"\r\n class=\"dropdown-item d-flex justify-content-between align-items-center cursor-pointer\"\r\n >\r\n <span class=\"align-items-center d-flex\"\r\n ><span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/eye.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n Columns</span\r\n >\r\n <div class=\"d-flex gap-2\">\r\n <span class=\"muted-text\">{{ columnsCount }}</span>\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n </div>\r\n </a>\r\n\r\n <div class=\"dropdown-divider\"></div>\r\n\r\n <!-- Filter -->\r\n <a\r\n class=\"dropdown-item cursor-pointer\"\r\n (click)=\"toggleOpenFilter(); activeTopButton = '';\"\r\n *ngIf=\"!showFilterRow\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2 mt-1 cursor-pointer\"\r\n ></span>\r\n Filter\r\n </a>\r\n\r\n <!-- Download -->\r\n <a\r\n class=\"dropdown-item cursor-pointer\"\r\n (click)=\"downloadCsv('csv')\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/download.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2 cursor-pointer\"\r\n ></span>\r\n CSV Export\r\n </a>\r\n <a\r\n *ngIf=\"enableExport\"\r\n class=\"dropdown-item cursor-pointer\"\r\n (click)=\"downloadCsv('xlsx')\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/download.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2 cursor-pointer\"\r\n ></span>\r\n Excel Export\r\n </a>\r\n <!-- Font Family & Font Size -->\r\n <div class=\"px-2 pb-2 pt-2\">\r\n <div class=\"d-flex gap-2\">\r\n <!-- Font Family -->\r\n <select\r\n class=\"form-select form-select-sm\"\r\n [(ngModel)]=\"fontFaimly\"\r\n (change)=\"onFontChange()\"\r\n >\r\n <option *ngFor=\"let font of fontFamilies\" [value]=\"font\">\r\n {{ font }}\r\n </option>\r\n </select>\r\n\r\n <!-- Font Size -->\r\n <select\r\n class=\"form-select form-select-sm\"\r\n (change)=\"onFontChange()\"\r\n [(ngModel)]=\"bodyTextFontsSize\"\r\n >\r\n <option *ngFor=\"let size of fontSizes\" [value]=\"size\">\r\n {{ size }}\r\n </option>\r\n </select>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Table Layout -->\r\n\r\n <ng-container *ngIf=\"activeTopButton === 'table-layout'\">\r\n <div\r\n *ngTemplateOutlet=\"tableLayout\"\r\n class=\"actions-dropdown mt-1\"\r\n style=\"position: absolute\"\r\n ></div>\r\n </ng-container>\r\n\r\n <!-- Table Presets -->\r\n <ng-container *ngIf=\"activeTopButton === 'table-presets'\">\r\n <div\r\n *ngTemplateOutlet=\"tablePreset\"\r\n class=\"actions-dropdown mt-1\"\r\n style=\"position: absolute\"\r\n ></div>\r\n </ng-container>\r\n\r\n <!-- Table Presets -->\r\n <ng-container *ngIf=\"activeTopButton === 'show-hide-columns'\">\r\n <div\r\n *ngTemplateOutlet=\"showHideColumns\"\r\n class=\"actions-dropdown mt-1\"\r\n style=\"position: absolute\"\r\n ></div>\r\n </ng-container>\r\n </div>\r\n\r\n <div class=\"action-buttons-row\" *ngIf=\"showFullScreenButton\">\r\n <a\r\n *ngIf=\"!isFullScreen\"\r\n class=\"button button-small btn btn-active-primary border border-primary expend d-flex justify-content-center align-items-center\"\r\n (click)=\"toggleFullscreen()\"\r\n data-bs-toggle=\"tooltip\"\r\n data-bs-placement=\"top\"\r\n title=\"Minimise\"\r\n [ngClass]=\"{ minArrow: !isFullScreen, maxArrow: isFullScreen }\"\r\n style=\"transition: color 0.2s\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/expend.svg'\"\r\n class=\"svg-icon svg-icon-2 mb-1\"\r\n ></span>\r\n </a>\r\n <a\r\n *ngIf=\"isFullScreen\"\r\n class=\"button button-small btn btn-active-primary border border-primary expend d-flex justify-content-center align-items-center\"\r\n (click)=\"toggleFullscreen()\"\r\n data-bs-toggle=\"tooltip\"\r\n data-bs-placement=\"top\"\r\n title=\"Maximise\"\r\n [ngClass]=\"{ minArrow: !isFullScreen, maxArrow: isFullScreen }\"\r\n style=\"transition: color 0.2s\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/minimize.svg'\"\r\n class=\"svg-icon svg-icon-2 mb-1\"\r\n ></span>\r\n </a>\r\n </div>\r\n <div>\r\n <!-- Example single danger button -->\r\n\r\n <!-- <button\r\n type=\"button\"\r\n class=\"btn btn-primary btn-sm d-flex gap-2 action-button\"\r\n (click)=\"toggleActions('actions')\"\r\n >\r\n Action\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/Vector.svg'\"\r\n class=\"data-grid-svg-icon\"\r\n ></span>\r\n </button>\r\n <div\r\n *ngIf=\"activeTopButton === 'actions'\"\r\n class=\"actions-dropdown mt-1\"\r\n >\r\n <div class=\"dropdown-menu show\">\r\n <a class=\"dropdown-item\" href=\"#\">Action</a>\r\n <a class=\"dropdown-item\" href=\"#\">Another action</a>\r\n <a class=\"dropdown-item\" href=\"#\">Something else here</a>\r\n <div class=\"dropdown-divider\"></div>\r\n <a class=\"dropdown-item\" href=\"#\">Separated link</a>\r\n </div>\r\n </div> -->\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div\r\n *ngIf=\"showFilters && !showFilterRow\"\r\n class=\"top-filter-row border-top py-2 d-flex justify-content-between align-items-center\"\r\n [style.height.px]=\"topFilterRowHeight\"\r\n >\r\n <!-- LEFT SIDE (Filter tags + Filter button) -->\r\n <div class=\"d-flex gap-2 align-items-center\">\r\n <ng-container>\r\n <div\r\n *ngFor=\"let col of activeFilteredColumns; trackBy: trackByField\"\r\n class=\"filter-tags\"\r\n >\r\n <div\r\n (click)=\"\r\n isActiveFilterOpen = true;\r\n activeTopButton = 'filter-columns';\r\n openFilter(col)\r\n \"\r\n class=\"d-flex justify-content-center align-items-center muted-text add-filter-button active-filters\"\r\n style=\"white-space: nowrap\"\r\n [class.active]=\"\r\n col?.field == selectedColumnForFilter?.field &&\r\n isActiveFilterOpen &&\r\n activeTopButton == 'filter-columns'\r\n \"\r\n >\r\n <span class=\"header-tag mt-0 d-flex align-items-center\">\r\n <span\r\n *ngIf=\"col?.pinned\"\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/pin.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n {{ col.header }}\r\n <span\r\n (click)=\"\r\n $event.stopPropagation(); removeColumnFilterFromColumn(col)\r\n \"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/cross-primary.svg'\r\n \"\r\n class=\"data-grid-svg-icon cross-secondary ms-2 mb-1\"\r\n ></span>\r\n </span>\r\n </div>\r\n\r\n <ng-container\r\n *ngIf=\"\r\n activeTopButton === 'filter-columns' &&\r\n col?.field == selectedColumnForFilter?.field &&\r\n isActiveFilterOpen\r\n \"\r\n >\r\n <div\r\n *ngTemplateOutlet=\"filterColumns; context: { column: col }\"\r\n class=\"actions-dropdown mt-1\"\r\n ></div>\r\n </ng-container>\r\n </div>\r\n </ng-container>\r\n\r\n <!-- Filter Button -->\r\n <div class=\"add-filter-button-menu\">\r\n <div\r\n (click)=\"toggleActions('filter-columns'); isActiveFilterOpen = false\"\r\n class=\"d-flex justify-content-center align-items-center muted-text add-filter-button button-filter\"\r\n style=\"width: 70px\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/plus.svg'\"\r\n class=\"me-2 data-grid-svg-icon\"\r\n ></span>\r\n Filter\r\n </div>\r\n\r\n <ng-container\r\n *ngIf=\"activeTopButton === 'filter-columns' && !isActiveFilterOpen\"\r\n >\r\n <div\r\n *ngTemplateOutlet=\"filterColumns\"\r\n class=\"actions-dropdown mt-1\"\r\n ></div>\r\n </ng-container>\r\n </div>\r\n </div>\r\n\r\n <!-- RIGHT SIDE (Update + Reset) -->\r\n <div class=\"d-flex gap-3 align-items-center\">\r\n <div\r\n (click)=\"savePreset()\"\r\n class=\"text-primary cursor-pointer all-filters-reset-button\"\r\n *ngIf=\"!checkFilterChangesEffect()\"\r\n >\r\n Update View\r\n </div>\r\n\r\n <div\r\n class=\"text-primary cursor-pointer all-filters-reset-button\"\r\n *ngIf=\"!tableFilterViewId && activeFilteredColumns?.length\"\r\n (click)=\"clearAllFilters()\"\r\n >\r\n Reset\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div\r\n [style.height]=\"\r\n showFilters ? 'calc(100% - ' + topFilterRowHeight + 'px)' : '100%'\r\n \"\r\n cdkDropListGroup\r\n class=\"data-grid-table-wrapper overflow-hidden\"\r\n #dataGridContainer\r\n [style.fontFamily]=\"fontFaimly\"\r\n [style.backgroundColor]=\"bodyBackgroundColor\"\r\n id=\"data-grid-main-container\"\r\n >\r\n <div\r\n *ngIf=\"showRowsGrouping\"\r\n [style.height.px]=\"headerRowHeight\"\r\n [cdkDropListData]=\"columns\"\r\n [style.backgroundColor]=\"\r\n topGroupedBadgesBackgroundColor || headerBackgroundColor\r\n \"\r\n cdkDropList\r\n (cdkDropListEntered)=\"enterToTopRowGrouping($event)\"\r\n (cdkDropListExited)=\"exitedFromTheTopRow($event)\"\r\n (cdkDropListDropped)=\"onDropTopGroup($event)\"\r\n [cdkDropListEnterPredicate]=\"canEnterToRowsGrouping\"\r\n id=\"rows-grouping-top-container\"\r\n class=\"border-below d-flex px-4 align-items-center\"\r\n >\r\n <div\r\n class=\"d-flex gap-2 align-items-center\"\r\n [style.color]=\"headerTextColor\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/justify.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n <div *ngIf=\"!draggingInGroupArea && !groupedColumns?.length\">\r\n Drag here to set row groups\r\n </div>\r\n <div\r\n cdkDropListOrientation=\"horizontal\"\r\n cdkDropList\r\n (cdkDropListDropped)=\"onGroupReorder($event)\"\r\n class=\"d-flex\"\r\n >\r\n <div\r\n cdkDrag\r\n [cdkDragLockAxis]=\"'x'\"\r\n *ngFor=\"\r\n let child of groupedColumns;\r\n let i = index;\r\n trackBy: trackByField\r\n \"\r\n class=\"d-flex align-items-center\"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n topGroupingRowPlaceholder;\r\n context: {\r\n $implicit: child,\r\n showChevron:\r\n groupedColumns.length > 1 && i != groupedColumns.length - 1\r\n }\r\n \"\r\n ></ng-container>\r\n <ng-template cdkDragPreview\r\n ><div class=\"p-2 border d-flex gap-2\">\r\n <div>\r\n <span\r\n *ngIf=\"!draggingInGroupArea\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/arrows-move.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n <div>{{ child.header }}</div>\r\n </div>\r\n </ng-template>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n <div\r\n class=\"d-flex overflow-hidden\"\r\n [style.height]=\"\r\n 'calc(100% - ' +\r\n (showRowsGrouping\r\n ? headerRowHeight + footerRowHeight\r\n : footerRowHeight) +\r\n 'px)'\r\n \"\r\n >\r\n <div\r\n class=\"h-100\"\r\n [style.width]=\"\r\n !showSideMenu\r\n ? '100%'\r\n : sideMenuVisible\r\n ? 'calc(100% - 280px)'\r\n : 'calc(100% - 30px)'\r\n \"\r\n >\r\n <div class=\"h-100 transition position-relative w-100\">\r\n <!-- ##################################################################################################################################################################################### -->\r\n <!-- ##################################################################################################################################################################################### -->\r\n <!-- Data Grid Header starts here -->\r\n <!-- ##################################################################################################################################################################################### -->\r\n <!-- ##################################################################################################################################################################################### -->\r\n\r\n <div\r\n class=\"data-grid-header-wrapper w-100\"\r\n [style.color]=\"headerTextColor\"\r\n [style.fontSize.px]=\"headerTextFontsSize\"\r\n [style.backgroundColor]=\"headerBackgroundColor\"\r\n [class.border-below]=\"!hasAnyVisibleColumn\"\r\n [style.height.px]=\"\r\n showColumnsGrouping && showFilterRow\r\n ? headerRowHeight * 3\r\n : showColumnsGrouping || showFilterRow\r\n ? headerRowHeight * 2\r\n : headerRowHeight\r\n \"\r\n >\r\n <!-- ********************************************************************************* -->\r\n <!-- ********************************************************************************* -->\r\n <!-- Data Grid Left Pinned Header starts here -->\r\n <!-- ********************************************************************************* -->\r\n <!-- ********************************************************************************* -->\r\n <div\r\n class=\"data-grid-header left-pinned\"\r\n #leftPinnedHeader\r\n [class.border-right]=\"hasLeftPinnedColumns\"\r\n >\r\n <div\r\n *ngIf=\"showSerialNumber\"\r\n [style.backgroundColor]=\"checkboxesBackgroundColor\"\r\n class=\"select-all-checkbox-cell border-below\"\r\n [style.width.px]=\"55\"\r\n [style.height.px]=\"\r\n showColumnsGrouping && showFilterRow\r\n ? headerRowHeight * 3\r\n : showColumnsGrouping || showFilterRow\r\n ? headerRowHeight * 2\r\n : headerRowHeight\r\n \"\r\n >\r\n S.No\r\n </div>\r\n <div\r\n *ngIf=\"showCheckboxes\"\r\n [style.backgroundColor]=\"checkboxesBackgroundColor\"\r\n class=\"select-all-checkbox-cell border-below\"\r\n [style.height.px]=\"\r\n showColumnsGrouping && showFilterRow\r\n ? headerRowHeight * 3\r\n : showColumnsGrouping || showFilterRow\r\n ? headerRowHeight * 2\r\n : headerRowHeight\r\n \"\r\n >\r\n <input\r\n *ngIf=\"hasAnyVisibleColumn\"\r\n style=\"width: 16px; height: 16px\"\r\n type=\"checkbox\"\r\n [indeterminate]=\"isIndeterminateState(dataSet)\"\r\n [checked]=\"isAllSelected(dataSet)\"\r\n (change)=\"toggleSelectAll(dataSet)\"\r\n />\r\n </div>\r\n <div\r\n [style.backgroundColor]=\"headerBackgroundColor\"\r\n class=\"d-flex\"\r\n cdkDropList\r\n id=\"left-pinned-header\"\r\n cdkDropListOrientation=\"horizontal\"\r\n [cdkDropListData]=\"leftPinnedColumns\"\r\n (cdkDropListEntered)=\"onDropListEnter($event, 'left')\"\r\n (cdkDropListSorted)=\"\r\n onSortGroup($event, 'previewLeftPinnedColumns')\r\n \"\r\n (cdkDropListDropped)=\"onDropGroup()\"\r\n style=\"min-width: 1px\"\r\n >\r\n <div\r\n class=\"dragable-header\"\r\n cdkDrag\r\n [cdkDragData]=\"col\"\r\n *ngFor=\"\r\n let col of leftPinnedColumns;\r\n let i = index;\r\n trackBy: trackByField\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n headerCell;\r\n context: {\r\n $implicit: col,\r\n index: i,\r\n section: 'previewLeftPinnedColumns'\r\n }\r\n \"\r\n ></ng-container>\r\n <ng-template cdkDragPreview\r\n ><div class=\"p-2 border d-flex gap-2\">\r\n <div>\r\n <span\r\n *ngIf=\"!draggingInGroupArea\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath +\r\n 'data-grid/icons/arrows-move.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n <div>{{ col.header }}</div>\r\n </div>\r\n </ng-template>\r\n <ng-template cdkDragPlaceholder>\r\n <div *ngIf=\"!draggingInGroupArea\">\r\n <div\r\n *ngTemplateOutlet=\"\r\n headerCell;\r\n context: {\r\n $implicit: col,\r\n index: i,\r\n section: ''\r\n }\r\n \"\r\n ></div>\r\n </div>\r\n <div\r\n *ngIf=\"draggingInGroupArea\"\r\n class=\"d-flex gap-2 ms-2\"\r\n style=\"opacity: 0.6\"\r\n >\r\n <ng-container\r\n *ngIf=\"col?.children?.length; else singleCol\"\r\n >\r\n <ng-container\r\n *ngFor=\"\r\n let child of col.children;\r\n let i = index;\r\n trackBy: trackByField\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n topGroupingRowPlaceholder;\r\n context: {\r\n $implicit: child,\r\n showChevron:\r\n col.children.length > 1 &&\r\n i != col.children.length - 1\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </ng-container>\r\n\r\n <ng-template #singleCol>\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n topGroupingRowPlaceholder;\r\n context: {\r\n $implicit: col,\r\n showChevron: col?.children?.length > 1\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-template>\r\n </div>\r\n </ng-template>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- ********************************************************************************* -->\r\n <!-- ********************************************************************************* -->\r\n <!-- Data Grid Center Pinned Header starts here -->\r\n <!-- ********************************************************************************* -->\r\n <!-- ********************************************************************************* -->\r\n <div\r\n class=\"data-grid-header center-scrollable\"\r\n #centerPinnedHeader\r\n (scroll)=\"onCenterBodyScroll($event)\"\r\n id=\"center-pinned-header\"\r\n cdkDropList\r\n [cdkDropListConnectedTo]=\"\r\n showRowsGrouping ? ['rows-grouping-top-container'] : []\r\n \"\r\n [cdkDropListData]=\"centerColumns\"\r\n cdkDropListOrientation=\"horizontal\"\r\n [cdkDropListSortingDisabled]=\"\r\n isDisableColumnGrouping && draggingInGroupArea\r\n \"\r\n (cdkDropListEntered)=\"onDropListEnter($event, 'center')\"\r\n (cdkDropListSorted)=\"onSortGroup($event, 'previewCenterColumns')\"\r\n (cdkDropListDropped)=\"onDropGroup()\"\r\n [style.maxWidth]=\"\r\n 'calc(100% - ' +\r\n (rightPinnedHeader.offsetWidth + leftPinnedHeader.offsetWidth) +\r\n 'px)'\r\n \"\r\n >\r\n <div\r\n *ngIf=\"groupedColumns?.length\"\r\n style=\"min-width: 200px\"\r\n class=\"h-100 align-items-center\"\r\n #columnsGroupedBox\r\n id=\"groupBoxHeaderDiv\"\r\n >\r\n <div\r\n class=\"d-flex w-100 justify-content-between align-items-center border-below\"\r\n [style.height.px]=\"\r\n showFilterRow ? headerRowHeight * 2 : headerRowHeight\r\n \"\r\n >\r\n <div class=\"ps-3\">Group</div>\r\n <div class=\"d-flex\">\r\n <div\r\n class=\"three-dots cursor-pointer\"\r\n (click)=\"\r\n openThreeDotsMenu($event, 'group');\r\n isThreeDotsFilterOpen = false\r\n \"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath +\r\n 'data-grid/icons/three-dots-vertical.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n <div\r\n (mousedown)=\"\r\n $event.stopPropagation(); onResizeGroupBox($event)\r\n \"\r\n class=\"resize-handle\"\r\n style=\"margin-right: -2px\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath +\r\n 'data-grid/icons/resize-handle.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div\r\n [style.height.px]=\"headerRowHeight\"\r\n class=\"border-below\"\r\n ></div>\r\n </div>\r\n <span\r\n class=\"d-flex align-items-center justify-content-center cursor-pointer border-below\"\r\n style=\"min-width: 30px; height: 100%\"\r\n *ngIf=\"gridType === 'Assets' || gridType === 'Tasks'\"\r\n >\r\n </span>\r\n <div\r\n class=\"dragable-header\"\r\n (cdkDragStarted)=\"\r\n checkColumnGroupingStatus(col);\r\n dragStartOnGroup(col);\r\n onDragStarted(col)\r\n \"\r\n (cdkDragMoved)=\"onDragMoved($event)\"\r\n (cdkDragEnded)=\"onDragEnded()\"\r\n cdkDrag\r\n [cdkDragData]=\"col\"\r\n *ngFor=\"\r\n let col of centerColumns;\r\n let i = index;\r\n trackBy: trackById\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n headerCell;\r\n context: {\r\n $implicit: col,\r\n index: i,\r\n section: 'previewCenterColumns'\r\n }\r\n \"\r\n >\r\n </ng-container>\r\n <ng-template cdkDragPreview\r\n ><div class=\"p-2 border d-flex gap-2\">\r\n <div>\r\n <span\r\n *ngIf=\"!isOutsideContainer\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath +\r\n (draggingInGroupArea\r\n ? 'data-grid/icons/justify.svg'\r\n : 'data-grid/icons/arrows-move.svg')\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n >\r\n </span>\r\n <span\r\n *ngIf=\"isOutsideContainer\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/eye-cross.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n >\r\n </span>\r\n </div>\r\n <div>{{ col.header }}</div>\r\n </div>\r\n </ng-template>\r\n <ng-template cdkDragPlaceholder>\r\n <div *ngIf=\"!draggingInGroupArea\">\r\n <div\r\n *ngTemplateOutlet=\"\r\n headerCell;\r\n context: {\r\n $implicit: col,\r\n index: i,\r\n section: 'centerColumns'\r\n }\r\n \"\r\n ></div>\r\n </div>\r\n <div\r\n *ngIf=\"draggingInGroupArea && !isOutsideContainer\"\r\n class=\"d-flex gap-2 ms-2\"\r\n style=\"opacity: 0.6\"\r\n >\r\n <ng-container *ngIf=\"col?.children?.length; else singleCol\">\r\n <ng-container\r\n *ngFor=\"\r\n let child of col.children;\r\n let i = index;\r\n trackBy: trackById\r\n \"\r\n >\r\n <ng-container *ngIf=\"child?.is_groupable\">\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n topGroupingRowPlaceholder;\r\n context: {\r\n $implicit: child,\r\n showChevron:\r\n col.children.length > 1 &&\r\n i != col.children.length - 1\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </ng-container>\r\n </ng-container>\r\n\r\n <ng-template #singleCol>\r\n <ng-container *ngIf=\"col?.is_groupable\">\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n topGroupingRowPlaceholder;\r\n context: {\r\n $implicit: col,\r\n showChevron: col?.children?.length > 1\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </ng-template>\r\n </div>\r\n </ng-template>\r\n </div>\r\n </div>\r\n\r\n <!-- ********************************************************************************* -->\r\n <!-- ********************************************************************************* -->\r\n <!-- Data Grid Right Pinned Header starts here -->\r\n <!-- ********************************************************************************* -->\r\n <!-- ********************************************************************************* -->\r\n <div\r\n [style.backgroundColor]=\"headerBackgroundColor\"\r\n cdkDropList\r\n id=\"right-pinned-header\"\r\n [cdkDropListConnectedTo]=\"\r\n showRowsGrouping ? ['rows-grouping-top-container'] : []\r\n \"\r\n cdkDropListOrientation=\"horizontal\"\r\n class=\"data-grid-header right-pinned\"\r\n (cdkDropListSorted)=\"\r\n onSortGroup($event, 'previewRightPinnedColumns')\r\n \"\r\n (cdkDropListEntered)=\"onDropListEnter($event, 'right')\"\r\n (cdkDropListDropped)=\"onDropGroup()\"\r\n #rightPinnedHeader\r\n class=\"right-pinned-header d-flex\"\r\n style=\"min-width: 0.2px\"\r\n >\r\n <div\r\n class=\"dragable-header\"\r\n cdkDrag\r\n [cdkDragData]=\"col\"\r\n *ngFor=\"\r\n let col of rightPinnedColumns;\r\n let i = index;\r\n trackBy: trackById\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n headerCell;\r\n context: {\r\n $implicit: col,\r\n pinnedRight: true,\r\n index: i,\r\n section: 'right'\r\n }\r\n \"\r\n ></ng-container>\r\n <ng-template cdkDragPreview\r\n ><div class=\"p-2 border d-flex gap-2\">\r\n <div>\r\n <span\r\n *ngIf=\"!draggingInGroupArea\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath +\r\n 'data-grid/icons/arrows-move.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n <div>{{ col.header }}</div>\r\n </div>\r\n </ng-template>\r\n <ng-template cdkDragPlaceholder>\r\n <div *ngIf=\"!draggingInGroupArea\">\r\n <div\r\n *ngTemplateOutlet=\"\r\n headerCell;\r\n context: {\r\n $implicit: col,\r\n index: i,\r\n section: 'right'\r\n }\r\n \"\r\n ></div>\r\n </div>\r\n <div\r\n *ngIf=\"draggingInGroupArea\"\r\n class=\"d-flex gap-2 ms-2\"\r\n style=\"opacity: 0.6\"\r\n >\r\n <ng-container *ngIf=\"col?.children?.length; else singleCol\">\r\n <ng-container\r\n *ngFor=\"\r\n let child of col.children;\r\n let i = index;\r\n trackBy: trackById\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n topGroupingRowPlaceholder;\r\n context: {\r\n $implicit: child,\r\n showChevron:\r\n col.children.length > 1 &&\r\n i != col.children.length - 1\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </ng-container>\r\n\r\n <ng-template #singleCol>\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n topGroupingRowPlaceholder;\r\n context: {\r\n $implicit: col,\r\n showChevron: col?.children?.length > 1\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-template>\r\n </div>\r\n </ng-template>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!--########################################################################################################################################################################################################################### -->\r\n <!--########################################################################################################################################################################################################################### -->\r\n <!-- Data Grid Body starts here -->\r\n <!--########################################################################################################################################################################################################################### -->\r\n <!--########################################################################################################################################################################################################################### -->\r\n <div\r\n class=\"h-100 d-flex justify-content-center align-items-center\"\r\n *ngIf=\"!dataSet?.length && !loading && !dataSetLoading\"\r\n >\r\n <!-- <div\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/record-not-found.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></div> -->\r\n <div>No Record Found</div>\r\n </div>\r\n\r\n <div\r\n class=\"position-absolute w-100 h-100 d-flex justify-content-center align-items-center loading-overlay\"\r\n *ngIf=\"loading || dataSetLoading\"\r\n style=\"\r\n z-index: 999;\r\n backdrop-filter: blur(1px);\r\n \"\r\n [style.backgroundColor]=\"bodyBackgroundColor\"\r\n >\r\n <div class=\"spinner-border text-primary\" role=\"status\">\r\n <!-- <span class=\"loader\"></span> -->\r\n <!-- <span class=\"visually-hidden\">Loading...</span> -->\r\n <!-- </div> -->\r\n </div>\r\n </div>\r\n\r\n <div\r\n class=\"data-grid-body-wrapper position-relative d-flex\"\r\n [style.height]=\"bodyWrapperHeight\"\r\n style=\"overflow-y: auto; overflow-x: hidden\"\r\n #mainScroll\r\n (scroll)=\"onMainScroll($event)\"\r\n [style.scrollbarWidth]=\"verticalScrollbarWidth\"\r\n >\r\n <!-- LEFT PINNED -->\r\n <div\r\n [style.height.px]=\"\r\n !groupedColumns.length ? originalDataSet.length * rowHeight : 0\r\n \"\r\n ></div>\r\n <div [class.h-100]=\"originalDataSet.length < 8\">\r\n <div\r\n class=\"data-grid-body left-pinned-body w-100\"\r\n style=\"overflow-y: hidden\"\r\n [class.border-right]=\"hasLeftPinnedColumns\"\r\n [class.transparent-border-right]=\"!hasLeftPinnedColumns\"\r\n [style.transform]=\"'translateY(' + translateY + 'px)'\"\r\n [style.backgroundColor]=\"leftPinnedBackgroundColor\"\r\n [class.h-100]=\"originalDataSet.length < 8\"\r\n *ngIf=\"!loading && !dataSetLoading\"\r\n [@rowDynamic]=\"rowAnimation\"\r\n\r\n \r\n >\r\n <ng-container\r\n *ngFor=\"\r\n let row of visibleRows;\r\n let i = index;\r\n trackBy: trackById\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n rowCell;\r\n context: {\r\n $implicit: row,\r\n columns: previewLeftPinnedColumns,\r\n isEven: (startIndex + i) % 2 === 0,\r\n isOdd: (startIndex + i) % 2 !== 0,\r\n isLeft: true,\r\n section: 'left',\r\n isTotalRow: false\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n <ng-container *ngIf=\"showTotalAmountRow && originalDataSet?.length\">\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n rowCell;\r\n context: {\r\n $implicit: { __virtualIndex: 0 },\r\n columns: previewLeftPinnedColumns,\r\n isEven: false,\r\n isOdd: false,\r\n section: 'left',\r\n isTotalRow: true\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </div>\r\n </div>\r\n\r\n <!-- CENTER -->\r\n <div\r\n class=\"h-100\"\r\n [style.width.px]=\"centerPinnedHeader.clientWidth\"\r\n [style.backgroundColor]=\"bodyBackgroundColor\"\r\n >\r\n <div\r\n class=\"data-grid-body center-scrollable\"\r\n [class.h-100]=\"originalDataSet.length < 8\"\r\n style=\"overflow-y: hidden; overflow-x: auto\"\r\n [style.transform]=\"'translateY(' + translateY + 'px)'\"\r\n [style.backgroundColor]=\"bodyBackgroundColor\"\r\n #centerScrollableBody\r\n (scroll)=\"onCenterBodyScroll($event)\"\r\n [style.boxShadow]=\"leftPinnedBoxshadow\"\r\n >\r\n <div [@rowDynamic]=\"rowAnimation\" *ngIf=\"!loading && !dataSetLoading\">\r\n <ng-container\r\n *ngFor=\"\r\n let row of visibleRows;\r\n let i = index;\r\n trackBy: trackById\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n rowCell;\r\n context: {\r\n $implicit: row,\r\n columns: previewCenterColumns,\r\n isEven: (startIndex + i) % 2 === 0,\r\n isOdd: (startIndex + i) % 2 !== 0,\r\n section: 'center',\r\n isTotalRow: false\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </div>\r\n <ng-container *ngIf=\"showTotalAmountRow && originalDataSet?.length\">\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n rowCell;\r\n context: {\r\n $implicit: { __virtualIndex: 0 },\r\n columns: previewCenterColumns,\r\n isEven: false,\r\n isOdd: false,\r\n section: 'center',\r\n isTotalRow: true\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </div>\r\n </div>\r\n\r\n <!-- RIGHT PINNED -->\r\n <div\r\n class=\"right-pinned-body-wrapper\"\r\n *ngIf=\"hasRightPinnedColumns\"\r\n [class.h-100]=\"originalDataSet.length < 8\"\r\n [style.maxWidth.px]=\"\r\n isScrollbarVisible\r\n ? rightPinnedHeader.offsetWidth - 15\r\n : rightPinnedHeader.offsetWidth\r\n \"\r\n [style.backgroundColor]=\"rightPinnedBackgroundColor\"\r\n >\r\n <div\r\n class=\"data-grid-body right-pinned-body w-100 h-100\"\r\n style=\"overflow-y: hidden\"\r\n [style.transform]=\"'translateY(' + translateY + 'px)'\"\r\n [style.boxShadow]=\"rightPinnedBoxshadow\"\r\n [style.backgroundColor]=\"rightPinnedBackgroundColor\"\r\n *ngIf=\"!loading && !dataSetLoading\"\r\n [@rowDynamic]=\"rowAnimation\"\r\n >\r\n <ng-container\r\n *ngFor=\"\r\n let row of visibleRows;\r\n let i = index;\r\n trackBy: trackById\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n rowCell;\r\n context: {\r\n $implicit: row,\r\n columns: previewRightPinnedColumns,\r\n isEven: (startIndex + i) % 2 === 0,\r\n isOdd: (startIndex + i) % 2 !== 0,\r\n section: 'right',\r\n isTotalRow: false\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n <ng-container *ngIf=\"showTotalAmountRow && originalDataSet?.length\">\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n rowCell;\r\n context: {\r\n $implicit: { __virtualIndex: 0 },\r\n columns: previewRightPinnedColumns,\r\n isEven: false,\r\n isOdd: false,\r\n section: 'right',\r\n isTotalRow: true\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </div>\r\n </div>\r\n\r\n <div\r\n style=\"top: auto; left: auto\"\r\n (click)=\"\r\n $event.stopPropagation();\r\n fullscreenImage = null;\r\n cdr.detectChanges()\r\n \"\r\n [style.width.px]=\"dataGridContainer.offsetWidth\"\r\n [style.height.px]=\"\r\n dataGridContainer.offsetHeight - (footerRowHeight + 100)\r\n \"\r\n class=\"image-modal full-image-modal\"\r\n *ngIf=\"fullscreenImage\"\r\n >\r\n <img\r\n (click)=\"$event.stopPropagation()\"\r\n [src]=\"fullscreenImage\"\r\n alt=\"Fullscreen Image\"\r\n />\r\n </div>\r\n <div\r\n *ngIf=\"selectedRows.size > 0 && showTaskbar\"\r\n class=\"taskbar w-100\"\r\n [style.bottom.px]=\"85\"\r\n >\r\n <div class=\"selected-rows-action-bar\" [@slideUp]>\r\n <span class=\"selected-count\">\r\n {{ selectedRows.size }} selected of\r\n {{\r\n paginationConfig.totalResults ||\r\n config?.paginationParams?.totalItems\r\n }}\r\n Total\r\n </span>\r\n <div class=\"action-buttons d-flex align-items-center\">\r\n <ng-container\r\n *ngFor=\"let action of taskbarActions; let i = index\"\r\n >\r\n <ng-container *ngIf=\"action?.has_permission\">\r\n <span\r\n class=\"action-btn verified btn {{ action }}\"\r\n (click)=\"onVerifyClick(action?.actionName)\"\r\n >{{ action?.actionName }}</span\r\n >\r\n <span\r\n *ngIf=\"\r\n taskbarActions.length > 1 &&\r\n i !== taskbarActions.length - 1 &&\r\n taskbarActions[i + 1]?.has_permission\r\n \"\r\n class=\"\"\r\n >|</span\r\n >\r\n </ng-container>\r\n </ng-container>\r\n <button (click)=\"clearSelectionState(tableType);selectedRows.clear();\" class=\"clear-btn ms-2 mt-2\">\r\n <i class=\"bi bi-x-circle\"></i> Clear Selection\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n <!-- Vertical Fake scroll Bar -->\r\n <!-- <div\r\n (scroll)=\"onMainFakeScroll($event)\"\r\n class=\"fake-scrollbar fake-scrollbar-vertical d-none\"\r\n [style.scrollbarWidth]=\"verticalScrollbarWidth\"\r\n [style.top.px]=\"\r\n showColumnsGrouping && showFilterRow\r\n ? headerRowHeight * 3\r\n : showColumnsGrouping || showFilterRow\r\n ? headerRowHeight * 2\r\n : headerRowHeight\r\n \"\r\n #fakeScroll\r\n [style.height]=\"bodyWrapperHeight\"\r\n style=\"\r\n overflow-y: auto;\r\n overflow-x: hidden;\r\n width: 17px;\r\n position: absolute;\r\n right: 0;\r\n background-color: f1f2f3;\r\n z-index: 10;\r\n \"\r\n >\r\n <div [style.height.px]=\"rowHeight * dataSetLength\"></div>\r\n </div> -->\r\n </div>\r\n\r\n <!-- Horizintal Fake Scrollbars -->\r\n <div\r\n class=\"d-flex justify-content-between\"\r\n *ngIf=\"hasScroll && !shouldRestoreScroll\"\r\n >\r\n <div\r\n [style.scrollbarWidth]=\"horizintalScrollbarWidth\"\r\n class=\"fake-horizintal-scrollbar\"\r\n #fakeScroll\r\n [style.width.px]=\"leftPinnedHeader.offsetWidth\"\r\n style=\"overflow-x: scroll\"\r\n ></div>\r\n <div\r\n [style.scrollbarWidth]=\"horizintalScrollbarWidth\"\r\n (scroll)=\"onCenterBodyScroll($event)\"\r\n class=\"fake-horizintal-scrollbar\"\r\n #horizintalFakeScroll\r\n [style.width.px]=\"centerPinnedHeader.offsetWidth\"\r\n >\r\n <div [style.width.px]=\"centerPinnedHeader.scrollWidth - 10\"></div>\r\n </div>\r\n <div\r\n [style.scrollbarWidth]=\"horizintalScrollbarWidth\"\r\n class=\"fake-horizintal-scrollbar\"\r\n #fakeScroll\r\n [style.width.px]=\"rightPinnedHeader.offsetWidth\"\r\n style=\"overflow-x: scroll\"\r\n ></div>\r\n </div>\r\n </div>\r\n\r\n <!-- Side Menu Implemented Here -->\r\n <div\r\n *ngIf=\"showSideMenu\"\r\n [style.width.px]=\"sideMenuVisible ? 280 : 30\"\r\n class=\"right-menu h-100\"\r\n [style.backgroundColor]=\"sidemenuBackgroundColor\"\r\n >\r\n <div class=\"h-100 d-flex flex-row-reverse\">\r\n <div\r\n style=\"width: 30px\"\r\n class=\"d-flex flex-column align-items-center cursor-pointer\"\r\n [class.border-start]=\"sideMenuVisible\"\r\n >\r\n <div\r\n (click)=\"toggleSideMenu('cols')\"\r\n [class.bg-fff]=\"\r\n currentOpenedSideMenue == 'cols' && sideMenuVisible\r\n \"\r\n [class.border-below]=\"sideMenuVisible\"\r\n class=\"columns-button d-flex flex-column align-items-center\"\r\n >\r\n <div>\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/ui-checks-grid.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n <div class=\"side-menue-text\">Columns</div>\r\n </div>\r\n\r\n <div\r\n (click)=\"toggleSideMenu('filtrs')\"\r\n [class.bg-fff]=\"\r\n currentOpenedSideMenue == 'filtrs' && sideMenuVisible\r\n \"\r\n [class.border-below]=\"\r\n sideMenuVisible && currentOpenedSideMenue == 'filtrs'\r\n \"\r\n class=\"columns-button d-flex flex-column align-items-center\"\r\n >\r\n <div>\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n <div class=\"side-menue-text\">Filter</div>\r\n </div>\r\n </div>\r\n <div\r\n class=\"h-100\"\r\n *ngIf=\"sideMenuVisible\"\r\n [ngStyle]=\"{ width: sideMenuVisible ? '250px' : '' }\"\r\n >\r\n <div class=\"h-100\">\r\n <ng-container\r\n *ngIf=\"currentOpenedSideMenue == 'cols' && sideMenuVisible\"\r\n >\r\n <ng-container *ngTemplateOutlet=\"columnPannel\"></ng-container>\r\n <!-- Column Items -->\r\n <div class=\"column-panel-body px-3\">\r\n <ng-container\r\n *ngFor=\"let col of columns; trackBy: trackByField\"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"columnPanelItem; context: { col: col }\"\r\n ></ng-container>\r\n </ng-container>\r\n </div>\r\n <hr />\r\n\r\n <div class=\"side-menu-row-groups\" style=\"height: 30%\">\r\n <ng-container\r\n *ngTemplateOutlet=\"sideMenuRowGroups\"\r\n ></ng-container>\r\n </div>\r\n </ng-container>\r\n <ng-container\r\n *ngIf=\"currentOpenedSideMenue == 'filtrs' && sideMenuVisible\"\r\n >\r\n <ng-container *ngTemplateOutlet=\"sideFilters\"></ng-container>\r\n </ng-container>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n <div\r\n [style.height.px]=\"footerRowHeight\"\r\n class=\"border-top\"\r\n [style.backgroundColor]=\"footerRowBackgroundColor\"\r\n >\r\n <!-- Rows: <span class=\"fw-500 ms-1\">{{ dataSet.length }}</span> -->\r\n\r\n <div\r\n class=\"pagination-container\"\r\n [style.height.px]=\"footerRowHeight\"\r\n [style.padding.px]=\"footerPadding\"\r\n >\r\n <div class=\"page-size\">\r\n <select\r\n [(ngModel)]=\"paginationConfig.limit\"\r\n (change)=\"onPageSizeChange()\"\r\n >\r\n <option *ngFor=\"let size of pageSizeOptions\" [value]=\"size\">\r\n {{ size }}\r\n </option>\r\n </select>\r\n <span class=\"separator\"> per page </span>\r\n </div>\r\n\r\n <div class=\"page-info\">\r\n Results:\r\n {{ (paginationConfig.page - 1) * paginationConfig.limit + 1 }}-{{\r\n paginationConfig.page * paginationConfig.limit <\r\n paginationConfig.totalResults\r\n ? paginationConfig.page * paginationConfig.limit\r\n : paginationConfig.totalResults\r\n }}\r\n of\r\n {{ paginationConfig.totalResults }}\r\n </div>\r\n\r\n <div class=\"page-buttons\">\r\n <button\r\n (click)=\"goToPage(paginationConfig.page - 1)\"\r\n [disabled]=\"paginationConfig.page === 1\"\r\n >\r\n \u2039\r\n </button>\r\n\r\n <ng-container *ngFor=\"let page of visiblePages\">\r\n <button\r\n *ngIf=\"page !== '...'\"\r\n (click)=\"goToPage(page)\"\r\n [class.active]=\"page === paginationConfig.page\"\r\n >\r\n {{ page }}\r\n </button>\r\n <span *ngIf=\"page === '...'\">...</span>\r\n </ng-container>\r\n\r\n <button\r\n (click)=\"goToPage(paginationConfig.page + 1)\"\r\n [disabled]=\"paginationConfig.page === paginationConfig.totalResults\"\r\n >\r\n \u203A\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<!-- ------------------------------------------------------------------------------------------------------------------------ -->\r\n<!-- ------------------------------------------------------------------------------------------------------------------------ -->\r\n<!-- Header Cell Template -->\r\n<!-- ------------------------------------------------------------------------------------------------------------------------ -->\r\n<!-- ------------------------------------------------------------------------------------------------------------------------ -->\r\n\r\n<ng-template\r\n #headerCell\r\n let-col\r\n let-pinnedRight=\"pinnedRight\"\r\n let-i=\"index\"\r\n let-columnIndex=\"index\"\r\n let-sections=\"section\"\r\n let-calledFromNestedPlaceholder=\"calledFromNestedPlaceholder\"\r\n>\r\n <div>\r\n <!-- Group Header -->\r\n <ng-container *ngIf=\"col.children?.length > 0; else flatHeader\">\r\n <div cdkDroplistGroup class=\"group-column-wrapper\">\r\n <!-- Parent Header -->\r\n <div\r\n *ngIf=\"shouldTheGroupHeaderShow(col)\"\r\n class=\"header-cell group-header\"\r\n [style.height.px]=\"headerRowHeight\"\r\n [style.min-height.px]=\"headerRowHeight\"\r\n [style.max-height.px]=\"headerRowHeight\"\r\n [class.border-right]=\"showVerticalBorder\"\r\n [style.gridColumn]=\"'span ' + col.children.length\"\r\n [style.fontWeight]=\"headerFontWeight\"\r\n [class.flex-row-reverse]=\"pinnedRight\"\r\n [class.justify-content-end]=\"pinnedRight\"\r\n style=\"grid-row: 1\"\r\n >\r\n <div\r\n class=\"group-header-content\"\r\n [title]=\"col.header\"\r\n [class.ms-2]=\"pinnedRight\"\r\n >\r\n {{ col.header }}\r\n </div>\r\n <div\r\n class=\"resize-handle\"\r\n (dblclick)=\"autosizeColumn(col.children)\"\r\n (mousedown)=\"\r\n $event.stopPropagation(); onResizeGroup($event, col, pinnedRight)\r\n \"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/resize-handle.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n </div>\r\n\r\n <!-- Child Headers and Filters -->\r\n\r\n <div\r\n class=\"d-flex\"\r\n cdkDropList\r\n cdkDropListOrientation=\"horizontal\"\r\n [cdkDropListData]=\"col.children\"\r\n (cdkDropListSorted)=\"onChildDroplistSorted($event, sections)\"\r\n (cdkDropListDropped)=\"onChildDroplistDroped($event)\"\r\n [cdkDropListSortingDisabled]=\"false\"\r\n [cdkDropListConnectedTo]=\"\r\n showRowsGrouping ? ['rows-grouping-top-container'] : []\r\n \"\r\n >\r\n <div\r\n cdkDrag\r\n [cdkDragData]=\"child\"\r\n *ngFor=\"let child of col.children; let i = index\"\r\n >\r\n <!-- Child Header -->\r\n <ng-container *ngIf=\"child.is_visible && !child['isRowGrouped']\">\r\n <div\r\n cdkDragHandle\r\n class=\"header-cell one-row-header-cells cursor-pointer\"\r\n [class.border-right]=\"showVerticalBorder\"\r\n [attr.field]=\"child.field\"\r\n [style.width.px]=\"child.width\"\r\n [style.min-width.px]=\"child.width\"\r\n [style.min-height.px]=\"headerRowHeight\"\r\n [style.max-height.px]=\"headerRowHeight\"\r\n [style.fontWeight]=\"headerFontWeight\"\r\n style=\"grid-row: 2\"\r\n [class.filter-applied-on-text]=\"isFilterAppliedOnColumn(child)\"\r\n >\r\n <div\r\n class=\"d-flex justify-content-between h-100 align-items-center w-100\"\r\n >\r\n <div\r\n class=\"d-flex justify-content-between align-items-center w-100\"\r\n [class.flex-row-reverse]=\"pinnedRight\"\r\n >\r\n <div\r\n class=\"text-ellipsis h-100 d-flex align-items-center w-100\"\r\n [title]=\"col.header\"\r\n [class.w-100]=\"pinnedRight\"\r\n >\r\n <div\r\n class=\"text-ellipsis h-100\"\r\n [class.editable-header]=\"child?.is_editable\"\r\n (click)=\"\r\n openThreeDotsMenu($event, child);\r\n openFilteronThreeDotsClick(child)\r\n \"\r\n >\r\n {{ child.header }}\r\n </div>\r\n </div>\r\n\r\n <div\r\n class=\"position-relative d-flex\"\r\n [class.flex-row-reverse]=\"pinnedRight\"\r\n >\r\n <div\r\n [class.me-2]=\"pinnedRight\"\r\n class=\"d-flex align-items-center\"\r\n *ngIf=\"child.pinned\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/pin-blue.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n <div\r\n class=\"three-dots p-1\"\r\n (click)=\"\r\n openThreeDotsMenu($event, child);\r\n isThreeDotsFilterOpen = false\r\n \"\r\n style=\"cursor: pointer\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath +\r\n 'data-grid/icons/three-dots-vertical.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n\r\n <!-- Only show menu if this column is active -->\r\n <div\r\n class=\"position-absolute\"\r\n *ngIf=\"activeCol === child\"\r\n style=\"top: -50%; z-index: 21\"\r\n [style.left.px]=\"\r\n -(!child?.pinned ? centerPinnedHeader.scrollLeft : 0)\r\n \"\r\n [style.top.px]=\"\r\n isThreeDotsFilterOpen\r\n ? showFilterRow || showColumnsGrouping\r\n ? headerRowHeight * 2 - 10\r\n : headerRowHeight - 10\r\n : 0\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n columnMenu;\r\n context: {\r\n col: child,\r\n isNestedTable: false,\r\n section: sections,\r\n columnIndex: columnIndex,\r\n childColIndex: i\r\n }\r\n \"\r\n ></ng-container>\r\n </div>\r\n\r\n <div\r\n class=\"resize-handle\"\r\n (dblclick)=\"autosizeColumn(child)\"\r\n (mousedown)=\"\r\n $event.stopPropagation();\r\n onResizeColumn($event, child)\r\n \"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath +\r\n 'data-grid/icons/resize-handle.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Filter Cell -->\r\n <div\r\n *ngIf=\"showFilterRow\"\r\n [style.backgroundColor]=\"headerBackgroundColor\"\r\n class=\"header-cell filter-cell\"\r\n [class.border-right]=\"showVerticalBorder\"\r\n [attr.field]=\"child.field\"\r\n [style.width.px]=\"child.width\"\r\n [style.min-width.px]=\"child.width\"\r\n [style.height.px]=\"headerRowHeight\"\r\n [style.min-height.px]=\"headerRowHeight\"\r\n [style.max-height.px]=\"headerRowHeight\"\r\n [class.border-right]=\"showVerticalBorder\"\r\n style=\"grid-row: 3\"\r\n >\r\n <div\r\n class=\"header-cell filter-cell\"\r\n [attr.field]=\"col.field\"\r\n [style.width.px]=\"col.width\"\r\n [style.min-width.px]=\"col.width\"\r\n [style.height.px]=\"headerRowHeight\"\r\n [style.min-height.px]=\"headerRowHeight\"\r\n [style.max-height.px]=\"headerRowHeight\"\r\n >\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Filter\"\r\n [(ngModel)]=\"child.filterValue\"\r\n (ngModelChange)=\"onFilterChange(child)\"\r\n (paste)=\"onFilterChange(child); applyDropdownFilter()\"\r\n [readonly]=\"\r\n child?.type == 'dropdown' || child?.type == 'image' || child?.type == 'array'\r\n \"\r\n [class.disabled-search-input]=\"\r\n child?.type == 'dropdown' || child?.type == 'image' || child?.type == 'array'\r\n \"\r\n (click)=\"\r\n $event.stopPropagation();\r\n openFilterFromDisabledSearchedInput(child)\r\n \"\r\n (keydown.enter)=\"applyDropdownFilter()\"\r\n (mousedown)=\"$event.stopPropagation()\"\r\n />\r\n <span\r\n class=\"filter-icon-wrapper\"\r\n (click)=\"$event.stopPropagation(); openFilter(child)\"\r\n [class.filter-applied]=\"isFilterAppliedOnColumn(child)\"\r\n [class.pe-none]=\"child?.type == 'image'\"\r\n ><span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n <span\r\n *ngIf=\"isFilterAppliedOnColumn(child)\"\r\n style=\"\r\n width: 7px;\r\n height: 7px;\r\n box-shadow: 0px 0px 3px #7486ff;\r\n background-color: rgb(0 163 233);\r\n position: absolute;\r\n right: 4px;\r\n top: 12px;\r\n \"\r\n class=\"rounded-circle d-block\"\r\n ></span\r\n ></span>\r\n\r\n <div\r\n class=\"position-absolute filter-row-filter-wrapper\"\r\n *ngIf=\"activeFilterCell?.field == child?.field\"\r\n style=\"top: 100%; right: 0; z-index: 99\"\r\n [style.left.px]=\"\r\n child?.pinned ? 0 : -centerPinnedHeader.scrollLeft\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"filterMenu; context: { col: child }\"\r\n ></ng-container>\r\n </div>\r\n </div>\r\n </div>\r\n </ng-container>\r\n <ng-template cdkDragPreview\r\n ><div class=\"p-2 border d-flex gap-2\">\r\n <div\r\n *ngIf=\"\r\n !draggingInGroupArea ||\r\n (child.is_groupable && draggingInGroupArea)\r\n \"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/arrows-move.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n <div *ngIf=\"draggingInGroupArea && !child.is_groupable\">\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/ban.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n <div>{{ child.header }}</div>\r\n </div>\r\n </ng-template>\r\n <ng-template cdkDragPlaceholder>\r\n <div *ngIf=\"!draggingInGroupArea\" class=\"position-relative\">\r\n <div\r\n *ngTemplateOutlet=\"\r\n childHeaderPlaceholder;\r\n context: {\r\n $implicit: child,\r\n index: i,\r\n sections: sections,\r\n calledFromNestedPlaceholder: true,\r\n }\r\n \"\r\n ></div>\r\n </div>\r\n <div\r\n *ngIf=\"draggingInGroupArea && child?.is_groupable\"\r\n class=\"d-flex gap-2 ms-2\"\r\n style=\"opacity: 0.6\"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n topGroupingRowPlaceholder;\r\n context: {\r\n $implicit: child,\r\n showChevron: false,\r\n pinnedRight: pinnedRight,\r\n sections: sections,\r\n index: i\r\n }\r\n \"\r\n ></ng-container>\r\n </div>\r\n </ng-template>\r\n </div>\r\n </div>\r\n </div>\r\n </ng-container>\r\n\r\n <!-- Flat Header || Single Header Cell-->\r\n <ng-template #flatHeader>\r\n <div\r\n class=\"group-column-wrapper\"\r\n *ngIf=\"col.is_visible && !col['isRowGrouped']\"\r\n >\r\n <!-- Full-height Header Cell (spans 2 rows visually) -->\r\n <div\r\n class=\"header-cell one-row-header-cells\"\r\n [attr.field]=\"col.field\"\r\n [style.width.px]=\"col.width\"\r\n [style.min-width.px]=\"col.width\"\r\n [class.border-right]=\"showVerticalBorder\"\r\n [style.min-height.px]=\"\r\n showColumnsGrouping ? headerRowHeight * 2 : headerRowHeight\r\n \"\r\n [style.height.px]=\"\r\n showColumnsGrouping ? headerRowHeight * 2 : headerRowHeight\r\n \"\r\n [style.fontWeight]=\"headerFontWeight\"\r\n style=\"grid-row: 1 / span 2\"\r\n >\r\n <div\r\n class=\"d-flex justify-content-between h-100 align-items-center w-100\"\r\n >\r\n <div\r\n class=\"d-flex justify-content-between w-100 align-items-center\"\r\n [class.flex-row-reverse]=\"pinnedRight\"\r\n >\r\n <div\r\n class=\"text-ellipsis h-100 d-flex align-items-center w-100\"\r\n [title]=\"col.header\"\r\n >\r\n <div\r\n class=\"text-ellipsis h-100 cursor-pointer\"\r\n [class.editable-header]=\"col?.is_editable\"\r\n [class.filter-applied-on-text]=\"isFilterAppliedOnColumn(col)\"\r\n (click)=\"\r\n openThreeDotsMenu($event, col);\r\n openFilteronThreeDotsClick(col)\r\n \"\r\n >\r\n {{ col.header }}\r\n </div>\r\n </div>\r\n\r\n <div\r\n class=\"position-relative d-flex\"\r\n [class.flex-row-reverse]=\"pinnedRight\"\r\n >\r\n <div\r\n [class.me-2]=\"pinnedRight\"\r\n class=\"d-flex align-items-center\"\r\n *ngIf=\"col?.pinned\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/pin-blue.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n <div\r\n [class.me-2]=\"col.order_by\"\r\n class=\"d-flex align-items-center\"\r\n *ngIf=\"sortingConfig?.field == col.field\"\r\n >\r\n <!-- Ascending Sort Icon -->\r\n <span\r\n *ngIf=\"sortingConfig?.order_by == 'asc'\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/sort-asc.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center mt-1 cursor-pointer\"\r\n (click)=\"sortDesc(col)\"\r\n [class.active]=\"sortingConfig?.order_by === 'asc'\"\r\n ></span>\r\n\r\n <!-- Descending Sort Icon -->\r\n <span\r\n *ngIf=\"sortingConfig?.order_by == 'desc'\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/sort-desc.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center mt-1 cursor-pointer\"\r\n (click)=\"sortAsc(col)\"\r\n [class.active]=\"sortingConfig?.order_by === 'desc'\"\r\n ></span>\r\n </div>\r\n <div\r\n class=\"three-dots p-1\"\r\n (click)=\"\r\n openThreeDotsMenu($event, col);\r\n isThreeDotsFilterOpen = false\r\n \"\r\n style=\"cursor: pointer\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath +\r\n 'data-grid/icons/three-dots-vertical.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n\r\n <!-- Only show menu if this column is active -->\r\n <div\r\n class=\"position-absolute\"\r\n *ngIf=\"activeCol === col\"\r\n style=\"top: -50%; z-index: 21\"\r\n [style.left.px]=\"\r\n -(!col?.pinned ? centerPinnedHeader.scrollLeft : 0)\r\n \"\r\n [style.top.px]=\"\r\n isThreeDotsFilterOpen\r\n ? showFilterRow || showColumnsGrouping\r\n ? headerRowHeight * 2 - 10\r\n : headerRowHeight - 10\r\n : 0\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n columnMenu;\r\n context: {\r\n col: col,\r\n isNestedTable: false,\r\n section: sections,\r\n columnIndex: columnIndex,\r\n childColIndex: 0\r\n },\r\n \"\r\n ></ng-container>\r\n </div>\r\n\r\n <div\r\n class=\"resize-handle\"\r\n [class.w-100]=\"col.pinned == 'right'\"\r\n (dblclick)=\"autosizeColumn(col)\"\r\n (mousedown)=\"\r\n $event.stopPropagation(); onResizeColumn($event, col)\r\n \"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/resize-handle.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Filter Cell -->\r\n <div\r\n *ngIf=\"showFilterRow\"\r\n [style.backgroundColor]=\"headerBackgroundColor\"\r\n class=\"header-cell filter-cell\"\r\n [class.border-right]=\"showVerticalBorder\"\r\n [attr.field]=\"col.field\"\r\n [style.width.px]=\"col.width\"\r\n [style.min-width.px]=\"col.width\"\r\n [style.height.px]=\"headerRowHeight\"\r\n [style.min-height.px]=\"headerRowHeight\"\r\n [style.max-height.px]=\"headerRowHeight\"\r\n >\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Filter\"\r\n [(ngModel)]=\"col.filterValue\"\r\n (ngModelChange)=\"onFilterChange(col)\"\r\n [readonly]=\"col?.type == 'dropdown' || col?.type == 'image' || col?.type == 'array'\"\r\n [class.disabled-search-input]=\"\r\n col?.type == 'dropdown' || col?.type == 'image' || col?.type == 'array'\r\n \"\r\n (paste)=\"onPasteInFilterRowSearch($event, col)\"\r\n (click)=\"\r\n $event.stopPropagation(); openFilterFromDisabledSearchedInput(col)\r\n \"\r\n (keydown.enter)=\"applyDropdownFilter()\"\r\n (mousedown)=\"$event.stopPropagation()\"\r\n />\r\n <span\r\n class=\"filter-icon-wrapper\"\r\n (click)=\"$event.stopPropagation(); openFilter(col)\"\r\n [class.filter-applied]=\"isFilterAppliedOnColumn(col)\"\r\n [class.pe-none]=\"col?.type == 'image'\"\r\n ><span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n <span\r\n *ngIf=\"isFilterAppliedOnColumn(col)\"\r\n style=\"\r\n width: 7px;\r\n height: 7px;\r\n box-shadow: 0px 0px 3px #7486ff;\r\n background-color: rgb(0 163 233);\r\n position: absolute;\r\n right: 4px;\r\n top: 12px;\r\n \"\r\n class=\"rounded-circle d-block\"\r\n ></span\r\n ></span>\r\n\r\n <div\r\n class=\"position-absolute filter-row-filter-wrapper\"\r\n *ngIf=\"activeFilterCell === col\"\r\n style=\"top: 100%; right: 0; z-index: 99\"\r\n [style.left.px]=\"col?.pinned ? 0 : -centerPinnedHeader.scrollLeft\"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"filterMenu; context: { col: col }\"\r\n ></ng-container>\r\n </div>\r\n </div>\r\n </div>\r\n </ng-template>\r\n </div>\r\n</ng-template>\r\n\r\n<!-- -------------------------------------------------------------------------------------------------------------------------------------------------------------------- -->\r\n<!-- -------------------------------------------------------------------------------------------------------------------------------------------------------------------- -->\r\n<!-- Body Cell Template -->\r\n<!-- -------------------------------------------------------------------------------------------------------------------------------------------------------------------- -->\r\n<!-- -------------------------------------------------------------------------------------------------------------------------------------------------------------------- -->\r\n\r\n<ng-template\r\n #rowCell\r\n let-row\r\n let-columns=\"columns\"\r\n let-isEven=\"isEven\"\r\n let-isOdd=\"isOdd\"\r\n let-isLeftSection=\"isLeft\"\r\n let-section=\"section\"\r\n let-rowIndex=\"rowIndex\"\r\n let-isTotalRow=\"isTotalRow\"\r\n>\r\n <!-- Check if row is a group -->\r\n <ng-container\r\n *ngTemplateOutlet=\"groupRowTemplate; context: { $implicit: row, depth: 0 }\"\r\n ></ng-container>\r\n <ng-template #groupRowTemplate let-row let-depth=\"depth\">\r\n <ng-container *ngIf=\"row.isGroup; else regularRow\">\r\n <!-- Group Header -->\r\n <div\r\n class=\"group-header-row d-flex align-items-center\"\r\n [style.height.px]=\"rowHeight\"\r\n [class.border-below]=\"section !== 'center'\"\r\n [style.width]=\"\r\n section === 'center'\r\n ? (centerScrollableBody?.scrollWidth ?? 0) + 'px'\r\n : '100%'\r\n \"\r\n >\r\n <div\r\n *ngIf=\"section == 'left'\"\r\n class=\"h-100 d-flex\"\r\n [style.width.px]=\"leftPinnedHeader.offsetWidth - 1\"\r\n [class.row-selected]=\"rowSelectedIndexes.has(row.__virtualIndex)\"\r\n >\r\n <div\r\n *ngIf=\"showSerialNumber\"\r\n style=\"width: 50px\"\r\n class=\"d-flex align-items-center h-100 border-right justify-content-end pe-2 s-no\"\r\n [style.backgroundColor]=\"checkboxesBackgroundColor\"\r\n [style.width.px]=\"55\"\r\n [style.cursor]=\"\r\n 'url(' +\r\n singleSpaAssetsPath +\r\n 'data-grid/icons/arrow-right.svg), auto'\r\n \"\r\n (mousedown)=\"onRowMouseDown(row.__virtualIndex, $event)\"\r\n (mouseover)=\"onRowMouseOver(row.__virtualIndex, $event)\"\r\n [style.color]=\"checkboxesColor\"\r\n >\r\n {{ getStartIndex() + (row.__virtualIndex - 1) || \"\" }}\r\n </div>\r\n <div\r\n *ngIf=\"showCheckboxes\"\r\n style=\"width: 50px\"\r\n class=\"d-flex align-items-center justify-content-center h-100 border-right\"\r\n [style.backgroundColor]=\"checkboxesBackgroundColor\"\r\n [class.row-selected]=\"rowSelectedIndexes.has(row.__virtualIndex)\"\r\n [class.left-selection-border]=\"\r\n rowSelectedIndexes.has(row.__virtualIndex)\r\n \"\r\n [class.first-row-selected]=\"firstSelectedRow === row.__virtualIndex\"\r\n [class.last-row-selected]=\"lastSelectedRow === row.__virtualIndex\"\r\n [style.color]=\"checkboxesColor\"\r\n >\r\n <input\r\n style=\"width: 16px; height: 16px\"\r\n type=\"checkbox\"\r\n [checked]=\"getGroupCheckedState(row) === true\"\r\n [indeterminate]=\"getGroupCheckedState(row) === undefined\"\r\n (change)=\"selectGroupRow($event, row)\"\r\n />\r\n\r\n </div>\r\n </div>\r\n\r\n <div\r\n *ngIf=\"section == 'center'\"\r\n [style.width.px]=\"centerPinnedHeader.scrollWidth\"\r\n [style.minWidth.px]=\"centerPinnedHeader.scrollWidth\"\r\n class=\"d-flex align-items-center ps-2 h-100 border-below\"\r\n [class.row-selected]=\"rowSelectedIndexes.has(row.__virtualIndex)\"\r\n [class.first-row-selected]=\"firstSelectedRow === row.__virtualIndex\"\r\n [class.last-row-selected]=\"lastSelectedRow === row.__virtualIndex\"\r\n >\r\n <div\r\n class=\"d-flex align-items-center justify-content-between\"\r\n [style.paddingLeft.px]=\"depth > 0 ? depth * 30 : 0\"\r\n >\r\n <span class=\"me-2 filter-icon-wrapper\" (click)=\"toggleExpand(row)\">\r\n <span\r\n class=\"data-grid-svg-icon align-items-center d-flex\"\r\n [inlineSVG]=\"\r\n row.isExpand\r\n ? singleSpaAssetsPath + 'data-grid/icons/chevron-down.svg'\r\n : singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\r\n \"\r\n ></span>\r\n </span>\r\n <strong (click)=\"toggleExpand(row)\" class=\"cursor-pointer\">\r\n {{ row.groupValue }} ({{ countLeafRows(row) }})\r\n </strong>\r\n </div>\r\n </div>\r\n\r\n <div\r\n *ngIf=\"section == 'right'\"\r\n [style.width.px]=\"rightPinnedHeader.offsetWidth\"\r\n [class.row-selected]=\"rowSelectedIndexes.has(row.__virtualIndex)\"\r\n [class.first-row-selected]=\"firstSelectedRow === row.__virtualIndex\"\r\n [class.last-row-selected]=\"lastSelectedRow === row.__virtualIndex\"\r\n ></div>\r\n </div>\r\n\r\n <!-- Recursive Children -->\r\n <div class=\"group-children\" *ngIf=\"row.isExpand\" [@slideToggle]>\r\n <ng-container\r\n *ngFor=\"let child of row.children; let i = index; trackBy: trackById\"\r\n >\r\n <ng-container *ngIf=\"child.isGroup; else dataRow\">\r\n <!-- Recursive call for nested group -->\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n groupRowTemplate;\r\n context: { $implicit: child, depth: depth + 1 }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n\r\n <ng-template #dataRow>\r\n <!-- Regular data row -->\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n rowCell;\r\n context: {\r\n $implicit: child,\r\n columns: columns,\r\n isEven: i % 2 === 0,\r\n isOdd: i % 2 !== 0,\r\n isLeft: isLeftSection,\r\n section: section,\r\n isTotalRow: isTotalRow\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-template>\r\n </ng-container>\r\n </div>\r\n </ng-container>\r\n </ng-template>\r\n\r\n <!-- Regular row (not a group) -->\r\n <ng-template #regularRow>\r\n <div\r\n class=\"d-flex\"\r\n [style.height.px]=\"rowHeight\"\r\n [style.minHeight.px]=\"rowHeight\"\r\n [style.maxHeight.px]=\"rowHeight\"\r\n >\r\n <span\r\n class=\"d-flex align-items-center justify-content-center cursor-pointer border-below\"\r\n style=\"min-width: 30px; height: 100%\"\r\n *ngIf=\"\r\n section == 'center' && (gridType === 'Assets' || gridType === 'Tasks')\r\n \"\r\n [ngStyle]=\"{\r\n 'background-color': rowSelectedIndexes.has(row.__virtualIndex)\r\n ? null\r\n : getBackgroundColor(row, isEven, section)\r\n }\"\r\n [class.selected-cell]=\"rowSelectedIndexes.has(row.__virtualIndex)\"\r\n [class.first-row-selected]=\"firstSelectedRow === row.__virtualIndex\"\r\n [class.last-row-selected]=\"lastSelectedRow === row.__virtualIndex\"\r\n >\r\n <span\r\n (click)=\"toggleDetailRowExpand(row)\"\r\n *ngIf=\"row?.detail?.result?.length || gridType === 'Tasks'\"\r\n class=\"data-grid-svg-icon filter-icon-wrapper\"\r\n [inlineSVG]=\"\r\n isDetailsExpanded(row)\r\n ? singleSpaAssetsPath + 'data-grid/icons/chevron-down.svg'\r\n : singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\r\n \"\r\n ></span>\r\n </span>\r\n <div\r\n [style.min-width.px]=\"\r\n section == 'center' && groupedColumns?.length ? groupBoxPadding : 0\r\n \"\r\n [class.row-selected]=\"rowSelectedIndexes.has(row.__virtualIndex)\"\r\n [class.first-row-selected]=\"firstSelectedRow === row.__virtualIndex\"\r\n [class.last-row-selected]=\"lastSelectedRow === row.__virtualIndex\"\r\n (contextmenu)=\"onRightClick($event, row)\"\r\n [style.height.px]=\"rowHeight\"\r\n class=\"data-grid-row h-100\"\r\n [class.even-row]=\"isEven\"\r\n [class.odd-row]=\"isOdd\"\r\n [class.hovered-row]=\"hoveredRowId === (row._id || row.id)\"\r\n (mouseenter)=\"onRowHover(row)\"\r\n (mouseleave)=\"onRowLeave()\"\r\n [ngStyle]=\"{\r\n 'background-color': getBackgroundColor(row, isEven, section)\r\n }\"\r\n [style.minHeight.px]=\"rowHeight\"\r\n [style.maxHeight.px]=\"rowHeight\"\r\n ></div>\r\n <div\r\n (contextmenu)=\"onRightClick($event, row)\"\r\n [style.height.px]=\"rowHeight\"\r\n class=\"data-grid-row\"\r\n [class.even-row]=\"isEven\"\r\n [class.odd-row]=\"isOdd\"\r\n [class.hovered-row]=\"hoveredRowId === (row._id || row.id)\"\r\n (mouseenter)=\"onRowHover(row)\"\r\n (mouseleave)=\"onRowLeave()\"\r\n [ngStyle]=\"{\r\n 'background-color': getBackgroundColor(row, isEven, section)\r\n }\"\r\n >\r\n <div\r\n [style.backgroundColor]=\"checkboxesBackgroundColor\"\r\n class=\"select-all-checkbox-cell justify-content-end pe-2 s-no\"\r\n [style.width.px]=\"55\"\r\n *ngIf=\"isLeftSection && showSerialNumber\"\r\n [style.cursor]=\"\r\n 'url(' +\r\n singleSpaAssetsPath +\r\n 'data-grid/icons/arrow-right.svg), auto'\r\n \"\r\n (mousedown)=\"onRowMouseDown(row.__virtualIndex, $event)\"\r\n (mouseover)=\"onRowMouseOver(row.__virtualIndex, $event)\"\r\n [style.color]=\"checkboxesColor\"\r\n >\r\n {{ getStartIndex() + (row.__virtualIndex - 1) }}\r\n </div>\r\n <div\r\n class=\"border-below\"\r\n [style.backgroundColor]=\"\r\n rowSelectedIndexes.has(row.__virtualIndex)\r\n ? selectedRowsBackgroundColor\r\n : checkboxesBackgroundColor\r\n \"\r\n class=\"select-all-checkbox-cell\"\r\n *ngIf=\"isLeftSection && showCheckboxes\"\r\n [class.left-selection-border]=\"\r\n rowSelectedIndexes.has(row.__virtualIndex)\r\n \"\r\n [class.first-row-selected]=\"firstSelectedRow === row.__virtualIndex\"\r\n [class.last-row-selected]=\"lastSelectedRow === row.__virtualIndex\"\r\n [style.minHeight.px]=\"rowHeight - 1\"\r\n [style.maxHeight.px]=\"rowHeight\"\r\n >\r\n <input\r\n *ngIf=\"hasAnyVisibleColumn\"\r\n style=\"width: 16px; height: 16px\"\r\n type=\"checkbox\"\r\n [checked]=\"isRowSelected(row)\"\r\n (change)=\"toggleRowSelection(row)\"\r\n />\r\n </div>\r\n\r\n <!-- Render all columns -->\r\n <ng-container\r\n *ngFor=\"\r\n let col of columns;\r\n trackBy: trackByField;\r\n let colIndex = index\r\n \"\r\n >\r\n <ng-container *ngIf=\"col.children?.length > 0; else flatColumn\">\r\n <ng-container\r\n *ngFor=\"\r\n let child of col.children;\r\n trackBy: trackByField;\r\n let subColIndex = index\r\n \"\r\n >\r\n <ng-container *ngIf=\"child?.is_visible && !child?.isRowGrouped\">\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n cellTemplate;\r\n context: {\r\n col: child,\r\n row: row,\r\n rowIndex: rowIndex,\r\n colIndex: colIndex,\r\n subColIndex: subColIndex,\r\n section: section,\r\n isTotalRow: isTotalRow\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </ng-container>\r\n </ng-container>\r\n\r\n <ng-template #flatColumn>\r\n <ng-container *ngIf=\"col?.is_visible && !col?.isRowGrouped\">\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n cellTemplate;\r\n context: {\r\n col: col,\r\n row: row,\r\n rowIndex: rowIndex,\r\n colIndex: colIndex,\r\n subColIndex: null,\r\n section: section,\r\n isTotalRow: isTotalRow\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </ng-template>\r\n </ng-container>\r\n </div>\r\n </div>\r\n\r\n <div\r\n [@slideToggle]\r\n *ngIf=\"section === 'left' && isDetailsExpanded(row)\"\r\n class=\"accordion-details\"\r\n style=\"max-height: 350px; overflow: hidden\"\r\n [style.maxHeight.px]=\"hasHorizontalScroll ? 339 : 341\"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n leftRightNestedPlaceholder;\r\n context: { $implicit: row }\r\n \"\r\n >\r\n </ng-container>\r\n </div>\r\n\r\n <div\r\n [@slideToggle]\r\n *ngIf=\"section === 'center' && isDetailsExpanded(row)\"\r\n class=\"accordion-details center-section\"\r\n style=\"\r\n max-height: 350px;\r\n overflow-y: hidden;\r\n overflow-x: auto;\r\n scrollbar-width: thin;\r\n \"\r\n #nestedTable\r\n [style.width]=\"\r\n hasRightPinnedColumns\r\n ? '100%'\r\n : hasVerticalScroll\r\n ? 'calc(100% - 12px)'\r\n : '100%'\r\n \"\r\n >\r\n <ng-container *ngIf=\"gridType == 'Assets'\">\r\n <ng-container\r\n *ngTemplateOutlet=\"nestedTableTemplate; context: { $implicit: row }\"\r\n ></ng-container>\r\n </ng-container>\r\n <ng-container *ngIf=\"gridType == 'Tasks'\">\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n taskManagementTemplate;\r\n context: { taskDetails: row }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </div>\r\n\r\n <div\r\n [@slideToggle]\r\n *ngIf=\"section === 'right' && isDetailsExpanded(row)\"\r\n class=\"accordion-details\"\r\n style=\"max-height: 350px; overflow: hidden\"\r\n [style.maxHeight.px]=\"hasHorizontalScroll ? 339 : 341\"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n leftRightNestedPlaceholder;\r\n context: { $implicit: row }\r\n \"\r\n >\r\n </ng-container>\r\n </div>\r\n </ng-template>\r\n</ng-template>\r\n\r\n<!-- Actual Cell is Here -->\r\n<ng-template\r\n #cellTemplate\r\n let-col=\"col\"\r\n let-row=\"row\"\r\n let-section=\"section\"\r\n let-subColIndex=\"subColIndex\"\r\n let-rowIndex=\"rowIndex\"\r\n let-colIndex=\"colIndex\"\r\n let-isTotalRow=\"isTotalRow\"\r\n>\r\n <div\r\n #cellContainer\r\n (click)=\"\r\n editingKey = ''; setActiveCell(row, col); collapseAllExpandedCells()\r\n \"\r\n [style.fontWeight]=\"bodyFontWeight\"\r\n [class.border-right]=\"showVerticalBorder\"\r\n class=\"cell overflow-visible position-relative data-grid-cell\"\r\n [attr.field]=\"col.field\"\r\n [style.width.px]=\"col.width\"\r\n [style.min-width.px]=\"col.width\"\r\n [style.fontSize.px]=\"bodyTextFontsSize\"\r\n [style.minHeight.px]=\"rowHeight\"\r\n [style.maxHeight.px]=\"rowHeight\"\r\n [class.active-cell]=\"\r\n isActiveCell(row, col) && !isEditing(row, col) && selectedKeys.size == 1\r\n \"\r\n (dblclick)=\"\r\n $event.stopPropagation();\r\n $event.preventDefault();\r\n enableEdit(row, col, false, cellContainer)\r\n \"\r\n [class.row-selected]=\"rowSelectedIndexes.has(row.__virtualIndex)\"\r\n [class.first-row-selected]=\"firstSelectedRow === row?.__virtualIndex\"\r\n [class.last-row-selected]=\"lastSelectedRow === row?.__virtualIndex\"\r\n tabindex=\"-1\"\r\n (keydown.enter)=\"$event.preventDefault(); enableEdit(row, col)\"\r\n (mousedown)=\"\r\n startSelection(\r\n row.__virtualIndex,\r\n colIndex,\r\n subColIndex ?? 0,\r\n col.field,\r\n $event,\r\n section\r\n )\r\n \"\r\n (mouseenter)=\"\r\n extendSelection(\r\n row.__virtualIndex,\r\n colIndex,\r\n subColIndex ?? 0,\r\n col.field,\r\n $event,\r\n section\r\n )\r\n \"\r\n (mouseup)=\"endSelection()\"\r\n [class.selected-cell]=\"\r\n isSelected(\r\n row.__virtualIndex,\r\n colIndex,\r\n subColIndex ?? 0,\r\n col.field,\r\n section\r\n )\r\n \"\r\n [class.top-border]=\"\r\n isTopBorder(row.__virtualIndex, colIndex, subColIndex, section)\r\n \"\r\n [class.bottom-border]=\"\r\n isBottomBorder(row.__virtualIndex, colIndex, subColIndex, section)\r\n \"\r\n [class.left-border]=\"\r\n isLeftBorder(row.__virtualIndex, colIndex, subColIndex, section)\r\n \"\r\n [class.right-border]=\"\r\n isRightBorder(row.__virtualIndex, colIndex, subColIndex, section)\r\n \"\r\n [class.top-left-corner]=\"\r\n isTopLeftCorner(row.__virtualIndex, colIndex, subColIndex, section)\r\n \"\r\n [class.top-right-corner]=\"\r\n isTopRightCorner(row.__virtualIndex, colIndex, subColIndex, section)\r\n \"\r\n [class.bottom-left-corner]=\"\r\n isBottomLeftCorner(row.__virtualIndex, colIndex, subColIndex, section)\r\n \"\r\n [class.bottom-right-corner]=\"\r\n isBottomRightCorner(row.__virtualIndex, colIndex, subColIndex, section)\r\n \"\r\n >\r\n <!-- (mousedown)=\"startSelection(row.__virtualIndex, colIndex, subColIndex ?? 0, col.field, $event)\"\r\n (mouseenter)=\"extendSelection(row.__virtualIndex, colIndex, subColIndex ?? 0, col.field, $event)\"\r\n (mouseup)=\"endSelection()\"\r\n [class.selected-cell]=\"isSelected(row.__virtualIndex, colIndex, subColIndex ?? 0, col.field)\" -->\r\n <div\r\n class=\"table-cell\"\r\n [class.active-for-editing]=\"\r\n isEditing(row, col) &&\r\n (getNestedValue(row, col.field)?.length === undefined ||\r\n getNestedValue(row, col.field)?.length <= 50)\r\n \"\r\n >\r\n <div\r\n (click)=\"$event.stopPropagation()\"\r\n *ngIf=\"\r\n isEditing(row, col) &&\r\n (getNestedValue(row, col.field)?.length === undefined ||\r\n (getNestedValue(row, col.field)?.length <= 50 &&\r\n !expandedCells.size));\r\n else viewMode\r\n \"\r\n >\r\n\r\n <ng-container *ngIf=\"col.cellEditor; else builtInEditors\">\r\n <ng-container\r\n [cellEditor]=\"col.cellEditor\"\r\n [rowData]=\"row\"\r\n [colData]=\"col\"\r\n [cellValue]=\"getNestedValue(row, col.field)\"\r\n (editorEvent)=\"finishEdit($event)\"\r\n ></ng-container>\r\n </ng-container>\r\n\r\n <ng-template #builtInEditors>\r\n <ng-container [ngSwitch]=\"col?.type\">\r\n <!-- Text Input -->\r\n <input\r\n [style.height.px]=\"rowHeight - 10\"\r\n *ngSwitchCase=\"'input'\"\r\n type=\"text\"\r\n [(ngModel)]=\"row[col.field]\"\r\n (blur)=\"disableEdit(row, col)\"\r\n autofocus\r\n (keydown.enter)=\"blurInput($event, row, col)\"\r\n class=\"form-control form-control-sm\"\r\n (mousedown)=\"$event.stopPropagation()\"\r\n />\r\n\r\n <!-- Number Input -->\r\n <input\r\n [style.height.px]=\"rowHeight - 8\"\r\n *ngSwitchCase=\"'number'\"\r\n #numberInput=\"ngModel\"\r\n #numberRef\r\n (keypress)=\"allowOnlyNumbers($event)\"\r\n type=\"number\"\r\n required\r\n [(ngModel)]=\"row[col.field]\"\r\n (blur)=\"disableEdit(row, col, numberInput)\"\r\n autofocus\r\n (keydown.enter)=\"blurInput($event, row, col)\"\r\n class=\"form-control form-control-sm\"\r\n [ngClass]=\"{\r\n 'is-invalid': numberInput.invalid\r\n }\"\r\n (mousedown)=\"$event.stopPropagation()\"\r\n />\r\n\r\n <!-- Date Input -->\r\n <input\r\n [style.height.px]=\"rowHeight - 8\"\r\n *ngSwitchCase=\"'date'\"\r\n type=\"date\"\r\n [(ngModel)]=\"row[col.field]\"\r\n (blur)=\"disableEdit(row, col, dateInput)\"\r\n autofocus\r\n class=\"form-control form-control-sm\"\r\n #dateInput=\"ngModel\"\r\n (keydown.enter)=\"blurInput($event, row, col)\"\r\n [ngClass]=\"{\r\n 'is-invalid': dateInput.invalid\r\n }\"\r\n (mousedown)=\"$event.stopPropagation()\"\r\n />\r\n\r\n <!-- Dropdown -->\r\n <!-- ng-select like dropdown -->\r\n <div\r\n *ngSwitchCase=\"'dropdown'\"\r\n class=\"dropdown w-100\"\r\n (blur)=\"disableEdit(row, col)\"\r\n >\r\n <!-- Trigger -->\r\n <button\r\n class=\"form-select form-select-sm text-start w-100 text-ellipsis\"\r\n type=\"button\"\r\n data-bs-toggle=\"dropdown\"\r\n aria-expanded=\"false\"\r\n [style.minHeight.px]=\"rowHeight - 10\"\r\n data-bs-display=\"static\"\r\n (mousedown)=\"$event.stopPropagation()\"\r\n >\r\n <ng-container>\r\n {{\r\n getNestedValue(row, col.field)?.value ||\r\n getNestedValue(row, col.field)?.name ||\r\n getNestedValue(row, col.field)\r\n }}\r\n </ng-container>\r\n <ng-template #placeholder> Select options... </ng-template>\r\n </button>\r\n\r\n <!-- Menu -->\r\n <div\r\n class=\"dropdown-menu w-100 p-0 cell-editing-dropdown-menu rounded-3\"\r\n [class.show]=\"isEditing(row, col)\"\r\n >\r\n <!-- Search -->\r\n <div class=\"px-2 py-1 editing-dropdown-search-input\" *ngIf=\"col?.column_dropdown_value?.length > 5\">\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Search...\"\r\n [(ngModel)]=\"editinDropdownSearch\"\r\n (mousedown)=\"$event.stopPropagation()\"\r\n />\r\n </div>\r\n <cdk-virtual-scroll-viewport \r\n itemSize=\"35\" \r\n class=\"dropdown-viewport\"\r\n style=\"height: 120px\"\r\n >\r\n <div\r\n [class.selected]=\"getNestedValue(row, col.field) == option?.value || getNestedValue(row, col.field) == option\"\r\n class=\"px-2 py-1 d-flex align-items-center dropdown-item\"\r\n *cdkVirtualFor=\"\r\n let option of col.column_dropdown_value \r\n | filter : editinDropdownSearch : 'value'\r\n \"\r\n (click)=\"setNestedValue(row, col, option, true); editingKey = null\"\r\n >\r\n <label\r\n \r\n class=\"form-check-label d-flex align-items-center mb-0 cursor-pointer\"\r\n [for]=\"col.field + '-' + (option.value || option)\"\r\n >\r\n {{ option.value || option }}\r\n </label>\r\n </div>\r\n </cdk-virtual-scroll-viewport>\r\n\r\n </div>\r\n </div>\r\n\r\n <input\r\n *ngSwitchCase=\"'email'\"\r\n [style.height.px]=\"rowHeight - 10\"\r\n [style.maxHeight.px]=\"rowHeight - 10\"\r\n #emailModel=\"ngModel\"\r\n #emailInput\r\n type=\"email\"\r\n [(ngModel)]=\"row[col.field]\"\r\n name=\"{{ col.field }}\"\r\n required\r\n pattern=\"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$\"\r\n (blur)=\"disableEdit(row, col, emailModel)\"\r\n (keydown.enter)=\"blurInput($event, row, col)\"\r\n autofocus\r\n class=\"form-control form-control-sm\"\r\n [ngClass]=\"{\r\n 'is-invalid': emailModel.invalid\r\n }\"\r\n (mousedown)=\"$event.stopPropagation()\"\r\n />\r\n <!-- Default fallback -->\r\n <input\r\n *ngSwitchDefault\r\n [style.height.px]=\"rowHeight - 10\"\r\n [style.maxHeight.px]=\"rowHeight - 10\"\r\n #textModel=\"ngModel\"\r\n #textInput\r\n type=\"text\"\r\n (keydown.enter)=\"blurInput($event, row, col)\"\r\n [(ngModel)]=\"row[col.field]\"\r\n name=\"{{ col.field }}\"\r\n required\r\n (blur)=\"disableEdit(row, col, textModel)\"\r\n autofocus\r\n class=\"form-control form-control-sm\"\r\n [ngClass]=\"{\r\n 'is-invalid': textModel.invalid\r\n }\"\r\n (mousedown)=\"$event.stopPropagation()\"\r\n />\r\n </ng-container>\r\n </ng-template>\r\n\r\n </div>\r\n\r\n <!-- Display mode -->\r\n <ng-template #viewMode>\r\n <div\r\n class=\"d-flex justify-content-between align-items-center w-100 overflow-hidden\"\r\n [ngClass]=\"getCellClasses(col, getNestedValue(row, col.field))\"\r\n >\r\n <!-- Field icon (for Tasks grid) -->\r\n <ng-container\r\n *ngIf=\"gridType === 'Tasks' && iconMap[col.field] && !isTotalRow\"\r\n >\r\n <span\r\n class=\"cursor-pointer me-2\"\r\n (click)=\"$event.preventDefault(); $event.stopPropagation()\"\r\n [inlineSVG]=\"iconMap[col.field](row, col)\"\r\n ></span>\r\n </ng-container>\r\n\r\n <!-- \u2705 Custom cell renderer support -->\r\n <ng-container *ngIf=\"col.cellRenderer; else defaultCell\">\r\n <ng-container\r\n [cellRenderInit]=\"col.cellRenderer\"\r\n [rowData]=\"row\"\r\n [colData]=\"col\"\r\n [cellValue]=\"getNestedValue(row, col?.field)\"\r\n (cellEvent)=\"onCellEvent($event)\"\r\n >\r\n </ng-container>\r\n </ng-container>\r\n\r\n <!-- \uD83E\uDDFE Default text-based cell rendering -->\r\n <ng-template #defaultCell>\r\n <div\r\n #cellText\r\n class=\"text-ellipsis flex-grow-1\"\r\n [title]=\"getCellTitle(row, col)\"\r\n >\r\n <!-- Normal cell -->\r\n <ng-container\r\n *ngIf=\"\r\n col?.type !== 'image' &&\r\n col?.field != 'image' &&\r\n col?.field != 'invoice.invoice_image' &&\r\n !isTotalRow\r\n \"\r\n >\r\n <ng-container *ngIf=\"col.is_amount\">{{\r\n currencySymbol\r\n }}</ng-container>\r\n {{getCellTitle(row, col)}}\r\n </ng-container>\r\n\r\n <!-- Total row -->\r\n <ng-container *ngIf=\"isTotalRow\">\r\n {{ getTotalAmount(col) }}\r\n </ng-container>\r\n\r\n <!-- Invoice Image -->\r\n <ng-container *ngIf=\"col.field == 'invoice.invoice_image'\">\r\n <div style=\"display: flex; align-items: center; zoom: 0.7\">\r\n <span\r\n title=\"{{ getNestedValue(row, col.field) || 'Attachment' }}\"\r\n (click)=\"downloadAttchment(getNestedValue(row, col.field))\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath +\r\n 'data-grid/document-icons/' +\r\n getExtention(getNestedValue(row, col.field)) +\r\n '.svg'\r\n \"\r\n ></span>\r\n </div>\r\n </ng-container>\r\n\r\n <!-- Image cell -->\r\n <ng-container *ngIf=\"col?.type == 'image' && !isTotalRow\">\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n defaultImagePlaceholder;\r\n context: { row: row, col: col }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </div>\r\n <span\r\n *ngIf=\"\r\n (!col?.cellRenderer && showCellDetailsBox &&\r\n getNestedValue(row, col.field)?.length > 50 && col?.type !== 'image') ||\r\n (isNestedValueArray(row, col.field) &&\r\n getNestedValue(row, col.field)?.length > 1)\r\n \"\r\n class=\"toggle-icon data-grid-svg-icon ms-2 cursor-pointer\"\r\n [inlineSVG]=\"\r\n isExpanded(row, col)\r\n ? singleSpaAssetsPath + 'data-grid/icons/chevron-down.svg'\r\n : singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\r\n \"\r\n (click)=\"\r\n $event.stopPropagation();\r\n toggleExpandOfLongCellText(row, col, columns, true)\r\n \"\r\n (dblclick)=\"$event.preventDefault(); $event.stopPropagation()\"\r\n ></span>\r\n </ng-template>\r\n <!-- Expand / Collapse icon -->\r\n </div>\r\n\r\n <!-- Expanded text -->\r\n <div\r\n class=\"position-absolute w-100 expanded-box\"\r\n *ngIf=\"isExpanded(row, col)\"\r\n [style.zIndex]=\"getZIndex(row, col)\"\r\n style=\"top: 100%; left: 0\"\r\n [attr.id]=\"(row.id || row._id) + '-' + (col.id || col._id)\"\r\n [class.invisible]=\"!showDetailsBox\"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n fullTextTemplate;\r\n context: {\r\n row: row,\r\n col: col,\r\n isArray: isNestedValueArray(row, col.field)\r\n }\r\n \"\r\n ></ng-container>\r\n </div>\r\n </ng-template>\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<!-- Headers Action List On clicking three dots -->\r\n\r\n<ng-template\r\n #columnMenu\r\n let-col=\"col\"\r\n let-isNestedTable=\"isNestedTable\"\r\n let-columns=\"columns\"\r\n let-section=\"section\"\r\n let-columnIndex=\"columnIndex\"\r\n let-childColIndex=\"childColIndex\"\r\n>\r\n <div\r\n class=\"column-menu three-dots-col-menu\"\r\n [class.visually-hidden]=\"isMenueHidden\"\r\n *ngIf=\"activeCol && !isThreeDotsFilterOpen\"\r\n [style.backgroundColor]=\"dropdownsBackgroundColor\"\r\n (click)=\"$event.stopPropagation()\"\r\n [style.color]=\"headerTextColor\"\r\n >\r\n <!-- Sort Ascending -->\r\n <div class=\"border-below pb-2\" [class.disable-sorting]=\"!col.is_sortable\">\r\n <span class=\"muted-text fs-7\" style=\"margin-left: 12px\">Sort</span>\r\n <div\r\n *ngIf=\"\r\n columnThreedotsMunuConfig?.showAscending &&\r\n (sortingConfig?.field != col.field ||\r\n sortingConfig?.order_by == 'desc')\r\n \"\r\n class=\"column-menu-item\"\r\n (click)=\"sortAsc(activeCol)\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrow-up.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n Sort Ascending\r\n </div>\r\n\r\n <!-- Sort Descending -->\r\n <div\r\n *ngIf=\"\r\n columnThreedotsMunuConfig?.showDescending &&\r\n (sortingConfig?.field != col.field ||\r\n sortingConfig?.order_by == 'asc')\r\n \"\r\n class=\"column-menu-item\"\r\n (click)=\"sortDesc(activeCol)\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrow-down.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n Sort Descending\r\n </div>\r\n\r\n <div\r\n *ngIf=\"\r\n sortingConfig?.field === col.field &&\r\n (sortingConfig?.order_by === 'asc' ||\r\n sortingConfig?.order_by === 'desc')\r\n \"\r\n class=\"column-menu-item\"\r\n (click)=\"resetSort(activeCol)\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/arrow-counterclockwise.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n Reset Sort\r\n </div>\r\n </div>\r\n <div class=\"py-2 border-below three-dots-filter\" [class.disable-sorting]=\"col?.type == 'image' || !col.is_search_able\">\r\n <div\r\n *ngIf=\"columnThreedotsMunuConfig?.showFilter\"\r\n class=\"column-menu-item three-dots-filter\"\r\n (click)=\"openFilteronThreeDotsClick(col)\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n Filter\r\n </div>\r\n </div>\r\n\r\n <div class=\"py-2 border-below\">\r\n <span class=\"muted-text fs-7\" style=\"margin-left: 12px\">Pin</span>\r\n <div\r\n *ngIf=\"columnThreedotsMunuConfig?.showPinleft && col?.pinned !== 'left'\"\r\n class=\"column-menu-item\"\r\n (click)=\"\r\n $event.stopPropagation();\r\n updateColumnPinInSourceByField(\r\n activeCol,\r\n 'left',\r\n isNestedTable,\r\n columns\r\n )\r\n \"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/pin-left.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span\r\n >Pin Left\r\n </div>\r\n\r\n <div\r\n *ngIf=\"\r\n columnThreedotsMunuConfig?.showPinright && col?.pinned !== 'right'\r\n \"\r\n class=\"column-menu-item\"\r\n (click)=\"\r\n $event.stopPropagation();\r\n updateColumnPinInSourceByField(\r\n activeCol,\r\n 'right',\r\n isNestedTable,\r\n columns\r\n )\r\n \"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/pin-right.svg'\"\r\n class=\"data-grid-svg-icon data-grid-svg-icon me-2\"\r\n ></span\r\n >Pin Right\r\n </div>\r\n\r\n <div\r\n *ngIf=\"col?.pinned\"\r\n class=\"column-menu-item\"\r\n (click)=\"\r\n $event.stopPropagation();\r\n updateColumnPinInSourceByField(\r\n activeCol,\r\n null,\r\n isNestedTable,\r\n columns\r\n )\r\n \"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/layout-three-columns.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span\r\n >Unpin\r\n </div>\r\n </div>\r\n\r\n <div\r\n *ngIf=\"columnThreedotsMunuConfig?.showAutosizeThisColumn\"\r\n class=\"column-menu-item\"\r\n (click)=\"autosizeColumn(activeCol)\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/arrows-expand-vertical.svg'\r\n \"\r\n class=\"me-2\"\r\n ></span>\r\n Autosize This Column\r\n </div>\r\n\r\n <!-- Autosize All Columns -->\r\n <div\r\n *ngIf=\"columnThreedotsMunuConfig?.showAutosizeAllColumns\"\r\n class=\"column-menu-item\"\r\n (click)=\"autosizeAllColumns()\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/arrows-angle-expand.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span\r\n >Autosize All Columns\r\n </div>\r\n\r\n <!-- Group By -->\r\n <div\r\n *ngIf=\"showRowsGrouping\"\r\n class=\"column-menu-item\"\r\n (click)=\"groupBy(activeCol)\"\r\n [class.disable-sorting]=\"!col.is_groupable\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/diagram-3.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n Group by {{ col.header }}\r\n </div>\r\n\r\n <!-- Choose Columns -->\r\n <div\r\n *ngIf=\"columnThreedotsMunuConfig?.showChoseColumns\"\r\n class=\"column-menu-item\"\r\n (click)=\"chooseColumns()\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/ui-checks-grid.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n Choose Columns\r\n </div>\r\n\r\n <!-- Reset Columns -->\r\n <div\r\n *ngIf=\"columnThreedotsMunuConfig?.showResetColumns\"\r\n class=\"column-menu-item\"\r\n (click)=\"resetColumns()\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/arrow-counterclockwise.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span\r\n >Reset Columns\r\n </div>\r\n </div>\r\n <div\r\n @slideToggle\r\n *ngIf=\"isThreeDotsFilterOpen && col?.is_search_able\"\r\n class=\"three-dots-col-menu position-relative\"\r\n [style.right.px]=\"getDynamicRight(col, section, columnIndex, childColIndex)\"\r\n [class.visually-hidden]=\"isMenueHidden\"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"filterMenu; context: { col: col }\"\r\n ></ng-container>\r\n </div>\r\n</ng-template>\r\n\r\n<!-- Filter Menue -->\r\n<ng-template #filterMenu let-col=\"col\">\r\n <div\r\n class=\"filter-menu-container filter-menu\"\r\n [style.backgroundColor]=\"dropdownsBackgroundColor\"\r\n >\r\n <!-- Dropdown Type -->\r\n <ng-container *ngIf=\"col?.type === 'dropdown'|| col?.type == 'array'; else textFilter\">\r\n <div class=\"filter-dropdown-section p-1\">\r\n <input\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Search...\"\r\n type=\"search\"\r\n [(ngModel)]=\"addFilterColumnInput\"\r\n />\r\n\r\n <div class=\"form-check mb-1 mt-2 ms-1 select-all-filter\">\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n [checked]=\"isAllSideFilterOptionsSelected(col)\"\r\n (change)=\"toggleSelectAllSideFilters(col, $event)\"\r\n id=\"selectAll_{{ col.field }}\"\r\n />\r\n <label class=\"form-check-label\" for=\"selectAll_{{ col.field }}\">\r\n Select All\r\n </label>\r\n </div>\r\n\r\n <!-- <div class=\"dropdown-options ps-1\">\r\n <div\r\n class=\"form-check mb-1\"\r\n *ngFor=\"\r\n let option of selectedColumnForFilter?.column_dropdown_value\r\n | filter : addFilterColumnInput : 'value';\r\n trackBy: trackById;\r\n let i = index\r\n \"\r\n >\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n [id]=\"i\"\r\n [checked]=\"\r\n currentFilterSelectedIds.has(option?.id ?? option?._id ?? option)\r\n \"\r\n (change)=\"toggleSelectionInFilter(option)\"\r\n />\r\n <label class=\"form-check-label fw-semibold\" [for]=\"i\">\r\n {{ option?.value ?? option?.name ?? option }}\r\n </label>\r\n </div>\r\n </div> -->\r\n <cdk-virtual-scroll-viewport\r\n itemSize=\"32\"\r\n class=\"filter-viewport\"\r\n style=\"height: 120px\"\r\n >\r\n <div\r\n class=\"form-check mb-1 ms-1\"\r\n *cdkVirtualFor=\"\r\n let option of selectedColumnForFilter?.column_dropdown_value\r\n | filter : addFilterColumnInput : 'value';\r\n trackBy: trackById\r\n \"\r\n >\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n [id]=\"option?.id ?? option?._id ?? option\"\r\n [checked]=\"\r\n currentFilterSelectedIds.has(option?.id ?? option?._id ?? option)\r\n \"\r\n (change)=\"toggleSelectionInFilter(option)\"\r\n />\r\n\r\n <label\r\n class=\"form-check-label fw-semibold\"\r\n [for]=\"option?.id ?? option?._id ?? option\"\r\n >\r\n {{ ((option?.value ?? option?.name ?? option) | titlecase ) }}\r\n </label>\r\n </div>\r\n </cdk-virtual-scroll-viewport>\r\n </div>\r\n </ng-container>\r\n\r\n <!-- Text Filter Section -->\r\n <ng-template #textFilter>\r\n <div class=\"filter-text-section\">\r\n <div class=\"form-group mb-2\">\r\n <select\r\n class=\"form-select form-select-sm custom-select\"\r\n [(ngModel)]=\"firstCondition\"\r\n >\r\n <ng-container *ngIf=\"selectedColumnForFilter?.type == 'string'\">\r\n <option value=\"contain\">Contains</option>\r\n <option value=\"does_not_contain\">Does Not Contain</option>\r\n <option value=\"equal\">Equals</option>\r\n <option value=\"before\">Starts With</option>\r\n <option value=\"after\">Ends With</option>\r\n </ng-container>\r\n\r\n <ng-container *ngIf=\"selectedColumnForFilter?.type == 'date'\">\r\n <option value=\"equal\">Equals To</option>\r\n <option value=\"not_equal\">Not Equal</option>\r\n <option value=\"after\">After</option>\r\n <option value=\"before\">Before</option>\r\n </ng-container>\r\n\r\n <ng-container *ngIf=\"selectedColumnForFilter?.type == 'number'\">\r\n <option value=\"equal\">Equals To</option>\r\n <option value=\"before\">Less Then </option>\r\n <option value=\"after\">Greater Then </option>\r\n <option value=\"less_then_equal\">less then Equal to</option>\r\n <option value=\"greater_then_equal\">Greater then Equal to </option>\r\n </ng-container>\r\n </select>\r\n </div>\r\n\r\n <input\r\n [type]=\"col?.type == 'string' ? 'text' : col?.type\"\r\n class=\"form-control form-control-sm mb-3\"\r\n placeholder=\"Value\"\r\n [(ngModel)]=\"firstValue\"\r\n #filterMenueTextchInput\r\n (keydown.enter)=\"applyDropdownFilter()\"\r\n />\r\n\r\n <div class=\"form-group mb-3 d-flex flex-row\">\r\n <div\r\n class=\"form-check form-check-inline m-0 col-4 d-flex align-items-center gap-1\"\r\n >\r\n <input\r\n class=\"form-check-input filter-radio-inputs\"\r\n type=\"radio\"\r\n name=\"condition\"\r\n [(ngModel)]=\"condition\"\r\n value=\"and\"\r\n id=\"and_{{ col.field }}\"\r\n (change)=\"cdr.detectChanges()\"\r\n />\r\n <label class=\"form-check-label mb-0 mt-1\" for=\"and_{{ col.field }}\"\r\n >AND</label\r\n >\r\n </div>\r\n <div\r\n class=\"form-check form-check-inline m-0 col-4 d-flex align-items-center gap-1 gap-1\"\r\n >\r\n <input\r\n class=\"form-check-input filter-radio-inputs\"\r\n type=\"radio\"\r\n name=\"condition\"\r\n [(ngModel)]=\"condition\"\r\n value=\"or\"\r\n id=\"or_{{ col.field }}\"\r\n (change)=\"cdr.detectChanges()\"\r\n />\r\n <label class=\"form-check-label mb-0 mt-1\" for=\"or_{{ col.field }}\"\r\n >OR</label\r\n >\r\n </div>\r\n <div\r\n class=\"form-check form-check-inline m-0 col-4 d-flex align-items-center gap-1 gap-1\"\r\n >\r\n <input\r\n class=\"form-check-input filter-radio-inputs\"\r\n type=\"radio\"\r\n name=\"condition\"\r\n [(ngModel)]=\"condition\"\r\n value=\"none\"\r\n id=\"none_{{ col.field }}\"\r\n (change)=\"cdr.detectChanges()\"\r\n />\r\n <label class=\"form-check-label mb-0 mt-1\" for=\"none_{{ col.field }}\"\r\n >None</label\r\n >\r\n </div>\r\n </div>\r\n <div @slideToggle *ngIf=\"firstValue && condition != 'none'\">\r\n <div class=\"form-group mb-2\">\r\n <select\r\n class=\"form-select form-select-sm custom-select\"\r\n [(ngModel)]=\"secondCondition\"\r\n >\r\n <ng-container *ngIf=\"selectedColumnForFilter?.type == 'string'\">\r\n <option value=\"contain\">Contains</option>\r\n <option value=\"does_not_contain\">Does Not Contain</option>\r\n <option value=\"equal\">Equals</option>\r\n <option value=\"before\">Starts With</option>\r\n <option value=\"after\">Ends With</option>\r\n </ng-container>\r\n\r\n <ng-container *ngIf=\"selectedColumnForFilter?.type == 'date'\">\r\n <option value=\"equal\">Equals To</option>\r\n <option value=\"not_equal\">Not Equal</option>\r\n <option value=\"after\">After</option>\r\n <option value=\"before\">Before</option>\r\n </ng-container>\r\n\r\n <ng-container *ngIf=\"selectedColumnForFilter?.type == 'number'\">\r\n <option value=\"equal\">Equals To</option>\r\n <option value=\"before\">Less Then </option>\r\n <option value=\"after\">Greater Then </option>\r\n <option value=\"less_then_equal\">less then Equal to</option>\r\n <option value=\"greater_then_equal\">Greater then Equal to </option>\r\n </ng-container>\r\n </select>\r\n </div>\r\n\r\n <input\r\n [type]=\"col?.type == 'string' ? 'text' : col?.type\"\r\n class=\"form-control form-control-sm mb-3\"\r\n placeholder=\"Second Value\"\r\n [(ngModel)]=\"secondValue\"\r\n />\r\n </div>\r\n </div>\r\n </ng-template>\r\n\r\n <!-- Actions -->\r\n <div class=\"d-flex gap-2 mt-2\">\r\n <div\r\n class=\"btn btn-sm btn-primary d-flex justify-content-center align-items-center w-100\"\r\n style=\"height: 30px\"\r\n (click)=\"applyDropdownFilter()\"\r\n >\r\n Apply\r\n </div>\r\n <div\r\n class=\"btn btn-sm btn-secondary d-flex justify-content-center align-items-center w-100\"\r\n style=\"height: 30px\"\r\n (click)=\"resetSideFilter(col)\"\r\n >\r\n Reset\r\n </div>\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<!-- Side Menue -->\r\n\r\n<!-- Column Pannel / Pivot Mode / Searching -->\r\n\r\n<ng-template #columnPannel>\r\n <div class=\"column-panel-header\">\r\n <!-- Pivot Toggle -->\r\n <div\r\n class=\"form-check form-switch d-flex align-items-center mb-2 pivot-mode px-5 ms-2 d-none\"\r\n >\r\n <input\r\n class=\"form-check-input me-2\"\r\n type=\"checkbox\"\r\n id=\"pivotToggle\"\r\n [(ngModel)]=\"pivotMode\"\r\n />\r\n <label class=\"form-check-label\" for=\"pivotToggle\">Pivot Mode</label>\r\n </div>\r\n\r\n <!-- Select All & Search -->\r\n <div class=\"d-flex align-items-center mb-2 px-3 mt-3\">\r\n <span class=\"filter-icon-wrapper me-2\" *ngIf=\"showColumnsGrouping\">\r\n <span\r\n class=\"toggle-icon data-grid-svg-icon\"\r\n [inlineSVG]=\"\r\n accordionState === 'all'\r\n ? singleSpaAssetsPath + 'data-grid/icons/chevron-down.svg'\r\n : accordionState === 'some'\r\n ? singleSpaAssetsPath + 'data-grid/icons/dash.svg'\r\n : singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\r\n \"\r\n (click)=\"toggleAllAccordions()\"\r\n ></span>\r\n </span>\r\n <input\r\n type=\"checkbox\"\r\n class=\"form-check-input me-2\"\r\n [checked]=\"allColumnsSelected()\"\r\n (change)=\"toggleAllColumnsVisibility()\"\r\n />\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Search columns...\"\r\n [(ngModel)]=\"columnSearch\"\r\n />\r\n </div>\r\n\r\n <!-- Separator -->\r\n <hr class=\"my-2\" />\r\n </div>\r\n</ng-template>\r\n\r\n<!-- Right Columns Menue -->\r\n\r\n<!-- Column Panel Item Template -->\r\n<ng-template #columnPanelItem let-col=\"col\">\r\n <!-- Group Column -->\r\n <ng-container *ngIf=\"col.children?.length\">\r\n <div class=\"column-group d-flex align-items-center mb-2\">\r\n <span class=\"filter-icon-wrapper me-2\">\r\n <span\r\n class=\"toggle-icon data-grid-svg-icon\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\r\n \"\r\n [class.rotate]=\"col.expanded\"\r\n (click)=\"col.expanded = !col.expanded\"\r\n ></span>\r\n </span>\r\n <input\r\n type=\"checkbox\"\r\n class=\"form-check-input me-2\"\r\n [id]=\"'group_' + col.header\"\r\n [checked]=\"isColumnVisible(col)\"\r\n (change)=\"toggleGroupVisibility(col)\"\r\n />\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/grid-3x2-gap.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center me-2\"\r\n ></span>\r\n <label\r\n class=\"d-flex align-items-center mb-0 w-100\"\r\n [for]=\"'group_' + col.header\"\r\n style=\"cursor: pointer\"\r\n >\r\n <span class=\"text-truncate\">{{ col.header }}</span>\r\n </label>\r\n </div>\r\n <div *ngIf=\"col.expanded\" class=\"ps-4\">\r\n <ng-container *ngFor=\"let child of col.children; trackBy: trackByField\">\r\n <ng-container\r\n *ngTemplateOutlet=\"columnPanelItem; context: { col: child }\"\r\n ></ng-container>\r\n </ng-container>\r\n </div>\r\n </ng-container>\r\n\r\n <!-- Leaf Column -->\r\n <ng-container *ngIf=\"!col.children?.length\">\r\n <div class=\"d-flex align-items-center mb-2\">\r\n <span class=\"me-2\" style=\"width: 1.5rem\"></span>\r\n <input\r\n type=\"checkbox\"\r\n class=\"form-check-input me-2\"\r\n [(ngModel)]=\"col.is_visible\"\r\n [id]=\"'col_' + col.field\"\r\n (change)=\"onSideMenuColumnsVisibilityChange()\"\r\n />\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/grid-3x2-gap.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center me-2\"\r\n ></span>\r\n <label\r\n class=\"d-flex align-items-center mb-0 w-100\"\r\n [for]=\"'col_' + col.field\"\r\n style=\"cursor: pointer\"\r\n >\r\n <span class=\"text-truncate\">{{ col.header }}</span>\r\n </label>\r\n </div>\r\n </ng-container>\r\n</ng-template>\r\n\r\n<!-- Columns Side Filter -->\r\n<ng-template #sideFilters>\r\n <div class=\"py-3 px-2 pe-3 h-100\">\r\n <div class=\"d-flex align-items-center mb-2\">\r\n <span class=\"filter-icon-wrapper me-2\" *ngIf=\"showColumnsGrouping\">\r\n <span\r\n class=\"toggle-icon data-grid-svg-icon\"\r\n [inlineSVG]=\"\r\n filterAccordionState === 'all'\r\n ? singleSpaAssetsPath + 'data-grid/icons/chevron-down.svg'\r\n : filterAccordionState === 'some'\r\n ? singleSpaAssetsPath + 'data-grid/icons/dash.svg'\r\n : singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\r\n \"\r\n (click)=\"toggleAllFilterAccordions()\"\r\n ></span>\r\n </span>\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Search...\"\r\n [(ngModel)]=\"columnSearch\"\r\n />\r\n </div>\r\n <div\r\n class=\"overflow-auto side-filter-columns-wrapper\"\r\n style=\"height: calc(100% - 70px); scrollbar-width: thin\"\r\n >\r\n <ng-container\r\n *ngFor=\"\r\n let col of columns | filter : columnSearch : 'header';\r\n trackBy: trackByField\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"filterPannelItem; context: { col: col }\"\r\n ></ng-container>\r\n </ng-container>\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template #filterPannelItem let-col=\"col\">\r\n <!-- Group Column -->\r\n <ng-container *ngIf=\"col.children?.length\">\r\n <div\r\n class=\"column-group d-flex align-items-center mb-2\"\r\n *ngIf=\"col?.type !== 'image'\"\r\n >\r\n <!-- Chevron toggle -->\r\n <span class=\"filter-icon-wrapper me-2\">\r\n <span\r\n class=\"toggle-icon data-grid-svg-icon\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\r\n \"\r\n [class.rotate]=\"col.expandedFilter\"\r\n (click)=\"col.expandedFilter = !col.expandedFilter\"\r\n ></span>\r\n </span>\r\n\r\n <!-- Group label toggle -->\r\n <label\r\n class=\"d-flex align-items-center mb-0 w-100\"\r\n style=\"cursor: pointer\"\r\n (click)=\"col.expandedFilter = !col.expandedFilter\"\r\n >\r\n <span class=\"fw-bold text-truncate\"\r\n >{{ col.header }}\r\n <span\r\n class=\"text-primary ms-1\"\r\n *ngIf=\"col?.query?._ids?.length || col?.query?._first_value\"\r\n >*</span\r\n >\r\n </span>\r\n </label>\r\n </div>\r\n\r\n <!-- Children columns -->\r\n <div *ngIf=\"col.expandedFilter\" class=\"ps-4\">\r\n <ng-container *ngFor=\"let child of col.children; trackBy: trackByField\">\r\n <ng-container\r\n *ngTemplateOutlet=\"filterPannelItem; context: { col: child }\"\r\n ></ng-container>\r\n </ng-container>\r\n </div>\r\n </ng-container>\r\n\r\n <!-- Leaf Column -->\r\n <ng-container *ngIf=\"!col.children?.length\">\r\n <div class=\"d-flex align-items-center mb-2\" *ngIf=\"col?.type !== 'image'\">\r\n <span\r\n class=\"me-2 filter-icon-wrapper me-2\"\r\n (click)=\"col.expandedFilter = !col.expandedFilter\"\r\n >\r\n <span\r\n class=\"toggle-icon data-grid-svg-icon\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\r\n \"\r\n [class.rotate]=\"col.expandedFilter\"\r\n ></span>\r\n </span>\r\n\r\n <label\r\n class=\"d-flex align-items-center mb-0 w-100\"\r\n style=\"cursor: pointer\"\r\n (click)=\"col.expandedFilter = !col.expandedFilter\"\r\n >\r\n <span class=\"text-truncate fw-bold\">{{ col.header }}</span>\r\n </label>\r\n </div>\r\n\r\n <!-- Show filter when expanded -->\r\n <div *ngIf=\"col.expandedFilter\" class=\"ps-4 pe-3\">\r\n <ng-container\r\n *ngTemplateOutlet=\"sideNestedFilter; context: { col: col }\"\r\n ></ng-container>\r\n </div>\r\n </ng-container>\r\n</ng-template>\r\n\r\n<!-- Side Nested Filters -->\r\n<ng-template #sideNestedFilter let-col=\"col\">\r\n <div class=\"\">\r\n <!-- Dropdown Type -->\r\n <ng-container *ngIf=\"col?.type === 'dropdown' || col?.type == 'array'; else textFilter\">\r\n <div class=\"p-1\">\r\n <!-- Search -->\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm mb-2\"\r\n placeholder=\"Search...\"\r\n [(ngModel)]=\"sideNestedFilterSearch\"\r\n />\r\n\r\n <!-- Select All -->\r\n <div class=\"form-check mb-1 ms-1 select-all-filter\">\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n [checked]=\"\r\n col.query?._ids?.length == col?.column_dropdown_value?.length\r\n \"\r\n (change)=\"toggleSelectAllSideFilters(col, $event)\"\r\n id=\"selectAll_{{ col.field }}\"\r\n />\r\n <label class=\"form-check-label\" for=\"selectAll_{{ col.field }}\">\r\n Select All\r\n </label>\r\n </div>\r\n\r\n <!-- Options -->\r\n <!-- <div class=\"dropdown-options\">\r\n <div\r\n class=\"form-check mb-1 ms-1\"\r\n *ngFor=\"\r\n let option of col?.column_dropdown_value\r\n | filter : sideNestedFilterSearch : 'value'\r\n \"\r\n >\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n [value]=\"option\"\r\n [checked]=\"\r\n col.query?._ids?.includes(option?._id || option?.id || option)\r\n \"\r\n (change)=\"onOptionToggle(col, option)\"\r\n id=\"option_{{ col.field }}_{{\r\n option?.id || option?._id || option\r\n }}\"\r\n />\r\n <label\r\n class=\"form-check-label\"\r\n [for]=\"\r\n 'option_' +\r\n col.field +\r\n '_' +\r\n (option?.id || option?._id || option)\r\n \"\r\n >\r\n {{ option.value || option }}\r\n </label>\r\n </div>\r\n </div> -->\r\n <cdk-virtual-scroll-viewport\r\n itemSize=\"32\"\r\n class=\"dropdown-viewport\"\r\n style=\"height: 120px\"\r\n >\r\n <div\r\n class=\"form-check mb-1 ms-1\"\r\n *cdkVirtualFor=\"\r\n let option of col?.column_dropdown_value\r\n | filter : sideNestedFilterSearch : 'value'\r\n \"\r\n >\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n [value]=\"option\"\r\n [checked]=\"\r\n col.query?._ids?.includes(option?._id || option?.id || option)\r\n \"\r\n (change)=\"onOptionToggle(col, option)\"\r\n id=\"option_{{ col.field }}_{{\r\n option?.id || option?._id || option\r\n }}\"\r\n />\r\n\r\n <label\r\n class=\"form-check-label\"\r\n [for]=\"\r\n 'option_' +\r\n col.field +\r\n '_' +\r\n (option?.id || option?._id || option)\r\n \"\r\n >\r\n {{( (option.value || option) | titlecase ) }}\r\n </label>\r\n </div>\r\n </cdk-virtual-scroll-viewport>\r\n\r\n\r\n <!-- Actions -->\r\n <!-- <div class=\"d-flex gap-2 mt-2\">\r\n <div\r\n class=\"btn btn-sm btn-primary d-flex justify-content-center align-items-center\"\r\n style=\"height: 22px;\"\r\n (click)=\"applySideFilter(col)\"\r\n >\r\n Apply\r\n </div>\r\n <div\r\n class=\"btn btn-sm btn-secondary d-flex justify-content-center align-items-center\" \r\n style=\"height: 22px;\"\r\n (click)=\"resetSideFilter(col)\"\r\n >\r\n Reset\r\n </div>\r\n </div> -->\r\n </div>\r\n </ng-container>\r\n\r\n <!-- Text Filter Section -->\r\n <ng-template #textFilter>\r\n <div class=\"filter-text-section\">\r\n <div class=\"form-group mb-2\">\r\n <select\r\n class=\"form-select form-select-sm\"\r\n [(ngModel)]=\"col.query.first_condition\"\r\n >\r\n <ng-container *ngIf=\"col?.type == 'string'\">\r\n <option value=\"contain\">Contains</option>\r\n <option value=\"does_not_contain\">Does Not Contain</option>\r\n <option value=\"equal\">Equals</option>\r\n <option value=\"before\">Starts With</option>\r\n <option value=\"after\">Ends With</option>\r\n </ng-container>\r\n\r\n <ng-container *ngIf=\"col?.type == 'date'\">\r\n <option value=\"equal\">Equals To</option>\r\n <option value=\"not_equal\">Not Equal</option>\r\n <option value=\"after\">After</option>\r\n <option value=\"before\">Before</option>\r\n </ng-container>\r\n\r\n <ng-container *ngIf=\"col?.type == 'number'\">\r\n <option value=\"equal\">Equals To</option>\r\n <option value=\"before\">Less Then </option>\r\n <option value=\"after\">Greater Then </option>\r\n <option value=\"less_then_equal\">less then Equal to</option>\r\n <option value=\"greater_then_equal\">Greater then Equal to </option>\r\n </ng-container>\r\n </select>\r\n </div>\r\n\r\n <input\r\n [type]=\"col?.type == 'date' ? 'date' : 'text'\"\r\n class=\"form-control form-control-sm mb-3\"\r\n placeholder=\"Value\"\r\n [(ngModel)]=\"col!.query!.first_value\"\r\n />\r\n\r\n <div\r\n class=\"form-group mb-3 d-flex flex-row muted\"\r\n style=\"font-size: 14px\"\r\n >\r\n <div\r\n class=\"form-check form-check-inline m-0 col-4 d-flex align-items-center gap-1\"\r\n >\r\n <input\r\n class=\"form-check-input filter-radio-inputs\"\r\n type=\"radio\"\r\n name=\"condition\"\r\n [(ngModel)]=\"col!.query.condition\"\r\n value=\"and\"\r\n id=\"and_{{ col.field }}\"\r\n />\r\n <label class=\"form-check-label mb-0 mt-1\" for=\"and_{{ col.field }}\"\r\n >AND</label\r\n >\r\n </div>\r\n <div\r\n class=\"form-check form-check-inline m-0 col-4 d-flex align-items-center gap-1\"\r\n >\r\n <input\r\n class=\"form-check-input filter-radio-inputs\"\r\n type=\"radio\"\r\n name=\"condition\"\r\n [(ngModel)]=\"col!.query.condition\"\r\n value=\"or\"\r\n id=\"or_{{ col.field }}\"\r\n />\r\n <label class=\"form-check-label mb-0 mt-1\" for=\"or_{{ col.field }}\"\r\n >OR</label\r\n >\r\n </div>\r\n <div\r\n class=\"form-check form-check-inline m-0 col-4 d-flex align-items-center gap-1\"\r\n >\r\n <input\r\n class=\"form-check-input filter-radio-inputs\"\r\n type=\"radio\"\r\n name=\"condition\"\r\n [(ngModel)]=\"col!.query.condition\"\r\n value=\"none\"\r\n id=\"none_{{ col.field }}\"\r\n />\r\n <label\r\n class=\"nnonem-check-label mb-0 mt-1\"\r\n for=\"none_{{ col.field }}\"\r\n >None</label\r\n >\r\n </div>\r\n </div>\r\n <ng-container\r\n *ngIf=\"col?.query?.first_value && col?.query?.condition !== 'none'\"\r\n >\r\n <div class=\"form-group mb-2\">\r\n <select\r\n class=\"form-select form-select-sm\"\r\n [(ngModel)]=\"col!.query.second_condition\"\r\n >\r\n <ng-container *ngIf=\"col?.type == 'string'\">\r\n <option value=\"contain\">Contains</option>\r\n <option value=\"does_not_contain\">Does Not Contain</option>\r\n <option value=\"equal\">Equals</option>\r\n <option value=\"before\">Starts With</option>\r\n <option value=\"after\">Ends With</option>\r\n </ng-container>\r\n\r\n <ng-container *ngIf=\"col?.type == 'date'\">\r\n <option value=\"equal\">Equals To</option>\r\n <option value=\"not_equal\">Not Equal</option>\r\n <option value=\"after\">After</option>\r\n <option value=\"before\">Before</option>\r\n </ng-container>\r\n\r\n <ng-container *ngIf=\"col?.type == 'number'\">\r\n <option value=\"equal\">Equals To</option>\r\n <option value=\"before\">Less Then </option>\r\n <option value=\"after\">Greater Then </option>\r\n <option value=\"less_then_equal\">less then Equal to</option>\r\n <option value=\"greater_then_equal\">Greater then Equal to </option>\r\n </ng-container>\r\n </select>\r\n </div>\r\n\r\n <input\r\n [type]=\"col?.type == 'date' ? 'date' : 'text'\"\r\n class=\"form-control form-control-sm mb-3\"\r\n placeholder=\"Second Value\"\r\n [(ngModel)]=\"col!.query.second_value\"\r\n />\r\n </ng-container>\r\n <!-- <div class=\"d-flex gap-2\">\r\n <div class=\"btn btn-sm btn-primary d-flex justify-content-center align-items-center\" style=\"height: 22px;\" (click)=\"applyDropdownFilter()\">apply</div>\r\n <div class=\"btn btn-sm btn-secondary d-flex justify-content-center align-items-center\" style=\"height: 22px;\" (click)=\"applyDropdownFilter()\">reset</div>\r\n\r\n </div> -->\r\n </div>\r\n </ng-template>\r\n <div\r\n class=\"d-flex justify-content-center gap-2 border-top\"\r\n style=\"height: 38px\"\r\n >\r\n <button\r\n type=\"button\"\r\n style=\"max-height: 30px\"\r\n class=\"btn btn-outline-secondary btn-light border w-100 d-flex align-items-center justify-content-center mt-1 btn-light\"\r\n (click)=\"$event.stopPropagation(); removeSideFilter(col)\"\r\n >\r\n <span>Clear</span>\r\n </button>\r\n <button\r\n type=\"button\"\r\n style=\"max-height: 30px\"\r\n class=\"btn btn-primary w-100 d-flex align-items-center justify-content-center mt-1\"\r\n (click)=\"applySideFilter(col)\"\r\n [class.disabled]=\"(col?.query.condition !== 'none' && !col?.query?.second_value)\"\r\n [class.pe-none]=\"(col!?.query.condition !== 'none' && !col?.query?.second_value)\"\r\n >\r\n <span style=\"margin-top: -1px\">Apply</span>\r\n </button>\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<!-- Centr Overlay for showing the chose columns -->\r\n\r\n<div *ngIf=\"showColumnPanel\" class=\"custom-modal-overlay\">\r\n <div\r\n class=\"custom-modal-content\"\r\n [style.backgroundColor]=\"dropdownsBackgroundColor\"\r\n (click)=\"$event.stopPropagation()\"\r\n >\r\n <ng-container *ngTemplateOutlet=\"modalColumnPannel\"></ng-container>\r\n </div>\r\n</div>\r\n\r\n<!-- The existing ng-template you provided -->\r\n<ng-template #modalColumnPannel>\r\n <div class=\"column-panel-header\">\r\n <div\r\n class=\"d-flex justify-content-between align-items-center px-2 ps-3 rounded-top-2 moda-header\"\r\n [style.height.px]=\"48\"\r\n >\r\n Choose Columns\r\n <span class=\"filter-icon-wrapper\" (click)=\"closeModalColumnPanel()\"\r\n ><span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/x.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span\r\n ></span>\r\n </div>\r\n <hr class=\"my-0\" />\r\n <div>\r\n <div class=\"d-flex align-items-center px-2 pe-3\" [style.height.px]=\"48\">\r\n <span class=\"filter-icon-wrapper me-2\" *ngIf=\"showColumnsGrouping\">\r\n <span\r\n class=\"toggle-icon data-grid-svg-icon\"\r\n [inlineSVG]=\"\r\n accordionState === 'all'\r\n ? singleSpaAssetsPath + 'data-grid/icons/chevron-down.svg'\r\n : accordionState === 'some'\r\n ? singleSpaAssetsPath + 'data-grid/icons/dash.svg'\r\n : singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\r\n \"\r\n (click)=\"toggleAllAccordions()\"\r\n ></span>\r\n </span>\r\n <input\r\n type=\"checkbox\"\r\n class=\"form-check-input me-2\"\r\n [checked]=\"allColumnsSelected()\"\r\n (change)=\"toggleAllColumnsVisibility()\"\r\n />\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Search columns...\"\r\n [(ngModel)]=\"choseColumnsSearch\"\r\n />\r\n </div>\r\n\r\n <hr class=\"mt-0 mb-1\" />\r\n <div class=\"px-2 overlay-scrollable\">\r\n <ng-container\r\n *ngFor=\"\r\n let col of columns | filter : choseColumnsSearch : 'header';\r\n trackBy: trackByField\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"columnPanelItem; context: { col: col }\"\r\n ></ng-container>\r\n </ng-container>\r\n </div>\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template #sideMenuRowGroups>\r\n <div class=\"d-flex flex-column h-100 d-none\">\r\n <div class=\"px-3 h-100\">\r\n <div class=\"d-flex gap-3 mb-4\">\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/justify.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n <span>Row Groups</span>\r\n </div>\r\n <div class=\"h-50\">\r\n <div\r\n class=\"px-3 py-2 border-dashed h-100 d-flex justify-content-center align-items-center\"\r\n style=\"font-size: 14px\"\r\n >\r\n Drag here to set row Groups\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <hr class=\"mt-4\" />\r\n\r\n <div class=\"px-3 h-100\">\r\n <div class=\"d-flex gap-3 mb-4\">\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/justify.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n <span>Values</span>\r\n </div>\r\n <div class=\"h-50 d-flex\">\r\n <div\r\n class=\"px-3 py-2 border-dashed h-100 d-flex justify-content-center align-items-center\"\r\n style=\"font-size: 14px\"\r\n >\r\n Drag here aggregate\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<!-- *************************************************** -->\r\n<!-- *************************************************** -->\r\n<!-- *************************************************** -->\r\n<!-- Drag Preview Template -->\r\n<!-- *************************************************** -->\r\n<!-- *************************************************** -->\r\n<ng-template #dragPreview let-col>\r\n <div class=\"p-2 border d-flex gap-2\">\r\n <div>\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrows-move.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n <div>{{ col.header }}</div>\r\n </div>\r\n</ng-template>\r\n\r\n<!-- Drag Placeholder Template -->\r\n<ng-template\r\n #dragPlaceholder\r\n let-col\r\n let-i=\"index\"\r\n let-section=\"section\"\r\n let-draggingInGroupArea=\"draggingInGroupArea\"\r\n>\r\n <div *ngIf=\"!draggingInGroupArea\">\r\n <div\r\n *ngTemplateOutlet=\"\r\n headerCell;\r\n context: { $implicit: col, index: i, section: section }\r\n \"\r\n ></div>\r\n </div>\r\n <div *ngIf=\"draggingInGroupArea\">New Placeholder</div>\r\n</ng-template>\r\n\r\n<!-- Top Group Row Placeholder -->\r\n<ng-template #topGroupingRowPlaceholder let-col let-showChevron=\"showChevron\">\r\n <div class=\"d-flex gap-2\">\r\n <div\r\n class=\"d-flex gap-2 top-row-grouping-placeholder\"\r\n [style.backgroundColor]=\"topGroupedBadgesBackgroundColor\"\r\n >\r\n <span\r\n cdkDragHandle\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/grid-3x2-gap.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n <span>{{ col.header }}</span>\r\n <span\r\n (click)=\"ungroupColumn(col)\"\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/x.svg'\"\r\n class=\"cursor-pointer data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n </div>\r\n <div *ngIf=\"showChevron\" style=\"opacity: 0.6; font-size: 14px\">\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template\r\n #childHeaderPlaceholder\r\n let-col\r\n let-pinnedRight=\"pinnedRight\"\r\n let-i=\"index\"\r\n let-sections=\"sections\"\r\n>\r\n <div\r\n class=\"header-cell one-row-header-cells\"\r\n [class.border-right]=\"showVerticalBorder\"\r\n [style.width.px]=\"col.width\"\r\n [style.min-width.px]=\"col.width\"\r\n [style.min-height.px]=\"headerRowHeight\"\r\n [style.max-height.px]=\"headerRowHeight\"\r\n [style.fontWeight]=\"headerFontWeight\"\r\n >\r\n <div class=\"d-flex justify-content-between h-100 align-items-center w-100\">\r\n <div\r\n class=\"d-flex justify-content-between align-items-center w-100\"\r\n [class.flex-row-reverse]=\"pinnedRight\"\r\n >\r\n <div\r\n class=\"text-ellipsis h-100 d-flex align-items-center\"\r\n [title]=\"col.header\"\r\n [class.w-100]=\"pinnedRight\"\r\n >\r\n {{ col.header }}\r\n </div>\r\n\r\n <div\r\n class=\"position-relative d-flex\"\r\n [class.flex-row-reverse]=\"pinnedRight\"\r\n >\r\n <div class=\"three-dots p-1\" style=\"cursor: pointer\">\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/three-dots-vertical.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n\r\n <div class=\"resize-handle\">\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/resize-handle.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n <div\r\n *ngIf=\"showFilterRow\"\r\n [style.backgroundColor]=\"headerBackgroundColor\"\r\n class=\"header-cell filter-cell\"\r\n [class.border-right]=\"showVerticalBorder\"\r\n [style.width.px]=\"col.width\"\r\n [style.min-width.px]=\"col.width\"\r\n [style.height.px]=\"headerRowHeight\"\r\n [style.min-height.px]=\"headerRowHeight\"\r\n [style.max-height.px]=\"headerRowHeight\"\r\n [class.border-right]=\"showVerticalBorder\"\r\n style=\"grid-row: 3\"\r\n >\r\n <div\r\n class=\"header-cell filter-cell\"\r\n [style.backgroundColor]=\"headerBackgroundColor\"\r\n [style.width.px]=\"col.width\"\r\n [style.min-width.px]=\"col.width\"\r\n [style.height.px]=\"headerRowHeight\"\r\n [style.min-height.px]=\"headerRowHeight\"\r\n [style.max-height.px]=\"headerRowHeight\"\r\n >\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Filter\"\r\n [(ngModel)]=\"col.filterValue\"\r\n [readonly]=\"col?.type == 'dropdown' || col?.type == 'image' || col?.type == 'array'\"\r\n [class.disabled-search-input]=\"\r\n col?.type == 'dropdown' || col?.type == 'image' || col?.type == 'array'\r\n \"\r\n />\r\n <span\r\n class=\"filter-icon-wrapper\"\r\n (click)=\"activeFilterCell = col; activeCol = null\"\r\n ><span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span\r\n ></span>\r\n\r\n <div\r\n class=\"position-absolute\"\r\n *ngIf=\"activeFilterCell === col\"\r\n style=\"top: 100%; right: 0; z-index: 10; left: 0\"\r\n ></div>\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template #tableLayout>\r\n <div\r\n (click)=\"$event.stopPropagation()\"\r\n class=\"p-3 shadow actions-dropdown mt-1 dropdown-menu show shadow custom-menu table-layout\"\r\n style=\"width: 320px\"\r\n >\r\n <div class=\"d-flex align-items-center mb-3\">\r\n <button\r\n class=\"btn btn-link p-0\"\r\n style=\"margin-left: -10px\"\r\n (click)=\"toggleActions('setting')\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrow-left.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n </button>\r\n <h6 class=\"mb-0 ms-2\" style=\"font-weight: 500\">Table Layout</h6>\r\n </div>\r\n <hr class=\"my-2\" />\r\n <div class=\"w-100 mb-3 d-flex\" role=\"group\">\r\n <input\r\n type=\"radio\"\r\n class=\"btn-check layout-button-check\"\r\n name=\"layoutSize\"\r\n id=\"small\"\r\n autocomplete=\"off\"\r\n (change)=\"changeTableLayout($event, 'small')\"\r\n [checked]=\"selectedTableLayout == 'small'\"\r\n />\r\n <label\r\n class=\"border d-flex flex-column align-items-center layout-button\"\r\n for=\"small\"\r\n [ngStyle]=\"{\r\n color: selectedTableLayout == 'small' ? '#000' : '#727272'\r\n }\"\r\n >\r\n <div class=\"preview-box border mb-1\" style=\"height: 8px\"></div>\r\n Small\r\n </label>\r\n\r\n <input\r\n type=\"radio\"\r\n class=\"btn-check layout-button-check\"\r\n name=\"layoutSize\"\r\n id=\"medium\"\r\n autocomplete=\"off\"\r\n [checked]=\"selectedTableLayout == 'medium'\"\r\n (change)=\"changeTableLayout($event, 'medium')\"\r\n />\r\n <label\r\n class=\"border mx-3 d-flex flex-column align-items-center layout-button\"\r\n for=\"medium\"\r\n [ngStyle]=\"{\r\n color: selectedTableLayout == 'medium' ? '#000' : '#727272'\r\n }\"\r\n >\r\n <div class=\"preview-box border mb-1\" style=\"height: 12px\"></div>\r\n Medium\r\n </label>\r\n\r\n <input\r\n type=\"radio\"\r\n class=\"btn-check layout-button-check\"\r\n name=\"layoutSize\"\r\n id=\"large\"\r\n autocomplete=\"off\"\r\n (change)=\"changeTableLayout($event, 'large')\"\r\n [checked]=\"selectedTableLayout == 'large'\"\r\n />\r\n <label\r\n class=\"border d-flex flex-column align-items-center layout-button\"\r\n for=\"large\"\r\n [ngStyle]=\"{\r\n color: selectedTableLayout == 'large' ? '#000' : '#727272'\r\n }\"\r\n >\r\n <div class=\"preview-box border mb-1\" style=\"height: 16px\"></div>\r\n Large\r\n </label>\r\n </div>\r\n\r\n <hr class=\"my-2\" />\r\n <div class=\"d-flex justify-content-between align-items-center mb-2\">\r\n <span>Show separators</span>\r\n <div class=\"form-check form-switch m-0\">\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n id=\"separators\"\r\n [(ngModel)]=\"showVerticalBorder\"\r\n (change)=\"onFontChange()\"\r\n />\r\n </div>\r\n </div>\r\n <div class=\"d-flex justify-content-between align-items-center\">\r\n <span>Row shading</span>\r\n <div class=\"form-check form-switch m-0\">\r\n <input\r\n class=\"form-check-input\"\r\n [(ngModel)]=\"rowShadingEnabled\"\r\n (change)=\"toggleRowShading()\"\r\n type=\"checkbox\"\r\n id=\"rowShading\"\r\n />\r\n </div>\r\n </div>\r\n <!-- <div class=\"d-flex justify-content-between align-items-center mb-2\">\r\n <span>Show Side Menu</span>\r\n <div class=\"form-check form-switch m-0\">\r\n <input\r\n class=\"form-check-input\"\r\n [(ngModel)]=\"showSideMenu\"\r\n type=\"checkbox\"\r\n id=\"rowShading\"\r\n />\r\n </div>\r\n </div>\r\n <div class=\"d-flex justify-content-between align-items-center mb-2\">\r\n <span>Show Filter Row</span>\r\n <div class=\"form-check form-switch m-0\">\r\n <input\r\n class=\"form-check-input\"\r\n [(ngModel)]=\"showFilterRow\"\r\n type=\"checkbox\"\r\n id=\"rowShading\"\r\n />\r\n </div>\r\n </div> -->\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template #tablePreset>\r\n <div\r\n *ngIf=\"activeSubButton !== 'save-preset'\"\r\n (click)=\"$event.stopPropagation()\"\r\n class=\"p-3 shadow actions-dropdown mt-1 dropdown-menu show shadow custom-menu table-layout\"\r\n style=\"width: 280px\"\r\n >\r\n <!-- Header -->\r\n <div class=\"d-flex justify-content-between align-items-center mb-3\">\r\n <div class=\"d-flex align-items-center\">\r\n <button\r\n class=\"btn btn-link p-0\"\r\n style=\"margin-left: -10px\"\r\n (click)=\"toggleActions('setting')\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrow-left.svg'\"\r\n class=\"data-grid-svg-icon\"\r\n ></span>\r\n </button>\r\n <h6 class=\"mb-0 ms-2\" style=\"font-weight: 500\">Table Presets</h6>\r\n </div>\r\n <!-- Save Preset Button with Dropdown -->\r\n <div>\r\n <a\r\n class=\"text-decoration-none text-primary\"\r\n type=\"button\"\r\n id=\"savePresetDropdown\"\r\n (click)=\"$event.stopPropagation(); toggleSubActions('save-preset')\"\r\n >\r\n {{ isTablePresetNotChanged ? \"Save preset\" : \"Update Preset\" }}\r\n </a>\r\n </div>\r\n </div>\r\n\r\n <!-- Search -->\r\n <div class=\"mb-3\">\r\n <div class=\"col-12 global-search\">\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/search.svg'\"\r\n class=\"data-grid-svg-icon mx-2 position-absolute icon\"\r\n ></span>\r\n <input\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Search...\"\r\n [(ngModel)]=\"searchTextPresetTable\"\r\n type=\"search\"\r\n />\r\n </div>\r\n </div>\r\n\r\n <!-- Preset List -->\r\n <ng-container\r\n *ngIf=\"\r\n tableView | filter : searchTextPresetTable : 'name' as filteredList\r\n \"\r\n >\r\n <!-- If filteredList exists and none is default -> show fallback -->\r\n <div\r\n class=\" pb-5 overflow-auto\"\r\n [style.maxHeight.px]=\"dataGridContainer.offsetHeight - 250\"\r\n >\r\n <div\r\n class=\"cursor-pointer\"\r\n (click)=\"\r\n clearAllFilters();\r\n openIndex = null;\r\n temp_state.id = '';\r\n activeTopButton = '';\r\n curretaTablePresetForUpdate = null\r\n \"\r\n >\r\n <div class=\"fw-semibold\">Default View</div>\r\n </div>\r\n <div class=\"d-flex justify-content-between\">\r\n <small class=\"text-dark\">Created by system</small>\r\n <span\r\n *ngIf=\"!tableFilterViewId && !hasAnyDefaultView()\"\r\n class=\"badge bg-light text-primary ms-2\"\r\n >Default</span\r\n >\r\n <!-- <span\r\n *ngIf=\"!tableFilterViewId && !hasAnyDefaultView()\"\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/check-blue.svg'\"\r\n class=\"me-2\"\r\n ></span> -->\r\n <div\r\n class=\"dropdown d-flex justify-content-end\"\r\n *ngIf=\"tableFilterViewId\"\r\n ></div>\r\n </div>\r\n\r\n <!-- The list: render each table from filteredList -->\r\n <div\r\n class=\"list-group list-group-flush\"\r\n *ngFor=\"\r\n let table of filteredList;\r\n let i = index;\r\n trackBy: trackByTable\r\n \"\r\n >\r\n <!-- Item -->\r\n <div\r\n (click)=\"\r\n $event.stopPropagation(); openIndex = null; activeTopButton = ''\r\n \"\r\n class=\"list-group-item px-0 d-flex justify-content-between align-items-center\"\r\n >\r\n <div (click)=\"selectFilter(table); openIndex = null\">\r\n <div class=\"fw-semibold\" style=\"cursor: pointer\">\r\n {{ table?.name }}\r\n <!-- {{table?.is_temp}} -->\r\n <span\r\n *ngIf=\"\r\n (table?.is_temp && !temp_state.id) ||\r\n temp_state.id == table.id\r\n \"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/check-blue.svg'\r\n \"\r\n class=\"me-2\"\r\n ></span>\r\n <span\r\n *ngIf=\"table?.is_default\"\r\n class=\"badge bg-light text-primary ms-2\"\r\n >Default</span\r\n >\r\n </div>\r\n <small class=\"text-dark\" *ngIf=\"table?.config?.filterNames\" [title]=\"table?.config?.filterNames\">\r\n {{\r\n table?.config?.filterNames?.length > 25\r\n ? (table?.config?.filterNames | slice:0:25) + '...'\r\n : table?.config?.filterNames\r\n }}\r\n ({{ table?.config?.totalCount }})\r\n </small>\r\n <small class=\"text-dark\" *ngIf=\"!table?.config?.filterNames\">{{ table?.createdAt | date : \"MMM d, y\" }}</small>\r\n </div>\r\n\r\n <div class=\"d-flex align-items-center\">\r\n <span\r\n *ngIf=\"table?.is_default\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/check-blue.svg'\r\n \"\r\n class=\"me-2\"\r\n ></span>\r\n\r\n <div class=\"dropdown\" *ngIf=\"!table?.is_default\">\r\n <div\r\n class=\"dropdown-wrapper\"\r\n (click)=\"$event.stopPropagation()\"\r\n >\r\n <button\r\n type=\"button\"\r\n class=\"btn-icon muted-text\"\r\n (click)=\"toggleMenu(i, $event)\"\r\n aria-haspopup=\"true\"\r\n [attr.aria-expanded]=\"openIndex === i\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath +\r\n 'data-grid/icons/horizontal-dots.svg'\r\n \"\r\n class=\"me-2\"\r\n ></span>\r\n </button>\r\n\r\n <!-- menu -->\r\n <ul\r\n *ngIf=\"openIndex === i\"\r\n class=\"custom-dropdown-menu position-fixed top-auto\"\r\n role=\"menu\"\r\n [style.right.px]=\"'unset'\"\r\n [style.left.px]=\"dataGridContainer.offsetWidth - 200\"\r\n style=\"top: unset; right: unset\"\r\n >\r\n <li role=\"none\">\r\n <button\r\n role=\"menuitem\"\r\n class=\"dropdown-item\"\r\n (click)=\"\r\n actionPreset(table, 'setPreset'); temp_state.id = ''\r\n \"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/star.svg'\r\n \"\r\n class=\"me-2\"\r\n ></span>\r\n Set as default\r\n </button>\r\n </li>\r\n\r\n <li role=\"none\" *ngIf=\"!table.confirmDelete\">\r\n <button\r\n role=\"menuitem\"\r\n class=\"dropdown-item text-danger\"\r\n (click)=\"table.confirmDelete = true\"\r\n >\r\n <span\r\n style=\"margin-top: -4px\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath +\r\n 'data-grid/icons/trash-red.svg'\r\n \"\r\n class=\"me-2\"\r\n ></span>\r\n Delete\r\n </button>\r\n </li>\r\n\r\n <li\r\n role=\"none\"\r\n *ngIf=\"table.confirmDelete\"\r\n class=\"confirm-block\"\r\n >\r\n <div class=\"px-3 py-2 text-center\">\r\n <div class=\"mb-2\">\r\n Are you sure you want to delete <br /><b\r\n >\u201C{{ table?.name }}\u201D</b\r\n >?\r\n </div>\r\n <div class=\"d-flex gap-2\">\r\n <button\r\n class=\"btn btn-sm btn-light me-2\"\r\n (click)=\"table.confirmDelete = false\"\r\n >\r\n Cancel\r\n </button>\r\n <button\r\n class=\"btn btn-sm btn-danger\"\r\n (click)=\"actionPreset(table, 'deletePreset')\"\r\n >\r\n Delete\r\n </button>\r\n </div>\r\n </div>\r\n </li>\r\n </ul>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n <!-- Item End Here -->\r\n </div>\r\n </div>\r\n </ng-container>\r\n </div>\r\n\r\n <div\r\n (click)=\"$event.stopPropagation()\"\r\n *ngIf=\"activeSubButton == 'save-preset'\"\r\n class=\"dropdown-menu p-3 badge mt-4 save-preset-dropdown mt-1\"\r\n aria-labelledby=\"savePresetDropdown\"\r\n style=\"min-width: 250px\"\r\n >\r\n <div class=\"fw-bold fs-14px mb-2\">\r\n {{ isTablePresetNotChanged ? \"Save preset\" : \"Update Preset\" }}\r\n </div>\r\n <div class=\"fs-14px mb-2\" style=\"line-height: 20px\">\r\n This will save the current table adjustments as a preset.\r\n </div>\r\n <!-- Input -->\r\n <div class=\"mb-2\">\r\n <label for=\"presetName\" class=\"form-label fs-12px fw-bold\"\r\n >Preset Name</label\r\n >\r\n <div class=\"col-12 global-search\">\r\n <input\r\n #presetNameCtrl=\"ngModel\"\r\n required\r\n [(ngModel)]=\"presetName\"\r\n [ngClass]=\"{\r\n 'is-invalid':\r\n presetNameCtrl.invalid &&\r\n (presetNameCtrl.dirty || presetNameCtrl.touched)\r\n }\"\r\n class=\"form-control form-control-sm ps-2\"\r\n placeholder=\"Enter preset name\"\r\n type=\"text\"\r\n />\r\n </div>\r\n </div>\r\n\r\n <!-- Checkbox -->\r\n <div class=\"form-check mb-2\">\r\n <input\r\n class=\"form-check-input\"\r\n [(ngModel)]=\"presetFilter\"\r\n type=\"checkbox\"\r\n id=\"saveFilters\"\r\n />\r\n <label class=\"form-check-label mt-1\" for=\"saveFilters\">\r\n Save active filters\r\n </label>\r\n </div>\r\n\r\n <!-- Save Button -->\r\n <div class=\"d-flex justify-content-center gap-2\" style=\"height: 32px\">\r\n <button\r\n type=\"button\"\r\n style=\"height: 32px\"\r\n class=\"btn border w-100 d-flex align-items-center justify-content-center btn-light\"\r\n (click)=\"$event.stopPropagation(); toggleActions('table-presets')\"\r\n style=\"margin-top: -2px\"\r\n >\r\n <span>Cancel</span>\r\n </button>\r\n <button\r\n [disabled]=\"closeDropdown.preset.loading\"\r\n (click)=\"savePreset(presetNameCtrl)\"\r\n type=\"button\"\r\n style=\"height: 32px\"\r\n class=\"btn btn-primary w-100 d-flex align-items-center justify-content-center\"\r\n >\r\n <span style=\"margin-top: -2px\" *ngIf=\"isTablePresetNotChanged\">\r\n <ng-container *ngIf=\"!closeDropdown.preset.loading\"\r\n >Save</ng-container\r\n >\r\n <ng-container *ngIf=\"closeDropdown.preset.loading\"\r\n ><span class=\"spinner-border spinner-border-sm\"></span\r\n ></ng-container>\r\n </span>\r\n <span style=\"white-space: nowrap\" *ngIf=\"!isTablePresetNotChanged\"\r\n >Update Preset</span\r\n >\r\n </button>\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template #showHideColumns>\r\n <div\r\n (click)=\"$event.stopPropagation()\"\r\n class=\"p-3 shadow actions-dropdown mt-1 dropdown-menu show shadow custom-menu table-layout\"\r\n style=\"width: 280px\"\r\n >\r\n <!-- Header -->\r\n <div class=\"d-flex justify-content-between align-items-center mb-3\">\r\n <div class=\"d-flex align-items-center\">\r\n <button\r\n class=\"btn btn-link p-0\"\r\n style=\"margin-left: -10px\"\r\n (click)=\"toggleActions('setting')\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrow-left.svg'\"\r\n class=\"data-grid-svg-icon\"\r\n ></span>\r\n </button>\r\n <h6 class=\"mb-0 ms-2\" style=\"font-weight: 500\">Columns</h6>\r\n </div>\r\n <a\r\n (click)=\"resetColumns()\"\r\n href=\"javascript:void(0)\"\r\n class=\"text-primary text-decoration-none d-none\"\r\n >Reset</a\r\n >\r\n </div>\r\n\r\n <!-- Search -->\r\n <div class=\"mb-3\">\r\n <div class=\"col-12 global-search\">\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/search.svg'\"\r\n class=\"mx-2 position-absolute icon data-grid-svg-icon\"\r\n ></span>\r\n <input\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Search column\"\r\n type=\"search\"\r\n [(ngModel)]=\"topShowHideColumns\"\r\n />\r\n </div>\r\n </div>\r\n <!-- Preset List -->\r\n <div\r\n class=\"list-group list-group-flush\"\r\n style=\"overflow: auto; scrollbar-width: thin\"\r\n [style.maxHeight.px]=\"dataGridContainer.offsetHeight - 220\"\r\n >\r\n <div class=\"muted-text show-hide-table-label d-flex justify-content-between\" *ngIf=\"hasAnyVisibleColumn\">\r\n Show in table\r\n <div class=\"form-check\">\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n id=\"hide_all\"\r\n [checked]=\"allColumnsSelected()\"\r\n (change)=\"toggleAllColumnsVisibility()\"\r\n />\r\n <label class=\"form-check-label fw-semibold\" for=\"hide_all\">\r\n Show/Hide All \r\n </label>\r\n </div>\r\n </div>\r\n <!-- Item -->\r\n <ng-container\r\n *ngFor=\"\r\n let col of columns | filter : topShowHideColumns : 'header';\r\n trackBy: trackByField\r\n \"\r\n >\r\n <div\r\n *ngIf=\"col.is_visible\"\r\n class=\"list-group-item border-0 px-0 d-flex justify-content-between align-items-center\"\r\n >\r\n <div class=\"d-flex gap-1\">\r\n <div>\r\n <span\r\n *ngIf=\"!col?.pinned\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/grip-vertical.svg'\r\n \"\r\n class=\"cursor-grap data-grid-svg-icon\"\r\n (mousedown)=\"$event.preventDefault()\"\r\n ></span>\r\n <span\r\n *ngIf=\"col?.pinned\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/pin-blue.svg'\r\n \"\r\n class=\"cursor-grap data-grid-svg-icon\"\r\n (mousedown)=\"$event.preventDefault()\"\r\n ></span>\r\n </div>\r\n <div class=\"fw-semibold\">\r\n {{ col.header }}\r\n </div>\r\n </div>\r\n <div\r\n *ngIf=\"!col?.query?.first_value && !col?.query?._ids?.length\"\r\n class=\"d-flex align-items-center cursor-pointer\"\r\n (click)=\"toggleColumnVisibility(col, false)\"\r\n [class.disabled]=\"visibleColumns().length <= 2 || col?.is_always_visible\"\r\n [class.pe-none]=\"visibleColumns().length <= 2 || col?.is_always_visible\"\r\n [class.opacity-50]=\"visibleColumns().length <= 2 || col?.is_always_visible\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/eye.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n </div>\r\n <div\r\n *ngIf=\"col?.query?.first_value || col?.query?._ids?.length\"\r\n class=\"d-flex align-items-center\"\r\n style=\"opacity: 0.5\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/eye.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n </div>\r\n </div>\r\n </ng-container>\r\n\r\n <!-- Item End Here -->\r\n\r\n <div\r\n class=\"dropdown-divider\"\r\n *ngIf=\"hasAnyVisibleColumn && hasAnyInVisibleColumn\"\r\n ></div>\r\n\r\n <div\r\n class=\"muted-text show-hide-table-label d-flex justify-content-between\"\r\n *ngIf=\"hasAnyInVisibleColumn\"\r\n >\r\n Hide in table\r\n <div class=\"form-check\">\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n id=\"show_all\"\r\n [checked]=\"allColumnsSelected()\"\r\n (change)=\"toggleAllColumnsVisibility()\"\r\n />\r\n <label class=\"form-check-label fw-semibold\" for=\"show_all\">\r\n Show/Hide All \r\n </label>\r\n </div>\r\n </div>\r\n <div class=\"list-group list-group-flush\">\r\n <ng-container *ngFor=\"let col of columns; trackBy: trackByField\">\r\n <div\r\n *ngIf=\"!col.is_visible\"\r\n class=\"list-group-item border-0 px-0 d-flex justify-content-between align-items-center\"\r\n >\r\n <div class=\"d-flex gap-1\">\r\n <div>\r\n <span\r\n *ngIf=\"!col?.pinned\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/grip-vertical.svg'\r\n \"\r\n class=\"data-grid-svg-icon cursor-grap\"\r\n (mousedown)=\"$event.preventDefault()\"\r\n ></span>\r\n <span\r\n *ngIf=\"col?.pinned\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/pin-blue.svg'\r\n \"\r\n class=\"data-grid-svg-icon cursor-grap\"\r\n (mousedown)=\"$event.preventDefault()\"\r\n ></span>\r\n </div>\r\n <div class=\"fw-semibold\">\r\n {{ col.header }}\r\n </div>\r\n </div>\r\n <div\r\n class=\"d-flex align-items-center cursor-pointer\"\r\n (click)=\"toggleColumnVisibility(col, true)\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/eye-cross.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n </div>\r\n </div>\r\n </ng-container>\r\n </div>\r\n\r\n <!-- Item End Here -->\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template #filterColumns let-col=\"column\">\r\n <div\r\n @slideToggle\r\n *ngIf=\"!isFilterOpen && activeTopButton == 'filter-columns'\"\r\n (click)=\"$event.stopPropagation()\"\r\n class=\"shadow actions-dropdown mt-1 show shadow custom-menu table-layout filter-columns\"\r\n style=\"width: 280px; right: unset; max-width: 230px\"\r\n [style.backgroundColor]=\"checkboxesBackgroundColor\"\r\n >\r\n <div class=\"mb-2 px-3\">\r\n <div class=\"col-12 global-search\">\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/search.svg'\"\r\n class=\"data-grid-svg-icon mx-2 position-absolute icon\"\r\n ></span>\r\n <input\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Filter by\"\r\n type=\"search\"\r\n [(ngModel)]=\"addFilterColumnInput\"\r\n />\r\n </div>\r\n </div>\r\n <div\r\n class=\"list-group list-group-flush\"\r\n style=\"max-height: calc(100vh - 500px); overflow: auto\"\r\n >\r\n <ng-container\r\n *ngFor=\"\r\n let col of columns | filter : addFilterColumnInput : 'header';\r\n trackBy: trackByField\r\n \"\r\n >\r\n <div\r\n (click)=\"openFilter(col)\"\r\n *ngIf=\"\r\n col.is_visible &&\r\n !col?.query?.first_value &&\r\n !col?.query?._ids?.length && col?.type !== 'image' && col.is_search_able\r\n \"\r\n class=\"list-group-item border-0 px-0 d-flex justify-content-between align-items-center dropdown-item cursor-pointer\"\r\n >\r\n <div class=\"d-flex gap-1\">\r\n <div style=\"margin-top: -3px\"></div>\r\n <div class=\"fw-semibold\">\r\n {{ col.header }}\r\n </div>\r\n </div>\r\n </div>\r\n </ng-container>\r\n </div>\r\n </div>\r\n\r\n <!-- Dropdown -->\r\n <div\r\n @slideToggle\r\n *ngIf=\"isFilterOpen && selectedColumnForFilter?.type == 'dropdown' || selectedColumnForFilter?.type == 'array'\"\r\n (click)=\"$event.stopPropagation()\"\r\n class=\"shadow actions-dropdown mt-1 show shadow custom-menu table-layout filter-columns pb-2\"\r\n style=\"width: 280px; right: unset; max-width: 230px\"\r\n [style.backgroundColor]=\"checkboxesBackgroundColor\"\r\n >\r\n <div class=\"px-3 my-2 border-below py-1 pb-2 mb-3 d-flex ps-1\">\r\n <span\r\n (click)=\"toggleActions('filter-columns'); isActiveFilterOpen = false\"\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrow-left.svg'\"\r\n class=\"data-grid-svg-icon me-2 cursor-pointer\"\r\n ></span\r\n ><b>{{ selectedColumnForFilter?.header }}</b>\r\n </div>\r\n <div class=\"mb-2 px-3\">\r\n <div\r\n class=\"col-12 global-search position-relative border rounded d-flex align-items-center flex-wrap px-2 filter-serach-inpt\"\r\n >\r\n <span\r\n *ngFor=\"let selected of selectedFilterOptions\"\r\n class=\"badge d-flex align-items-center gap-1 me-1 mb-1 top-row-filter-dropdown\"\r\n >\r\n {{ selected?.value ? selected.value : selected }}\r\n <span\r\n (click)=\"toggleSelectionInFilter(selected)\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/cross-primary.svg'\r\n \"\r\n class=\"me-2\"\r\n ></span>\r\n </span>\r\n <input\r\n class=\"form-control form-control-sm border-0 flex-grow-1\"\r\n style=\"padding: 0\"\r\n [placeholder]=\"selectedFilterOptions?.length ? '' : 'Filter by'\"\r\n type=\"search\"\r\n [(ngModel)]=\"searchTextForFilterDropDown\"\r\n (keydown.backspace)=\"handleBackspace($event)\"\r\n />\r\n </div>\r\n </div>\r\n <div\r\n class=\"list-group list-group-flush\"\r\n style=\"max-height: calc(100vh - 600px); overflow: auto\"\r\n >\r\n <ng-container\r\n *ngFor=\"\r\n let col of selectedColumnForFilter.column_dropdown_value\r\n | filter : searchTextForFilterDropDown : 'value';\r\n let i = index\r\n \"\r\n >\r\n <div\r\n class=\"list-group-item border-0 px-2 d-flex justify-content-between align-items-center dropdown-item cursor-pointer\"\r\n >\r\n <div class=\"form-check\">\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n [id]=\"i\"\r\n [checked]=\"currentFilterSelectedIds.has(col.id || col._id || col)\"\r\n (change)=\"toggleSelectionInFilter(col)\"\r\n />\r\n <label class=\"form-check-label fw-semibold\" [for]=\"i\">\r\n {{ col?.value || col?.name || col }}\r\n </label>\r\n </div>\r\n </div>\r\n </ng-container>\r\n </div>\r\n <div\r\n class=\"d-flex justify-content-center gap-2 px-2 border-top\"\r\n style=\"height: 38px\"\r\n >\r\n <button\r\n type=\"button\"\r\n style=\"height: 32px\"\r\n class=\"btn btn-outline-secondary btn-light border w-100 d-flex align-items-center justify-content-center mt-1 btn-light\"\r\n (click)=\"$event.stopPropagation(); resetFilterChanges()\"\r\n >\r\n <span>Cancel</span>\r\n </button>\r\n <button\r\n type=\"button\"\r\n style=\"height: 32px\"\r\n class=\"btn btn-primary w-100 d-flex align-items-center justify-content-center mt-1\"\r\n (click)=\"applyDropdownFilter()\"\r\n >\r\n <span style=\"margin-top: -2px\">Save</span>\r\n </button>\r\n </div>\r\n </div>\r\n\r\n <!-- For Text fields and number fields-->\r\n\r\n <div\r\n @slideToggle\r\n *ngIf=\"\r\n isFilterOpen &&\r\n (selectedColumnForFilter?.type == 'string' ||\r\n selectedColumnForFilter?.type == 'number' ||\r\n selectedColumnForFilter?.type == 'date')\r\n \"\r\n (click)=\"$event.stopPropagation()\"\r\n class=\"shadow actions-dropdown mt-1 show shadow custom-menu table-layout filter-columns pb-2\"\r\n style=\"width: 210px; right: unset; max-width: 230px\"\r\n [style.backgroundColor]=\"checkboxesBackgroundColor\"\r\n >\r\n <div class=\"px-3 border-below py-1 pb-2 d-flex ps-1\">\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrow-left.svg'\"\r\n (click)=\"toggleActions('filter-columns'); isActiveFilterOpen = false\"\r\n class=\"data-grid-svg-icon me-2 cursor-pointer\"\r\n ></span\r\n ><b>{{ selectedColumnForFilter?.header }}</b>\r\n </div>\r\n <div class=\"col-12 position-relative p-2 text-filter\">\r\n <div class=\"mb-2\">\r\n <select\r\n class=\"form-select form-select-sm custom-select border\"\r\n [(ngModel)]=\"firstCondition\"\r\n >\r\n <ng-container *ngIf=\"selectedColumnForFilter?.type == 'string'\">\r\n <option value=\"contain\">Contains</option>\r\n <option value=\"does_not_contain\">Does Not Contain</option>\r\n <option value=\"equal\">Equals</option>\r\n <option value=\"before\">Starts With</option>\r\n <option value=\"after\">Ends With</option>\r\n </ng-container>\r\n\r\n <ng-container *ngIf=\"selectedColumnForFilter?.type == 'date'\">\r\n <option value=\"equal\">Equals To</option>\r\n <option value=\"not_equal\">Not Equal</option>\r\n <option value=\"after\">After</option>\r\n <option value=\"before\">Before</option>\r\n </ng-container>\r\n\r\n <ng-container *ngIf=\"selectedColumnForFilter?.type == 'number'\">\r\n <option value=\"equal\">Equals To</option>\r\n <option value=\"before\">Less Then </option>\r\n <option value=\"after\">Greater Then </option>\r\n <option value=\"less_then_equal\">less then Equal to</option>\r\n <option value=\"greater_then_equal\">Greater then Equal to </option>\r\n </ng-container>\r\n </select>\r\n </div>\r\n <div class=\"mb-2\">\r\n <input\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Enter first value\"\r\n type=\"search\"\r\n [type]=\"\r\n selectedColumnForFilter?.type == 'string'\r\n ? 'text'\r\n : selectedColumnForFilter?.type\r\n \"\r\n [(ngModel)]=\"firstValue\"\r\n (keydown.enter)=\"applyDropdownFilter()\"\r\n />\r\n </div>\r\n <div>\r\n <div class=\"d-flex my-3 d-flex flex-row\" style=\"font-size: 14px\">\r\n <div\r\n class=\"form-check form-check-inline col-4 m-0 d-flex align-items-center gap-1\"\r\n >\r\n <input\r\n class=\"form-check-input\"\r\n type=\"radio\"\r\n id=\"logicalAnd\"\r\n name=\"logicalOperator\"\r\n value=\"and\"\r\n [(ngModel)]=\"condition\"\r\n />\r\n <label class=\"form-check-label mb-0 mt-1\" for=\"logicalAnd\"\r\n >AND</label\r\n >\r\n </div>\r\n\r\n <div\r\n class=\"form-check form-check-inline col-4 m-0 d-flex align-items-center gap-1\"\r\n >\r\n <input\r\n class=\"form-check-input\"\r\n type=\"radio\"\r\n id=\"logicalOr\"\r\n name=\"logicalOperator\"\r\n value=\"or\"\r\n [(ngModel)]=\"condition\"\r\n />\r\n <label class=\"form-check-label mb-0 mt-1\" for=\"logicalOr\">OR</label>\r\n </div>\r\n\r\n <div\r\n class=\"form-check form-check-inline col-4 m-0 d-flex align-items-center gap-1\"\r\n >\r\n <input\r\n class=\"form-check-input\"\r\n type=\"radio\"\r\n id=\"logicalNone\"\r\n name=\"logicalOperator\"\r\n value=\"none\"\r\n [(ngModel)]=\"condition\"\r\n />\r\n <label class=\"form-check-label mb-0 mt-1\" for=\"logicalNone\"\r\n >None</label\r\n >\r\n </div>\r\n </div>\r\n\r\n <ng-container *ngIf=\"condition !== 'none' && firstValue\">\r\n <div class=\"mb-2 mt-3\">\r\n <!-- Second condition select -->\r\n <select\r\n class=\"form-select form-select-sm border\"\r\n [(ngModel)]=\"secondCondition\"\r\n >\r\n <ng-container *ngIf=\"selectedColumnForFilter?.type == 'string'\">\r\n <option value=\"contain\">Contains</option>\r\n <option value=\"does_not_contain\">Does Not Contain</option>\r\n <option value=\"equal\">Equals</option>\r\n <option value=\"before\">Starts With</option>\r\n <option value=\"after\">Ends With</option>\r\n </ng-container>\r\n\r\n <ng-container *ngIf=\"selectedColumnForFilter?.type == 'date'\">\r\n <option value=\"equal\">Equals To</option>\r\n <option value=\"not_equal\">Not Equal</option>\r\n <option value=\"after\">After</option>\r\n <option value=\"before\">Before</option>\r\n </ng-container>\r\n <ng-container *ngIf=\"selectedColumnForFilter?.type == 'number'\">\r\n <option value=\"equal\">Equals To</option>\r\n <option value=\"before\">Less Then </option>\r\n <option value=\"after\">Greater Then </option>\r\n <option value=\"less_then_equal\">less then Equal to</option>\r\n <option value=\"greater_then_equal\">Greater then Equal to </option>\r\n </ng-container>\r\n </select>\r\n </div>\r\n\r\n <div class=\"mb-2\">\r\n <!-- Second value input -->\r\n <input\r\n [type]=\"\r\n selectedColumnForFilter?.type == 'string'\r\n ? 'text'\r\n : selectedColumnForFilter?.type\r\n \"\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Enter second value\"\r\n type=\"search\"\r\n [(ngModel)]=\"secondValue\"\r\n (keydown.enter)=\"applyDropdownFilter()\"\r\n />\r\n </div>\r\n </ng-container>\r\n </div>\r\n </div>\r\n\r\n <div\r\n class=\"d-flex justify-content-center gap-2 px-2 border-top\"\r\n style=\"height: 38px\"\r\n >\r\n <button\r\n [disabled]=\"!currentFilterSelectedIds?.size && !firstValue\"\r\n type=\"button\"\r\n style=\"height: 32px\"\r\n class=\"btn btn-outline-secondary btn-light border w-100 d-flex align-items-center justify-content-center mt-1 btn-light\"\r\n (click)=\"$event.stopPropagation(); resetTextFilterChanges()\"\r\n >\r\n <span>Cancel</span>\r\n </button>\r\n <button\r\n [disabled]=\"(currentFilterSelectedIds?.size === 0 && !firstValue) || (condition !== 'none' && !secondValue)\"\r\n type=\"button\"\r\n style=\"height: 32px\"\r\n class=\"btn btn-primary w-100 d-flex align-items-center justify-content-center mt-1\"\r\n (click)=\"applyDropdownFilter()\"\r\n >\r\n <span style=\"margin-top: -2px\">Apply</span>\r\n </button>\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<!-- Edit dropdown here -->\r\n<ng-template let-col>\r\n <div class=\"drop-down-edit\"></div>\r\n</ng-template>\r\n\r\n<ng-template\r\n #fullTextTemplate\r\n let-row=\"row\"\r\n let-col=\"col\"\r\n let-isArray=\"isArray\"\r\n>\r\n <div\r\n class=\"full-text-box\"\r\n (dblclick)=\"$event.stopPropagation(); $event.preventDefault()\"\r\n (click)=\"$event.stopPropagation(); $event.preventDefault()\"\r\n [style.maxHeight.px]=\"dataGridContainer.offsetHeight / 2\"\r\n >\r\n <ng-container *ngIf=\"!isEditing(row, col)\">\r\n <div\r\n *ngIf=\"!isArray\"\r\n class=\"full-text-content\"\r\n [style.maxHeight.px]=\"dataGridContainer.offsetHeight / 2\"\r\n (dblclick)=\"\r\n $event.stopPropagation();\r\n $event.preventDefault();\r\n enableEdit(row, col, true)\r\n \"\r\n (click)=\"$event.stopPropagation(); $event.preventDefault()\"\r\n >\r\n {{\r\n getNestedValue(row, col.field)?.value ||\r\n getNestedValue(row, col.field)?.name ||\r\n getNestedValue(row, col.field)\r\n }}\r\n </div>\r\n <div *ngIf=\"isArray\">\r\n <ul>\r\n <ng-container\r\n *ngFor=\"let item of getNestedValue(row, col.field); let i = index\"\r\n >\r\n <li *ngIf=\"i !== 0\">\r\n <ng-container>\r\n {{\r\n item?.department_name ||\r\n item?.roleName ||\r\n item?.full_name ||\r\n \"-\"\r\n }}\r\n </ng-container>\r\n </li>\r\n </ng-container>\r\n </ul>\r\n </div>\r\n </ng-container>\r\n <ng-container *ngIf=\"isEditing(row, col)\">\r\n <textarea\r\n (dblclick)=\"\r\n $event.stopPropagation();\r\n $event.preventDefault();\r\n enableEdit(row, col, true)\r\n \"\r\n #textModel=\"ngModel\"\r\n rows=\"4\"\r\n #textAreadInput\r\n [(ngModel)]=\"row[col.field]\"\r\n name=\"{{ col.field }}\"\r\n required\r\n (blur)=\"disableEdit(row, col, textModel)\"\r\n (keydown.enter)=\"textAreadInput.blur()\"\r\n autofocus\r\n class=\"form-control\"\r\n [ngClass]=\"{\r\n 'is-invalid': textModel.invalid\r\n }\"\r\n (mousedown)=\"$event.stopPropagation()\"\r\n ></textarea>\r\n </ng-container>\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template #defaultImagePlaceholder let-row=\"row\" let-col=\"col\">\r\n <span\r\n class=\"px-2 d-flex w-100 cell-content image-placeholder\"\r\n [title]=\"row?.full_name || row?.name || 'N/A'\"\r\n >\r\n <ng-container\r\n *ngIf=\"\r\n row?.logo ||\r\n row?.assetImage ||\r\n row?.invoice?.invoice_image ||\r\n row?.invoice_image;\r\n else placeholder\r\n \"\r\n >\r\n <span\r\n (click)=\"fullscreenImage = row?.profile_pictures?.[4]?.path ||\r\n row?.logo ||\r\n row?.assetImage ||\r\n row?.invoice_image\"\r\n class=\"pic\"\r\n [style.width.px]=\"rowHeight - 10\"\r\n [style.height.px]=\"rowHeight - 10\"\r\n [class.assets-pic]=\"gridType == 'Assets'\"\r\n >\r\n <img\r\n [width]=\"rowHeight - 12\"\r\n [height]=\"rowHeight - 12\"\r\n [style.width.px]=\"rowHeight - 10\"\r\n [style.height.px]=\"rowHeight - 10\"\r\n [src]=\"\r\n row?.profile_pictures?.[4]?.path ||\r\n row?.logo ||\r\n row?.assetImage ||\r\n row?.invoice_image\r\n \"\r\n alt=\"icon\"\r\n class=\"option-icon\"\r\n loading=\"lazy\"\r\n />\r\n </span>\r\n </ng-container>\r\n <!-- <div\r\n class=\"fullscreen-overlay\"\r\n *ngIf=\"fullscreenImage\"\r\n (click)=\"fullscreenImage = null\"\r\n >\r\n <img [src]=\"fullscreenImage\" class=\"fullscreen-img\" />\r\n </div> -->\r\n\r\n <ng-template #placeholder>\r\n <span\r\n [ngClass]=\"getDynamicClass(row?.full_name || row?.name)\"\r\n class=\"pic d-flex align-items-center rounded-circle\"\r\n [style.width.px]=\"rowHeight - 12\"\r\n [style.height.px]=\"rowHeight - 12\"\r\n [style.fontSize.px]=\"rowHeight / 3\"\r\n [class.assets-pic]=\"gridType == 'Assets'\"\r\n >\r\n {{ getInitials(row?.full_name) }}\r\n </span>\r\n </ng-template>\r\n </span>\r\n</ng-template>\r\n\r\n<!-- Right Click Menue -->\r\n<div\r\n [class.invisible]=\"!positionedYet\"\r\n class=\"context-menu p-2\"\r\n *ngIf=\"actionHide && actions?.length\"\r\n [ngStyle]=\"{ 'top.px': yPos, 'left.px': xPos }\"\r\n [class.show]=\"isVisible\"\r\n appendTo=\"body\"\r\n>\r\n <ul>\r\n <li\r\n *ngFor=\"let action of actions\"\r\n class=\"rounded d-flex align-items-center\"\r\n (click)=\"onActionClick(action)\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/' + action + '.svg'\"\r\n class=\"data-grid-svg-icon right-click-menu-icons me-2\"\r\n ></span>\r\n <span class=\"text-capitalize fw-500\">{{ action }}</span>\r\n </li>\r\n </ul>\r\n</div>\r\n\r\n<!-- Details Toggle from bottom -->\r\n\r\n<ng-template #nestedTableTemplate let-row>\r\n <div\r\n class=\"nested-table table table-sm w-100 mb-0 center-nested-table w-100\"\r\n style=\"table-layout: fixed !important\"\r\n #nestedTableContainer\r\n >\r\n <thead\r\n #nestedHeader\r\n [style.backgroundColor]=\"nestedTableHeaderBackgroundColor\"\r\n >\r\n <div\r\n cdkDropList\r\n [cdkDropListData]=\"row?.detail.columns\"\r\n cdkDropListOrientation=\"horizontal\"\r\n (cdkDropListDropped)=\"dropColumn($event, row)\"\r\n (cdkDropListSorted)=\"onNestedColSort($event, previewNestedCols)\"\r\n [style.height.px]=\"nestedTableHeaderRowHeight\"\r\n class=\"d-flex tr border-below\"\r\n >\r\n <div\r\n *ngFor=\"let col of row.detail.columns; let i = index\"\r\n [style.width.px]=\"col?.width || 250\"\r\n [style.minWidth.px]=\"col?.width || 250\"\r\n [style.maxWidth.px]=\"col?.width || 250\"\r\n class=\"px-4 th\"\r\n [attr.field]=\"col.field\"\r\n [style.backgroundColor]=\"nestedTableHeaderBackgroundColor\"\r\n cdkDrag\r\n >\r\n <div\r\n class=\"d-flex h-100 justify-content-between position-relative align-items-center\"\r\n >\r\n <div class=\"text-ellipsis\" (click)=\"sortNestedCol(col, row)\">\r\n {{ col.header }}\r\n </div>\r\n <div class=\"d-flex gap-2\">\r\n <span\r\n *ngIf=\"currentSubSortColumn == col.field\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath +\r\n (col?.order_by == 'desc'\r\n ? 'data-grid/icons/sort-desc.svg'\r\n : 'data-grid/icons/sort-asc.svg')\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center ms-2 start-50\"\r\n >\r\n </span>\r\n <!-- <div\r\n class=\"three-dots p-1\"\r\n (click)=\"openThreeDotsMenu($event, col)\"\r\n style=\"cursor: pointer\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath +\r\n 'data-grid/icons/three-dots-vertical.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div> -->\r\n\r\n <!-- Only show menu if this column is active -->\r\n <div\r\n class=\"position-absolute\"\r\n *ngIf=\"activeCol === col\"\r\n style=\"top: -50%; z-index: 21; left: 0\"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n columnMenu;\r\n context: {\r\n col: col,\r\n isNestedTable: true,\r\n columns: row?.detail.columns\r\n }\r\n \"\r\n ></ng-container>\r\n </div>\r\n <div\r\n class=\"resize-handle\"\r\n (click)=\"$event.stopPropagation()\"\r\n (mousedown)=\"\r\n $event.preventDefault();\r\n onResizeColumn($event, col);\r\n $event.stopPropagation()\r\n \"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/resize-handle.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n </div>\r\n </div>\r\n <ng-template cdkDragPreview>\r\n <div class=\"p-2 border d-flex gap-2\">\r\n <div>\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/arrows-move.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n <div>{{ col.header }}</div>\r\n </div>\r\n </ng-template>\r\n </div>\r\n </div>\r\n </thead>\r\n <div\r\n [style.width.px]=\"nestedHeader.offsetWidth - 10\"\r\n [style.minWidth.px]=\"nestedHeader.offsetWidth - 10\"\r\n >\r\n <cdk-virtual-scroll-viewport\r\n [itemSize]=\"nestedTablerowHeight\"\r\n class=\"viewport\"\r\n [style.height.px]=\"\r\n (row?.detail?.result?.length < 5\r\n ? nestedTablerowHeight * row?.detail?.result?.length + 40\r\n : 300) + (hasHorizontalScroll ? -12 : 1)\r\n \"\r\n [style.width.px]=\"nestedHeader.offsetWidth - 10\"\r\n [style.minWidth.px]=\"nestedHeader.offsetWidth - 10\"\r\n >\r\n <div\r\n class=\"cursor-pointer border-below d-flex tr\"\r\n *cdkVirtualFor=\"let d of row?.detail?.result; trackBy: trackById\"\r\n [style.height.px]=\"nestedTablerowHeight\"\r\n [style.width.px]=\"nestedHeader?.offsetWidth\"\r\n [style.minWidth.px]=\"nestedHeader?.offsetWidth\"\r\n [style.backgroundColor]=\"bodyBackgroundColor\"\r\n (contextmenu)=\"onRightClick($event, d)\"\r\n >\r\n <div\r\n class=\"px-4 py-0 td\"\r\n *ngFor=\"let col of previewNestedCols; let j = index\"\r\n [style.fontSize.px]=\"nestedTablerowFontsize\"\r\n [attr.field]=\"col.field\"\r\n [style.width.px]=\"col?.width || 250\"\r\n [style.minWidth.px]=\"col?.width || 250\"\r\n [style.maxWidth.px]=\"col?.width || 250\"\r\n >\r\n <div\r\n [style.height.px]=\"nestedTablerowHeight - 1\"\r\n [style.max-width.px]=\"col?.width\"\r\n class=\"d-flex align-items-center\"\r\n >\r\n <!-- {{ d[col.field] || (col.is_amount ? 0 : \"-\") }} -->\r\n <div\r\n #cellText\r\n class=\"text-ellipsis flex-grow-1\"\r\n [title]=\"\r\n col?.type === 'date'\r\n ? (getNestedValue(d, col.field) | date : dateFormat)\r\n : getNestedValue(d, col.field) || '-'\r\n \"\r\n >\r\n <ng-container *ngIf=\"col?.type !== 'image'\">\r\n <ng-container *ngIf=\"col.is_amount\">{{\r\n currencySymbol\r\n }}</ng-container>\r\n {{\r\n !isNestedValueArray(d, col.field)\r\n ? col?.type === 'date'\r\n ? (isDate(getNestedValue(d, col.field))\r\n ? (getNestedValue(d, col.field) | date: dateFormat)\r\n : (getNestedValue(d, col.field)?.value ||\r\n getNestedValue(d, col.field)?.name ||\r\n getNestedValue(d, col.field) ||\r\n '-'))\r\n : (getNestedValue(d, col.field)?.value ||\r\n getNestedValue(d, col.field)?.name ||\r\n getNestedValue(d, col.field) ||\r\n (col.is_amount ? 0: '-'))\r\n : (getNestedValue(d, col.field)?.[0]?.department_name ||\r\n getNestedValue(d, col.field)?.[0]?.roleName || getNestedValue(d, col.field)?.[0]?.full_name ||\r\n '-')\r\n }}\r\n </ng-container>\r\n <ng-container *ngIf=\"false\">\r\n {{ getTotalAmount(col) }}\r\n </ng-container>\r\n <ng-container *ngIf=\"col?.type == 'image'\">\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n defaultImagePlaceholder;\r\n context: {\r\n row: d,\r\n col: col,\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </cdk-virtual-scroll-viewport>\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template #leftRightNestedPlaceholder let-row>\r\n <table\r\n class=\"nested-table table table-sm w-100 mb-0\"\r\n [style.backgroundColor]=\"bodyBackgroundColor\"\r\n [style.height.px]=\"\r\n gridType == 'Assets'\r\n ? (nestedTableContainer?.nativeElement?.offsetHeight ?? 0) + 12\r\n : (taskManagementContainer?.nativeElement?.offsetHeight ?? 0)\r\n \"\r\n >\r\n <!-- <div class=\"thead\">\r\n <div\r\n class=\"tr d-flex border-below\"\r\n [style.height.px]=\"nestedTableHeaderRowHeight\"\r\n [style.backgroundColor]=\"headerBackgroundColor\"\r\n >\r\n <div class=\"th\" *ngFor=\"let _ of [1, 2, 3, 4, 5]\"></div>\r\n </div>\r\n </div> -->\r\n <!-- <div class=\"tbody\">\r\n <div\r\n class=\"tr border-below\"\r\n [style.height.px]=\"nestedTablerowHeight\"\r\n *ngFor=\"let _ of row?.detail?.result\"\r\n [style.backgroundColor]=\"headerBackgroundColor\"\r\n >\r\n <div class=\"td\" *ngFor=\"let __ of [1, 2, 3, 4, 5]\" class=\"py-0\">\r\n <span\r\n [style.height.px]=\"nestedTablerowHeight\"\r\n [style.max-width.px]=\"nestedTablerowHeight\"\r\n ></span>\r\n </div>\r\n </div>\r\n </div> -->\r\n </table>\r\n</ng-template>\r\n\r\n<ng-template #taskManagementTemplate let-taskDetails=\"taskDetails\">\r\n <div\r\n class=\"p-4\"\r\n #taskManagementContainer\r\n [style.backgroundColor]=\"nestedTableHeaderBackgroundColor\"\r\n [style.fontFaimly]=\"fontFaimly\"\r\n >\r\n <div class=\"d-flex justify-content-between\">\r\n <div class=\"col-4\">\r\n <div class=\"item-title\">Description</div>\r\n <!-- <div class=\"item-content firstDiv\">\r\n {{ taskDetails.description }}\r\n </div> -->\r\n <p\r\n [style.fontSize]=\"bodyTextFontsSize\"\r\n class=\"item-content firstDiv taskDescription pe-4\"\r\n [innerHTML]=\"getSafeComment(taskDetails?.editor_description)\"\r\n (click)=\"openFullImage($event)\"\r\n ></p>\r\n </div>\r\n <div class=\"col-4\">\r\n <div class=\"item-title\">Attachments</div>\r\n <h5 *ngIf=\"taskDetails?.attachments?.length == 0\">\r\n No Attachments found\r\n </h5>\r\n <div\r\n *ngIf=\"taskDetails?.attachments?.length\"\r\n class=\"item-content d-flex flex-wrap\"\r\n style=\"gap: 10px\"\r\n >\r\n <a\r\n *ngFor=\"let attachement of taskDetails?.attachments; let i = index\"\r\n class=\"symbol-label fs-2 fw-semibold text-success cursor-pointer\"\r\n >\r\n <span\r\n title=\"{{ taskDetails?.attachments_name[i] || 'Attachment' }}\"\r\n (click)=\"downloadAttchment(attachement)\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath +\r\n 'data-grid/document-icons/' +\r\n getExtention(attachement) +\r\n '.svg'\r\n \"\r\n >\r\n </span>\r\n </a>\r\n </div>\r\n </div>\r\n <div class=\"col-4\">\r\n <div class=\"item-title\">\r\n Comments ({{ taskDetails?.comments?.length }})\r\n </div>\r\n <h5 *ngIf=\"taskDetails?.comments?.length == 0\">No Comments found</h5>\r\n <div *ngIf=\"taskDetails?.comments?.length\" class=\"item-content\">\r\n <div class=\"comment\" *ngFor=\"let comment of taskDetails.comments\">\r\n <div class=\"d-flex align-items-center pe-3\">\r\n <img\r\n class=\"pic image-input-wrapper\"\r\n [style.width.px]=\"rowHeight - 12\"\r\n [style.height.px]=\"rowHeight - 12\"\r\n *ngIf=\"comment?.comment_by.logo\"\r\n src=\"{{ comment?.comment_by.logo }}\"\r\n alt=\"{{ comment.comment_by.full_name }}\"\r\n />\r\n <!-- <app-default-image-placeholder *ngIf=\"!comment?.comment_by.logo\" title=\"{{ comment.comment_by.full_name }}\" [name]=\"comment.comment_by.full_name\"></app-default-image-placeholder> -->\r\n <span\r\n *ngIf=\"!comment?.comment_by.logo\"\r\n [ngClass]=\"getDynamicClass(comment.comment_by.full_name)\"\r\n class=\"pic d-flex align-items-center rounded-circle\"\r\n [style.width.px]=\"rowHeight - 12\"\r\n [style.height.px]=\"rowHeight - 12\"\r\n [style.fontSize.px]=\"rowHeight / 3\"\r\n title=\"{{ comment.comment_by.full_name }}\"\r\n >\r\n {{ getInitials(comment.comment_by.full_name) }}\r\n </span>\r\n </div>\r\n <div>\r\n <div class=\"comment-author fs-14px\">\r\n {{ comment?.comment_by.full_name }}\r\n </div>\r\n <div\r\n class=\"comment-content forCommentImg\"\r\n [innerHTML]=\"getSafeComment(comment.comment)\"\r\n ></div>\r\n <div class=\"comment-timestamp\">\r\n {{ comment.comment_date | date }}\r\n </div>\r\n <div class=\"comment-timestamp\">\r\n Replies: ({{ comment.replies.length }})\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n</ng-template>\r\n", styles: ["@charset \"UTF-8\";@import\"bootstrap/dist/css/bootstrap.min.css\";.data-grid-table-wrapper{height:100%;width:100%;border:1px solid #d9d9db;border-radius:12px;position:relative}.data-grid-header{position:sticky;top:0}.data-grid-header{display:flex}.header-row{display:grid;width:100%}.header-cell{display:flex;align-items:center;position:relative;width:100%;padding:8px 0 8px 8px;font-weight:700;border-bottom:1px solid #d9d9db;white-space:nowrap;min-width:80px;font-weight:600}.header-cell .filter-applied-on-text{color:#5d9cff!important}.filter-cell{padding:4px!important;display:flex;align-items:center;gap:8px;width:100%}.filter-cell .filter-applied{background-color:#bddef9}.border-right{border-right:1px solid #d9d9db}.merged-grid{display:grid;grid-auto-rows:40px;border-bottom:1px solid #ccc}.span-two-rows{grid-row:span 2;display:flex;justify-content:space-between;align-items:center}.group-header{display:flex;justify-content:space-between;position:relative}.group-header-content{position:sticky;left:10px;overflow:hidden;text-overflow:ellipsis}.resize-handle{width:6px;cursor:e-resize;right:0;top:0;color:#00000026;margin-right:4px}.group-header .resize-handle{top:25%}.h-100{height:100%}.data-grid-body{position:relative;overflow-y:auto;overflow-x:hidden}.cell{padding:8px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;height:100%;display:flex;align-items:center}.data-grid-row{display:flex;width:100%;min-width:max-content;align-items:center;border-bottom:1px solid #d9d9db}.hovered-row{background-color:#ccc}.checkbox-row{border-bottom:#d9d9db}.w-100{width:100%}.data-grid-header-wrapper{display:flex;position:relative;overflow:hidden;-webkit-user-select:none;user-select:none}.data-grid-header{display:flex;position:relative;z-index:1}.left-pinned,.right-pinned{position:sticky;top:0}.right-pinned-header{position:absolute;right:0;border-left:1px solid #d9d9db;z-index:unset}.left-pinned{left:0}.right-pinned{right:0;border-left:1px solid #d9d9db}.center-scrollable{z-index:unset!important;overflow-x:auto;overflow-y:visible;white-space:nowrap;scrollbar-width:none;-ms-overflow-style:none}.center-scrollable::-webkit-scrollbar{display:none}.data-grid-body-wrapper{-webkit-user-select:none;user-select:none;display:flex}.center-scrollable-body{overflow-x:auto;scrollbar-width:none;-ms-overflow-style:none}.center-scrollable-body::-webkit-scrollbar{display:none}.left-pinned-body,.right-pinned-body{position:sticky;top:0;z-index:unset;background:#fff;scrollbar-width:none;-ms-overflow-style:none}.left-pinned-body::-webkit-scrollbar,.right-pinned-body::-webkit-scrollbar{display:none}.left-pinned-body{left:0}.border-end{border-right:1px solid #d9d9db!important}.right-pinned-body{right:0;border-left:1px solid #d9d9db}.fake-scroll-bar{height:14px;overflow:scroll;margin-bottom:10px}.text-ellipsis{overflow:hidden;text-overflow:ellipsis}.select-all-checkbox-cell{width:50px;display:flex;justify-content:center;align-items:center;height:100%;border-right:1px solid #d9d9db}.select-all-checkbox-cell input{width:16px;height:14px}.border-below{border-bottom:1px solid #d9d9db!important}.three-dots{width:22px;height:22px;display:flex;justify-content:center;align-items:center;border-radius:3px;margin-right:8px;cursor:pointer}.three-dots:hover{background-color:#ccc!important}.filter-icon-wrapper{min-height:22px;max-height:22px;min-width:22px;max-width:22px;display:flex;justify-content:center;align-items:center;border-radius:3px;cursor:pointer;transition:background-color .3s ease}.filter-icon-wrapper:hover{background-color:#ccc}.column-menu,.filter-menu{box-shadow:0 0 16px #00000026;border-radius:4px}.column-menu{background:#fff;width:100%;width:240px;border:1px solid #ddd;box-shadow:0 0 16px #00000026;border:1px solid #d9d9db;padding:4px 0;font-size:14px;position:fixed}.column-menu-item{padding:8px 12px;cursor:pointer;display:flex;align-items:center;transition:background-color .2s ease}.column-menu-item:hover{background-color:#deebf7}.pin-parent{position:relative;width:100%!important}.column-submenu{position:absolute;top:0;left:100%;background:#fff;border:1px solid #ddd;width:130px;box-shadow:0 0 16px #00000026;border:1px solid #d9d9db;display:none;padding:4px 0;z-index:10;border-radius:4px}.pin-parent:hover .column-submenu{display:block}.filter-menu-container{position:fixed;width:210px;background:#fff;border:1px solid #ddd;border-radius:4px;padding:12px;box-shadow:0 0 16px #00000026;border:1px solid #d9d9db;z-index:1000;font-size:14px}.filter-menu-header{font-weight:600;margin-bottom:10px}.filter-dropdown-section{max-height:350px;overflow-y:auto}.dropdown-options{overflow-y:auto;scrollbar-width:thin;height:100%}.filter-text-section select,.filter-text-section input{width:100%}.filter-radio-inputs{width:14px!important;height:14px!important}.right-menu{border-left:1px solid #d9d9db;font-size:14px}.border-start{border-left:1px solid #d9d9db!important}.column-panel-item{font-size:.875rem;color:#333}.toggle-icon{cursor:pointer;transition:transform .2s ease}.toggle-icon.rotate{transform:rotate(90deg)}.grab-icon{cursor:grab;color:#6c757d}.text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.cursor-pointer{cursor:pointer}.pivot-mode{height:48px}.chevron-wrapper{width:30px;height:20px;cursor:pointer;border-radius:3px;display:flex;justify-content:center;align-items:center;transition:background-color .3s ease;margin-right:8px}.chevron-wrapper:hover{background-color:#cac7c7}.chevron-wrapper i{font-size:14px}.column-panel-body{height:70%;overflow:auto;scrollbar-width:thin}.side-menue-text{transform:rotate(90deg);position:relative;font-weight:700;margin-top:40px}.columns-button{padding-top:20px;padding-bottom:35px;width:29px}.fake-scroll-content{height:12px}.fake-scrollbar{width:25px}.fake-scrollbar div{min-width:1px}.fake-horizintal-scrollbar div{min-height:1px}.side-filter-columns-wrapper{height:calc(100% - 25px)}.custom-modal-overlay{position:fixed;top:0;left:0;width:100%;height:100%;overflow:hidden;display:flex;justify-content:center;align-items:center;z-index:1050}.custom-modal-overlay .moda-header{background-color:#f8f8f8}.custom-modal-content{background-color:#fff;border-radius:8px;min-width:300px;max-width:400px;box-shadow:0 5px 20px #0000004d}.overlay-scrollable{height:250px;overflow:auto}.footer-row{border-top:1px solid #d9d9db;padding-left:32px}.fake-horizintal-scrollbar{position:relative;bottom:17px;overflow-x:auto;overflow-y:hidden;height:17px}.border-dashed{border:1px dashed #d9d9db}.cdk-drag-preview{box-sizing:border-box!important;border-radius:4px!important;box-shadow:0 5px 5px -3px #0003,0 8px 10px 1px #00000024,0 3px 14px 2px #0000001f!important;background-color:#f3f4f5!important;border:1px solid #d9d9db!important;z-index:9999!important}.data-grid-header-wrapper ::ng-deep .cdk-drag-placeholder{display:block!important;background:#fff!important;opacity:1!important}.cdk-drag-animating{transition:transform .25s cubic-bezier(0,0,.2,1)!important}.top-row-grouping-placeholder{display:flex;align-items:center;border-radius:12px;font-size:14px;padding-inline:6px;border:1px solid #d9d9db}.top-row-grouping-placeholder .bi-x{cursor:pointer;color:#7a7a7a}.top-row-grouping-placeholder .bi-x:hover{color:#111}.right-pinned-body-wrapper{position:absolute;right:0}.actions-dropdown{position:absolute;right:200px;z-index:1050;background-color:#fff;border-radius:8px!important;cursor:default}.bg-fff{background-color:#fff}.actions-dropdown-setting{right:250px}.action-button{background-color:#007cf5!important;border-radius:8px!important;padding:8px 16px!important;font-size:14px;height:32px;align-items:center}.global-search{max-width:380px!important;display:flex!important;align-items:center!important}.global-search span{margin-top:-4px!important}.global-search input{padding-left:28px;border-radius:8px!important}.global-search input:focus{outline:none!important;box-shadow:none!important}.active .top-icon ::ng-deep svg path{stroke:#007cf5!important}.dropdown-menu{background-color:#fff!important;border:1px solid #d9d9db!important;border-radius:8px!important}.custom-menu{width:220px;border-radius:8px;padding:4px 0;background-color:#fff}.custom-menu .dropdown-item{font-size:14px;padding:8px 14px}.custom-menu .dropdown-item:hover{background-color:#f5f5f5;border-radius:6px}.table-layout{right:0;background:#fff;border-radius:8px!important}.actions-dropdown,.table-layout,.custom-menu,.dropdown-menu{background:#fff;border-radius:8px!important;border:1px solid #ccc!important;background-color:#fff}.preview-box{width:40px;height:10px;border-radius:3px;background-color:transparent;transition:background-color .2s ease-in-out}.btn-check:checked+label .preview-box{background-color:var(--bs-primary)}.preview-box{width:40px;height:10px;border-radius:3px;border:2px solid transparent;transition:border-color .2s ease-in-out}#small:checked+label .preview-box{border-color:#007cf5!important;background-color:transparent!important}#medium:checked+label .preview-box{border-color:#007cf5!important;background-color:transparent!important}#large:checked+label .preview-box{border-color:#007cf5!important;background-color:transparent!important}.btn-check:checked+.btn{background-color:transparent!important;border-color:#007cf5!important}.layout-button{padding:8px 28px!important;width:82px;border-radius:8px!important}.show-hide-table-label{position:sticky;top:0;z-index:99;background:#fff}.cursor-grap{cursor:grabbing}.pagination-container{display:flex;align-items:center;gap:12px;font-size:13px;color:#333}.page-size select{padding:3px 6px;border:1px solid #ccc;border-radius:6px;background:#fff;font-size:13px}.page-info{margin-left:10px}.page-buttons{display:flex;gap:4px;margin-left:auto;align-items:center}.page-buttons button{padding:3px 8px;border:1px solid #ccc;background:#fff;border-radius:4px;cursor:pointer;font-size:13px;line-height:1.2}.page-buttons button.active{background:#eee;font-weight:600}.page-buttons button:disabled{opacity:.5;cursor:not-allowed}.page-buttons span{padding:0 6px;color:#666}.page-size .separator{padding:0 8px;border-right:1px solid #ccc;margin-right:8px}.page-size .separator .actions-dropdown{position:fixed;right:200px;z-index:1050;background-color:#fff}.fs-14px{font-size:14px}.fs-12px{font-size:12px!important}.save-preset-dropdown{background:#fff;color:#111!important;right:0;font-weight:400!important;text-align:left!important;max-width:250px!important;text-wrap:auto!important;top:14px;font-size:14px!important}.add-filter-button{height:28px;cursor:pointer;border-radius:4px}.add-filter-button:hover,.button-filter:hover{color:#000!important}.button-filter:hover ::ng-deep svg path{stroke:#000!important}.table-layout .dropdown-item{border-radius:0!important;padding-inline:16px!important;font-size:14px;padding-block:6px!important}.table-layout .dropdown-item:hover{background-color:transparent!important}.filter-serach-inpt{max-height:230px!important;overflow:auto;scrollbar-width:thin;padding-top:4px;background-color:#f7f7f7;border-color:#dedede;border-radius:8px}.filter-serach-inpt .badge{color:#007cf5!important;background-color:#e6f2ff!important;border-radius:8px!important;padding:8px!important;font-weight:500!important;font-size:12px!important;height:24px!important}.filter-serach-inpt .badge ::ng-deep svg{cursor:pointer}.filter-serach-inpt .badge ::ng-deep svg:hover path{stroke:#040081!important}.filter-serach-inpt input{background-color:#f7f7f7;padding:0;height:26px;margin-top:-5px}.text-filter select{border:0}.text-filter select option{font-size:14px;font-weight:500}.text-filter select:focus{border:0}.text-filter input:focus,.text-filter select:focus{box-shadow:none!important}.active-filters{background-color:#f7f7f7;white-space:nowrap;background:#f7f7f7;padding-inline:8px;height:28px;font-size:14px;font-weight:500;border-radius:8px;box-shadow:none}.active-filters .header-tag{white-space:nowrap}.filter-tags .active{background-color:#e6f2ff}.filter-tags .active .header-tag{color:#007cf5!important}.table-cell{cursor:pointer;width:100%}.table-cell input:focus{outline:0!important;border:0!important;width:100%!important;box-shadow:none!important}.active-for-editing{outline:2.5px solid #007cf5!important;border-radius:4px;border:0!important;width:100%!important}.active-cell{outline:none!important;box-shadow:inset 0 0 0 1.5px #007cf5}span[inlineSVG]{width:16px;height:16px;display:inline-block}.cell .dropdown-menu{min-width:unset!important}.cell .dropdown-menu .item{transition:background-color .3s ease;display:flex;align-items:center;-webkit-user-select:none;user-select:none}.cell .dropdown-menu .item:hover{background-color:#f0f8ff}.cell .cell-editin-dropdown{scrollbar-width:thin!important;-webkit-user-select:none;user-select:none}.fw-semibold{font-weight:500!important}:host ::ng-deep .three-dots-col-menu svg,:host ::ng-deep .three-dots-col-menu svg path{stroke:#000!important}.fs-7{font-size:12px!important}.fs-8{font-size:10px!important}.all-filters-reset-button:hover{opacity:.7}.full-text-box{background:#fff;position:relative;display:flex;align-items:center;z-index:1050;border:1px solid #dedede;border-radius:8px;padding:12px 14px;box-shadow:0 2px 8px #00000026;max-height:400px;overflow:auto}.full-text-box ul{max-height:400px}.full-text-content{border-radius:8px;max-height:70vh;overflow:auto;white-space:pre-wrap}.pic{border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:22px}.pic-comb2{background-color:#fbe7bf;color:#fd7f31}.pic-comb1{background-color:#d9ecbf;color:#65b500}.pic-comb4{background-color:#fdd3d7;color:#f64e60}.w-40px{width:40px}.h-40px{height:40px}.pic{border-radius:50%;overflow:hidden}.image-placeholder .pic{font-size:14px;font-weight:600;letter-spacing:.5px}.header-cell{font-weight:600}.header-cell,.cell{box-sizing:border-box}.transparent-border-right{border-right:1px solid transparent!important}.resizing-highlight{position:relative}.resizing-highlight:before{content:\"\";position:absolute;top:-1px;right:-1px;width:2px;height:calc(100% + 2px);background:#7cb9f6;z-index:1000;pointer-events:none}.resizing-highlight-right{position:relative}.resizing-highlight-right:before{content:\"\";position:absolute;top:-1px;left:-1px;width:2px;height:calc(100% + 2px);background:#7cb9f6;z-index:1000;pointer-events:none}.resizing-highlight-right:first-child{width:1px}.editable-header{border-bottom:1px dashed #666}.muted-text{color:#727272!important}.context-menu{position:fixed;display:none;background:#fff;border:1px solid #dcdcdc;box-shadow:#0000003d 0 3px 8px;z-index:1000;width:150px;border-radius:8px;font-weight:600}.context-menu.show{display:block}.context-menu ul{list-style:none;margin:0;padding:0}.context-menu li{padding:10px;cursor:pointer;color:#99a1b7}.context-menu li ::ng-deep svg{width:16px;height:16px;display:inline-block;color:#727272}.context-menu li ::ng-deep svg path{stroke:#727272}.context-menu li:hover{background-color:#f0f0f5!important}.invisible{visibility:hidden!important}.fw-500{font-weight:500!important}.taskbar{position:fixed;display:flex;justify-content:center;z-index:1000}.taskbar .action-btn{transition:opacity text-decoration .3s ease}.taskbar .action-btn:hover{text-decoration:underline;opacity:.8}.taskbar .delete{color:#ea0000}.selected-count,.action-btn,.dropdown-content a{font-weight:500;font-size:14px}.selected-rows-action-bar{background-color:#1a1a1a;color:#fff;padding:4px 24px;border-radius:8px;display:flex;align-items:center;justify-content:space-between;gap:24px;box-shadow:0 -4px 12px #00000026}.selected-rows-action-bar .btn:active,.selected-rows-action-bar .btn:focus{outline:0!important;border:0!important;border-color:transparent!important}.selected-rows-action-bar .action-btn{color:#fff!important}.cell .dropdown-menu,.cell .form-select,.cell input{color:#000!important}.cell input::placeholder{color:#727272!important}.cell .badge{border-radius:50px!important;height:26px;align-items:center}.cell .badge-danger{color:#ea5353!important;border:1px solid #ea5353!important;background-color:#ff00000d!important}.cell .badge-success{background-color:#84ca8130!important;border:1.5px solid rgb(70,227,114)!important;color:#46e372!important}.cell .badge-warning{background-color:#fff3dc!important;color:orange!important;border:1px solid #ffa000!important}.cell .badge-info{color:#00bad1;background-color:#e8fbfd;border:1px solid #00bad1}.cell .badge-secondary{color:#6c757d;background-color:#f1f3f5;border:1px solid #6c757d}.header-tag ::ng-deep svg path{stroke:#727272!important}.cross-secondary:hover ::ng-deep svg path{stroke:#000!important}.disable-sorting{pointer-events:none;opacity:.5}.rows-grouping-top-container ::ng-deep .cdk-drag-placeholder{background-color:transparent!important}input.is-invalid:focus{border:2.5px solid red!important;outline:none}.table-cell input.is-invalid:focus{border:2.5px solid red!important;outline-color:red!important;outline:none!important;box-shadow:none!important}.active-for-editing:has(input.is-invalid:focus){outline:none!important;box-shadow:none!important;border:0!important}.selected-cell,.row-selected{background-color:#c2e0fe}.first-row-selected{border-top:2px solid #2196f3!important}.last-row-selected{border-bottom:2px solid #2196f3!important}.left-selection-border{border-left:2px solid #2196f3!important}.s-no{font-size:14px;font-weight:500}.top-border{border-top:2px solid #2196f3!important}.bottom-border{border-bottom:2px solid #2196f3!important}.left-border{border-left:2px solid #2196f3!important}.border-left{border-left:1px solid #d9d9db}.right-border{border-right:2px solid #2196f3!important}.top-left-corner{border-top-left-radius:4px}.top-right-corner{border-top-right-radius:4px}.bottom-left-corner{border-bottom-left-radius:4px}.bottom-right-corner{border-bottom-right-radius:4px}.flash-bg{animation:flashAnim 1000s ease}@keyframes flashAnim{0%{background-color:#48a2fc}50%{background-color:#c2e0fe}to{background-color:#c2e0fe}}.cut-flash-bg{animation:cut-flash .8s ease}@keyframes cut-flash{0%{background-color:#f006}50%{background-color:#f00c}to{background-color:#c2e0fe}}.accordion-details .center-section .table .tbody .tr:hover .td{background-color:#f0f8ff!important}.editing-dropdown-search-input input:focus{border:1px solid #86b7fe!important}.nested-table .thead{position:sticky;top:0}.dropdown-wrapper{position:relative;display:inline-block}.btn-icon{background:transparent;border:0;padding:.25rem .5rem;cursor:pointer}.custom-dropdown-menu{position:absolute;right:0;top:calc(100% + 6px);min-width:200px;list-style:none;margin:0;padding:.25rem 0;background:#fff!important;border:1px solid rgba(0,0,0,.08);box-shadow:0 6px 18px #00000014;border-radius:.35rem;z-index:1200}.custom-dropdown-menu .dropdown-item{display:block;width:100%;padding:.5rem 1rem;text-align:left;background:transparent;border:none}.custom-dropdown-menu .dropdown-item:hover{background:#00000008}.cell-editing-dropdown-menu .dropdown-item{width:99%}.cell-editing-dropdown-menu .selected{background-color:#f0f8ff}.confirm-block{padding:0}.center-nested-table .tr:hover .td{background-color:#f0f8ff}.table ::ng-deep .cdk-drag-placeholder{background-color:#fff!important}.assets-pic{border-radius:8px!important}.fullscreen-overlay{position:fixed;top:0;left:0;width:100vw;height:100vh;background:#000c;display:flex;align-items:center;justify-content:center;z-index:1000;cursor:zoom-out}.fullscreen-img{max-width:90%;max-height:90%;border-radius:8px;box-shadow:0 0 15px #00000080}.position-sticky{z-index:2}.viewport{display:block!important;overflow:visible!important}.nested-table ::ng-deep .cdk-virtual-scroll-content-wrapper{padding:0!important}.nested-table ::ng-deep .cdk-virtual-scroll-viewport{overflow-x:hidden!important}.disabled-search-input{background-color:#f5f5f5;cursor:pointer!important}.right-click-menu-icons ::ng-deep svg path{stroke-width:2!important}.loader{animation:rotate 1s infinite;height:50px;width:50px}.loader:before,.loader:after{border-radius:50%;content:\"\";display:block;height:20px;width:20px}.loader:before{animation:ball1 1s infinite;background-color:#fff;box-shadow:30px 0 #ff3d00;margin-bottom:10px}.loader:after{animation:ball2 1s infinite;background-color:#ff3d00;box-shadow:30px 0 #fff}@keyframes rotate{0%{transform:rotate(0) scale(.8)}50%{transform:rotate(360deg) scale(1.2)}to{transform:rotate(720deg) scale(.8)}}@keyframes ball1{0%{box-shadow:30px 0 #ff3d00}50%{box-shadow:0 0 #ff3d00;margin-bottom:0;transform:translate(15px,15px)}to{box-shadow:30px 0 #ff3d00;margin-bottom:10px}}@keyframes ball2{0%{box-shadow:30px 0 #fff}50%{box-shadow:0 0 #fff;margin-top:-20px;transform:translate(15px,15px)}to{box-shadow:30px 0 #fff;margin-top:0}}.rows-grouping-top-container ::ng-deep .cdk-drag-placeholder{opacity:.7!important}.action-button{background-color:#6f61cf!important;color:#fff!important;border-radius:6px!important;font-weight:500!important;margin-top:-4px}.action-button:hover{background-color:#6a5fb3!important}.action-buttons-row .button{display:inline-flex;align-items:center;justify-content:center;overflow:hidden;color:#fff;border-radius:6px;height:34px;padding:0 10px;white-space:nowrap;transition:max-width .4s ease,background-color .3s ease;max-width:40px;background-color:transparent;border:1px solid #6F61CF}.action-buttons-row .button .label-hidden{opacity:0;margin-left:8px;transition:opacity .3s ease;pointer-events:none;display:none}.action-buttons-row .button:hover{max-width:200px;background-color:#6f61cf}.action-buttons-row .button:hover .label-hidden{opacity:1;pointer-events:auto;margin-left:8px!important;display:block}.action-buttons-row ::ng-deep .button .svg-icon svg path{stroke:#6f61cf;transition:fill .3s ease,stroke .3s ease}.action-buttons-row ::ng-deep .button:hover .svg-icon svg path{stroke:#fff!important}::ng-deep .nav-tabs .nav-link{border:none!important;border-bottom:2px solid transparent!important;border-radius:0!important;background:transparent!important}::ng-deep .nav-tabs .nav-link:hover,::ng-deep .nav-tabs .nav-link:focus{border:none!important;border-bottom:2px solid transparent!important;outline:none!important;background:transparent!important}::ng-deep .nav-tabs .nav-link.active{border:none!important;border-bottom:2px solid var(--bs-primary)!important;background:transparent!important;color:var(--bs-primary)!important}.open-top{top:-150%!important}.muted{color:#7a7a7a!important}.item-title{font-size:1.2em;font-weight:700;margin-bottom:10px}.item-image{width:100%;border-radius:10px}.comment{display:flex;align-items:center;margin-bottom:10px}.comment-avatar{width:40px;height:40px;border-radius:50%;margin-right:10px}.comment-author{font-weight:700}.comment-content{font-size:.9em;line-height:1.4}.comment-timestamp{font-size:.8em;color:#888;margin-left:auto}.des_low{text-overflow:ellipsis;white-space:nowrap;overflow:hidden;width:242px;display:block;text-transform:capitalize!important}.firstDiv{word-break:break-word;overflow-wrap:break-word;white-space:normal}.container{display:flex;flex-wrap:wrap;margin:20px;gap:20px;background-color:#fff;padding:20px;border-radius:10px}.item{width:calc(33.33% - 20px);background-color:#fff;padding:20px;border-radius:10px;box-shadow:0 2px 5px #0000001a}.forCommentImg{width:70px;border-radius:16px;margin:8px 0;cursor:pointer}.image-modal img{max-width:90%;max-height:90%;border-radius:8px;box-shadow:0 4px 10px #00000080}.full-image-modal{position:fixed;background:#000c;display:flex;justify-content:center;align-items:center;z-index:1000}.full-image-modal .full-image{max-width:90%;max-height:90%;border-radius:8px;box-shadow:0 0 10px #fff3}.item-content{font-size:14px;line-height:1.5;max-height:220px;overflow-y:auto}.image-modal.full-image-modal{position:fixed;width:100vw;height:100vh;background-color:#000c;display:flex;justify-content:center;align-items:center;z-index:9999;overflow:hidden;cursor:zoom-out}.image-modal.full-image-modal img{border-radius:8px;box-shadow:0 4px 20px #0006;object-fit:contain;transition:transform .3s ease}.image-modal.full-image-modal img:hover{transform:scale(1.02)}::ng-deep .custom-overlay-wrapper .custom-overlay{position:fixed;top:0;left:0;width:100vw;height:100vh;background:#000000d9;display:flex;align-items:center;justify-content:center;z-index:9999}::ng-deep .custom-overlay-wrapper .custom-modal{background:#fff;border-radius:12px;box-shadow:0 8px 25px #0003;width:360px;max-width:90%;padding:24px;text-align:center;animation:fadeInScale .25s ease}::ng-deep .custom-overlay-wrapper .custom-modal-body .modal-message{font-size:16px;margin-bottom:20px;color:#333}::ng-deep .custom-overlay-wrapper .modal-actions{display:flex;justify-content:center;gap:12px}::ng-deep .custom-overlay-wrapper .modal-actions button{min-width:90px;padding:8px 14px;border-radius:6px;border:none;font-weight:500;cursor:pointer;transition:background-color .2s ease}::ng-deep .custom-overlay-wrapper .btn-confirm{background-color:#007bff;color:#fff}::ng-deep .custom-overlay-wrapper .btn-confirm:hover{background-color:#0069d9}::ng-deep .custom-overlay-wrapper .btn-cancel{background-color:#e4e4e4;color:#333}::ng-deep .custom-overlay-wrapper .btn-cancel:hover{background-color:#d6d6d6}@keyframes fadeInScale{0%{opacity:0;transform:scale(.95)}to{opacity:1;transform:scale(1)}}.clear-btn{background:linear-gradient(135deg,#f53545,#f53545);border:none;color:#fff;font-size:13px;padding:3px 6px;border-radius:20px;font-weight:500;display:inline-flex;align-items:center;gap:6px;cursor:pointer;transition:all .3s ease;box-shadow:0 2px 6px #ff5f6d66;position:relative;bottom:4px}.clear-btn:hover{transform:translateY(-2px);box-shadow:0 4px 10px #ff5f6d99;background:linear-gradient(135deg,#f53545,#f53545)}.clear-btn i{font-size:16px;vertical-align:middle}.cell-editin-dropdown .deopdown-item{width:100%!important;box-shadow:none!important;border-radius:4px;cursor:pointer;padding-block:8px!important}.cell-editin-dropdown .deopdown-item:hover{background-color:#f1f1f1}\n"] }]
|
|
6548
|
+
], template: "<div class=\"position-relative h-100\">\r\n <div\r\n class=\"d-flex justify-content-between mb-2 align-items-center position-relative\"\r\n >\r\n <div class=\"d-flex gap-2\">\r\n <div class=\"nav nav-tabs\" *ngIf=\"true\">\r\n <div class=\"nav nav-tabs\" id=\"nav-tab\" role=\"tablist\">\r\n <span\r\n *ngFor=\"let tab of tabs; let i = index\"\r\n (click)=\"setActiveTab(tab)\"\r\n class=\"nav-link cursor-pointer\"\r\n [class.active]=\"activeTab == tab\"\r\n >\r\n {{ tab }}\r\n </span>\r\n </div>\r\n </div>\r\n <div class=\"global-search\" [style.width.px]=\"350\">\r\n <span\r\n *ngIf=\"enableGlobalSearch\"\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/search.svg'\"\r\n class=\"data-grid-svg-icon mx-2 position-absolute icon\"\r\n ></span>\r\n <input\r\n #globalSearchInput\r\n *ngIf=\"enableGlobalSearch\"\r\n style=\"height: 36px\"\r\n class=\"form-control\"\r\n placeholder=\"Type to search, then press Enter\"\r\n [(ngModel)]=\"tableSearch\"\r\n (keydown.enter)=\"onGlobalSearch()\"\r\n (input)=\"onSearchInput($event)\"\r\n type=\"search\"\r\n />\r\n </div>\r\n </div>\r\n <div class=\"d-flex gap-2 align-items-center table-right-top-actions\">\r\n <ng-container *ngFor=\"let button of buttons\">\r\n <div\r\n class=\"d-flex align-items-center gap-2 action-buttons-row\"\r\n *ngIf=\"button?.has_permission\"\r\n >\r\n <a\r\n href=\"JavaScript:void(0)\"\r\n (click)=\"onActionButtonClick(button.name)\"\r\n class=\"button button-small btn border border-primary btn-active-primary me-2 p-0 d-flex align-items-center justify-content-center px-3\"\r\n >\r\n <span\r\n *ngIf=\"button.is_showIcon\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/' + button.icon + '.svg'\r\n \"\r\n class=\"svg-icon svg-icon-2\"\r\n ></span>\r\n <span\r\n class=\"label-hidden text-white\"\r\n [class.ms-0]=\"button.is_showIcon\"\r\n >{{ button?.name }}</span\r\n >\r\n </a>\r\n </div>\r\n </ng-container>\r\n <div\r\n *ngIf=\"!showFilterRow\"\r\n class=\"cursor-pointer position-relative action-buttons-row\"\r\n (click)=\"toggleOpenFilter()\"\r\n [class.active]=\"showFilters\"\r\n >\r\n <a\r\n href=\"JavaScript:void(0)\"\r\n class=\"button button-small btn btn-active-primary border border-primary me-2 p-0 d-flex align-items-center justify-content-center px-3\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\"\r\n class=\"svg-icon svg-icon-2\"\r\n ></span>\r\n <span class=\"label-hidden text-white\">Filters</span>\r\n </a>\r\n <span\r\n *ngIf=\"activeFilteredColumns?.length\"\r\n style=\"\r\n width: 7px;\r\n height: 7px;\r\n box-shadow: 0px 0px 3px #0022ff;\r\n background-color: rgb(0, 60, 255);\r\n position: absolute;\r\n right: 16px;\r\n top: 10px;\r\n \"\r\n class=\"rounded-circle d-block\"\r\n ></span>\r\n </div>\r\n <div\r\n class=\"cursor-pointer d-none\"\r\n (click)=\"toggleActions('advance-filter')\"\r\n [class.active]=\"activeTopButton === 'advance-filter'\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/zoom-charge.svg'\"\r\n class=\"data-grid-svg-icon top-icon me-2\"\r\n ></span>\r\n </div>\r\n <div\r\n class=\"cursor-pointer action-buttons-row\"\r\n (click)=\"toggleActions('setting')\"\r\n [class.active]=\"\r\n activeTopButton === 'setting' ||\r\n activeTopButton === 'table-layout' ||\r\n activeTopButton === 'table-presets' ||\r\n activeTopButton === 'show-hide-columns'\r\n \"\r\n >\r\n <!-- <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/settings-2.svg'\"\r\n class=\"data-grid-svg-icon top-icon me-2\"\r\n ></span> -->\r\n <a\r\n href=\"JavaScript:void(0)\"\r\n class=\"button button-small btn btn-active-primary border border-primary me-2 p-0 d-flex align-items-center justify-content-center px-3\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/settings-2.svg'\"\r\n class=\"svg-icon svg-icon-2\"\r\n ></span>\r\n <span class=\"label-hidden text-white\">Setting</span>\r\n </a>\r\n\r\n <div\r\n *ngIf=\"activeTopButton === 'setting'\"\r\n class=\"actions-dropdown mt-1 actions-dropdown-setting\"\r\n style=\"position: absolute\"\r\n >\r\n <div class=\"dropdown-menu show shadow custom-menu\">\r\n <!-- Table Layout -->\r\n <a\r\n class=\"dropdown-item d-flex justify-content-between align-items-center cursor-pointer\"\r\n (click)=\"$event.stopPropagation(); toggleActions('table-layout')\"\r\n >\r\n <span\r\n ><span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/table-2.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n Table Layout</span\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n </a>\r\n <!-- Table Presets -->\r\n <a\r\n (click)=\"$event.stopPropagation(); toggleActions('table-presets')\"\r\n class=\"dropdown-item d-flex justify-content-between align-items-center cursor-pointer\"\r\n >\r\n <span\r\n ><span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/list-details.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n Table Presets</span\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n </a>\r\n\r\n <!-- Columns -->\r\n <a\r\n *ngIf=\"!showSideMenu\"\r\n (click)=\"\r\n $event.stopPropagation(); toggleActions('show-hide-columns')\r\n \"\r\n class=\"dropdown-item d-flex justify-content-between align-items-center cursor-pointer\"\r\n >\r\n <span class=\"align-items-center d-flex\"\r\n ><span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/eye.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n Columns</span\r\n >\r\n <div class=\"d-flex gap-2\">\r\n <span class=\"muted-text\">{{ columnsCount }}</span>\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n </div>\r\n </a>\r\n\r\n <div class=\"dropdown-divider\"></div>\r\n\r\n <!-- Filter -->\r\n <a\r\n class=\"dropdown-item cursor-pointer\"\r\n (click)=\"toggleOpenFilter(); activeTopButton = '';\"\r\n *ngIf=\"!showFilterRow\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2 mt-1 cursor-pointer\"\r\n ></span>\r\n Filter\r\n </a>\r\n\r\n <!-- Download -->\r\n <a\r\n class=\"dropdown-item cursor-pointer\"\r\n (click)=\"downloadCsv('csv')\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/download.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2 cursor-pointer\"\r\n ></span>\r\n CSV Export\r\n </a>\r\n <a\r\n *ngIf=\"enableExport\"\r\n class=\"dropdown-item cursor-pointer\"\r\n (click)=\"downloadCsv('xlsx')\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/download.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2 cursor-pointer\"\r\n ></span>\r\n Excel Export\r\n </a>\r\n <!-- Font Family & Font Size -->\r\n <div class=\"px-2 pb-2 pt-2\">\r\n <div class=\"d-flex gap-2\">\r\n <!-- Font Family -->\r\n <select\r\n class=\"form-select form-select-sm\"\r\n [(ngModel)]=\"fontFaimly\"\r\n (change)=\"onFontChange()\"\r\n >\r\n <option *ngFor=\"let font of fontFamilies\" [value]=\"font\">\r\n {{ font }}\r\n </option>\r\n </select>\r\n\r\n <!-- Font Size -->\r\n <select\r\n class=\"form-select form-select-sm\"\r\n (change)=\"onFontChange()\"\r\n [(ngModel)]=\"bodyTextFontsSize\"\r\n >\r\n <option *ngFor=\"let size of fontSizes\" [value]=\"size\">\r\n {{ size }}\r\n </option>\r\n </select>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Table Layout -->\r\n\r\n <ng-container *ngIf=\"activeTopButton === 'table-layout'\">\r\n <div\r\n *ngTemplateOutlet=\"tableLayout\"\r\n class=\"actions-dropdown mt-1\"\r\n style=\"position: absolute\"\r\n ></div>\r\n </ng-container>\r\n\r\n <!-- Table Presets -->\r\n <ng-container *ngIf=\"activeTopButton === 'table-presets'\">\r\n <div\r\n *ngTemplateOutlet=\"tablePreset\"\r\n class=\"actions-dropdown mt-1\"\r\n style=\"position: absolute\"\r\n ></div>\r\n </ng-container>\r\n\r\n <!-- Table Presets -->\r\n <ng-container *ngIf=\"activeTopButton === 'show-hide-columns'\">\r\n <div\r\n *ngTemplateOutlet=\"showHideColumns\"\r\n class=\"actions-dropdown mt-1\"\r\n style=\"position: absolute\"\r\n ></div>\r\n </ng-container>\r\n </div>\r\n\r\n <div class=\"action-buttons-row\" *ngIf=\"showFullScreenButton\">\r\n <a\r\n *ngIf=\"!isFullScreen\"\r\n class=\"button button-small btn btn-active-primary border border-primary expend d-flex justify-content-center align-items-center\"\r\n (click)=\"toggleFullscreen()\"\r\n data-bs-toggle=\"tooltip\"\r\n data-bs-placement=\"top\"\r\n title=\"Minimise\"\r\n [ngClass]=\"{ minArrow: !isFullScreen, maxArrow: isFullScreen }\"\r\n style=\"transition: color 0.2s\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/expend.svg'\"\r\n class=\"svg-icon svg-icon-2 mb-1\"\r\n ></span>\r\n </a>\r\n <a\r\n *ngIf=\"isFullScreen\"\r\n class=\"button button-small btn btn-active-primary border border-primary expend d-flex justify-content-center align-items-center\"\r\n (click)=\"toggleFullscreen()\"\r\n data-bs-toggle=\"tooltip\"\r\n data-bs-placement=\"top\"\r\n title=\"Maximise\"\r\n [ngClass]=\"{ minArrow: !isFullScreen, maxArrow: isFullScreen }\"\r\n style=\"transition: color 0.2s\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/minimize.svg'\"\r\n class=\"svg-icon svg-icon-2 mb-1\"\r\n ></span>\r\n </a>\r\n </div>\r\n <div>\r\n <!-- Example single danger button -->\r\n\r\n <!-- <button\r\n type=\"button\"\r\n class=\"btn btn-primary btn-sm d-flex gap-2 action-button\"\r\n (click)=\"toggleActions('actions')\"\r\n >\r\n Action\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/Vector.svg'\"\r\n class=\"data-grid-svg-icon\"\r\n ></span>\r\n </button>\r\n <div\r\n *ngIf=\"activeTopButton === 'actions'\"\r\n class=\"actions-dropdown mt-1\"\r\n >\r\n <div class=\"dropdown-menu show\">\r\n <a class=\"dropdown-item\" href=\"#\">Action</a>\r\n <a class=\"dropdown-item\" href=\"#\">Another action</a>\r\n <a class=\"dropdown-item\" href=\"#\">Something else here</a>\r\n <div class=\"dropdown-divider\"></div>\r\n <a class=\"dropdown-item\" href=\"#\">Separated link</a>\r\n </div>\r\n </div> -->\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div\r\n *ngIf=\"showFilters && !showFilterRow\"\r\n class=\"top-filter-row border-top py-2 d-flex justify-content-between align-items-center\"\r\n [style.height.px]=\"topFilterRowHeight\"\r\n >\r\n <!-- LEFT SIDE (Filter tags + Filter button) -->\r\n <div class=\"d-flex gap-2 align-items-center\">\r\n <ng-container>\r\n <div\r\n *ngFor=\"let col of activeFilteredColumns; trackBy: trackByField\"\r\n class=\"filter-tags\"\r\n >\r\n <div\r\n (click)=\"\r\n isActiveFilterOpen = true;\r\n activeTopButton = 'filter-columns';\r\n openFilter(col)\r\n \"\r\n class=\"d-flex justify-content-center align-items-center muted-text add-filter-button active-filters\"\r\n style=\"white-space: nowrap\"\r\n [class.active]=\"\r\n col?.field == selectedColumnForFilter?.field &&\r\n isActiveFilterOpen &&\r\n activeTopButton == 'filter-columns'\r\n \"\r\n >\r\n <span class=\"header-tag mt-0 d-flex align-items-center\">\r\n <span\r\n *ngIf=\"col?.pinned\"\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/pin.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n {{ col.header }}\r\n <span\r\n (click)=\"\r\n $event.stopPropagation(); removeColumnFilterFromColumn(col)\r\n \"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/cross-primary.svg'\r\n \"\r\n class=\"data-grid-svg-icon cross-secondary ms-2 mb-1\"\r\n ></span>\r\n </span>\r\n </div>\r\n\r\n <ng-container\r\n *ngIf=\"\r\n activeTopButton === 'filter-columns' &&\r\n col?.field == selectedColumnForFilter?.field &&\r\n isActiveFilterOpen\r\n \"\r\n >\r\n <div\r\n *ngTemplateOutlet=\"filterColumns; context: { column: col }\"\r\n class=\"actions-dropdown mt-1\"\r\n ></div>\r\n </ng-container>\r\n </div>\r\n </ng-container>\r\n\r\n <!-- Filter Button -->\r\n <div class=\"add-filter-button-menu\">\r\n <div\r\n (click)=\"toggleActions('filter-columns'); isActiveFilterOpen = false\"\r\n class=\"d-flex justify-content-center align-items-center muted-text add-filter-button button-filter\"\r\n style=\"width: 70px\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/plus.svg'\"\r\n class=\"me-2 data-grid-svg-icon\"\r\n ></span>\r\n Filter\r\n </div>\r\n\r\n <ng-container\r\n *ngIf=\"activeTopButton === 'filter-columns' && !isActiveFilterOpen\"\r\n >\r\n <div\r\n *ngTemplateOutlet=\"filterColumns\"\r\n class=\"actions-dropdown mt-1\"\r\n ></div>\r\n </ng-container>\r\n </div>\r\n </div>\r\n\r\n <!-- RIGHT SIDE (Update + Reset) -->\r\n <div class=\"d-flex gap-3 align-items-center\">\r\n <div\r\n (click)=\"savePreset()\"\r\n class=\"text-primary cursor-pointer all-filters-reset-button\"\r\n *ngIf=\"!checkFilterChangesEffect()\"\r\n >\r\n Update View\r\n </div>\r\n\r\n <div\r\n class=\"text-primary cursor-pointer all-filters-reset-button\"\r\n *ngIf=\"!tableFilterViewId && activeFilteredColumns?.length\"\r\n (click)=\"clearAllFilters()\"\r\n >\r\n Reset\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div\r\n [style.height]=\"\r\n showFilters ? 'calc(100% - ' + topFilterRowHeight + 'px)' : '100%'\r\n \"\r\n cdkDropListGroup\r\n class=\"data-grid-table-wrapper overflow-hidden\"\r\n #dataGridContainer\r\n [style.fontFamily]=\"fontFaimly\"\r\n [style.backgroundColor]=\"bodyBackgroundColor\"\r\n id=\"data-grid-main-container\"\r\n >\r\n <div\r\n *ngIf=\"showRowsGrouping\"\r\n [style.height.px]=\"headerRowHeight\"\r\n [cdkDropListData]=\"columns\"\r\n [style.backgroundColor]=\"\r\n topGroupedBadgesBackgroundColor || headerBackgroundColor\r\n \"\r\n cdkDropList\r\n (cdkDropListEntered)=\"enterToTopRowGrouping($event)\"\r\n (cdkDropListExited)=\"exitedFromTheTopRow($event)\"\r\n (cdkDropListDropped)=\"onDropTopGroup($event)\"\r\n [cdkDropListEnterPredicate]=\"canEnterToRowsGrouping\"\r\n id=\"rows-grouping-top-container\"\r\n class=\"border-below d-flex px-4 align-items-center\"\r\n >\r\n <div\r\n class=\"d-flex gap-2 align-items-center\"\r\n [style.color]=\"headerTextColor\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/justify.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n <div *ngIf=\"!draggingInGroupArea && !groupedColumns?.length\">\r\n Drag here to set row groups\r\n </div>\r\n <div\r\n cdkDropListOrientation=\"horizontal\"\r\n cdkDropList\r\n (cdkDropListDropped)=\"onGroupReorder($event)\"\r\n class=\"d-flex\"\r\n >\r\n <div\r\n cdkDrag\r\n [cdkDragLockAxis]=\"'x'\"\r\n *ngFor=\"\r\n let child of groupedColumns;\r\n let i = index;\r\n trackBy: trackByField\r\n \"\r\n class=\"d-flex align-items-center\"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n topGroupingRowPlaceholder;\r\n context: {\r\n $implicit: child,\r\n showChevron:\r\n groupedColumns.length > 1 && i != groupedColumns.length - 1\r\n }\r\n \"\r\n ></ng-container>\r\n <ng-template cdkDragPreview\r\n ><div class=\"p-2 border d-flex gap-2\">\r\n <div>\r\n <span\r\n *ngIf=\"!draggingInGroupArea\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/arrows-move.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n <div>{{ child.header }}</div>\r\n </div>\r\n </ng-template>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n <div\r\n class=\"d-flex overflow-hidden\"\r\n [style.height]=\"\r\n 'calc(100% - ' +\r\n (showRowsGrouping\r\n ? headerRowHeight + footerRowHeight\r\n : footerRowHeight) +\r\n 'px)'\r\n \"\r\n >\r\n <div\r\n class=\"h-100\"\r\n [style.width]=\"\r\n !showSideMenu\r\n ? '100%'\r\n : sideMenuVisible\r\n ? 'calc(100% - 280px)'\r\n : 'calc(100% - 30px)'\r\n \"\r\n >\r\n <div class=\"h-100 transition position-relative w-100\">\r\n <!-- ##################################################################################################################################################################################### -->\r\n <!-- ##################################################################################################################################################################################### -->\r\n <!-- Data Grid Header starts here -->\r\n <!-- ##################################################################################################################################################################################### -->\r\n <!-- ##################################################################################################################################################################################### -->\r\n\r\n <div\r\n class=\"data-grid-header-wrapper w-100\"\r\n [style.color]=\"headerTextColor\"\r\n [style.fontSize.px]=\"headerTextFontsSize\"\r\n [style.backgroundColor]=\"headerBackgroundColor\"\r\n [class.border-below]=\"!hasAnyVisibleColumn\"\r\n [style.height.px]=\"\r\n showColumnsGrouping && showFilterRow\r\n ? headerRowHeight * 3\r\n : showColumnsGrouping || showFilterRow\r\n ? headerRowHeight * 2\r\n : headerRowHeight\r\n \"\r\n >\r\n <!-- ********************************************************************************* -->\r\n <!-- ********************************************************************************* -->\r\n <!-- Data Grid Left Pinned Header starts here -->\r\n <!-- ********************************************************************************* -->\r\n <!-- ********************************************************************************* -->\r\n <div\r\n class=\"data-grid-header left-pinned\"\r\n #leftPinnedHeader\r\n [class.border-right]=\"hasLeftPinnedColumns\"\r\n >\r\n <div\r\n *ngIf=\"showSerialNumber\"\r\n [style.backgroundColor]=\"checkboxesBackgroundColor\"\r\n class=\"select-all-checkbox-cell border-below\"\r\n [style.width.px]=\"55\"\r\n [style.height.px]=\"\r\n showColumnsGrouping && showFilterRow\r\n ? headerRowHeight * 3\r\n : showColumnsGrouping || showFilterRow\r\n ? headerRowHeight * 2\r\n : headerRowHeight\r\n \"\r\n >\r\n S.No\r\n </div>\r\n <div\r\n *ngIf=\"showCheckboxes\"\r\n [style.backgroundColor]=\"checkboxesBackgroundColor\"\r\n class=\"select-all-checkbox-cell border-below\"\r\n [style.height.px]=\"\r\n showColumnsGrouping && showFilterRow\r\n ? headerRowHeight * 3\r\n : showColumnsGrouping || showFilterRow\r\n ? headerRowHeight * 2\r\n : headerRowHeight\r\n \"\r\n >\r\n <input\r\n *ngIf=\"hasAnyVisibleColumn\"\r\n style=\"width: 16px; height: 16px\"\r\n type=\"checkbox\"\r\n [indeterminate]=\"isIndeterminateState(dataSet)\"\r\n [checked]=\"isAllSelected(dataSet)\"\r\n (change)=\"toggleSelectAll(dataSet)\"\r\n />\r\n </div>\r\n <div\r\n [style.backgroundColor]=\"headerBackgroundColor\"\r\n class=\"d-flex\"\r\n cdkDropList\r\n id=\"left-pinned-header\"\r\n cdkDropListOrientation=\"horizontal\"\r\n [cdkDropListData]=\"leftPinnedColumns\"\r\n (cdkDropListEntered)=\"onDropListEnter($event, 'left')\"\r\n (cdkDropListSorted)=\"\r\n onSortGroup($event, 'previewLeftPinnedColumns')\r\n \"\r\n (cdkDropListDropped)=\"onDropGroup()\"\r\n style=\"min-width: 1px\"\r\n >\r\n <div\r\n class=\"dragable-header\"\r\n cdkDrag\r\n [cdkDragData]=\"col\"\r\n *ngFor=\"\r\n let col of leftPinnedColumns;\r\n let i = index;\r\n trackBy: trackByField\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n headerCell;\r\n context: {\r\n $implicit: col,\r\n index: i,\r\n section: 'previewLeftPinnedColumns'\r\n }\r\n \"\r\n ></ng-container>\r\n <ng-template cdkDragPreview\r\n ><div class=\"p-2 border d-flex gap-2\">\r\n <div>\r\n <span\r\n *ngIf=\"!draggingInGroupArea\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath +\r\n 'data-grid/icons/arrows-move.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n <div>{{ col.header }}</div>\r\n </div>\r\n </ng-template>\r\n <ng-template cdkDragPlaceholder>\r\n <div *ngIf=\"!draggingInGroupArea\">\r\n <div\r\n *ngTemplateOutlet=\"\r\n headerCell;\r\n context: {\r\n $implicit: col,\r\n index: i,\r\n section: ''\r\n }\r\n \"\r\n ></div>\r\n </div>\r\n <div\r\n *ngIf=\"draggingInGroupArea\"\r\n class=\"d-flex gap-2 ms-2\"\r\n style=\"opacity: 0.6\"\r\n >\r\n <ng-container\r\n *ngIf=\"col?.children?.length; else singleCol\"\r\n >\r\n <ng-container\r\n *ngFor=\"\r\n let child of col.children;\r\n let i = index;\r\n trackBy: trackByField\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n topGroupingRowPlaceholder;\r\n context: {\r\n $implicit: child,\r\n showChevron:\r\n col.children.length > 1 &&\r\n i != col.children.length - 1\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </ng-container>\r\n\r\n <ng-template #singleCol>\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n topGroupingRowPlaceholder;\r\n context: {\r\n $implicit: col,\r\n showChevron: col?.children?.length > 1\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-template>\r\n </div>\r\n </ng-template>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- ********************************************************************************* -->\r\n <!-- ********************************************************************************* -->\r\n <!-- Data Grid Center Pinned Header starts here -->\r\n <!-- ********************************************************************************* -->\r\n <!-- ********************************************************************************* -->\r\n <div\r\n class=\"data-grid-header center-scrollable\"\r\n #centerPinnedHeader\r\n (scroll)=\"onCenterBodyScroll($event)\"\r\n id=\"center-pinned-header\"\r\n cdkDropList\r\n [cdkDropListConnectedTo]=\"\r\n showRowsGrouping ? ['rows-grouping-top-container'] : []\r\n \"\r\n [cdkDropListData]=\"centerColumns\"\r\n cdkDropListOrientation=\"horizontal\"\r\n [cdkDropListSortingDisabled]=\"\r\n isDisableColumnGrouping && draggingInGroupArea\r\n \"\r\n (cdkDropListEntered)=\"onDropListEnter($event, 'center')\"\r\n (cdkDropListSorted)=\"onSortGroup($event, 'previewCenterColumns')\"\r\n (cdkDropListDropped)=\"onDropGroup()\"\r\n [style.maxWidth]=\"\r\n 'calc(100% - ' +\r\n (rightPinnedHeader.offsetWidth + leftPinnedHeader.offsetWidth) +\r\n 'px)'\r\n \"\r\n >\r\n <div\r\n *ngIf=\"groupedColumns?.length\"\r\n style=\"min-width: 200px\"\r\n class=\"h-100 align-items-center\"\r\n #columnsGroupedBox\r\n id=\"groupBoxHeaderDiv\"\r\n >\r\n <div\r\n class=\"d-flex w-100 justify-content-between align-items-center border-below\"\r\n [style.height.px]=\"\r\n showFilterRow ? headerRowHeight * 2 : headerRowHeight\r\n \"\r\n >\r\n <div class=\"ps-3\">Group</div>\r\n <div class=\"d-flex\">\r\n <div\r\n class=\"three-dots cursor-pointer\"\r\n (click)=\"\r\n openThreeDotsMenu($event, 'group');\r\n isThreeDotsFilterOpen = false\r\n \"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath +\r\n 'data-grid/icons/three-dots-vertical.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n <div\r\n (mousedown)=\"\r\n $event.stopPropagation(); onResizeGroupBox($event)\r\n \"\r\n class=\"resize-handle\"\r\n style=\"margin-right: -2px\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath +\r\n 'data-grid/icons/resize-handle.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div\r\n [style.height.px]=\"headerRowHeight\"\r\n class=\"border-below\"\r\n ></div>\r\n </div>\r\n <span\r\n class=\"d-flex align-items-center justify-content-center cursor-pointer border-below\"\r\n style=\"min-width: 30px; height: 100%\"\r\n *ngIf=\"gridType === 'Assets' || gridType === 'Tasks'\"\r\n >\r\n </span>\r\n <div\r\n class=\"dragable-header\"\r\n (cdkDragStarted)=\"\r\n checkColumnGroupingStatus(col);\r\n dragStartOnGroup(col);\r\n onDragStarted(col)\r\n \"\r\n (cdkDragMoved)=\"onDragMoved($event)\"\r\n (cdkDragEnded)=\"onDragEnded()\"\r\n cdkDrag\r\n [cdkDragData]=\"col\"\r\n *ngFor=\"\r\n let col of centerColumns;\r\n let i = index;\r\n trackBy: trackById\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n headerCell;\r\n context: {\r\n $implicit: col,\r\n index: i,\r\n section: 'previewCenterColumns'\r\n }\r\n \"\r\n >\r\n </ng-container>\r\n <ng-template cdkDragPreview\r\n ><div class=\"p-2 border d-flex gap-2\">\r\n <div>\r\n <span\r\n *ngIf=\"!isOutsideContainer\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath +\r\n (draggingInGroupArea\r\n ? 'data-grid/icons/justify.svg'\r\n : 'data-grid/icons/arrows-move.svg')\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n >\r\n </span>\r\n <span\r\n *ngIf=\"isOutsideContainer\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/eye-cross.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n >\r\n </span>\r\n </div>\r\n <div>{{ col.header }}</div>\r\n </div>\r\n </ng-template>\r\n <ng-template cdkDragPlaceholder>\r\n <div *ngIf=\"!draggingInGroupArea\">\r\n <div\r\n *ngTemplateOutlet=\"\r\n headerCell;\r\n context: {\r\n $implicit: col,\r\n index: i,\r\n section: 'centerColumns'\r\n }\r\n \"\r\n ></div>\r\n </div>\r\n <div\r\n *ngIf=\"draggingInGroupArea && !isOutsideContainer\"\r\n class=\"d-flex gap-2 ms-2\"\r\n style=\"opacity: 0.6\"\r\n >\r\n <ng-container *ngIf=\"col?.children?.length; else singleCol\">\r\n <ng-container\r\n *ngFor=\"\r\n let child of col.children;\r\n let i = index;\r\n trackBy: trackById\r\n \"\r\n >\r\n <ng-container *ngIf=\"child?.is_groupable\">\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n topGroupingRowPlaceholder;\r\n context: {\r\n $implicit: child,\r\n showChevron:\r\n col.children.length > 1 &&\r\n i != col.children.length - 1\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </ng-container>\r\n </ng-container>\r\n\r\n <ng-template #singleCol>\r\n <ng-container *ngIf=\"col?.is_groupable\">\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n topGroupingRowPlaceholder;\r\n context: {\r\n $implicit: col,\r\n showChevron: col?.children?.length > 1\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </ng-template>\r\n </div>\r\n </ng-template>\r\n </div>\r\n </div>\r\n\r\n <!-- ********************************************************************************* -->\r\n <!-- ********************************************************************************* -->\r\n <!-- Data Grid Right Pinned Header starts here -->\r\n <!-- ********************************************************************************* -->\r\n <!-- ********************************************************************************* -->\r\n <div\r\n [style.backgroundColor]=\"headerBackgroundColor\"\r\n cdkDropList\r\n id=\"right-pinned-header\"\r\n [cdkDropListConnectedTo]=\"\r\n showRowsGrouping ? ['rows-grouping-top-container'] : []\r\n \"\r\n cdkDropListOrientation=\"horizontal\"\r\n class=\"data-grid-header right-pinned\"\r\n (cdkDropListSorted)=\"\r\n onSortGroup($event, 'previewRightPinnedColumns')\r\n \"\r\n (cdkDropListEntered)=\"onDropListEnter($event, 'right')\"\r\n (cdkDropListDropped)=\"onDropGroup()\"\r\n #rightPinnedHeader\r\n class=\"right-pinned-header d-flex\"\r\n style=\"min-width: 0.2px\"\r\n >\r\n <div\r\n class=\"dragable-header\"\r\n cdkDrag\r\n [cdkDragData]=\"col\"\r\n *ngFor=\"\r\n let col of rightPinnedColumns;\r\n let i = index;\r\n trackBy: trackById\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n headerCell;\r\n context: {\r\n $implicit: col,\r\n pinnedRight: true,\r\n index: i,\r\n section: 'right'\r\n }\r\n \"\r\n ></ng-container>\r\n <ng-template cdkDragPreview\r\n ><div class=\"p-2 border d-flex gap-2\">\r\n <div>\r\n <span\r\n *ngIf=\"!draggingInGroupArea\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath +\r\n 'data-grid/icons/arrows-move.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n <div>{{ col.header }}</div>\r\n </div>\r\n </ng-template>\r\n <ng-template cdkDragPlaceholder>\r\n <div *ngIf=\"!draggingInGroupArea\">\r\n <div\r\n *ngTemplateOutlet=\"\r\n headerCell;\r\n context: {\r\n $implicit: col,\r\n index: i,\r\n section: 'right'\r\n }\r\n \"\r\n ></div>\r\n </div>\r\n <div\r\n *ngIf=\"draggingInGroupArea\"\r\n class=\"d-flex gap-2 ms-2\"\r\n style=\"opacity: 0.6\"\r\n >\r\n <ng-container *ngIf=\"col?.children?.length; else singleCol\">\r\n <ng-container\r\n *ngFor=\"\r\n let child of col.children;\r\n let i = index;\r\n trackBy: trackById\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n topGroupingRowPlaceholder;\r\n context: {\r\n $implicit: child,\r\n showChevron:\r\n col.children.length > 1 &&\r\n i != col.children.length - 1\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </ng-container>\r\n\r\n <ng-template #singleCol>\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n topGroupingRowPlaceholder;\r\n context: {\r\n $implicit: col,\r\n showChevron: col?.children?.length > 1\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-template>\r\n </div>\r\n </ng-template>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!--########################################################################################################################################################################################################################### -->\r\n <!--########################################################################################################################################################################################################################### -->\r\n <!-- Data Grid Body starts here -->\r\n <!--########################################################################################################################################################################################################################### -->\r\n <!--########################################################################################################################################################################################################################### -->\r\n <div\r\n class=\"h-100 d-flex justify-content-center align-items-center\"\r\n *ngIf=\"!dataSet?.length && !loading && !dataSetLoading\"\r\n >\r\n <!-- <div\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/record-not-found.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></div> -->\r\n <div>No Record Found</div>\r\n </div>\r\n\r\n <div\r\n class=\"position-absolute w-100 h-100 d-flex justify-content-center align-items-center loading-overlay\"\r\n *ngIf=\"loading || dataSetLoading\"\r\n style=\"\r\n z-index: 999;\r\n backdrop-filter: blur(1px);\r\n \"\r\n [style.backgroundColor]=\"bodyBackgroundColor\"\r\n >\r\n <div class=\"spinner-border text-primary\" role=\"status\">\r\n <!-- <span class=\"loader\"></span> -->\r\n <!-- <span class=\"visually-hidden\">Loading...</span> -->\r\n <!-- </div> -->\r\n </div>\r\n </div>\r\n\r\n <div\r\n class=\"data-grid-body-wrapper position-relative d-flex\"\r\n [style.height]=\"bodyWrapperHeight\"\r\n style=\"overflow-y: auto; overflow-x: hidden\"\r\n #mainScroll\r\n (scroll)=\"onMainScroll($event)\"\r\n [style.scrollbarWidth]=\"verticalScrollbarWidth\"\r\n >\r\n <!-- LEFT PINNED -->\r\n <div\r\n [style.height.px]=\"\r\n !groupedColumns.length ? originalDataSet.length * rowHeight : 0\r\n \"\r\n ></div>\r\n <div [class.h-100]=\"originalDataSet.length < 8\">\r\n <div\r\n class=\"data-grid-body left-pinned-body w-100\"\r\n style=\"overflow-y: hidden\"\r\n [class.border-right]=\"hasLeftPinnedColumns\"\r\n [class.transparent-border-right]=\"!hasLeftPinnedColumns\"\r\n [style.transform]=\"'translateY(' + translateY + 'px)'\"\r\n [style.backgroundColor]=\"leftPinnedBackgroundColor\"\r\n [class.h-100]=\"originalDataSet.length < 8\"\r\n *ngIf=\"!loading && !dataSetLoading\"\r\n [@rowDynamic]=\"rowAnimation\"\r\n\r\n \r\n >\r\n <ng-container\r\n *ngFor=\"\r\n let row of visibleRows;\r\n let i = index;\r\n trackBy: trackById\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n rowCell;\r\n context: {\r\n $implicit: row,\r\n columns: previewLeftPinnedColumns,\r\n isEven: (startIndex + i) % 2 === 0,\r\n isOdd: (startIndex + i) % 2 !== 0,\r\n isLeft: true,\r\n section: 'left',\r\n isTotalRow: false\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n <ng-container *ngIf=\"showTotalAmountRow && originalDataSet?.length\">\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n rowCell;\r\n context: {\r\n $implicit: { __virtualIndex: 0 },\r\n columns: previewLeftPinnedColumns,\r\n isEven: false,\r\n isOdd: false,\r\n section: 'left',\r\n isTotalRow: true\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </div>\r\n </div>\r\n\r\n <!-- CENTER -->\r\n <div\r\n class=\"h-100\"\r\n [style.width.px]=\"centerPinnedHeader.clientWidth\"\r\n [style.backgroundColor]=\"bodyBackgroundColor\"\r\n >\r\n <div\r\n class=\"data-grid-body center-scrollable\"\r\n [class.h-100]=\"originalDataSet.length < 8\"\r\n style=\"overflow-y: hidden; overflow-x: auto\"\r\n [style.transform]=\"'translateY(' + translateY + 'px)'\"\r\n [style.backgroundColor]=\"bodyBackgroundColor\"\r\n #centerScrollableBody\r\n (scroll)=\"onCenterBodyScroll($event)\"\r\n [style.boxShadow]=\"leftPinnedBoxshadow\"\r\n >\r\n <div [@rowDynamic]=\"rowAnimation\" *ngIf=\"!loading && !dataSetLoading\">\r\n <ng-container\r\n *ngFor=\"\r\n let row of visibleRows;\r\n let i = index;\r\n trackBy: trackById\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n rowCell;\r\n context: {\r\n $implicit: row,\r\n columns: previewCenterColumns,\r\n isEven: (startIndex + i) % 2 === 0,\r\n isOdd: (startIndex + i) % 2 !== 0,\r\n section: 'center',\r\n isTotalRow: false\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </div>\r\n <ng-container *ngIf=\"showTotalAmountRow && originalDataSet?.length\">\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n rowCell;\r\n context: {\r\n $implicit: { __virtualIndex: 0 },\r\n columns: previewCenterColumns,\r\n isEven: false,\r\n isOdd: false,\r\n section: 'center',\r\n isTotalRow: true\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </div>\r\n </div>\r\n\r\n <!-- RIGHT PINNED -->\r\n <div\r\n class=\"right-pinned-body-wrapper\"\r\n *ngIf=\"hasRightPinnedColumns\"\r\n [class.h-100]=\"originalDataSet.length < 8\"\r\n [style.maxWidth.px]=\"\r\n isScrollbarVisible\r\n ? rightPinnedHeader.offsetWidth - 15\r\n : rightPinnedHeader.offsetWidth\r\n \"\r\n [style.backgroundColor]=\"rightPinnedBackgroundColor\"\r\n >\r\n <div\r\n class=\"data-grid-body right-pinned-body w-100 h-100\"\r\n style=\"overflow-y: hidden\"\r\n [style.transform]=\"'translateY(' + translateY + 'px)'\"\r\n [style.boxShadow]=\"rightPinnedBoxshadow\"\r\n [style.backgroundColor]=\"rightPinnedBackgroundColor\"\r\n *ngIf=\"!loading && !dataSetLoading\"\r\n [@rowDynamic]=\"rowAnimation\"\r\n >\r\n <ng-container\r\n *ngFor=\"\r\n let row of visibleRows;\r\n let i = index;\r\n trackBy: trackById\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n rowCell;\r\n context: {\r\n $implicit: row,\r\n columns: previewRightPinnedColumns,\r\n isEven: (startIndex + i) % 2 === 0,\r\n isOdd: (startIndex + i) % 2 !== 0,\r\n section: 'right',\r\n isTotalRow: false\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n <ng-container *ngIf=\"showTotalAmountRow && originalDataSet?.length\">\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n rowCell;\r\n context: {\r\n $implicit: { __virtualIndex: 0 },\r\n columns: previewRightPinnedColumns,\r\n isEven: false,\r\n isOdd: false,\r\n section: 'right',\r\n isTotalRow: true\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </div>\r\n </div>\r\n\r\n <div\r\n style=\"top: auto; left: auto\"\r\n (click)=\"\r\n $event.stopPropagation();\r\n fullscreenImage = null;\r\n cdr.detectChanges()\r\n \"\r\n [style.width.px]=\"dataGridContainer.offsetWidth\"\r\n [style.height.px]=\"\r\n dataGridContainer.offsetHeight - (footerRowHeight + 100)\r\n \"\r\n class=\"image-modal full-image-modal\"\r\n *ngIf=\"fullscreenImage\"\r\n >\r\n <img\r\n (click)=\"$event.stopPropagation()\"\r\n [src]=\"fullscreenImage\"\r\n alt=\"Fullscreen Image\"\r\n />\r\n </div>\r\n <div\r\n *ngIf=\"selectedRows.size > 0 && showTaskbar\"\r\n class=\"taskbar w-100\"\r\n [style.bottom.px]=\"85\"\r\n >\r\n <div class=\"selected-rows-action-bar\" [@slideUp]>\r\n <span class=\"selected-count\">\r\n {{ selectedRows.size }} selected of\r\n {{\r\n paginationConfig.totalResults ||\r\n config?.paginationParams?.totalItems\r\n }}\r\n Total\r\n </span>\r\n <div class=\"action-buttons d-flex align-items-center\">\r\n <ng-container\r\n *ngFor=\"let action of taskbarActions; let i = index\"\r\n >\r\n <ng-container *ngIf=\"action?.has_permission\">\r\n <span\r\n class=\"action-btn verified btn {{ action }}\"\r\n (click)=\"onVerifyClick(action?.actionName)\"\r\n >{{ action?.actionName }}</span\r\n >\r\n <span\r\n *ngIf=\"\r\n taskbarActions.length > 1 &&\r\n i !== taskbarActions.length - 1 &&\r\n taskbarActions[i + 1]?.has_permission\r\n \"\r\n class=\"\"\r\n >|</span\r\n >\r\n </ng-container>\r\n </ng-container>\r\n <button (click)=\"clearSelectionState(tableType);selectedRows.clear();\" class=\"clear-btn ms-2 mt-2\">\r\n <i class=\"bi bi-x-circle\"></i> Clear Selection\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n <!-- Vertical Fake scroll Bar -->\r\n <!-- <div\r\n (scroll)=\"onMainFakeScroll($event)\"\r\n class=\"fake-scrollbar fake-scrollbar-vertical d-none\"\r\n [style.scrollbarWidth]=\"verticalScrollbarWidth\"\r\n [style.top.px]=\"\r\n showColumnsGrouping && showFilterRow\r\n ? headerRowHeight * 3\r\n : showColumnsGrouping || showFilterRow\r\n ? headerRowHeight * 2\r\n : headerRowHeight\r\n \"\r\n #fakeScroll\r\n [style.height]=\"bodyWrapperHeight\"\r\n style=\"\r\n overflow-y: auto;\r\n overflow-x: hidden;\r\n width: 17px;\r\n position: absolute;\r\n right: 0;\r\n background-color: f1f2f3;\r\n z-index: 10;\r\n \"\r\n >\r\n <div [style.height.px]=\"rowHeight * dataSetLength\"></div>\r\n </div> -->\r\n </div>\r\n\r\n <!-- Horizintal Fake Scrollbars -->\r\n <div\r\n class=\"d-flex justify-content-between\"\r\n *ngIf=\"hasScroll && !shouldRestoreScroll\"\r\n >\r\n <div\r\n [style.scrollbarWidth]=\"horizintalScrollbarWidth\"\r\n class=\"fake-horizintal-scrollbar\"\r\n #fakeScroll\r\n [style.width.px]=\"leftPinnedHeader.offsetWidth\"\r\n style=\"overflow-x: scroll\"\r\n ></div>\r\n <div\r\n [style.scrollbarWidth]=\"horizintalScrollbarWidth\"\r\n (scroll)=\"onCenterBodyScroll($event)\"\r\n class=\"fake-horizintal-scrollbar\"\r\n #horizintalFakeScroll\r\n [style.width.px]=\"centerPinnedHeader.offsetWidth\"\r\n >\r\n <div [style.width.px]=\"centerPinnedHeader.scrollWidth - 10\"></div>\r\n </div>\r\n <div\r\n [style.scrollbarWidth]=\"horizintalScrollbarWidth\"\r\n class=\"fake-horizintal-scrollbar\"\r\n #fakeScroll\r\n [style.width.px]=\"rightPinnedHeader.offsetWidth\"\r\n style=\"overflow-x: scroll\"\r\n ></div>\r\n </div>\r\n </div>\r\n\r\n <!-- Side Menu Implemented Here -->\r\n <div\r\n *ngIf=\"showSideMenu\"\r\n [style.width.px]=\"sideMenuVisible ? 280 : 30\"\r\n class=\"right-menu h-100\"\r\n [style.backgroundColor]=\"sidemenuBackgroundColor\"\r\n >\r\n <div class=\"h-100 d-flex flex-row-reverse\">\r\n <div\r\n style=\"width: 30px\"\r\n class=\"d-flex flex-column align-items-center cursor-pointer\"\r\n [class.border-start]=\"sideMenuVisible\"\r\n >\r\n <div\r\n (click)=\"toggleSideMenu('cols')\"\r\n [class.bg-fff]=\"\r\n currentOpenedSideMenue == 'cols' && sideMenuVisible\r\n \"\r\n [class.border-below]=\"sideMenuVisible\"\r\n class=\"columns-button d-flex flex-column align-items-center\"\r\n >\r\n <div>\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/ui-checks-grid.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n <div class=\"side-menue-text\">Columns</div>\r\n </div>\r\n\r\n <div\r\n (click)=\"toggleSideMenu('filtrs')\"\r\n [class.bg-fff]=\"\r\n currentOpenedSideMenue == 'filtrs' && sideMenuVisible\r\n \"\r\n [class.border-below]=\"\r\n sideMenuVisible && currentOpenedSideMenue == 'filtrs'\r\n \"\r\n class=\"columns-button d-flex flex-column align-items-center\"\r\n >\r\n <div>\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n <div class=\"side-menue-text\">Filter</div>\r\n </div>\r\n </div>\r\n <div\r\n class=\"h-100\"\r\n *ngIf=\"sideMenuVisible\"\r\n [ngStyle]=\"{ width: sideMenuVisible ? '250px' : '' }\"\r\n >\r\n <div class=\"h-100\">\r\n <ng-container\r\n *ngIf=\"currentOpenedSideMenue == 'cols' && sideMenuVisible\"\r\n >\r\n <ng-container *ngTemplateOutlet=\"columnPannel\"></ng-container>\r\n <!-- Column Items -->\r\n <div class=\"column-panel-body px-3\">\r\n <ng-container\r\n *ngFor=\"let col of columns; trackBy: trackByField\"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"columnPanelItem; context: { col: col }\"\r\n ></ng-container>\r\n </ng-container>\r\n </div>\r\n <hr />\r\n\r\n <div class=\"side-menu-row-groups\" style=\"height: 30%\">\r\n <ng-container\r\n *ngTemplateOutlet=\"sideMenuRowGroups\"\r\n ></ng-container>\r\n </div>\r\n </ng-container>\r\n <ng-container\r\n *ngIf=\"currentOpenedSideMenue == 'filtrs' && sideMenuVisible\"\r\n >\r\n <ng-container *ngTemplateOutlet=\"sideFilters\"></ng-container>\r\n </ng-container>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n <div\r\n [style.height.px]=\"footerRowHeight\"\r\n class=\"border-top\"\r\n [style.backgroundColor]=\"footerRowBackgroundColor\"\r\n >\r\n <!-- Rows: <span class=\"fw-500 ms-1\">{{ dataSet.length }}</span> -->\r\n\r\n <div\r\n class=\"pagination-container\"\r\n [style.height.px]=\"footerRowHeight\"\r\n [style.padding.px]=\"footerPadding\"\r\n >\r\n <div class=\"page-size\">\r\n <select\r\n [(ngModel)]=\"paginationConfig.limit\"\r\n (change)=\"onPageSizeChange()\"\r\n >\r\n <option *ngFor=\"let size of pageSizeOptions\" [value]=\"size\">\r\n {{ size }}\r\n </option>\r\n </select>\r\n <span class=\"separator\"> per page </span>\r\n </div>\r\n\r\n <div class=\"page-info\">\r\n Results:\r\n {{ (paginationConfig.page - 1) * paginationConfig.limit + 1 }}-{{\r\n paginationConfig.page * paginationConfig.limit <\r\n paginationConfig.totalResults\r\n ? paginationConfig.page * paginationConfig.limit\r\n : paginationConfig.totalResults\r\n }}\r\n of\r\n {{ paginationConfig.totalResults }}\r\n </div>\r\n\r\n <div class=\"page-buttons\">\r\n <button\r\n (click)=\"goToPage(paginationConfig.page - 1)\"\r\n [disabled]=\"paginationConfig.page === 1\"\r\n >\r\n \u2039\r\n </button>\r\n\r\n <ng-container *ngFor=\"let page of visiblePages\">\r\n <button\r\n *ngIf=\"page !== '...'\"\r\n (click)=\"goToPage(page)\"\r\n [class.active]=\"page === paginationConfig.page\"\r\n >\r\n {{ page }}\r\n </button>\r\n <span *ngIf=\"page === '...'\">...</span>\r\n </ng-container>\r\n\r\n <button\r\n (click)=\"goToPage(paginationConfig.page + 1)\"\r\n [disabled]=\"paginationConfig.page === paginationConfig.totalResults\"\r\n >\r\n \u203A\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<!-- ------------------------------------------------------------------------------------------------------------------------ -->\r\n<!-- ------------------------------------------------------------------------------------------------------------------------ -->\r\n<!-- Header Cell Template -->\r\n<!-- ------------------------------------------------------------------------------------------------------------------------ -->\r\n<!-- ------------------------------------------------------------------------------------------------------------------------ -->\r\n\r\n<ng-template\r\n #headerCell\r\n let-col\r\n let-pinnedRight=\"pinnedRight\"\r\n let-i=\"index\"\r\n let-columnIndex=\"index\"\r\n let-sections=\"section\"\r\n let-calledFromNestedPlaceholder=\"calledFromNestedPlaceholder\"\r\n>\r\n <div>\r\n <!-- Group Header -->\r\n <ng-container *ngIf=\"col.children?.length > 0; else flatHeader\">\r\n <div cdkDroplistGroup class=\"group-column-wrapper\">\r\n <!-- Parent Header -->\r\n <div\r\n *ngIf=\"shouldTheGroupHeaderShow(col)\"\r\n class=\"header-cell group-header\"\r\n [style.height.px]=\"headerRowHeight\"\r\n [style.min-height.px]=\"headerRowHeight\"\r\n [style.max-height.px]=\"headerRowHeight\"\r\n [class.border-right]=\"showVerticalBorder\"\r\n [style.gridColumn]=\"'span ' + col.children.length\"\r\n [style.fontWeight]=\"headerFontWeight\"\r\n [class.flex-row-reverse]=\"pinnedRight\"\r\n [class.justify-content-end]=\"pinnedRight\"\r\n style=\"grid-row: 1\"\r\n >\r\n <div\r\n class=\"group-header-content\"\r\n [title]=\"col.header\"\r\n [class.ms-2]=\"pinnedRight\"\r\n >\r\n {{ col.header }}\r\n </div>\r\n <div\r\n class=\"resize-handle\"\r\n (dblclick)=\"autosizeColumn(col.children)\"\r\n (mousedown)=\"\r\n $event.stopPropagation(); onResizeGroup($event, col, pinnedRight)\r\n \"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/resize-handle.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n </div>\r\n\r\n <!-- Child Headers and Filters -->\r\n\r\n <div\r\n class=\"d-flex\"\r\n cdkDropList\r\n cdkDropListOrientation=\"horizontal\"\r\n [cdkDropListData]=\"col.children\"\r\n (cdkDropListSorted)=\"onChildDroplistSorted($event, sections)\"\r\n (cdkDropListDropped)=\"onChildDroplistDroped($event)\"\r\n [cdkDropListSortingDisabled]=\"false\"\r\n [cdkDropListConnectedTo]=\"\r\n showRowsGrouping ? ['rows-grouping-top-container'] : []\r\n \"\r\n >\r\n <div\r\n cdkDrag\r\n [cdkDragData]=\"child\"\r\n *ngFor=\"let child of col.children; let i = index\"\r\n >\r\n <!-- Child Header -->\r\n <ng-container *ngIf=\"child.is_visible && !child['isRowGrouped']\">\r\n <div\r\n cdkDragHandle\r\n class=\"header-cell one-row-header-cells cursor-pointer\"\r\n [class.border-right]=\"showVerticalBorder\"\r\n [attr.field]=\"child.field\"\r\n [style.width.px]=\"child.width\"\r\n [style.min-width.px]=\"child.width\"\r\n [style.min-height.px]=\"headerRowHeight\"\r\n [style.max-height.px]=\"headerRowHeight\"\r\n [style.fontWeight]=\"headerFontWeight\"\r\n style=\"grid-row: 2\"\r\n [class.filter-applied-on-text]=\"isFilterAppliedOnColumn(child)\"\r\n >\r\n <div\r\n class=\"d-flex justify-content-between h-100 align-items-center w-100\"\r\n >\r\n <div\r\n class=\"d-flex justify-content-between align-items-center w-100\"\r\n [class.flex-row-reverse]=\"pinnedRight\"\r\n >\r\n <div\r\n class=\"text-ellipsis h-100 d-flex align-items-center w-100\"\r\n [title]=\"col.header\"\r\n [class.w-100]=\"pinnedRight\"\r\n >\r\n <div\r\n class=\"text-ellipsis h-100\"\r\n [class.editable-header]=\"child?.is_editable\"\r\n (click)=\"\r\n openThreeDotsMenu($event, child);\r\n openFilteronThreeDotsClick(child)\r\n \"\r\n >\r\n {{ child.header }}\r\n </div>\r\n </div>\r\n\r\n <div\r\n class=\"position-relative d-flex\"\r\n [class.flex-row-reverse]=\"pinnedRight\"\r\n >\r\n <div\r\n [class.me-2]=\"pinnedRight\"\r\n class=\"d-flex align-items-center\"\r\n *ngIf=\"child.pinned\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/pin-blue.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n <div\r\n class=\"three-dots p-1\"\r\n (click)=\"\r\n openThreeDotsMenu($event, child);\r\n isThreeDotsFilterOpen = false\r\n \"\r\n style=\"cursor: pointer\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath +\r\n 'data-grid/icons/three-dots-vertical.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n\r\n <!-- Only show menu if this column is active -->\r\n <div\r\n class=\"position-absolute\"\r\n *ngIf=\"activeCol === child\"\r\n style=\"top: -50%; z-index: 21\"\r\n [style.left.px]=\"\r\n -(!child?.pinned ? centerPinnedHeader.scrollLeft : 0)\r\n \"\r\n [style.top.px]=\"\r\n isThreeDotsFilterOpen\r\n ? showFilterRow || showColumnsGrouping\r\n ? headerRowHeight * 2 - 10\r\n : headerRowHeight - 10\r\n : 0\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n columnMenu;\r\n context: {\r\n col: child,\r\n isNestedTable: false,\r\n section: sections,\r\n columnIndex: columnIndex,\r\n childColIndex: i\r\n }\r\n \"\r\n ></ng-container>\r\n </div>\r\n\r\n <div\r\n class=\"resize-handle\"\r\n (dblclick)=\"autosizeColumn(child)\"\r\n (mousedown)=\"\r\n $event.stopPropagation();\r\n onResizeColumn($event, child)\r\n \"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath +\r\n 'data-grid/icons/resize-handle.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Filter Cell -->\r\n <div\r\n *ngIf=\"showFilterRow\"\r\n [style.backgroundColor]=\"headerBackgroundColor\"\r\n class=\"header-cell filter-cell\"\r\n [class.border-right]=\"showVerticalBorder\"\r\n [attr.field]=\"child.field\"\r\n [style.width.px]=\"child.width\"\r\n [style.min-width.px]=\"child.width\"\r\n [style.height.px]=\"headerRowHeight\"\r\n [style.min-height.px]=\"headerRowHeight\"\r\n [style.max-height.px]=\"headerRowHeight\"\r\n [class.border-right]=\"showVerticalBorder\"\r\n style=\"grid-row: 3\"\r\n >\r\n <div\r\n class=\"header-cell filter-cell\"\r\n [attr.field]=\"col.field\"\r\n [style.width.px]=\"col.width\"\r\n [style.min-width.px]=\"col.width\"\r\n [style.height.px]=\"headerRowHeight\"\r\n [style.min-height.px]=\"headerRowHeight\"\r\n [style.max-height.px]=\"headerRowHeight\"\r\n >\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Filter\"\r\n [(ngModel)]=\"child.filterValue\"\r\n (ngModelChange)=\"onFilterChange(child)\"\r\n (paste)=\"onFilterChange(child); applyDropdownFilter()\"\r\n [readonly]=\"\r\n child?.type == 'dropdown' || child?.type == 'image' || child?.type == 'array'\r\n \"\r\n [class.disabled-search-input]=\"\r\n child?.type == 'dropdown' || child?.type == 'image' || child?.type == 'array'\r\n \"\r\n (click)=\"\r\n $event.stopPropagation();\r\n openFilterFromDisabledSearchedInput(child)\r\n \"\r\n (keydown.enter)=\"applyDropdownFilter()\"\r\n (mousedown)=\"$event.stopPropagation()\"\r\n />\r\n <span\r\n class=\"filter-icon-wrapper\"\r\n (click)=\"$event.stopPropagation(); openFilter(child)\"\r\n [class.filter-applied]=\"isFilterAppliedOnColumn(child)\"\r\n [class.pe-none]=\"child?.type == 'image'\"\r\n ><span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n <span\r\n *ngIf=\"isFilterAppliedOnColumn(child)\"\r\n style=\"\r\n width: 7px;\r\n height: 7px;\r\n box-shadow: 0px 0px 3px #7486ff;\r\n background-color: rgb(0 163 233);\r\n position: absolute;\r\n right: 4px;\r\n top: 12px;\r\n \"\r\n class=\"rounded-circle d-block\"\r\n ></span\r\n ></span>\r\n\r\n <div\r\n class=\"position-absolute filter-row-filter-wrapper\"\r\n *ngIf=\"activeFilterCell?.field == child?.field\"\r\n style=\"top: 100%; right: 0; z-index: 99\"\r\n [style.left.px]=\"\r\n child?.pinned ? 0 : -centerPinnedHeader.scrollLeft\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"filterMenu; context: { col: child }\"\r\n ></ng-container>\r\n </div>\r\n </div>\r\n </div>\r\n </ng-container>\r\n <ng-template cdkDragPreview\r\n ><div class=\"p-2 border d-flex gap-2\">\r\n <div\r\n *ngIf=\"\r\n !draggingInGroupArea ||\r\n (child.is_groupable && draggingInGroupArea)\r\n \"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/arrows-move.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n <div *ngIf=\"draggingInGroupArea && !child.is_groupable\">\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/ban.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n <div>{{ child.header }}</div>\r\n </div>\r\n </ng-template>\r\n <ng-template cdkDragPlaceholder>\r\n <div *ngIf=\"!draggingInGroupArea\" class=\"position-relative\">\r\n <div\r\n *ngTemplateOutlet=\"\r\n childHeaderPlaceholder;\r\n context: {\r\n $implicit: child,\r\n index: i,\r\n sections: sections,\r\n calledFromNestedPlaceholder: true,\r\n }\r\n \"\r\n ></div>\r\n </div>\r\n <div\r\n *ngIf=\"draggingInGroupArea && child?.is_groupable\"\r\n class=\"d-flex gap-2 ms-2\"\r\n style=\"opacity: 0.6\"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n topGroupingRowPlaceholder;\r\n context: {\r\n $implicit: child,\r\n showChevron: false,\r\n pinnedRight: pinnedRight,\r\n sections: sections,\r\n index: i\r\n }\r\n \"\r\n ></ng-container>\r\n </div>\r\n </ng-template>\r\n </div>\r\n </div>\r\n </div>\r\n </ng-container>\r\n\r\n <!-- Flat Header || Single Header Cell-->\r\n <ng-template #flatHeader>\r\n <div\r\n class=\"group-column-wrapper\"\r\n *ngIf=\"col.is_visible && !col['isRowGrouped']\"\r\n >\r\n <!-- Full-height Header Cell (spans 2 rows visually) -->\r\n <div\r\n class=\"header-cell one-row-header-cells\"\r\n [attr.field]=\"col.field\"\r\n [style.width.px]=\"col.width\"\r\n [style.min-width.px]=\"col.width\"\r\n [class.border-right]=\"showVerticalBorder\"\r\n [style.min-height.px]=\"\r\n showColumnsGrouping ? headerRowHeight * 2 : headerRowHeight\r\n \"\r\n [style.height.px]=\"\r\n showColumnsGrouping ? headerRowHeight * 2 : headerRowHeight\r\n \"\r\n [style.fontWeight]=\"headerFontWeight\"\r\n style=\"grid-row: 1 / span 2\"\r\n >\r\n <div\r\n class=\"d-flex justify-content-between h-100 align-items-center w-100\"\r\n >\r\n <div\r\n class=\"d-flex justify-content-between w-100 align-items-center\"\r\n [class.flex-row-reverse]=\"pinnedRight\"\r\n >\r\n <div\r\n class=\"text-ellipsis h-100 d-flex align-items-center w-100\"\r\n [title]=\"col.header\"\r\n >\r\n <div\r\n class=\"text-ellipsis h-100 cursor-pointer\"\r\n [class.editable-header]=\"col?.is_editable\"\r\n [class.filter-applied-on-text]=\"isFilterAppliedOnColumn(col)\"\r\n (click)=\"\r\n openThreeDotsMenu($event, col);\r\n openFilteronThreeDotsClick(col)\r\n \"\r\n >\r\n {{ col.header }}\r\n </div>\r\n </div>\r\n\r\n <div\r\n class=\"position-relative d-flex\"\r\n [class.flex-row-reverse]=\"pinnedRight\"\r\n >\r\n <div\r\n [class.me-2]=\"pinnedRight\"\r\n class=\"d-flex align-items-center\"\r\n *ngIf=\"col?.pinned\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/pin-blue.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n <div\r\n [class.me-2]=\"col.order_by\"\r\n class=\"d-flex align-items-center\"\r\n *ngIf=\"sortingConfig?.field == col.field\"\r\n >\r\n <!-- Ascending Sort Icon -->\r\n <span\r\n *ngIf=\"sortingConfig?.order_by == 'asc'\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/sort-asc.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center mt-1 cursor-pointer\"\r\n (click)=\"sortDesc(col)\"\r\n [class.active]=\"sortingConfig?.order_by === 'asc'\"\r\n ></span>\r\n\r\n <!-- Descending Sort Icon -->\r\n <span\r\n *ngIf=\"sortingConfig?.order_by == 'desc'\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/sort-desc.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center mt-1 cursor-pointer\"\r\n (click)=\"sortAsc(col)\"\r\n [class.active]=\"sortingConfig?.order_by === 'desc'\"\r\n ></span>\r\n </div>\r\n <div\r\n class=\"three-dots p-1\"\r\n (click)=\"\r\n openThreeDotsMenu($event, col);\r\n isThreeDotsFilterOpen = false\r\n \"\r\n style=\"cursor: pointer\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath +\r\n 'data-grid/icons/three-dots-vertical.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n\r\n <!-- Only show menu if this column is active -->\r\n <div\r\n class=\"position-absolute\"\r\n *ngIf=\"activeCol === col\"\r\n style=\"top: -50%; z-index: 21\"\r\n [style.left.px]=\"\r\n -(!col?.pinned ? centerPinnedHeader.scrollLeft : 0)\r\n \"\r\n [style.top.px]=\"\r\n isThreeDotsFilterOpen\r\n ? showFilterRow || showColumnsGrouping\r\n ? headerRowHeight * 2 - 10\r\n : headerRowHeight - 10\r\n : 0\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n columnMenu;\r\n context: {\r\n col: col,\r\n isNestedTable: false,\r\n section: sections,\r\n columnIndex: columnIndex,\r\n childColIndex: 0\r\n },\r\n \"\r\n ></ng-container>\r\n </div>\r\n\r\n <div\r\n class=\"resize-handle\"\r\n [class.w-100]=\"col.pinned == 'right'\"\r\n (dblclick)=\"autosizeColumn(col)\"\r\n (mousedown)=\"\r\n $event.stopPropagation(); onResizeColumn($event, col)\r\n \"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/resize-handle.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Filter Cell -->\r\n <div\r\n *ngIf=\"showFilterRow\"\r\n [style.backgroundColor]=\"headerBackgroundColor\"\r\n class=\"header-cell filter-cell\"\r\n [class.border-right]=\"showVerticalBorder\"\r\n [attr.field]=\"col.field\"\r\n [style.width.px]=\"col.width\"\r\n [style.min-width.px]=\"col.width\"\r\n [style.height.px]=\"headerRowHeight\"\r\n [style.min-height.px]=\"headerRowHeight\"\r\n [style.max-height.px]=\"headerRowHeight\"\r\n >\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Filter\"\r\n [(ngModel)]=\"col.filterValue\"\r\n (ngModelChange)=\"onFilterChange(col)\"\r\n [readonly]=\"col?.type == 'dropdown' || col?.type == 'image' || col?.type == 'array'\"\r\n [class.disabled-search-input]=\"\r\n col?.type == 'dropdown' || col?.type == 'image' || col?.type == 'array'\r\n \"\r\n (paste)=\"onPasteInFilterRowSearch($event, col)\"\r\n (click)=\"\r\n $event.stopPropagation(); openFilterFromDisabledSearchedInput(col)\r\n \"\r\n (keydown.enter)=\"applyDropdownFilter()\"\r\n (mousedown)=\"$event.stopPropagation()\"\r\n />\r\n <span\r\n class=\"filter-icon-wrapper\"\r\n (click)=\"$event.stopPropagation(); openFilter(col)\"\r\n [class.filter-applied]=\"isFilterAppliedOnColumn(col)\"\r\n [class.pe-none]=\"col?.type == 'image'\"\r\n ><span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n <span\r\n *ngIf=\"isFilterAppliedOnColumn(col)\"\r\n style=\"\r\n width: 7px;\r\n height: 7px;\r\n box-shadow: 0px 0px 3px #7486ff;\r\n background-color: rgb(0 163 233);\r\n position: absolute;\r\n right: 4px;\r\n top: 12px;\r\n \"\r\n class=\"rounded-circle d-block\"\r\n ></span\r\n ></span>\r\n\r\n <div\r\n class=\"position-absolute filter-row-filter-wrapper\"\r\n *ngIf=\"activeFilterCell === col\"\r\n style=\"top: 100%; right: 0; z-index: 99\"\r\n [style.left.px]=\"col?.pinned ? 0 : -centerPinnedHeader.scrollLeft\"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"filterMenu; context: { col: col }\"\r\n ></ng-container>\r\n </div>\r\n </div>\r\n </div>\r\n </ng-template>\r\n </div>\r\n</ng-template>\r\n\r\n<!-- -------------------------------------------------------------------------------------------------------------------------------------------------------------------- -->\r\n<!-- -------------------------------------------------------------------------------------------------------------------------------------------------------------------- -->\r\n<!-- Body Cell Template -->\r\n<!-- -------------------------------------------------------------------------------------------------------------------------------------------------------------------- -->\r\n<!-- -------------------------------------------------------------------------------------------------------------------------------------------------------------------- -->\r\n\r\n<ng-template\r\n #rowCell\r\n let-row\r\n let-columns=\"columns\"\r\n let-isEven=\"isEven\"\r\n let-isOdd=\"isOdd\"\r\n let-isLeftSection=\"isLeft\"\r\n let-section=\"section\"\r\n let-rowIndex=\"rowIndex\"\r\n let-isTotalRow=\"isTotalRow\"\r\n>\r\n <!-- Check if row is a group -->\r\n <ng-container\r\n *ngTemplateOutlet=\"groupRowTemplate; context: { $implicit: row, depth: 0 }\"\r\n ></ng-container>\r\n <ng-template #groupRowTemplate let-row let-depth=\"depth\">\r\n <ng-container *ngIf=\"row.isGroup; else regularRow\">\r\n <!-- Group Header -->\r\n <div\r\n class=\"group-header-row d-flex align-items-center\"\r\n [style.height.px]=\"rowHeight\"\r\n [class.border-below]=\"section !== 'center'\"\r\n [style.width]=\"\r\n section === 'center'\r\n ? (centerScrollableBody?.scrollWidth ?? 0) + 'px'\r\n : '100%'\r\n \"\r\n >\r\n <div\r\n *ngIf=\"section == 'left'\"\r\n class=\"h-100 d-flex\"\r\n [style.width.px]=\"leftPinnedHeader.offsetWidth - 1\"\r\n [class.row-selected]=\"rowSelectedIndexes.has(row.__virtualIndex)\"\r\n >\r\n <div\r\n *ngIf=\"showSerialNumber\"\r\n style=\"width: 50px\"\r\n class=\"d-flex align-items-center h-100 border-right justify-content-end pe-2 s-no\"\r\n [style.backgroundColor]=\"checkboxesBackgroundColor\"\r\n [style.width.px]=\"55\"\r\n [style.cursor]=\"\r\n 'url(' +\r\n singleSpaAssetsPath +\r\n 'data-grid/icons/arrow-right.svg), auto'\r\n \"\r\n (mousedown)=\"onRowMouseDown(row.__virtualIndex, $event)\"\r\n (mouseover)=\"onRowMouseOver(row.__virtualIndex, $event)\"\r\n [style.color]=\"checkboxesColor\"\r\n >\r\n {{ getStartIndex() + (row.__virtualIndex - 1) || \"\" }}\r\n </div>\r\n <div\r\n *ngIf=\"showCheckboxes\"\r\n style=\"width: 50px\"\r\n class=\"d-flex align-items-center justify-content-center h-100 border-right\"\r\n [style.backgroundColor]=\"checkboxesBackgroundColor\"\r\n [class.row-selected]=\"rowSelectedIndexes.has(row.__virtualIndex)\"\r\n [class.left-selection-border]=\"\r\n rowSelectedIndexes.has(row.__virtualIndex)\r\n \"\r\n [class.first-row-selected]=\"firstSelectedRow === row.__virtualIndex\"\r\n [class.last-row-selected]=\"lastSelectedRow === row.__virtualIndex\"\r\n [style.color]=\"checkboxesColor\"\r\n >\r\n <input\r\n style=\"width: 16px; height: 16px\"\r\n type=\"checkbox\"\r\n [checked]=\"getGroupCheckedState(row) === true\"\r\n [indeterminate]=\"getGroupCheckedState(row) === undefined\"\r\n (change)=\"selectGroupRow($event, row)\"\r\n />\r\n\r\n </div>\r\n </div>\r\n\r\n <div\r\n *ngIf=\"section == 'center'\"\r\n [style.width.px]=\"centerPinnedHeader.scrollWidth\"\r\n [style.minWidth.px]=\"centerPinnedHeader.scrollWidth\"\r\n class=\"d-flex align-items-center ps-2 h-100 border-below\"\r\n [class.row-selected]=\"rowSelectedIndexes.has(row.__virtualIndex)\"\r\n [class.first-row-selected]=\"firstSelectedRow === row.__virtualIndex\"\r\n [class.last-row-selected]=\"lastSelectedRow === row.__virtualIndex\"\r\n >\r\n <div\r\n class=\"d-flex align-items-center justify-content-between\"\r\n [style.paddingLeft.px]=\"depth > 0 ? depth * 30 : 0\"\r\n >\r\n <span class=\"me-2 filter-icon-wrapper\" (click)=\"toggleExpand(row)\">\r\n <span\r\n class=\"data-grid-svg-icon align-items-center d-flex\"\r\n [inlineSVG]=\"\r\n row.isExpand\r\n ? singleSpaAssetsPath + 'data-grid/icons/chevron-down.svg'\r\n : singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\r\n \"\r\n ></span>\r\n </span>\r\n <strong (click)=\"toggleExpand(row)\" class=\"cursor-pointer\">\r\n {{ row.groupValue }} ({{ countLeafRows(row) }})\r\n </strong>\r\n </div>\r\n </div>\r\n\r\n <div\r\n *ngIf=\"section == 'right'\"\r\n [style.width.px]=\"rightPinnedHeader.offsetWidth\"\r\n [class.row-selected]=\"rowSelectedIndexes.has(row.__virtualIndex)\"\r\n [class.first-row-selected]=\"firstSelectedRow === row.__virtualIndex\"\r\n [class.last-row-selected]=\"lastSelectedRow === row.__virtualIndex\"\r\n ></div>\r\n </div>\r\n\r\n <!-- Recursive Children -->\r\n <div class=\"group-children\" *ngIf=\"row.isExpand\" [@slideToggle]>\r\n <ng-container\r\n *ngFor=\"let child of row.children; let i = index; trackBy: trackById\"\r\n >\r\n <ng-container *ngIf=\"child.isGroup; else dataRow\">\r\n <!-- Recursive call for nested group -->\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n groupRowTemplate;\r\n context: { $implicit: child, depth: depth + 1 }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n\r\n <ng-template #dataRow>\r\n <!-- Regular data row -->\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n rowCell;\r\n context: {\r\n $implicit: child,\r\n columns: columns,\r\n isEven: i % 2 === 0,\r\n isOdd: i % 2 !== 0,\r\n isLeft: isLeftSection,\r\n section: section,\r\n isTotalRow: isTotalRow\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-template>\r\n </ng-container>\r\n </div>\r\n </ng-container>\r\n </ng-template>\r\n\r\n <!-- Regular row (not a group) -->\r\n <ng-template #regularRow>\r\n <div\r\n class=\"d-flex\"\r\n [style.height.px]=\"rowHeight\"\r\n [style.minHeight.px]=\"rowHeight\"\r\n [style.maxHeight.px]=\"rowHeight\"\r\n >\r\n <span\r\n class=\"d-flex align-items-center justify-content-center cursor-pointer border-below\"\r\n style=\"min-width: 30px; height: 100%\"\r\n *ngIf=\"\r\n section == 'center' && (gridType === 'Assets' || gridType === 'Tasks')\r\n \"\r\n [ngStyle]=\"{\r\n 'background-color': rowSelectedIndexes.has(row.__virtualIndex)\r\n ? null\r\n : getBackgroundColor(row, isEven, section)\r\n }\"\r\n [class.selected-cell]=\"rowSelectedIndexes.has(row.__virtualIndex)\"\r\n [class.first-row-selected]=\"firstSelectedRow === row.__virtualIndex\"\r\n [class.last-row-selected]=\"lastSelectedRow === row.__virtualIndex\"\r\n >\r\n <span\r\n (click)=\"toggleDetailRowExpand(row)\"\r\n *ngIf=\"row?.detail?.result?.length || gridType === 'Tasks'\"\r\n class=\"data-grid-svg-icon filter-icon-wrapper\"\r\n [inlineSVG]=\"\r\n isDetailsExpanded(row)\r\n ? singleSpaAssetsPath + 'data-grid/icons/chevron-down.svg'\r\n : singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\r\n \"\r\n ></span>\r\n </span>\r\n <div\r\n [style.min-width.px]=\"\r\n section == 'center' && groupedColumns?.length ? groupBoxPadding : 0\r\n \"\r\n [class.row-selected]=\"rowSelectedIndexes.has(row.__virtualIndex)\"\r\n [class.first-row-selected]=\"firstSelectedRow === row.__virtualIndex\"\r\n [class.last-row-selected]=\"lastSelectedRow === row.__virtualIndex\"\r\n (contextmenu)=\"onRightClick($event, row)\"\r\n [style.height.px]=\"rowHeight\"\r\n class=\"data-grid-row h-100\"\r\n [class.even-row]=\"isEven\"\r\n [class.odd-row]=\"isOdd\"\r\n [class.hovered-row]=\"hoveredRowId === (row._id || row.id)\"\r\n (mouseenter)=\"onRowHover(row)\"\r\n (mouseleave)=\"onRowLeave()\"\r\n [ngStyle]=\"{\r\n 'background-color': getBackgroundColor(row, isEven, section)\r\n }\"\r\n [style.minHeight.px]=\"rowHeight\"\r\n [style.maxHeight.px]=\"rowHeight\"\r\n ></div>\r\n <div\r\n (contextmenu)=\"onRightClick($event, row)\"\r\n [style.height.px]=\"rowHeight\"\r\n class=\"data-grid-row\"\r\n [class.even-row]=\"isEven\"\r\n [class.odd-row]=\"isOdd\"\r\n [class.hovered-row]=\"hoveredRowId === (row._id || row.id)\"\r\n (mouseenter)=\"onRowHover(row)\"\r\n (mouseleave)=\"onRowLeave()\"\r\n [ngStyle]=\"{\r\n 'background-color': getBackgroundColor(row, isEven, section)\r\n }\"\r\n >\r\n <div\r\n [style.backgroundColor]=\"checkboxesBackgroundColor\"\r\n class=\"select-all-checkbox-cell justify-content-end pe-2 s-no\"\r\n [style.width.px]=\"55\"\r\n *ngIf=\"isLeftSection && showSerialNumber\"\r\n [style.cursor]=\"\r\n 'url(' +\r\n singleSpaAssetsPath +\r\n 'data-grid/icons/arrow-right.svg), auto'\r\n \"\r\n (mousedown)=\"onRowMouseDown(row.__virtualIndex, $event)\"\r\n (mouseover)=\"onRowMouseOver(row.__virtualIndex, $event)\"\r\n [style.color]=\"checkboxesColor\"\r\n >\r\n {{ getStartIndex() + (row.__virtualIndex - 1) }}\r\n </div>\r\n <div\r\n [style.backgroundColor]=\"\r\n rowSelectedIndexes.has(row.__virtualIndex)\r\n ? selectedRowsBackgroundColor\r\n : checkboxesBackgroundColor\r\n \"\r\n class=\"select-all-checkbox-cell\"\r\n *ngIf=\"isLeftSection && showCheckboxes\"\r\n [class.left-selection-border]=\"\r\n rowSelectedIndexes.has(row.__virtualIndex)\r\n \"\r\n [class.first-row-selected]=\"firstSelectedRow === row.__virtualIndex\"\r\n [class.last-row-selected]=\"lastSelectedRow === row.__virtualIndex\"\r\n [style.minHeight.px]=\"rowHeight - 1\"\r\n [style.maxHeight.px]=\"rowHeight\"\r\n >\r\n <input\r\n *ngIf=\"hasAnyVisibleColumn\"\r\n style=\"width: 16px; height: 16px\"\r\n type=\"checkbox\"\r\n [checked]=\"isRowSelected(row)\"\r\n (change)=\"toggleRowSelection(row)\"\r\n />\r\n </div>\r\n\r\n <!-- Render all columns -->\r\n <ng-container\r\n *ngFor=\"\r\n let col of columns;\r\n trackBy: trackByField;\r\n let colIndex = index\r\n \"\r\n >\r\n <ng-container *ngIf=\"col.children?.length > 0; else flatColumn\">\r\n <ng-container\r\n *ngFor=\"\r\n let child of col.children;\r\n trackBy: trackByField;\r\n let subColIndex = index\r\n \"\r\n >\r\n <ng-container *ngIf=\"child?.is_visible && !child?.isRowGrouped\">\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n cellTemplate;\r\n context: {\r\n col: child,\r\n row: row,\r\n rowIndex: rowIndex,\r\n colIndex: colIndex,\r\n subColIndex: subColIndex,\r\n section: section,\r\n isTotalRow: isTotalRow\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </ng-container>\r\n </ng-container>\r\n\r\n <ng-template #flatColumn>\r\n <ng-container *ngIf=\"col?.is_visible && !col?.isRowGrouped\">\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n cellTemplate;\r\n context: {\r\n col: col,\r\n row: row,\r\n rowIndex: rowIndex,\r\n colIndex: colIndex,\r\n subColIndex: null,\r\n section: section,\r\n isTotalRow: isTotalRow\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </ng-template>\r\n </ng-container>\r\n </div>\r\n </div>\r\n\r\n <div\r\n [@slideToggle]\r\n *ngIf=\"section === 'left' && isDetailsExpanded(row)\"\r\n class=\"accordion-details\"\r\n style=\"max-height: 350px; overflow: hidden\"\r\n [style.maxHeight.px]=\"hasHorizontalScroll ? 339 : 341\"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n leftRightNestedPlaceholder;\r\n context: { $implicit: row }\r\n \"\r\n >\r\n </ng-container>\r\n </div>\r\n\r\n <div\r\n [@slideToggle]\r\n *ngIf=\"section === 'center' && isDetailsExpanded(row)\"\r\n class=\"accordion-details center-section\"\r\n style=\"\r\n max-height: 350px;\r\n overflow-y: hidden;\r\n overflow-x: auto;\r\n scrollbar-width: thin;\r\n \"\r\n #nestedTable\r\n [style.width]=\"\r\n hasRightPinnedColumns\r\n ? '100%'\r\n : hasVerticalScroll\r\n ? 'calc(100% - 12px)'\r\n : '100%'\r\n \"\r\n >\r\n <ng-container *ngIf=\"gridType == 'Assets'\">\r\n <ng-container\r\n *ngTemplateOutlet=\"nestedTableTemplate; context: { $implicit: row }\"\r\n ></ng-container>\r\n </ng-container>\r\n <ng-container *ngIf=\"gridType == 'Tasks'\">\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n taskManagementTemplate;\r\n context: { taskDetails: row }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </div>\r\n\r\n <div\r\n [@slideToggle]\r\n *ngIf=\"section === 'right' && isDetailsExpanded(row)\"\r\n class=\"accordion-details\"\r\n style=\"max-height: 350px; overflow: hidden\"\r\n [style.maxHeight.px]=\"hasHorizontalScroll ? 339 : 341\"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n leftRightNestedPlaceholder;\r\n context: { $implicit: row }\r\n \"\r\n >\r\n </ng-container>\r\n </div>\r\n </ng-template>\r\n</ng-template>\r\n\r\n<!-- Actual Cell is Here -->\r\n<ng-template\r\n #cellTemplate\r\n let-col=\"col\"\r\n let-row=\"row\"\r\n let-section=\"section\"\r\n let-subColIndex=\"subColIndex\"\r\n let-rowIndex=\"rowIndex\"\r\n let-colIndex=\"colIndex\"\r\n let-isTotalRow=\"isTotalRow\"\r\n>\r\n <div\r\n #cellContainer\r\n (click)=\"\r\n editingKey = ''; setActiveCell(row, col); collapseAllExpandedCells()\r\n \"\r\n [style.fontWeight]=\"bodyFontWeight\"\r\n [class.border-right]=\"showVerticalBorder\"\r\n class=\"cell overflow-visible position-relative data-grid-cell\"\r\n [attr.field]=\"col.field\"\r\n [style.width.px]=\"col.width\"\r\n [style.min-width.px]=\"col.width\"\r\n [style.fontSize.px]=\"bodyTextFontsSize\"\r\n [style.minHeight.px]=\"rowHeight\"\r\n [style.maxHeight.px]=\"rowHeight\"\r\n [class.active-cell]=\"\r\n isActiveCell(row, col) && !isEditing(row, col) && selectedKeys.size == 1\r\n \"\r\n (dblclick)=\"\r\n $event.stopPropagation();\r\n $event.preventDefault();\r\n enableEdit(row, col, false, cellContainer)\r\n \"\r\n [class.row-selected]=\"rowSelectedIndexes.has(row.__virtualIndex)\"\r\n [class.first-row-selected]=\"firstSelectedRow === row?.__virtualIndex\"\r\n [class.last-row-selected]=\"lastSelectedRow === row?.__virtualIndex\"\r\n tabindex=\"-1\"\r\n (keydown.enter)=\"$event.preventDefault(); enableEdit(row, col)\"\r\n (mousedown)=\"\r\n startSelection(\r\n row.__virtualIndex,\r\n colIndex,\r\n subColIndex ?? 0,\r\n col.field,\r\n $event,\r\n section\r\n )\r\n \"\r\n (mouseenter)=\"\r\n extendSelection(\r\n row.__virtualIndex,\r\n colIndex,\r\n subColIndex ?? 0,\r\n col.field,\r\n $event,\r\n section\r\n )\r\n \"\r\n (mouseup)=\"endSelection()\"\r\n [class.selected-cell]=\"\r\n isSelected(\r\n row.__virtualIndex,\r\n colIndex,\r\n subColIndex ?? 0,\r\n col.field,\r\n section\r\n )\r\n \"\r\n [class.top-border]=\"\r\n isTopBorder(row.__virtualIndex, colIndex, subColIndex, section)\r\n \"\r\n [class.bottom-border]=\"\r\n isBottomBorder(row.__virtualIndex, colIndex, subColIndex, section)\r\n \"\r\n [class.left-border]=\"\r\n isLeftBorder(row.__virtualIndex, colIndex, subColIndex, section)\r\n \"\r\n [class.right-border]=\"\r\n isRightBorder(row.__virtualIndex, colIndex, subColIndex, section)\r\n \"\r\n [class.top-left-corner]=\"\r\n isTopLeftCorner(row.__virtualIndex, colIndex, subColIndex, section)\r\n \"\r\n [class.top-right-corner]=\"\r\n isTopRightCorner(row.__virtualIndex, colIndex, subColIndex, section)\r\n \"\r\n [class.bottom-left-corner]=\"\r\n isBottomLeftCorner(row.__virtualIndex, colIndex, subColIndex, section)\r\n \"\r\n [class.bottom-right-corner]=\"\r\n isBottomRightCorner(row.__virtualIndex, colIndex, subColIndex, section)\r\n \"\r\n >\r\n <!-- (mousedown)=\"startSelection(row.__virtualIndex, colIndex, subColIndex ?? 0, col.field, $event)\"\r\n (mouseenter)=\"extendSelection(row.__virtualIndex, colIndex, subColIndex ?? 0, col.field, $event)\"\r\n (mouseup)=\"endSelection()\"\r\n [class.selected-cell]=\"isSelected(row.__virtualIndex, colIndex, subColIndex ?? 0, col.field)\" -->\r\n <div\r\n class=\"table-cell\"\r\n [class.active-for-editing]=\"\r\n isEditing(row, col) &&\r\n (getNestedValue(row, col.field)?.length === undefined ||\r\n getNestedValue(row, col.field)?.length <= 50)\r\n \"\r\n >\r\n <div\r\n (click)=\"$event.stopPropagation()\"\r\n *ngIf=\"\r\n isEditing(row, col) &&\r\n (getNestedValue(row, col.field)?.length === undefined ||\r\n (getNestedValue(row, col.field)?.length <= 50 &&\r\n !expandedCells.size));\r\n else viewMode\r\n \"\r\n >\r\n\r\n <ng-container *ngIf=\"col.cellEditor; else builtInEditors\">\r\n <ng-container\r\n [cellEditor]=\"col.cellEditor\"\r\n [rowData]=\"row\"\r\n [colData]=\"col\"\r\n [cellValue]=\"getNestedValue(row, col.field)\"\r\n (editorEvent)=\"finishEdit($event)\"\r\n ></ng-container>\r\n </ng-container>\r\n\r\n <ng-template #builtInEditors>\r\n <ng-container [ngSwitch]=\"col?.type\">\r\n <!-- Text Input -->\r\n <input\r\n [style.height.px]=\"rowHeight - 10\"\r\n *ngSwitchCase=\"'input'\"\r\n type=\"text\"\r\n [(ngModel)]=\"row[col.field]\"\r\n (blur)=\"disableEdit(row, col)\"\r\n autofocus\r\n (keydown.enter)=\"blurInput($event, row, col)\"\r\n class=\"form-control form-control-sm\"\r\n (mousedown)=\"$event.stopPropagation()\"\r\n />\r\n\r\n <!-- Number Input -->\r\n <input\r\n [style.height.px]=\"rowHeight - 8\"\r\n *ngSwitchCase=\"'number'\"\r\n #numberInput=\"ngModel\"\r\n #numberRef\r\n (keypress)=\"allowOnlyNumbers($event)\"\r\n type=\"number\"\r\n required\r\n [(ngModel)]=\"row[col.field]\"\r\n (blur)=\"disableEdit(row, col, numberInput)\"\r\n autofocus\r\n (keydown.enter)=\"blurInput($event, row, col)\"\r\n class=\"form-control form-control-sm\"\r\n [ngClass]=\"{\r\n 'is-invalid': numberInput.invalid\r\n }\"\r\n (mousedown)=\"$event.stopPropagation()\"\r\n />\r\n\r\n <!-- Date Input -->\r\n <input\r\n [style.height.px]=\"rowHeight - 8\"\r\n *ngSwitchCase=\"'date'\"\r\n type=\"date\"\r\n [(ngModel)]=\"row[col.field]\"\r\n (blur)=\"disableEdit(row, col, dateInput)\"\r\n autofocus\r\n class=\"form-control form-control-sm\"\r\n #dateInput=\"ngModel\"\r\n (keydown.enter)=\"blurInput($event, row, col)\"\r\n [ngClass]=\"{\r\n 'is-invalid': dateInput.invalid\r\n }\"\r\n (mousedown)=\"$event.stopPropagation()\"\r\n />\r\n\r\n <!-- Dropdown -->\r\n <!-- ng-select like dropdown -->\r\n <div\r\n *ngSwitchCase=\"'dropdown'\"\r\n class=\"dropdown w-100\"\r\n (blur)=\"disableEdit(row, col)\"\r\n >\r\n <!-- Trigger -->\r\n <button\r\n class=\"form-select form-select-sm text-start w-100 text-ellipsis\"\r\n type=\"button\"\r\n data-bs-toggle=\"dropdown\"\r\n aria-expanded=\"false\"\r\n [style.minHeight.px]=\"rowHeight - 10\"\r\n data-bs-display=\"static\"\r\n (mousedown)=\"$event.stopPropagation()\"\r\n >\r\n <ng-container>\r\n {{\r\n getNestedValue(row, col.field)?.value ||\r\n getNestedValue(row, col.field)?.name ||\r\n getNestedValue(row, col.field)\r\n }}\r\n </ng-container>\r\n <ng-template #placeholder> Select options... </ng-template>\r\n </button>\r\n\r\n <!-- Menu -->\r\n <div\r\n class=\"dropdown-menu w-100 p-0 cell-editing-dropdown-menu rounded-3\"\r\n [class.show]=\"isEditing(row, col)\"\r\n >\r\n <!-- Search -->\r\n <div class=\"px-2 py-1 editing-dropdown-search-input\" *ngIf=\"col?.column_dropdown_value?.length > 5\">\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Search...\"\r\n [(ngModel)]=\"editinDropdownSearch\"\r\n (mousedown)=\"$event.stopPropagation()\"\r\n />\r\n </div>\r\n <cdk-virtual-scroll-viewport \r\n itemSize=\"35\" \r\n class=\"dropdown-viewport\"\r\n style=\"height: 120px\"\r\n >\r\n <div\r\n [class.selected]=\"getNestedValue(row, col.field) == option?.value || getNestedValue(row, col.field) == option\"\r\n class=\"px-2 py-1 d-flex align-items-center dropdown-item\"\r\n *cdkVirtualFor=\"\r\n let option of col.column_dropdown_value \r\n | filter : editinDropdownSearch : 'value'\r\n \"\r\n (click)=\"setNestedValue(row, col, option, true); editingKey = null\"\r\n >\r\n <label\r\n \r\n class=\"form-check-label d-flex align-items-center mb-0 cursor-pointer\"\r\n [for]=\"col.field + '-' + (option.value || option)\"\r\n >\r\n {{ option.value || option }}\r\n </label>\r\n </div>\r\n </cdk-virtual-scroll-viewport>\r\n\r\n </div>\r\n </div>\r\n\r\n <input\r\n *ngSwitchCase=\"'email'\"\r\n [style.height.px]=\"rowHeight - 10\"\r\n [style.maxHeight.px]=\"rowHeight - 10\"\r\n #emailModel=\"ngModel\"\r\n #emailInput\r\n type=\"email\"\r\n [(ngModel)]=\"row[col.field]\"\r\n name=\"{{ col.field }}\"\r\n required\r\n pattern=\"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$\"\r\n (blur)=\"disableEdit(row, col, emailModel)\"\r\n (keydown.enter)=\"blurInput($event, row, col)\"\r\n autofocus\r\n class=\"form-control form-control-sm\"\r\n [ngClass]=\"{\r\n 'is-invalid': emailModel.invalid\r\n }\"\r\n (mousedown)=\"$event.stopPropagation()\"\r\n />\r\n <!-- Default fallback -->\r\n <input\r\n *ngSwitchDefault\r\n [style.height.px]=\"rowHeight - 10\"\r\n [style.maxHeight.px]=\"rowHeight - 10\"\r\n #textModel=\"ngModel\"\r\n #textInput\r\n type=\"text\"\r\n (keydown.enter)=\"blurInput($event, row, col)\"\r\n [(ngModel)]=\"row[col.field]\"\r\n name=\"{{ col.field }}\"\r\n required\r\n (blur)=\"disableEdit(row, col, textModel)\"\r\n autofocus\r\n class=\"form-control form-control-sm\"\r\n [ngClass]=\"{\r\n 'is-invalid': textModel.invalid\r\n }\"\r\n (mousedown)=\"$event.stopPropagation()\"\r\n />\r\n </ng-container>\r\n </ng-template>\r\n\r\n </div>\r\n\r\n <!-- Display mode -->\r\n <ng-template #viewMode>\r\n <div\r\n class=\"d-flex justify-content-between align-items-center w-100 overflow-hidden\"\r\n [ngClass]=\"getCellClasses(col, getNestedValue(row, col.field))\"\r\n >\r\n <!-- Field icon (for Tasks grid) -->\r\n <ng-container\r\n *ngIf=\"gridType === 'Tasks' && iconMap[col.field] && !isTotalRow\"\r\n >\r\n <span\r\n class=\"cursor-pointer me-2\"\r\n (click)=\"$event.preventDefault(); $event.stopPropagation()\"\r\n [inlineSVG]=\"iconMap[col.field](row, col)\"\r\n ></span>\r\n </ng-container>\r\n\r\n <!-- \u2705 Custom cell renderer support -->\r\n <ng-container *ngIf=\"col.cellRenderer; else defaultCell\">\r\n <ng-container\r\n [cellRenderInit]=\"col.cellRenderer\"\r\n [rowData]=\"row\"\r\n [colData]=\"col\"\r\n [cellValue]=\"getNestedValue(row, col?.field)\"\r\n (cellEvent)=\"onCellEvent($event)\"\r\n >\r\n </ng-container>\r\n </ng-container>\r\n\r\n <!-- \uD83E\uDDFE Default text-based cell rendering -->\r\n <ng-template #defaultCell>\r\n <div\r\n #cellText\r\n class=\"text-ellipsis flex-grow-1\"\r\n [title]=\"getCellTitle(row, col)\"\r\n >\r\n <!-- Normal cell -->\r\n <ng-container\r\n *ngIf=\"\r\n col?.type !== 'image' &&\r\n col?.field != 'image' &&\r\n col?.field != 'invoice.invoice_image' &&\r\n !isTotalRow\r\n \"\r\n >\r\n <ng-container *ngIf=\"col.is_amount\">{{\r\n currencySymbol\r\n }}</ng-container>\r\n {{getCellTitle(row, col)}}\r\n </ng-container>\r\n\r\n <!-- Total row -->\r\n <ng-container *ngIf=\"isTotalRow\">\r\n {{ getTotalAmount(col) }}\r\n </ng-container>\r\n\r\n <!-- Invoice Image -->\r\n <ng-container *ngIf=\"col.field == 'invoice.invoice_image'\">\r\n <div style=\"display: flex; align-items: center; zoom: 0.7\">\r\n <span\r\n title=\"{{ getNestedValue(row, col.field) || 'Attachment' }}\"\r\n (click)=\"downloadAttchment(getNestedValue(row, col.field))\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath +\r\n 'data-grid/document-icons/' +\r\n getExtention(getNestedValue(row, col.field)) +\r\n '.svg'\r\n \"\r\n ></span>\r\n </div>\r\n </ng-container>\r\n\r\n <!-- Image cell -->\r\n <ng-container *ngIf=\"col?.type == 'image' && !isTotalRow\">\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n defaultImagePlaceholder;\r\n context: { row: row, col: col }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </div>\r\n <span\r\n *ngIf=\"\r\n (!col?.cellRenderer && showCellDetailsBox &&\r\n getNestedValue(row, col.field)?.length > 50 && col?.type !== 'image') ||\r\n (isNestedValueArray(row, col.field) &&\r\n getNestedValue(row, col.field)?.length > 1)\r\n \"\r\n class=\"toggle-icon data-grid-svg-icon ms-2 cursor-pointer\"\r\n [inlineSVG]=\"\r\n isExpanded(row, col)\r\n ? singleSpaAssetsPath + 'data-grid/icons/chevron-down.svg'\r\n : singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\r\n \"\r\n (click)=\"\r\n $event.stopPropagation();\r\n toggleExpandOfLongCellText(row, col, columns, true)\r\n \"\r\n (dblclick)=\"$event.preventDefault(); $event.stopPropagation()\"\r\n ></span>\r\n </ng-template>\r\n <!-- Expand / Collapse icon -->\r\n </div>\r\n\r\n <!-- Expanded text -->\r\n <div\r\n class=\"position-absolute w-100 expanded-box\"\r\n *ngIf=\"isExpanded(row, col)\"\r\n [style.zIndex]=\"getZIndex(row, col)\"\r\n style=\"top: 100%; left: 0\"\r\n [attr.id]=\"(row.id || row._id) + '-' + (col.id || col._id)\"\r\n [class.invisible]=\"!showDetailsBox\"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n fullTextTemplate;\r\n context: {\r\n row: row,\r\n col: col,\r\n isArray: isNestedValueArray(row, col.field)\r\n }\r\n \"\r\n ></ng-container>\r\n </div>\r\n </ng-template>\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<!-- Headers Action List On clicking three dots -->\r\n\r\n<ng-template\r\n #columnMenu\r\n let-col=\"col\"\r\n let-isNestedTable=\"isNestedTable\"\r\n let-columns=\"columns\"\r\n let-section=\"section\"\r\n let-columnIndex=\"columnIndex\"\r\n let-childColIndex=\"childColIndex\"\r\n>\r\n <div\r\n class=\"column-menu three-dots-col-menu\"\r\n [class.visually-hidden]=\"isMenueHidden\"\r\n *ngIf=\"activeCol && !isThreeDotsFilterOpen\"\r\n [style.backgroundColor]=\"dropdownsBackgroundColor\"\r\n (click)=\"$event.stopPropagation()\"\r\n [style.color]=\"headerTextColor\"\r\n >\r\n <!-- Sort Ascending -->\r\n <div class=\"border-below pb-2\" [class.disable-sorting]=\"!col.is_sortable\">\r\n <span class=\"muted-text fs-7\" style=\"margin-left: 12px\">Sort</span>\r\n <div\r\n *ngIf=\"\r\n columnThreedotsMunuConfig?.showAscending &&\r\n (sortingConfig?.field != col.field ||\r\n sortingConfig?.order_by == 'desc')\r\n \"\r\n class=\"column-menu-item\"\r\n (click)=\"sortAsc(activeCol)\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrow-up.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n Sort Ascending\r\n </div>\r\n\r\n <!-- Sort Descending -->\r\n <div\r\n *ngIf=\"\r\n columnThreedotsMunuConfig?.showDescending &&\r\n (sortingConfig?.field != col.field ||\r\n sortingConfig?.order_by == 'asc')\r\n \"\r\n class=\"column-menu-item\"\r\n (click)=\"sortDesc(activeCol)\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrow-down.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n Sort Descending\r\n </div>\r\n\r\n <div\r\n *ngIf=\"\r\n sortingConfig?.field === col.field &&\r\n (sortingConfig?.order_by === 'asc' ||\r\n sortingConfig?.order_by === 'desc')\r\n \"\r\n class=\"column-menu-item\"\r\n (click)=\"resetSort(activeCol)\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/arrow-counterclockwise.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n Reset Sort\r\n </div>\r\n </div>\r\n <div class=\"py-2 border-below three-dots-filter\" [class.disable-sorting]=\"col?.type == 'image' || !col.is_search_able\">\r\n <div\r\n *ngIf=\"columnThreedotsMunuConfig?.showFilter\"\r\n class=\"column-menu-item three-dots-filter\"\r\n (click)=\"openFilteronThreeDotsClick(col)\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n Filter\r\n </div>\r\n </div>\r\n\r\n <div class=\"py-2 border-below\">\r\n <span class=\"muted-text fs-7\" style=\"margin-left: 12px\">Pin</span>\r\n <div\r\n *ngIf=\"columnThreedotsMunuConfig?.showPinleft && col?.pinned !== 'left'\"\r\n class=\"column-menu-item\"\r\n (click)=\"\r\n $event.stopPropagation();\r\n updateColumnPinInSourceByField(\r\n activeCol,\r\n 'left',\r\n isNestedTable,\r\n columns\r\n )\r\n \"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/pin-left.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span\r\n >Pin Left\r\n </div>\r\n\r\n <div\r\n *ngIf=\"\r\n columnThreedotsMunuConfig?.showPinright && col?.pinned !== 'right'\r\n \"\r\n class=\"column-menu-item\"\r\n (click)=\"\r\n $event.stopPropagation();\r\n updateColumnPinInSourceByField(\r\n activeCol,\r\n 'right',\r\n isNestedTable,\r\n columns\r\n )\r\n \"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/pin-right.svg'\"\r\n class=\"data-grid-svg-icon data-grid-svg-icon me-2\"\r\n ></span\r\n >Pin Right\r\n </div>\r\n\r\n <div\r\n *ngIf=\"col?.pinned\"\r\n class=\"column-menu-item\"\r\n (click)=\"\r\n $event.stopPropagation();\r\n updateColumnPinInSourceByField(\r\n activeCol,\r\n null,\r\n isNestedTable,\r\n columns\r\n )\r\n \"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/layout-three-columns.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span\r\n >Unpin\r\n </div>\r\n </div>\r\n\r\n <div\r\n *ngIf=\"columnThreedotsMunuConfig?.showAutosizeThisColumn\"\r\n class=\"column-menu-item\"\r\n (click)=\"autosizeColumn(activeCol)\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/arrows-expand-vertical.svg'\r\n \"\r\n class=\"me-2\"\r\n ></span>\r\n Autosize This Column\r\n </div>\r\n\r\n <!-- Autosize All Columns -->\r\n <div\r\n *ngIf=\"columnThreedotsMunuConfig?.showAutosizeAllColumns\"\r\n class=\"column-menu-item\"\r\n (click)=\"autosizeAllColumns()\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/arrows-angle-expand.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span\r\n >Autosize All Columns\r\n </div>\r\n\r\n <!-- Group By -->\r\n <div\r\n *ngIf=\"showRowsGrouping\"\r\n class=\"column-menu-item\"\r\n (click)=\"groupBy(activeCol)\"\r\n [class.disable-sorting]=\"!col.is_groupable\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/diagram-3.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n Group by {{ col.header }}\r\n </div>\r\n\r\n <!-- Choose Columns -->\r\n <div\r\n *ngIf=\"columnThreedotsMunuConfig?.showChoseColumns\"\r\n class=\"column-menu-item\"\r\n (click)=\"chooseColumns()\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/ui-checks-grid.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n Choose Columns\r\n </div>\r\n\r\n <!-- Reset Columns -->\r\n <div\r\n *ngIf=\"columnThreedotsMunuConfig?.showResetColumns\"\r\n class=\"column-menu-item\"\r\n (click)=\"resetColumns()\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/arrow-counterclockwise.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span\r\n >Reset Columns\r\n </div>\r\n </div>\r\n <div\r\n @slideToggle\r\n *ngIf=\"isThreeDotsFilterOpen && col?.is_search_able\"\r\n class=\"three-dots-col-menu position-relative\"\r\n [style.right.px]=\"getDynamicRight(col, section, columnIndex, childColIndex)\"\r\n [class.visually-hidden]=\"isMenueHidden\"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"filterMenu; context: { col: col }\"\r\n ></ng-container>\r\n </div>\r\n</ng-template>\r\n\r\n<!-- Filter Menue -->\r\n<ng-template #filterMenu let-col=\"col\">\r\n <div\r\n class=\"filter-menu-container filter-menu\"\r\n [style.backgroundColor]=\"dropdownsBackgroundColor\"\r\n >\r\n <!-- Dropdown Type -->\r\n <ng-container *ngIf=\"col?.type === 'dropdown' || col?.type === 'array'; else textFilter\">\r\n <div class=\"filter-dropdown-section p-1\">\r\n\r\n <!-- Search input -->\r\n <input\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Search...\"\r\n type=\"search\"\r\n [(ngModel)]=\"addFilterColumnInput\"\r\n />\r\n\r\n <!-- Filter + Result Handling -->\r\n <ng-container\r\n *ngIf=\"\r\n (selectedColumnForFilter?.column_dropdown_value\r\n | filter : addFilterColumnInput : 'value') as filteredOptions\r\n \"\r\n >\r\n\r\n <!-- DATA FOUND -->\r\n <ng-container *ngIf=\"filteredOptions.length; else noDataFound\">\r\n\r\n <!-- Select All (only when data exists) -->\r\n <div class=\"form-check mb-1 mt-2 ms-1 select-all-filter\">\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n [checked]=\"\r\n (currentFilterSelectedIds?.size ?? 0) ===\r\n (selectedColumnForFilter?.column_dropdown_value?.length ?? 0)\r\n \"\r\n [indeterminate]=\"\r\n (currentFilterSelectedIds?.size ?? 0) > 0 &&\r\n (currentFilterSelectedIds?.size ?? 0) <\r\n (selectedColumnForFilter?.column_dropdown_value?.length ?? 0)\r\n \"\r\n (change)=\"toggleSelectAllSideFilters(col, $event)\"\r\n id=\"selectAll_{{ col.field }}\"\r\n />\r\n\r\n <label class=\"form-check-label\" for=\"selectAll_{{ col.field }}\">\r\n Select All\r\n </label>\r\n </div>\r\n\r\n <!-- Virtual Scroll -->\r\n <cdk-virtual-scroll-viewport\r\n itemSize=\"32\"\r\n class=\"filter-viewport\"\r\n style=\"height: 120px\"\r\n >\r\n <div\r\n class=\"form-check mb-1 ms-1\"\r\n *cdkVirtualFor=\"let option of filteredOptions; trackBy: trackById\"\r\n >\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n [id]=\"option?.id ?? option?._id ?? option\"\r\n [checked]=\"\r\n currentFilterSelectedIds.has(option?.id ?? option?._id ?? option)\r\n \"\r\n (change)=\"toggleSelectionInFilter(option)\"\r\n />\r\n\r\n <label\r\n class=\"form-check-label fw-semibold\"\r\n [for]=\"option?.id ?? option?._id ?? option\"\r\n >\r\n {{ (option?.value ?? option?.name ?? option) | titlecase }}\r\n </label>\r\n </div>\r\n </cdk-virtual-scroll-viewport>\r\n\r\n </ng-container>\r\n\r\n <!-- NO DATA FOUND -->\r\n <ng-template #noDataFound>\r\n <div\r\n class=\"text-center text-muted mt-2\"\r\n *ngIf=\"addFilterColumnInput\"\r\n >\r\n No Record Found\r\n </div>\r\n </ng-template>\r\n\r\n </ng-container>\r\n </div>\r\n</ng-container>\r\n\r\n\r\n <!-- Text Filter Section -->\r\n <ng-template #textFilter>\r\n <div class=\"filter-text-section\">\r\n <div class=\"form-group mb-2\">\r\n <select\r\n class=\"form-select form-select-sm custom-select\"\r\n [(ngModel)]=\"firstCondition\"\r\n >\r\n <ng-container *ngIf=\"selectedColumnForFilter?.type == 'string'\">\r\n <option value=\"contain\">Contains</option>\r\n <option value=\"does_not_contain\">Does Not Contain</option>\r\n <option value=\"equal\">Equals</option>\r\n <option value=\"before\">Starts With</option>\r\n <option value=\"after\">Ends With</option>\r\n </ng-container>\r\n\r\n <ng-container *ngIf=\"selectedColumnForFilter?.type == 'date' || selectedColumnForFilter?.type == 'time'\">\r\n <option value=\"equal\">Equals To</option>\r\n <option value=\"not_equal\">Not Equal</option>\r\n <option value=\"after\">After</option>\r\n <option value=\"before\">Before</option>\r\n </ng-container>\r\n\r\n <ng-container *ngIf=\"selectedColumnForFilter?.type == 'number'\">\r\n <option value=\"equal\">Equals To</option>\r\n <option value=\"before\">Less Then </option>\r\n <option value=\"after\">Greater Then </option>\r\n <option value=\"less_then_equal\">less then Equal to</option>\r\n <option value=\"greater_then_equal\">Greater then Equal to </option>\r\n </ng-container>\r\n </select>\r\n </div>\r\n\r\n <input\r\n [type]=\"col?.type == 'string' ? 'text' : col?.type\"\r\n class=\"form-control form-control-sm mb-3\"\r\n placeholder=\"Value\"\r\n [(ngModel)]=\"firstValue\"\r\n #filterMenueTextchInput\r\n (keydown.enter)=\"applyDropdownFilter()\"\r\n />\r\n\r\n <div class=\"form-group mb-3 d-flex flex-row\">\r\n <div\r\n class=\"form-check form-check-inline m-0 col-4 d-flex align-items-center gap-1\"\r\n >\r\n <input\r\n class=\"form-check-input filter-radio-inputs\"\r\n type=\"radio\"\r\n name=\"condition\"\r\n [(ngModel)]=\"condition\"\r\n value=\"and\"\r\n id=\"and_{{ col.field }}\"\r\n (change)=\"cdr.detectChanges()\"\r\n />\r\n <label class=\"form-check-label mb-0 mt-1\" for=\"and_{{ col.field }}\"\r\n >AND</label\r\n >\r\n </div>\r\n <div\r\n class=\"form-check form-check-inline m-0 col-4 d-flex align-items-center gap-1 gap-1\"\r\n >\r\n <input\r\n class=\"form-check-input filter-radio-inputs\"\r\n type=\"radio\"\r\n name=\"condition\"\r\n [(ngModel)]=\"condition\"\r\n value=\"or\"\r\n id=\"or_{{ col.field }}\"\r\n (change)=\"cdr.detectChanges()\"\r\n />\r\n <label class=\"form-check-label mb-0 mt-1\" for=\"or_{{ col.field }}\"\r\n >OR</label\r\n >\r\n </div>\r\n <div\r\n class=\"form-check form-check-inline m-0 col-4 d-flex align-items-center gap-1 gap-1\"\r\n >\r\n <input\r\n class=\"form-check-input filter-radio-inputs\"\r\n type=\"radio\"\r\n name=\"condition\"\r\n [(ngModel)]=\"condition\"\r\n value=\"none\"\r\n id=\"none_{{ col.field }}\"\r\n (change)=\"cdr.detectChanges()\"\r\n />\r\n <label class=\"form-check-label mb-0 mt-1\" for=\"none_{{ col.field }}\"\r\n >None</label\r\n >\r\n </div>\r\n </div>\r\n <div @slideToggle *ngIf=\"firstValue && condition != 'none'\">\r\n <div class=\"form-group mb-2\">\r\n <select\r\n class=\"form-select form-select-sm custom-select\"\r\n [(ngModel)]=\"secondCondition\"\r\n >\r\n <ng-container *ngIf=\"selectedColumnForFilter?.type == 'string'\">\r\n <option value=\"contain\">Contains</option>\r\n <option value=\"does_not_contain\">Does Not Contain</option>\r\n <option value=\"equal\">Equals</option>\r\n <option value=\"before\">Starts With</option>\r\n <option value=\"after\">Ends With</option>\r\n </ng-container>\r\n\r\n <ng-container *ngIf=\"selectedColumnForFilter?.type == 'date' || selectedColumnForFilter?.type == 'time'\">\r\n <option value=\"equal\">Equals To</option>\r\n <option value=\"not_equal\">Not Equal</option>\r\n <option value=\"after\">After</option>\r\n <option value=\"before\">Before</option>\r\n </ng-container>\r\n\r\n <ng-container *ngIf=\"selectedColumnForFilter?.type == 'number'\">\r\n <option value=\"equal\">Equals To</option>\r\n <option value=\"before\">Less Then </option>\r\n <option value=\"after\">Greater Then </option>\r\n <option value=\"less_then_equal\">less then Equal to</option>\r\n <option value=\"greater_then_equal\">Greater then Equal to </option>\r\n </ng-container>\r\n </select>\r\n </div>\r\n\r\n <input\r\n [type]=\"col?.type == 'string' ? 'text' : col?.type\"\r\n class=\"form-control form-control-sm mb-3\"\r\n placeholder=\"Second Value\"\r\n [(ngModel)]=\"secondValue\"\r\n />\r\n </div>\r\n </div>\r\n </ng-template>\r\n\r\n <!-- Actions -->\r\n <div class=\"d-flex gap-2 mt-2\">\r\n <div\r\n class=\"btn btn-sm btn-primary d-flex justify-content-center align-items-center w-100\"\r\n style=\"height: 30px\"\r\n (click)=\"applyDropdownFilter()\"\r\n >\r\n Apply\r\n </div>\r\n <div\r\n class=\"btn btn-sm btn-secondary d-flex justify-content-center align-items-center w-100\"\r\n style=\"height: 30px\"\r\n (click)=\"resetSideFilter(col)\"\r\n >\r\n Reset\r\n </div>\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<!-- Side Menue -->\r\n\r\n<!-- Column Pannel / Pivot Mode / Searching -->\r\n\r\n<ng-template #columnPannel>\r\n <div class=\"column-panel-header\">\r\n <!-- Pivot Toggle -->\r\n <div\r\n class=\"form-check form-switch d-flex align-items-center mb-2 pivot-mode px-5 ms-2 d-none\"\r\n >\r\n <input\r\n class=\"form-check-input me-2\"\r\n type=\"checkbox\"\r\n id=\"pivotToggle\"\r\n [(ngModel)]=\"pivotMode\"\r\n />\r\n <label class=\"form-check-label\" for=\"pivotToggle\">Pivot Mode</label>\r\n </div>\r\n\r\n <!-- Select All & Search -->\r\n <div class=\"d-flex align-items-center mb-2 px-3 mt-3\">\r\n <span class=\"filter-icon-wrapper me-2\" *ngIf=\"showColumnsGrouping\">\r\n <span\r\n class=\"toggle-icon data-grid-svg-icon\"\r\n [inlineSVG]=\"\r\n accordionState === 'all'\r\n ? singleSpaAssetsPath + 'data-grid/icons/chevron-down.svg'\r\n : accordionState === 'some'\r\n ? singleSpaAssetsPath + 'data-grid/icons/dash.svg'\r\n : singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\r\n \"\r\n (click)=\"toggleAllAccordions()\"\r\n ></span>\r\n </span>\r\n <input\r\n type=\"checkbox\"\r\n class=\"form-check-input me-2\"\r\n [checked]=\"allColumnsSelected()\"\r\n (change)=\"toggleAllColumnsVisibility()\"\r\n />\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Search columns...\"\r\n [(ngModel)]=\"columnSearch\"\r\n />\r\n </div>\r\n\r\n <!-- Separator -->\r\n <hr class=\"my-2\" />\r\n </div>\r\n</ng-template>\r\n\r\n<!-- Right Columns Menue -->\r\n\r\n<!-- Column Panel Item Template -->\r\n<ng-template #columnPanelItem let-col=\"col\">\r\n <!-- Group Column -->\r\n <ng-container *ngIf=\"col.children?.length\">\r\n <div class=\"column-group d-flex align-items-center mb-2\">\r\n <span class=\"filter-icon-wrapper me-2\">\r\n <span\r\n class=\"toggle-icon data-grid-svg-icon\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\r\n \"\r\n [class.rotate]=\"col.expanded\"\r\n (click)=\"col.expanded = !col.expanded\"\r\n ></span>\r\n </span>\r\n <input\r\n type=\"checkbox\"\r\n class=\"form-check-input me-2\"\r\n [id]=\"'group_' + col.header\"\r\n [checked]=\"isColumnVisible(col)\"\r\n (change)=\"toggleGroupVisibility(col)\"\r\n />\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/grid-3x2-gap.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center me-2\"\r\n ></span>\r\n <label\r\n class=\"d-flex align-items-center mb-0 w-100\"\r\n [for]=\"'group_' + col.header\"\r\n style=\"cursor: pointer\"\r\n >\r\n <span class=\"text-truncate\">{{ col.header }}</span>\r\n </label>\r\n </div>\r\n <div *ngIf=\"col.expanded\" class=\"ps-4\">\r\n <ng-container *ngFor=\"let child of col.children; trackBy: trackByField\">\r\n <ng-container\r\n *ngTemplateOutlet=\"columnPanelItem; context: { col: child }\"\r\n ></ng-container>\r\n </ng-container>\r\n </div>\r\n </ng-container>\r\n\r\n <!-- Leaf Column -->\r\n <ng-container *ngIf=\"!col.children?.length\">\r\n <div class=\"d-flex align-items-center mb-2\">\r\n <span class=\"me-2\" style=\"width: 1.5rem\"></span>\r\n <input\r\n type=\"checkbox\"\r\n class=\"form-check-input me-2\"\r\n [(ngModel)]=\"col.is_visible\"\r\n [id]=\"'col_' + col.field\"\r\n (change)=\"onSideMenuColumnsVisibilityChange()\"\r\n />\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/grid-3x2-gap.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center me-2\"\r\n ></span>\r\n <label\r\n class=\"d-flex align-items-center mb-0 w-100\"\r\n [for]=\"'col_' + col.field\"\r\n style=\"cursor: pointer\"\r\n >\r\n <span class=\"text-truncate\">{{ col.header }}</span>\r\n </label>\r\n </div>\r\n </ng-container>\r\n</ng-template>\r\n\r\n<!-- Columns Side Filter -->\r\n<ng-template #sideFilters>\r\n <div class=\"py-3 px-2 pe-3 h-100\">\r\n <div class=\"d-flex align-items-center mb-2\">\r\n <span class=\"filter-icon-wrapper me-2\" *ngIf=\"showColumnsGrouping\">\r\n <span\r\n class=\"toggle-icon data-grid-svg-icon\"\r\n [inlineSVG]=\"\r\n filterAccordionState === 'all'\r\n ? singleSpaAssetsPath + 'data-grid/icons/chevron-down.svg'\r\n : filterAccordionState === 'some'\r\n ? singleSpaAssetsPath + 'data-grid/icons/dash.svg'\r\n : singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\r\n \"\r\n (click)=\"toggleAllFilterAccordions()\"\r\n ></span>\r\n </span>\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Search...\"\r\n [(ngModel)]=\"columnSearch\"\r\n />\r\n </div>\r\n <div\r\n class=\"overflow-auto side-filter-columns-wrapper\"\r\n style=\"height: calc(100% - 70px); scrollbar-width: thin\"\r\n >\r\n <ng-container\r\n *ngFor=\"\r\n let col of columns | filter : columnSearch : 'header';\r\n trackBy: trackByField\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"filterPannelItem; context: { col: col }\"\r\n ></ng-container>\r\n </ng-container>\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template #filterPannelItem let-col=\"col\">\r\n <!-- Group Column -->\r\n <ng-container *ngIf=\"col.children?.length\">\r\n <div\r\n class=\"column-group d-flex align-items-center mb-2\"\r\n *ngIf=\"col?.type !== 'image'\"\r\n >\r\n <!-- Chevron toggle -->\r\n <span class=\"filter-icon-wrapper me-2\">\r\n <span\r\n class=\"toggle-icon data-grid-svg-icon\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\r\n \"\r\n [class.rotate]=\"col.expandedFilter\"\r\n (click)=\"col.expandedFilter = !col.expandedFilter\"\r\n ></span>\r\n </span>\r\n\r\n <!-- Group label toggle -->\r\n <label\r\n class=\"d-flex align-items-center mb-0 w-100\"\r\n style=\"cursor: pointer\"\r\n (click)=\"col.expandedFilter = !col.expandedFilter\"\r\n >\r\n <span class=\"fw-bold text-truncate\"\r\n >{{ col.header }}\r\n <span\r\n class=\"text-primary ms-1\"\r\n *ngIf=\"col?.query?._ids?.length || col?.query?._first_value\"\r\n >*</span\r\n >\r\n </span>\r\n </label>\r\n </div>\r\n\r\n <!-- Children columns -->\r\n <div *ngIf=\"col.expandedFilter\" class=\"ps-4\">\r\n <ng-container *ngFor=\"let child of col.children; trackBy: trackByField\">\r\n <ng-container\r\n *ngTemplateOutlet=\"filterPannelItem; context: { col: child }\"\r\n ></ng-container>\r\n </ng-container>\r\n </div>\r\n </ng-container>\r\n\r\n <!-- Leaf Column -->\r\n <ng-container *ngIf=\"!col.children?.length\">\r\n <div class=\"d-flex align-items-center mb-2\" *ngIf=\"col?.type !== 'image'\">\r\n <span\r\n class=\"me-2 filter-icon-wrapper me-2\"\r\n (click)=\"col.expandedFilter = !col.expandedFilter\"\r\n >\r\n <span\r\n class=\"toggle-icon data-grid-svg-icon\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\r\n \"\r\n [class.rotate]=\"col.expandedFilter\"\r\n ></span>\r\n </span>\r\n\r\n <label\r\n class=\"d-flex align-items-center mb-0 w-100\"\r\n style=\"cursor: pointer\"\r\n (click)=\"col.expandedFilter = !col.expandedFilter\"\r\n >\r\n <span class=\"text-truncate fw-bold\">{{ col.header }}</span>\r\n </label>\r\n </div>\r\n\r\n <!-- Show filter when expanded -->\r\n <div [@slideToggle] *ngIf=\"col.expandedFilter\" class=\"ps-4 pe-3\">\r\n <ng-container\r\n *ngTemplateOutlet=\"sideNestedFilter; context: { col: col }\"\r\n ></ng-container>\r\n </div>\r\n </ng-container>\r\n</ng-template>\r\n\r\n<!-- Side Nested Filters -->\r\n<ng-template #sideNestedFilter let-col=\"col\">\r\n <div class=\"\">\r\n\r\n <ng-container *ngIf=\"col?.type === 'dropdown' || col?.type == 'array'; else textFilter\">\r\n <div class=\"p-1\">\r\n\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm mb-2\"\r\n placeholder=\"Search...\"\r\n [(ngModel)]=\"sideNestedFilterSearch\"\r\n />\r\n\r\n <ng-container\r\n *ngIf=\"\r\n (col?.column_dropdown_value\r\n | filter : sideNestedFilterSearch : 'value') as filteredOptions\r\n \"\r\n >\r\n <ng-container *ngIf=\"filteredOptions.length; else noDataFound\">\r\n <div class=\"form-check mb-1 ms-1 select-all-filter\">\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n [checked]=\"\r\n col.query?._ids?.length == col?.column_dropdown_value?.length\r\n \"\r\n (change)=\"toggleSelectAllSideFilters(col, $event)\"\r\n [indeterminate]=\"(col.query?._ids?.length !== col?.column_dropdown_value?.length && col.query?._ids?.length)\"\r\n id=\"selectAll_{{ col.field }}\"\r\n />\r\n <label class=\"form-check-label\" for=\"selectAll_{{ col.field }}\">\r\n Select All\r\n </label>\r\n </div>\r\n <cdk-virtual-scroll-viewport\r\n itemSize=\"32\"\r\n class=\"dropdown-viewport\"\r\n style=\"height: 120px\"\r\n >\r\n <div\r\n class=\"form-check mb-1 ms-1\"\r\n *cdkVirtualFor=\"let option of filteredOptions\"\r\n >\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n [value]=\"option\"\r\n [checked]=\"\r\n col.query?._ids?.includes(option?._id || option?.id || option)\r\n \"\r\n (change)=\"onOptionToggle(col, option)\"\r\n id=\"option_{{ col.field }}_{{\r\n option?.id || option?._id || option\r\n }}\"\r\n />\r\n\r\n <label\r\n class=\"form-check-label\"\r\n [for]=\"\r\n 'option_' +\r\n col.field +\r\n '_' +\r\n (option?.id || option?._id || option)\r\n \"\r\n >\r\n {{ (option.value || option) | titlecase }}\r\n </label>\r\n </div>\r\n </cdk-virtual-scroll-viewport>\r\n\r\n </ng-container>\r\n <ng-template #noDataFound>\r\n <div\r\n class=\"text-center text-muted mt-2\"\r\n *ngIf=\"sideNestedFilterSearch\"\r\n >\r\n No Record Found\r\n </div>\r\n </ng-template>\r\n\r\n </ng-container>\r\n\r\n </div>\r\n </ng-container>\r\n\r\n\r\n <!-- Text Filter Section -->\r\n <ng-template #textFilter>\r\n <div class=\"filter-text-section\">\r\n <div class=\"form-group mb-2\">\r\n <select\r\n class=\"form-select form-select-sm\"\r\n [(ngModel)]=\"col.query.first_condition\"\r\n >\r\n <ng-container *ngIf=\"col?.type == 'string'\">\r\n <option value=\"contain\">Contains</option>\r\n <option value=\"does_not_contain\">Does Not Contain</option>\r\n <option value=\"equal\">Equals</option>\r\n <option value=\"before\">Starts With</option>\r\n <option value=\"after\">Ends With</option>\r\n </ng-container>\r\n\r\n <ng-container *ngIf=\"col?.type == 'date' || col?.type == 'time'\">\r\n <option value=\"equal\">Equals To</option>\r\n <option value=\"not_equal\">Not Equal</option>\r\n <option value=\"after\">After</option>\r\n <option value=\"before\">Before</option>FV\r\n </ng-container>\r\n\r\n <ng-container *ngIf=\"col?.type == 'number'\">\r\n <option value=\"equal\">Equals To</option>\r\n <option value=\"before\">Less Then </option>\r\n <option value=\"after\">Greater Then </option>\r\n <option value=\"less_then_equal\">less then Equal to</option>\r\n <option value=\"greater_then_equal\">Greater then Equal to </option>FV\r\n </ng-container>\r\n </select>\r\n </div>\r\n\r\n <input\r\n [type]=\"col?.type == 'date' ? 'date' : (col?.type == 'number' ? 'number': 'text')\"\r\n class=\"form-control form-control-sm mb-3\"\r\n placeholder=\"Value\"\r\n [(ngModel)]=\"col!.query!.first_value\"\r\n />\r\n\r\n <div\r\n class=\"form-group mb-3 d-flex flex-row muted\"\r\n style=\"font-size: 14px\"\r\n >\r\n <div\r\n class=\"form-check form-check-inline m-0 col-4 d-flex align-items-center gap-1\"\r\n >\r\n <input\r\n class=\"form-check-input filter-radio-inputs\"\r\n type=\"radio\"\r\n name=\"condition\"\r\n [(ngModel)]=\"col!.query.condition\"\r\n value=\"and\"\r\n id=\"and_{{ col.field }}\"\r\n />\r\n <label class=\"form-check-label mb-0 mt-1\" for=\"and_{{ col.field }}\"\r\n >AND</label\r\n >\r\n </div>\r\n <div\r\n class=\"form-check form-check-inline m-0 col-4 d-flex align-items-center gap-1\"\r\n >\r\n <input\r\n class=\"form-check-input filter-radio-inputs\"\r\n type=\"radio\"\r\n name=\"condition\"\r\n [(ngModel)]=\"col!.query.condition\"\r\n value=\"or\"\r\n id=\"or_{{ col.field }}\"\r\n />\r\n <label class=\"form-check-label mb-0 mt-1\" for=\"or_{{ col.field }}\"\r\n >OR</label\r\n >\r\n </div>\r\n <div\r\n class=\"form-check form-check-inline m-0 col-4 d-flex align-items-center gap-1\"\r\n >\r\n <input\r\n class=\"form-check-input filter-radio-inputs\"\r\n type=\"radio\"\r\n name=\"condition\"\r\n [(ngModel)]=\"col!.query.condition\"\r\n value=\"none\"\r\n id=\"none_{{ col.field }}\"\r\n />\r\n <label\r\n class=\"nnonem-check-label mb-0 mt-1\"\r\n for=\"none_{{ col.field }}\"\r\n >None</label\r\n >\r\n </div>\r\n </div>\r\n <ng-container\r\n *ngIf=\"col?.query?.first_value && col?.query?.condition !== 'none'\"\r\n >\r\n <div class=\"form-group mb-2\">\r\n <select\r\n class=\"form-select form-select-sm\"\r\n [(ngModel)]=\"col!.query.second_condition\"\r\n >\r\n <ng-container *ngIf=\"col?.type == 'string'\">\r\n <option value=\"contain\">Contains</option>\r\n <option value=\"does_not_contain\">Does Not Contain</option>\r\n <option value=\"equal\">Equals</option>\r\n <option value=\"before\">Starts With</option>\r\n <option value=\"after\">Ends With</option>\r\n </ng-container>\r\n\r\n <ng-container *ngIf=\"col?.type == 'date' || col?.type == 'time'\">\r\n <option value=\"equal\">Equals To</option>\r\n <option value=\"not_equal\">Not Equal</option>\r\n <option value=\"after\">After</option>\r\n <option value=\"before\">Before</option>\r\n </ng-container>\r\n\r\n <ng-container *ngIf=\"col?.type == 'number'\">\r\n <option value=\"equal\">Equals To</option>\r\n <option value=\"before\">Less Then </option>\r\n <option value=\"after\">Greater Then </option>\r\n <option value=\"less_then_equal\">less then Equal to</option>\r\n <option value=\"greater_then_equal\">Greater then Equal to </option>\r\n </ng-container>\r\n </select>\r\n </div>\r\n\r\n <input\r\n [type]=\"col?.type == 'date' ? 'date' : 'text'\"\r\n class=\"form-control form-control-sm mb-3\"\r\n placeholder=\"Second Value\"\r\n [(ngModel)]=\"col!.query.second_value\"\r\n />\r\n </ng-container>\r\n <!-- <div class=\"d-flex gap-2\">\r\n <div class=\"btn btn-sm btn-primary d-flex justify-content-center align-items-center\" style=\"height: 22px;\" (click)=\"applyDropdownFilter()\">apply</div>\r\n <div class=\"btn btn-sm btn-secondary d-flex justify-content-center align-items-center\" style=\"height: 22px;\" (click)=\"applyDropdownFilter()\">reset</div>\r\n\r\n </div> -->\r\n </div>\r\n </ng-template>\r\n <div\r\n class=\"d-flex justify-content-center gap-2 border-top\"\r\n style=\"height: 38px\"\r\n >\r\n <button\r\n type=\"button\"\r\n style=\"max-height: 30px\"\r\n class=\"btn btn-outline-secondary btn-light border w-100 d-flex align-items-center justify-content-center mt-1 btn-light\"\r\n (click)=\"$event.stopPropagation(); removeSideFilter(col)\"\r\n >\r\n <span>Clear</span>\r\n </button>\r\n <button\r\n type=\"button\"\r\n style=\"max-height: 30px\"\r\n class=\"btn btn-primary w-100 d-flex align-items-center justify-content-center mt-1\"\r\n (click)=\"applySideFilter(col)\"\r\n [class.disabled]=\"(col?.query.condition !== 'none' && !col?.query?.second_value)\"\r\n [class.pe-none]=\"(col!?.query.condition !== 'none' && !col?.query?.second_value)\"\r\n >\r\n <span style=\"margin-top: -1px\">Apply</span>\r\n </button>\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<!-- Centr Overlay for showing the chose columns -->\r\n\r\n<div *ngIf=\"showColumnPanel\" class=\"custom-modal-overlay\">\r\n <div\r\n class=\"custom-modal-content\"\r\n [style.backgroundColor]=\"dropdownsBackgroundColor\"\r\n (click)=\"$event.stopPropagation()\"\r\n >\r\n <ng-container *ngTemplateOutlet=\"modalColumnPannel\"></ng-container>\r\n </div>\r\n</div>\r\n\r\n<!-- The existing ng-template you provided -->\r\n<ng-template #modalColumnPannel>\r\n <div class=\"column-panel-header\">\r\n <div\r\n class=\"d-flex justify-content-between align-items-center px-2 ps-3 rounded-top-2 moda-header\"\r\n [style.height.px]=\"48\"\r\n >\r\n Choose Columns\r\n <span class=\"filter-icon-wrapper\" (click)=\"closeModalColumnPanel()\"\r\n ><span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/x.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span\r\n ></span>\r\n </div>\r\n <hr class=\"my-0\" />\r\n <div>\r\n <div class=\"d-flex align-items-center px-2 pe-3\" [style.height.px]=\"48\">\r\n <span class=\"filter-icon-wrapper me-2\" *ngIf=\"showColumnsGrouping\">\r\n <span\r\n class=\"toggle-icon data-grid-svg-icon\"\r\n [inlineSVG]=\"\r\n accordionState === 'all'\r\n ? singleSpaAssetsPath + 'data-grid/icons/chevron-down.svg'\r\n : accordionState === 'some'\r\n ? singleSpaAssetsPath + 'data-grid/icons/dash.svg'\r\n : singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\r\n \"\r\n (click)=\"toggleAllAccordions()\"\r\n ></span>\r\n </span>\r\n <input\r\n type=\"checkbox\"\r\n class=\"form-check-input me-2\"\r\n [checked]=\"allColumnsSelected()\"\r\n (change)=\"toggleAllColumnsVisibility()\"\r\n />\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Search columns...\"\r\n [(ngModel)]=\"choseColumnsSearch\"\r\n />\r\n </div>\r\n\r\n <hr class=\"mt-0 mb-1\" />\r\n <div class=\"px-2 overlay-scrollable\">\r\n <ng-container\r\n *ngFor=\"\r\n let col of columns | filter : choseColumnsSearch : 'header';\r\n trackBy: trackByField\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"columnPanelItem; context: { col: col }\"\r\n ></ng-container>\r\n </ng-container>\r\n </div>\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template #sideMenuRowGroups>\r\n <div class=\"d-flex flex-column h-100 d-none\">\r\n <div class=\"px-3 h-100\">\r\n <div class=\"d-flex gap-3 mb-4\">\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/justify.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n <span>Row Groups</span>\r\n </div>\r\n <div class=\"h-50\">\r\n <div\r\n class=\"px-3 py-2 border-dashed h-100 d-flex justify-content-center align-items-center\"\r\n style=\"font-size: 14px\"\r\n >\r\n Drag here to set row Groups\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <hr class=\"mt-4\" />\r\n\r\n <div class=\"px-3 h-100\">\r\n <div class=\"d-flex gap-3 mb-4\">\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/justify.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n <span>Values</span>\r\n </div>\r\n <div class=\"h-50 d-flex\">\r\n <div\r\n class=\"px-3 py-2 border-dashed h-100 d-flex justify-content-center align-items-center\"\r\n style=\"font-size: 14px\"\r\n >\r\n Drag here aggregate\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<!-- *************************************************** -->\r\n<!-- *************************************************** -->\r\n<!-- *************************************************** -->\r\n<!-- Drag Preview Template -->\r\n<!-- *************************************************** -->\r\n<!-- *************************************************** -->\r\n<ng-template #dragPreview let-col>\r\n <div class=\"p-2 border d-flex gap-2\">\r\n <div>\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrows-move.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n <div>{{ col.header }}</div>\r\n </div>\r\n</ng-template>\r\n\r\n<!-- Drag Placeholder Template -->\r\n<ng-template\r\n #dragPlaceholder\r\n let-col\r\n let-i=\"index\"\r\n let-section=\"section\"\r\n let-draggingInGroupArea=\"draggingInGroupArea\"\r\n>\r\n <div *ngIf=\"!draggingInGroupArea\">\r\n <div\r\n *ngTemplateOutlet=\"\r\n headerCell;\r\n context: { $implicit: col, index: i, section: section }\r\n \"\r\n ></div>\r\n </div>\r\n <div *ngIf=\"draggingInGroupArea\">New Placeholder</div>\r\n</ng-template>\r\n\r\n<!-- Top Group Row Placeholder -->\r\n<ng-template #topGroupingRowPlaceholder let-col let-showChevron=\"showChevron\">\r\n <div class=\"d-flex gap-2\">\r\n <div\r\n class=\"d-flex gap-2 top-row-grouping-placeholder\"\r\n [style.backgroundColor]=\"topGroupedBadgesBackgroundColor\"\r\n >\r\n <span\r\n cdkDragHandle\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/grid-3x2-gap.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n <span>{{ col.header }}</span>\r\n <span\r\n (click)=\"ungroupColumn(col)\"\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/x.svg'\"\r\n class=\"cursor-pointer data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n </div>\r\n <div *ngIf=\"showChevron\" style=\"opacity: 0.6; font-size: 14px\">\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template\r\n #childHeaderPlaceholder\r\n let-col\r\n let-pinnedRight=\"pinnedRight\"\r\n let-i=\"index\"\r\n let-sections=\"sections\"\r\n>\r\n <div\r\n class=\"header-cell one-row-header-cells\"\r\n [class.border-right]=\"showVerticalBorder\"\r\n [style.width.px]=\"col.width\"\r\n [style.min-width.px]=\"col.width\"\r\n [style.min-height.px]=\"headerRowHeight\"\r\n [style.max-height.px]=\"headerRowHeight\"\r\n [style.fontWeight]=\"headerFontWeight\"\r\n >\r\n <div class=\"d-flex justify-content-between h-100 align-items-center w-100\">\r\n <div\r\n class=\"d-flex justify-content-between align-items-center w-100\"\r\n [class.flex-row-reverse]=\"pinnedRight\"\r\n >\r\n <div\r\n class=\"text-ellipsis h-100 d-flex align-items-center\"\r\n [title]=\"col.header\"\r\n [class.w-100]=\"pinnedRight\"\r\n >\r\n {{ col.header }}\r\n </div>\r\n\r\n <div\r\n class=\"position-relative d-flex\"\r\n [class.flex-row-reverse]=\"pinnedRight\"\r\n >\r\n <div class=\"three-dots p-1\" style=\"cursor: pointer\">\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/three-dots-vertical.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n\r\n <div class=\"resize-handle\">\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/resize-handle.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n <div\r\n *ngIf=\"showFilterRow\"\r\n [style.backgroundColor]=\"headerBackgroundColor\"\r\n class=\"header-cell filter-cell\"\r\n [class.border-right]=\"showVerticalBorder\"\r\n [style.width.px]=\"col.width\"\r\n [style.min-width.px]=\"col.width\"\r\n [style.height.px]=\"headerRowHeight\"\r\n [style.min-height.px]=\"headerRowHeight\"\r\n [style.max-height.px]=\"headerRowHeight\"\r\n [class.border-right]=\"showVerticalBorder\"\r\n style=\"grid-row: 3\"\r\n >\r\n <div\r\n class=\"header-cell filter-cell\"\r\n [style.backgroundColor]=\"headerBackgroundColor\"\r\n [style.width.px]=\"col.width\"\r\n [style.min-width.px]=\"col.width\"\r\n [style.height.px]=\"headerRowHeight\"\r\n [style.min-height.px]=\"headerRowHeight\"\r\n [style.max-height.px]=\"headerRowHeight\"\r\n >\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Filter\"\r\n [(ngModel)]=\"col.filterValue\"\r\n [readonly]=\"col?.type == 'dropdown' || col?.type == 'image' || col?.type == 'array'\"\r\n [class.disabled-search-input]=\"\r\n col?.type == 'dropdown' || col?.type == 'image' || col?.type == 'array'\r\n \"\r\n />\r\n <span\r\n class=\"filter-icon-wrapper\"\r\n (click)=\"activeFilterCell = col; activeCol = null\"\r\n ><span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span\r\n ></span>\r\n\r\n <div\r\n class=\"position-absolute\"\r\n *ngIf=\"activeFilterCell === col\"\r\n style=\"top: 100%; right: 0; z-index: 10; left: 0\"\r\n ></div>\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template #tableLayout>\r\n <div\r\n (click)=\"$event.stopPropagation()\"\r\n class=\"p-3 shadow actions-dropdown mt-1 dropdown-menu show shadow custom-menu table-layout\"\r\n style=\"width: 320px\"\r\n >\r\n <div class=\"d-flex align-items-center mb-3\">\r\n <button\r\n class=\"btn btn-link p-0\"\r\n style=\"margin-left: -10px\"\r\n (click)=\"toggleActions('setting')\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrow-left.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n </button>\r\n <h6 class=\"mb-0 ms-2\" style=\"font-weight: 500\">Table Layout</h6>\r\n </div>\r\n <hr class=\"my-2\" />\r\n <div class=\"w-100 mb-3 d-flex\" role=\"group\">\r\n <input\r\n type=\"radio\"\r\n class=\"btn-check layout-button-check\"\r\n name=\"layoutSize\"\r\n id=\"small\"\r\n autocomplete=\"off\"\r\n (change)=\"changeTableLayout($event, 'small')\"\r\n [checked]=\"selectedTableLayout == 'small'\"\r\n />\r\n <label\r\n class=\"border d-flex flex-column align-items-center layout-button\"\r\n for=\"small\"\r\n [ngStyle]=\"{\r\n color: selectedTableLayout == 'small' ? '#000' : '#727272'\r\n }\"\r\n >\r\n <div class=\"preview-box border mb-1\" style=\"height: 8px\"></div>\r\n Small\r\n </label>\r\n\r\n <input\r\n type=\"radio\"\r\n class=\"btn-check layout-button-check\"\r\n name=\"layoutSize\"\r\n id=\"medium\"\r\n autocomplete=\"off\"\r\n [checked]=\"selectedTableLayout == 'medium'\"\r\n (change)=\"changeTableLayout($event, 'medium')\"\r\n />\r\n <label\r\n class=\"border mx-3 d-flex flex-column align-items-center layout-button\"\r\n for=\"medium\"\r\n [ngStyle]=\"{\r\n color: selectedTableLayout == 'medium' ? '#000' : '#727272'\r\n }\"\r\n >\r\n <div class=\"preview-box border mb-1\" style=\"height: 12px\"></div>\r\n Medium\r\n </label>\r\n\r\n <input\r\n type=\"radio\"\r\n class=\"btn-check layout-button-check\"\r\n name=\"layoutSize\"\r\n id=\"large\"\r\n autocomplete=\"off\"\r\n (change)=\"changeTableLayout($event, 'large')\"\r\n [checked]=\"selectedTableLayout == 'large'\"\r\n />\r\n <label\r\n class=\"border d-flex flex-column align-items-center layout-button\"\r\n for=\"large\"\r\n [ngStyle]=\"{\r\n color: selectedTableLayout == 'large' ? '#000' : '#727272'\r\n }\"\r\n >\r\n <div class=\"preview-box border mb-1\" style=\"height: 16px\"></div>\r\n Large\r\n </label>\r\n </div>\r\n\r\n <hr class=\"my-2\" />\r\n <div class=\"d-flex justify-content-between align-items-center mb-2\">\r\n <span>Show separators</span>\r\n <div class=\"form-check form-switch m-0\">\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n id=\"separators\"\r\n [(ngModel)]=\"showVerticalBorder\"\r\n (change)=\"onFontChange()\"\r\n />\r\n </div>\r\n </div>\r\n <div class=\"d-flex justify-content-between align-items-center\">\r\n <span>Row shading</span>\r\n <div class=\"form-check form-switch m-0\">\r\n <input\r\n class=\"form-check-input\"\r\n [(ngModel)]=\"rowShadingEnabled\"\r\n (change)=\"toggleRowShading()\"\r\n type=\"checkbox\"\r\n id=\"rowShading\"\r\n />\r\n </div>\r\n </div>\r\n <!-- <div class=\"d-flex justify-content-between align-items-center mb-2\">\r\n <span>Show Side Menu</span>\r\n <div class=\"form-check form-switch m-0\">\r\n <input\r\n class=\"form-check-input\"\r\n [(ngModel)]=\"showSideMenu\"\r\n type=\"checkbox\"\r\n id=\"rowShading\"\r\n />\r\n </div>\r\n </div>\r\n <div class=\"d-flex justify-content-between align-items-center mb-2\">\r\n <span>Show Filter Row</span>\r\n <div class=\"form-check form-switch m-0\">\r\n <input\r\n class=\"form-check-input\"\r\n [(ngModel)]=\"showFilterRow\"\r\n type=\"checkbox\"\r\n id=\"rowShading\"\r\n />\r\n </div>\r\n </div> -->\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template #tablePreset>\r\n <div\r\n *ngIf=\"activeSubButton !== 'save-preset'\"\r\n (click)=\"$event.stopPropagation()\"\r\n class=\"p-3 shadow actions-dropdown mt-1 dropdown-menu show shadow custom-menu table-layout\"\r\n style=\"width: 280px\"\r\n >\r\n <!-- Header -->\r\n <div class=\"d-flex justify-content-between align-items-center mb-3\">\r\n <div class=\"d-flex align-items-center\">\r\n <button\r\n class=\"btn btn-link p-0\"\r\n style=\"margin-left: -10px\"\r\n (click)=\"toggleActions('setting')\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrow-left.svg'\"\r\n class=\"data-grid-svg-icon\"\r\n ></span>\r\n </button>\r\n <h6 class=\"mb-0 ms-2\" style=\"font-weight: 500\">Table Presets</h6>\r\n </div>\r\n <!-- Save Preset Button with Dropdown -->\r\n <div>\r\n <a\r\n class=\"text-decoration-none text-primary\"\r\n type=\"button\"\r\n id=\"savePresetDropdown\"\r\n (click)=\"$event.stopPropagation(); toggleSubActions('save-preset')\"\r\n >\r\n {{ isTablePresetNotChanged ? \"Save preset\" : \"Update Preset\" }}\r\n </a>\r\n </div>\r\n </div>\r\n\r\n <!-- Search -->\r\n <div class=\"mb-3\">\r\n <div class=\"col-12 global-search\">\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/search.svg'\"\r\n class=\"data-grid-svg-icon mx-2 position-absolute icon\"\r\n ></span>\r\n <input\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Search...\"\r\n [(ngModel)]=\"searchTextPresetTable\"\r\n type=\"search\"\r\n />\r\n </div>\r\n </div>\r\n\r\n <!-- Preset List -->\r\n <ng-container\r\n *ngIf=\"\r\n tableView | filter : searchTextPresetTable : 'name' as filteredList\r\n \"\r\n >\r\n <!-- If filteredList exists and none is default -> show fallback -->\r\n <div\r\n class=\" pb-5 overflow-auto\"\r\n [style.maxHeight.px]=\"dataGridContainer.offsetHeight - 250\"\r\n >\r\n <div\r\n class=\"cursor-pointer\"\r\n (click)=\"\r\n clearAllFilters(true);\r\n openIndex = null;\r\n temp_state.id = '';\r\n activeTopButton = '';\r\n curretaTablePresetForUpdate = null\r\n \"\r\n >\r\n <div class=\"fw-semibold\">Default View</div>\r\n </div>\r\n <div class=\"d-flex justify-content-between\">\r\n <small class=\"text-dark\">Created by system</small>\r\n <span\r\n *ngIf=\"!tableFilterViewId && !hasAnyDefaultView()\"\r\n class=\"badge bg-light text-primary ms-2\"\r\n >Default</span\r\n >\r\n <!-- <span\r\n *ngIf=\"!tableFilterViewId && !hasAnyDefaultView()\"\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/check-blue.svg'\"\r\n class=\"me-2\"\r\n ></span> -->\r\n <div\r\n class=\"dropdown d-flex justify-content-end\"\r\n *ngIf=\"tableFilterViewId\"\r\n ></div>\r\n </div>\r\n\r\n <!-- The list: render each table from filteredList -->\r\n <div\r\n class=\"list-group list-group-flush\"\r\n *ngFor=\"\r\n let table of filteredList;\r\n let i = index;\r\n trackBy: trackByTable\r\n \"\r\n >\r\n <!-- Item -->\r\n <div\r\n (click)=\"\r\n $event.stopPropagation(); openIndex = null; activeTopButton = ''\r\n \"\r\n class=\"list-group-item px-0 d-flex justify-content-between align-items-center\"\r\n >\r\n <div (click)=\"selectFilter(table); openIndex = null\">\r\n <div class=\"fw-semibold\" style=\"cursor: pointer\">\r\n {{ table?.name }}\r\n <!-- {{table?.is_temp}} -->\r\n <span\r\n *ngIf=\"\r\n (table?.is_temp && !temp_state.id) ||\r\n temp_state.id == table.id\r\n \"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/check-blue.svg'\r\n \"\r\n class=\"me-2\"\r\n ></span>\r\n <span\r\n *ngIf=\"table?.is_default\"\r\n class=\"badge bg-light text-primary ms-2\"\r\n >Default</span\r\n >\r\n </div>\r\n <small class=\"text-dark\" *ngIf=\"table?.config?.filterNames\" [title]=\"table?.config?.filterNames\">\r\n {{\r\n table?.config?.filterNames?.length > 25\r\n ? (table?.config?.filterNames | slice:0:25) + '...'\r\n : table?.config?.filterNames\r\n }}\r\n ({{ table?.config?.totalCount }})\r\n </small>\r\n <small class=\"text-dark\" *ngIf=\"!table?.config?.filterNames\">{{ table?.createdAt | date : \"MMM d, y\" }}</small>\r\n </div>\r\n\r\n <div class=\"d-flex align-items-center\">\r\n <span\r\n *ngIf=\"table?.is_default\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/check-blue.svg'\r\n \"\r\n class=\"me-2\"\r\n ></span>\r\n\r\n <div class=\"dropdown\" *ngIf=\"!table?.is_default\">\r\n <div\r\n class=\"dropdown-wrapper\"\r\n (click)=\"$event.stopPropagation()\"\r\n >\r\n <button\r\n type=\"button\"\r\n class=\"btn-icon muted-text\"\r\n (click)=\"toggleMenu(i, $event)\"\r\n aria-haspopup=\"true\"\r\n [attr.aria-expanded]=\"openIndex === i\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath +\r\n 'data-grid/icons/horizontal-dots.svg'\r\n \"\r\n class=\"me-2\"\r\n ></span>\r\n </button>\r\n\r\n <!-- menu -->\r\n <ul\r\n *ngIf=\"openIndex === i\"\r\n class=\"custom-dropdown-menu position-fixed top-auto\"\r\n role=\"menu\"\r\n [style.right.px]=\"'unset'\"\r\n [style.left.px]=\"dataGridContainer.offsetWidth - 200\"\r\n style=\"top: unset; right: unset\"\r\n >\r\n <li role=\"none\">\r\n <button\r\n role=\"menuitem\"\r\n class=\"dropdown-item\"\r\n (click)=\"\r\n actionPreset(table, 'setPreset'); temp_state.id = ''\r\n \"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/star.svg'\r\n \"\r\n class=\"me-2\"\r\n ></span>\r\n Set as default\r\n </button>\r\n </li>\r\n\r\n <li role=\"none\" *ngIf=\"!table.confirmDelete\">\r\n <button\r\n role=\"menuitem\"\r\n class=\"dropdown-item text-danger\"\r\n (click)=\"table.confirmDelete = true\"\r\n >\r\n <span\r\n style=\"margin-top: -4px\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath +\r\n 'data-grid/icons/trash-red.svg'\r\n \"\r\n class=\"me-2\"\r\n ></span>\r\n Delete\r\n </button>\r\n </li>\r\n\r\n <li\r\n role=\"none\"\r\n *ngIf=\"table.confirmDelete\"\r\n class=\"confirm-block\"\r\n >\r\n <div class=\"px-3 py-2 text-center\">\r\n <div class=\"mb-2\">\r\n Are you sure you want to delete <br /><b\r\n >\u201C{{ table?.name }}\u201D</b\r\n >?\r\n </div>\r\n <div class=\"d-flex gap-2\">\r\n <button\r\n class=\"btn btn-sm btn-light me-2\"\r\n (click)=\"table.confirmDelete = false\"\r\n >\r\n Cancel\r\n </button>\r\n <button\r\n class=\"btn btn-sm btn-danger\"\r\n (click)=\"actionPreset(table, 'deletePreset')\"\r\n >\r\n Delete\r\n </button>\r\n </div>\r\n </div>\r\n </li>\r\n </ul>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n <!-- Item End Here -->\r\n </div>\r\n </div>\r\n </ng-container>\r\n </div>\r\n\r\n <div\r\n (click)=\"$event.stopPropagation()\"\r\n *ngIf=\"activeSubButton == 'save-preset'\"\r\n class=\"dropdown-menu p-3 badge mt-4 save-preset-dropdown mt-1\"\r\n aria-labelledby=\"savePresetDropdown\"\r\n style=\"min-width: 250px\"\r\n >\r\n <div class=\"fw-bold fs-14px mb-2\">\r\n {{ isTablePresetNotChanged ? \"Save preset\" : \"Update Preset\" }}\r\n </div>\r\n <div class=\"fs-14px mb-2\" style=\"line-height: 20px\">\r\n This will save the current table adjustments as a preset.\r\n </div>\r\n <!-- Input -->\r\n <div class=\"mb-2\">\r\n <label for=\"presetName\" class=\"form-label fs-12px fw-bold\"\r\n >Preset Name</label\r\n >\r\n <div class=\"col-12 global-search\">\r\n <input\r\n #presetNameCtrl=\"ngModel\"\r\n required\r\n [(ngModel)]=\"presetName\"\r\n [ngClass]=\"{\r\n 'is-invalid':\r\n presetNameCtrl.invalid &&\r\n (presetNameCtrl.dirty || presetNameCtrl.touched)\r\n }\"\r\n class=\"form-control form-control-sm ps-2\"\r\n placeholder=\"Enter preset name\"\r\n type=\"text\"\r\n />\r\n </div>\r\n </div>\r\n\r\n <!-- Checkbox -->\r\n <div class=\"form-check mb-2\">\r\n <input\r\n class=\"form-check-input\"\r\n [(ngModel)]=\"presetFilter\"\r\n type=\"checkbox\"\r\n id=\"saveFilters\"\r\n />\r\n <label class=\"form-check-label mt-1\" for=\"saveFilters\">\r\n Save active filters\r\n </label>\r\n </div>\r\n\r\n <!-- Save Button -->\r\n <div class=\"d-flex justify-content-center gap-2\" style=\"height: 32px\">\r\n <button\r\n type=\"button\"\r\n style=\"height: 32px\"\r\n class=\"btn border w-100 d-flex align-items-center justify-content-center btn-light\"\r\n (click)=\"$event.stopPropagation(); toggleActions('table-presets')\"\r\n style=\"margin-top: -2px\"\r\n >\r\n <span>Cancel</span>\r\n </button>\r\n <button\r\n [disabled]=\"closeDropdown.preset.loading\"\r\n (click)=\"savePreset(presetNameCtrl)\"\r\n type=\"button\"\r\n style=\"height: 32px\"\r\n class=\"btn btn-primary w-100 d-flex align-items-center justify-content-center\"\r\n >\r\n <span style=\"margin-top: -2px\" *ngIf=\"isTablePresetNotChanged\">\r\n <ng-container *ngIf=\"!closeDropdown.preset.loading\"\r\n >Save</ng-container\r\n >\r\n <ng-container *ngIf=\"closeDropdown.preset.loading\"\r\n ><span class=\"spinner-border spinner-border-sm\"></span\r\n ></ng-container>\r\n </span>\r\n <span style=\"white-space: nowrap\" *ngIf=\"!isTablePresetNotChanged\"\r\n >Update Preset</span\r\n >\r\n </button>\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template #showHideColumns>\r\n <div\r\n (click)=\"$event.stopPropagation()\"\r\n class=\"p-3 shadow actions-dropdown mt-1 dropdown-menu show shadow custom-menu table-layout\"\r\n style=\"width: 280px\"\r\n >\r\n <!-- Header -->\r\n <div class=\"d-flex justify-content-between align-items-center mb-3\">\r\n <div class=\"d-flex align-items-center\">\r\n <button\r\n class=\"btn btn-link p-0\"\r\n style=\"margin-left: -10px\"\r\n (click)=\"toggleActions('setting')\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrow-left.svg'\"\r\n class=\"data-grid-svg-icon\"\r\n ></span>\r\n </button>\r\n <h6 class=\"mb-0 ms-2\" style=\"font-weight: 500\">Columns</h6>\r\n </div>\r\n <a\r\n (click)=\"resetColumns()\"\r\n href=\"javascript:void(0)\"\r\n class=\"text-primary text-decoration-none d-none\"\r\n >Reset</a\r\n >\r\n </div>\r\n\r\n <!-- Search -->\r\n <div class=\"mb-3\">\r\n <div class=\"col-12 global-search\">\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/search.svg'\"\r\n class=\"mx-2 position-absolute icon data-grid-svg-icon\"\r\n ></span>\r\n <input\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Search column\"\r\n type=\"search\"\r\n [(ngModel)]=\"topShowHideColumns\"\r\n />\r\n </div>\r\n </div>\r\n <!-- Preset List -->\r\n <div\r\n class=\"list-group list-group-flush\"\r\n style=\"overflow: auto; scrollbar-width: thin\"\r\n [style.maxHeight.px]=\"dataGridContainer.offsetHeight - 220\"\r\n >\r\n <div class=\"muted-text show-hide-table-label d-flex justify-content-between\" *ngIf=\"hasAnyVisibleColumn\">\r\n Show in table\r\n <div class=\"form-check\">\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n id=\"hide_all\"\r\n [checked]=\"allColumnsSelected()\"\r\n (change)=\"toggleAllColumnsVisibility()\"\r\n />\r\n <label class=\"form-check-label fw-semibold\" for=\"hide_all\">\r\n Show/Hide All \r\n </label>\r\n </div>\r\n </div>\r\n <!-- Item -->\r\n <ng-container\r\n *ngFor=\"\r\n let col of columns | filter : topShowHideColumns : 'header';\r\n trackBy: trackByField\r\n \"\r\n >\r\n <div\r\n *ngIf=\"col.is_visible\"\r\n class=\"list-group-item border-0 px-0 d-flex justify-content-between align-items-center\"\r\n >\r\n <div class=\"d-flex gap-1\">\r\n <div>\r\n <span\r\n *ngIf=\"!col?.pinned\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/grip-vertical.svg'\r\n \"\r\n class=\"cursor-grap data-grid-svg-icon\"\r\n (mousedown)=\"$event.preventDefault()\"\r\n ></span>\r\n <span\r\n *ngIf=\"col?.pinned\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/pin-blue.svg'\r\n \"\r\n class=\"cursor-grap data-grid-svg-icon\"\r\n (mousedown)=\"$event.preventDefault()\"\r\n ></span>\r\n </div>\r\n <div class=\"fw-semibold\">\r\n {{ col.header }}\r\n </div>\r\n </div>\r\n <div\r\n *ngIf=\"!col?.query?.first_value && !col?.query?._ids?.length\"\r\n class=\"d-flex align-items-center cursor-pointer\"\r\n (click)=\"toggleColumnVisibility(col, false)\"\r\n [class.disabled]=\"visibleColumns().length <= 2 || col?.is_always_visible\"\r\n [class.pe-none]=\"visibleColumns().length <= 2 || col?.is_always_visible\"\r\n [class.opacity-50]=\"visibleColumns().length <= 2 || col?.is_always_visible\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/eye.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n </div>\r\n <div\r\n *ngIf=\"col?.query?.first_value || col?.query?._ids?.length\"\r\n class=\"d-flex align-items-center\"\r\n style=\"opacity: 0.5\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/eye.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n </div>\r\n </div>\r\n </ng-container>\r\n\r\n <!-- Item End Here -->\r\n\r\n <div\r\n class=\"dropdown-divider\"\r\n *ngIf=\"hasAnyVisibleColumn && hasAnyInVisibleColumn\"\r\n ></div>\r\n\r\n <div\r\n class=\"muted-text show-hide-table-label d-flex justify-content-between\"\r\n *ngIf=\"hasAnyInVisibleColumn\"\r\n >\r\n Hide in table\r\n <div class=\"form-check\">\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n id=\"show_all\"\r\n [checked]=\"allColumnsSelected()\"\r\n (change)=\"toggleAllColumnsVisibility()\"\r\n />\r\n <label class=\"form-check-label fw-semibold\" for=\"show_all\">\r\n Show/Hide All \r\n </label>\r\n </div>\r\n </div>\r\n <div class=\"list-group list-group-flush\">\r\n <ng-container *ngFor=\"let col of columns | filter : topShowHideColumns : 'header'; trackBy: trackByField\">\r\n <div\r\n *ngIf=\"!col.is_visible\"\r\n class=\"list-group-item border-0 px-0 d-flex justify-content-between align-items-center\"\r\n >\r\n <div class=\"d-flex gap-1\">\r\n <div>\r\n <span\r\n *ngIf=\"!col?.pinned\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/grip-vertical.svg'\r\n \"\r\n class=\"data-grid-svg-icon cursor-grap\"\r\n (mousedown)=\"$event.preventDefault()\"\r\n ></span>\r\n <span\r\n *ngIf=\"col?.pinned\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/pin-blue.svg'\r\n \"\r\n class=\"data-grid-svg-icon cursor-grap\"\r\n (mousedown)=\"$event.preventDefault()\"\r\n ></span>\r\n </div>\r\n <div class=\"fw-semibold\">\r\n {{ col.header }}\r\n </div>\r\n </div>\r\n <div\r\n class=\"d-flex align-items-center cursor-pointer\"\r\n (click)=\"toggleColumnVisibility(col, true)\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/eye-cross.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n </div>\r\n </div>\r\n </ng-container>\r\n </div>\r\n\r\n <!-- Item End Here -->\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template #filterColumns let-col=\"column\">\r\n <div\r\n @slideToggle\r\n *ngIf=\"!isFilterOpen && activeTopButton == 'filter-columns'\"\r\n (click)=\"$event.stopPropagation()\"\r\n class=\"shadow actions-dropdown mt-1 show shadow custom-menu table-layout filter-columns\"\r\n style=\"width: 280px; right: unset; max-width: 230px\"\r\n [style.backgroundColor]=\"checkboxesBackgroundColor\"\r\n >\r\n <div class=\"mb-2 px-3\">\r\n <div class=\"col-12 global-search\">\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/search.svg'\"\r\n class=\"data-grid-svg-icon mx-2 position-absolute icon\"\r\n ></span>\r\n <input\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Filter by\"\r\n type=\"search\"\r\n [(ngModel)]=\"addFilterColumnInput\"\r\n />\r\n </div>\r\n </div>\r\n <div\r\n class=\"list-group list-group-flush\"\r\n style=\"max-height: calc(100vh - 500px); overflow: auto\"\r\n >\r\n <ng-container\r\n *ngFor=\"\r\n let col of columns | filter : addFilterColumnInput : 'header';\r\n trackBy: trackByField\r\n \"\r\n >\r\n <div\r\n (click)=\"openFilter(col)\"\r\n *ngIf=\"\r\n col.is_visible &&\r\n !col?.query?.first_value &&\r\n !col?.query?._ids?.length && col?.type !== 'image' && col.is_search_able\r\n \"\r\n class=\"list-group-item border-0 px-0 d-flex justify-content-between align-items-center dropdown-item cursor-pointer\"\r\n >\r\n <div class=\"d-flex gap-1\">\r\n <div style=\"margin-top: -3px\"></div>\r\n <div class=\"fw-semibold\">\r\n {{ col.header }}\r\n </div>\r\n </div>\r\n </div>\r\n </ng-container>\r\n </div>\r\n </div>\r\n\r\n <!-- Dropdown -->\r\n <div\r\n @slideToggle\r\n *ngIf=\"isFilterOpen && selectedColumnForFilter?.type == 'dropdown' || selectedColumnForFilter?.type == 'array'\"\r\n (click)=\"$event.stopPropagation()\"\r\n class=\"shadow actions-dropdown mt-1 show shadow custom-menu table-layout filter-columns pb-2\"\r\n style=\"width: 280px; right: unset; max-width: 230px\"\r\n [style.backgroundColor]=\"checkboxesBackgroundColor\"\r\n >\r\n <div class=\"px-3 my-2 border-below py-1 pb-2 mb-3 d-flex ps-1\">\r\n <span\r\n (click)=\"toggleActions('filter-columns'); isActiveFilterOpen = false\"\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrow-left.svg'\"\r\n class=\"data-grid-svg-icon me-2 cursor-pointer\"\r\n ></span\r\n ><b>{{ selectedColumnForFilter?.header }}</b>\r\n </div>\r\n <div class=\"mb-2 px-3\">\r\n <div\r\n class=\"col-12 global-search position-relative border rounded d-flex align-items-center flex-wrap px-2 filter-serach-inpt\"\r\n >\r\n <span\r\n *ngFor=\"let selected of selectedFilterOptions\"\r\n class=\"badge d-flex align-items-center gap-1 me-1 mb-1 top-row-filter-dropdown\"\r\n >\r\n {{ selected?.value ? selected.value : selected }}\r\n <span\r\n (click)=\"toggleSelectionInFilter(selected)\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/cross-primary.svg'\r\n \"\r\n class=\"me-2\"\r\n ></span>\r\n </span>\r\n <input\r\n class=\"form-control form-control-sm border-0 flex-grow-1\"\r\n style=\"padding: 0\"\r\n [placeholder]=\"selectedFilterOptions?.length ? '' : 'Filter by'\"\r\n type=\"search\"\r\n [(ngModel)]=\"searchTextForFilterDropDown\"\r\n (keydown.backspace)=\"handleBackspace($event)\"\r\n />\r\n </div>\r\n </div>\r\n <div\r\n class=\"list-group list-group-flush\"\r\n style=\"max-height: calc(100vh - 600px); overflow: auto\"\r\n >\r\n <ng-container\r\n *ngFor=\"\r\n let col of selectedColumnForFilter.column_dropdown_value\r\n | filter : searchTextForFilterDropDown : 'value';\r\n let i = index\r\n \"\r\n >\r\n <div\r\n class=\"list-group-item border-0 px-2 d-flex justify-content-between align-items-center dropdown-item cursor-pointer\"\r\n >\r\n <div class=\"form-check\">\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n [id]=\"i\"\r\n [checked]=\"currentFilterSelectedIds.has(col.id || col._id || col)\"\r\n (change)=\"toggleSelectionInFilter(col)\"\r\n />\r\n <label class=\"form-check-label fw-semibold\" [for]=\"i\">\r\n {{ col?.value || col?.name || col }}\r\n </label>\r\n </div>\r\n </div>\r\n </ng-container>\r\n </div>\r\n <div\r\n class=\"d-flex justify-content-center gap-2 px-2 border-top\"\r\n style=\"height: 38px\"\r\n >\r\n <button\r\n type=\"button\"\r\n style=\"height: 32px\"\r\n class=\"btn btn-outline-secondary btn-light border w-100 d-flex align-items-center justify-content-center mt-1 btn-light\"\r\n (click)=\"$event.stopPropagation(); resetFilterChanges()\"\r\n >\r\n <span>Cancel</span>\r\n </button>\r\n <button\r\n type=\"button\"\r\n style=\"height: 32px\"\r\n class=\"btn btn-primary w-100 d-flex align-items-center justify-content-center mt-1\"\r\n (click)=\"applyDropdownFilter()\"\r\n >\r\n <span style=\"margin-top: -2px\">Save</span>\r\n </button>\r\n </div>\r\n </div>\r\n\r\n <!-- For Text fields and number fields-->\r\n\r\n <div\r\n @slideToggle\r\n *ngIf=\"\r\n isFilterOpen &&\r\n (selectedColumnForFilter?.type == 'string' ||\r\n selectedColumnForFilter?.type == 'number' ||\r\n selectedColumnForFilter?.type == 'time' ||\r\n selectedColumnForFilter?.type == 'date')\r\n \"\r\n (click)=\"$event.stopPropagation()\"\r\n class=\"shadow actions-dropdown mt-1 show shadow custom-menu table-layout filter-columns pb-2\"\r\n style=\"width: 210px; right: unset; max-width: 230px\"\r\n [style.backgroundColor]=\"checkboxesBackgroundColor\"\r\n >\r\n <div class=\"px-3 border-below py-1 pb-2 d-flex ps-1\">\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrow-left.svg'\"\r\n (click)=\"toggleActions('filter-columns'); isActiveFilterOpen = false\"\r\n class=\"data-grid-svg-icon me-2 cursor-pointer\"\r\n ></span\r\n ><b>{{ selectedColumnForFilter?.header }}</b>\r\n </div>\r\n <div class=\"col-12 position-relative p-2 text-filter\">\r\n <div class=\"mb-2\">\r\n <select\r\n class=\"form-select form-select-sm custom-select border\"\r\n [(ngModel)]=\"firstCondition\"\r\n >\r\n <ng-container *ngIf=\"selectedColumnForFilter?.type == 'string'\">\r\n <option value=\"contain\">Contains</option>\r\n <option value=\"does_not_contain\">Does Not Contain</option>\r\n <option value=\"equal\">Equals</option>\r\n <option value=\"before\">Starts With</option>\r\n <option value=\"after\">Ends With</option>\r\n </ng-container>\r\n\r\n <ng-container *ngIf=\"selectedColumnForFilter?.type == 'date' || selectedColumnForFilter?.type == 'time'\">\r\n <option value=\"equal\">Equals To</option>\r\n <option value=\"not_equal\">Not Equal</option>\r\n <option value=\"after\">After</option>\r\n <option value=\"before\">Before</option>\r\n </ng-container>\r\n\r\n <ng-container *ngIf=\"selectedColumnForFilter?.type == 'number'\">\r\n <option value=\"equal\">Equals To</option>\r\n <option value=\"before\">Less Then </option>\r\n <option value=\"after\">Greater Then </option>\r\n <option value=\"less_then_equal\">less then Equal to</option>\r\n <option value=\"greater_then_equal\">Greater then Equal to </option>\r\n </ng-container>\r\n </select>\r\n </div>\r\n <div class=\"mb-2\">\r\n <input\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Enter first value\"\r\n type=\"search\"\r\n [type]=\"\r\n selectedColumnForFilter?.type == 'string'\r\n ? 'text'\r\n : selectedColumnForFilter?.type\r\n \"\r\n [(ngModel)]=\"firstValue\"\r\n (keydown.enter)=\"applyDropdownFilter()\"\r\n />\r\n </div>\r\n <div>\r\n <div class=\"d-flex my-3 d-flex flex-row\" style=\"font-size: 14px\">\r\n <div\r\n class=\"form-check form-check-inline col-4 m-0 d-flex align-items-center gap-1\"\r\n >\r\n <input\r\n class=\"form-check-input\"\r\n type=\"radio\"\r\n id=\"logicalAnd\"\r\n name=\"logicalOperator\"\r\n value=\"and\"\r\n [(ngModel)]=\"condition\"\r\n />\r\n <label class=\"form-check-label mb-0 mt-1\" for=\"logicalAnd\"\r\n >AND</label\r\n >\r\n </div>\r\n\r\n <div\r\n class=\"form-check form-check-inline col-4 m-0 d-flex align-items-center gap-1\"\r\n >\r\n <input\r\n class=\"form-check-input\"\r\n type=\"radio\"\r\n id=\"logicalOr\"\r\n name=\"logicalOperator\"\r\n value=\"or\"\r\n [(ngModel)]=\"condition\"\r\n />\r\n <label class=\"form-check-label mb-0 mt-1\" for=\"logicalOr\">OR</label>\r\n </div>\r\n\r\n <div\r\n class=\"form-check form-check-inline col-4 m-0 d-flex align-items-center gap-1\"\r\n >\r\n <input\r\n class=\"form-check-input\"\r\n type=\"radio\"\r\n id=\"logicalNone\"\r\n name=\"logicalOperator\"\r\n value=\"none\"\r\n [(ngModel)]=\"condition\"\r\n />\r\n <label class=\"form-check-label mb-0 mt-1\" for=\"logicalNone\"\r\n >None</label\r\n >\r\n </div>\r\n </div>\r\n\r\n <ng-container *ngIf=\"condition !== 'none' && firstValue\">\r\n <div class=\"mb-2 mt-3\">\r\n <!-- Second condition select -->\r\n <select\r\n class=\"form-select form-select-sm border\"\r\n [(ngModel)]=\"secondCondition\"\r\n >\r\n <ng-container *ngIf=\"selectedColumnForFilter?.type == 'string'\">\r\n <option value=\"contain\">Contains</option>\r\n <option value=\"does_not_contain\">Does Not Contain</option>\r\n <option value=\"equal\">Equals</option>\r\n <option value=\"before\">Starts With</option>\r\n <option value=\"after\">Ends With</option>\r\n </ng-container>\r\n\r\n <ng-container *ngIf=\"selectedColumnForFilter?.type == 'date' || selectedColumnForFilter?.type == 'time'\">\r\n <option value=\"equal\">Equals To</option>\r\n <option value=\"not_equal\">Not Equal</option>\r\n <option value=\"after\">After</option>\r\n <option value=\"before\">Before</option>\r\n </ng-container>\r\n <ng-container *ngIf=\"selectedColumnForFilter?.type == 'number'\">\r\n <option value=\"equal\">Equals To</option>\r\n <option value=\"before\">Less Then </option>\r\n <option value=\"after\">Greater Then </option>\r\n <option value=\"less_then_equal\">less then Equal to</option>\r\n <option value=\"greater_then_equal\">Greater then Equal to </option>\r\n </ng-container>\r\n </select>\r\n </div>\r\n\r\n <div class=\"mb-2\">\r\n <!-- Second value input -->\r\n <input\r\n [type]=\"\r\n selectedColumnForFilter?.type == 'string'\r\n ? 'text'\r\n : selectedColumnForFilter?.type\r\n \"\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Enter second value\"\r\n type=\"search\"\r\n [(ngModel)]=\"secondValue\"\r\n (keydown.enter)=\"applyDropdownFilter()\"\r\n />\r\n </div>\r\n </ng-container>\r\n </div>\r\n </div>\r\n\r\n <div\r\n class=\"d-flex justify-content-center gap-2 px-2 border-top\"\r\n style=\"height: 38px\"\r\n >\r\n <button\r\n [disabled]=\"!currentFilterSelectedIds?.size && !firstValue\"\r\n type=\"button\"\r\n style=\"height: 32px\"\r\n class=\"btn btn-outline-secondary btn-light border w-100 d-flex align-items-center justify-content-center mt-1 btn-light\"\r\n (click)=\"$event.stopPropagation(); resetTextFilterChanges()\"\r\n >\r\n <span>Cancel</span>\r\n </button>\r\n <button\r\n [disabled]=\"(currentFilterSelectedIds?.size === 0 && !firstValue) || (condition !== 'none' && !secondValue)\"\r\n type=\"button\"\r\n style=\"height: 32px\"\r\n class=\"btn btn-primary w-100 d-flex align-items-center justify-content-center mt-1\"\r\n (click)=\"applyDropdownFilter()\"\r\n >\r\n <span style=\"margin-top: -2px\">Apply</span>\r\n </button>\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<!-- Edit dropdown here -->\r\n<ng-template let-col>\r\n <div class=\"drop-down-edit\"></div>\r\n</ng-template>\r\n\r\n<ng-template\r\n #fullTextTemplate\r\n let-row=\"row\"\r\n let-col=\"col\"\r\n let-isArray=\"isArray\"\r\n>\r\n <div\r\n class=\"full-text-box\"\r\n (dblclick)=\"$event.stopPropagation(); $event.preventDefault()\"\r\n (click)=\"$event.stopPropagation(); $event.preventDefault()\"\r\n [style.maxHeight.px]=\"dataGridContainer.offsetHeight / 2\"\r\n >\r\n <ng-container *ngIf=\"!isEditing(row, col)\">\r\n <div\r\n *ngIf=\"!isArray\"\r\n class=\"full-text-content\"\r\n [style.maxHeight.px]=\"dataGridContainer.offsetHeight / 2\"\r\n (dblclick)=\"\r\n $event.stopPropagation();\r\n $event.preventDefault();\r\n enableEdit(row, col, true)\r\n \"\r\n (click)=\"$event.stopPropagation(); $event.preventDefault()\"\r\n >\r\n {{\r\n getNestedValue(row, col.field)?.value ||\r\n getNestedValue(row, col.field)?.name ||\r\n getNestedValue(row, col.field)\r\n }}\r\n </div>\r\n <div *ngIf=\"isArray\">\r\n <ul>\r\n <ng-container\r\n *ngFor=\"let item of getNestedValue(row, col.field); let i = index\"\r\n >\r\n <li *ngIf=\"i !== 0\">\r\n <ng-container>\r\n {{\r\n item?.department_name ||\r\n item?.roleName ||\r\n item?.full_name ||\r\n \"-\"\r\n }}\r\n </ng-container>\r\n </li>\r\n </ng-container>\r\n </ul>\r\n </div>\r\n </ng-container>\r\n <ng-container *ngIf=\"isEditing(row, col)\">\r\n <textarea\r\n (dblclick)=\"\r\n $event.stopPropagation();\r\n $event.preventDefault();\r\n enableEdit(row, col, true)\r\n \"\r\n #textModel=\"ngModel\"\r\n rows=\"4\"\r\n #textAreadInput\r\n [(ngModel)]=\"row[col.field]\"\r\n name=\"{{ col.field }}\"\r\n required\r\n (blur)=\"disableEdit(row, col, textModel)\"\r\n (keydown.enter)=\"textAreadInput.blur()\"\r\n autofocus\r\n class=\"form-control\"\r\n [ngClass]=\"{\r\n 'is-invalid': textModel.invalid\r\n }\"\r\n (mousedown)=\"$event.stopPropagation()\"\r\n ></textarea>\r\n </ng-container>\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template #defaultImagePlaceholder let-row=\"row\" let-col=\"col\">\r\n <span\r\n class=\"px-2 d-flex w-100 cell-content image-placeholder\"\r\n [title]=\"row?.full_name || row?.name || 'N/A'\"\r\n >\r\n <ng-container\r\n *ngIf=\"\r\n row?.logo ||\r\n row?.assetImage ||\r\n row?.invoice?.invoice_image ||\r\n row?.invoice_image;\r\n else placeholder\r\n \"\r\n >\r\n <span\r\n (click)=\"fullscreenImage = row?.profile_pictures?.[4]?.path ||\r\n row?.logo ||\r\n row?.assetImage ||\r\n row?.invoice_image\"\r\n class=\"pic\"\r\n [style.width.px]=\"rowHeight - 10\"\r\n [style.height.px]=\"rowHeight - 10\"\r\n [class.assets-pic]=\"gridType == 'Assets'\"\r\n >\r\n <img\r\n [width]=\"rowHeight - 12\"\r\n [height]=\"rowHeight - 12\"\r\n [style.width.px]=\"rowHeight - 10\"\r\n [style.height.px]=\"rowHeight - 10\"\r\n [src]=\"\r\n row?.profile_pictures?.[4]?.path ||\r\n row?.logo ||\r\n row?.assetImage ||\r\n row?.invoice_image\r\n \"\r\n alt=\"icon\"\r\n class=\"option-icon\"\r\n loading=\"lazy\"\r\n />\r\n </span>\r\n </ng-container>\r\n <!-- <div\r\n class=\"fullscreen-overlay\"\r\n *ngIf=\"fullscreenImage\"\r\n (click)=\"fullscreenImage = null\"\r\n >\r\n <img [src]=\"fullscreenImage\" class=\"fullscreen-img\" />\r\n </div> -->\r\n\r\n <ng-template #placeholder>\r\n <span\r\n [ngClass]=\"getDynamicClass(row?.full_name || row?.name)\"\r\n class=\"pic d-flex align-items-center rounded-circle\"\r\n [style.width.px]=\"rowHeight - 12\"\r\n [style.height.px]=\"rowHeight - 12\"\r\n [style.fontSize.px]=\"rowHeight / 3\"\r\n [class.assets-pic]=\"gridType == 'Assets'\"\r\n >\r\n {{ getInitials(row?.full_name) }}\r\n </span>\r\n </ng-template>\r\n </span>\r\n</ng-template>\r\n\r\n<!-- Right Click Menue -->\r\n<div\r\n [class.invisible]=\"!positionedYet\"\r\n class=\"context-menu p-2\"\r\n *ngIf=\"actionHide && actions?.length\"\r\n [ngStyle]=\"{ 'top.px': yPos, 'left.px': xPos }\"\r\n [class.show]=\"isVisible\"\r\n appendTo=\"body\"\r\n>\r\n <ul>\r\n <li\r\n *ngFor=\"let action of actions\"\r\n class=\"rounded d-flex align-items-center\"\r\n (click)=\"onActionClick(action)\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/' + action + '.svg'\"\r\n class=\"data-grid-svg-icon right-click-menu-icons me-2\"\r\n ></span>\r\n <span class=\"text-capitalize fw-500\">{{ action }}</span>\r\n </li>\r\n </ul>\r\n</div>\r\n\r\n<!-- Details Toggle from bottom -->\r\n\r\n<ng-template #nestedTableTemplate let-row>\r\n <div\r\n class=\"nested-table table table-sm w-100 mb-0 center-nested-table w-100\"\r\n style=\"table-layout: fixed !important\"\r\n #nestedTableContainer\r\n >\r\n <thead\r\n #nestedHeader\r\n [style.backgroundColor]=\"nestedTableHeaderBackgroundColor\"\r\n >\r\n <div\r\n cdkDropList\r\n [cdkDropListData]=\"row?.detail.columns\"\r\n cdkDropListOrientation=\"horizontal\"\r\n (cdkDropListDropped)=\"dropColumn($event, row)\"\r\n (cdkDropListSorted)=\"onNestedColSort($event, previewNestedCols)\"\r\n [style.height.px]=\"nestedTableHeaderRowHeight\"\r\n class=\"d-flex tr border-below\"\r\n >\r\n <div\r\n *ngFor=\"let col of row.detail.columns; let i = index\"\r\n [style.width.px]=\"col?.width || 250\"\r\n [style.minWidth.px]=\"col?.width || 250\"\r\n [style.maxWidth.px]=\"col?.width || 250\"\r\n class=\"px-4 th\"\r\n [attr.field]=\"col.field\"\r\n [style.backgroundColor]=\"nestedTableHeaderBackgroundColor\"\r\n cdkDrag\r\n >\r\n <div\r\n class=\"d-flex h-100 justify-content-between position-relative align-items-center\"\r\n >\r\n <div class=\"text-ellipsis\" (click)=\"sortNestedCol(col, row)\">\r\n {{ col.header }}\r\n </div>\r\n <div class=\"d-flex gap-2\">\r\n <span\r\n *ngIf=\"currentSubSortColumn == col.field\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath +\r\n (col?.order_by == 'desc'\r\n ? 'data-grid/icons/sort-desc.svg'\r\n : 'data-grid/icons/sort-asc.svg')\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center ms-2 start-50\"\r\n >\r\n </span>\r\n <!-- <div\r\n class=\"three-dots p-1\"\r\n (click)=\"openThreeDotsMenu($event, col)\"\r\n style=\"cursor: pointer\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath +\r\n 'data-grid/icons/three-dots-vertical.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div> -->\r\n\r\n <!-- Only show menu if this column is active -->\r\n <div\r\n class=\"position-absolute\"\r\n *ngIf=\"activeCol === col\"\r\n style=\"top: -50%; z-index: 21; left: 0\"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n columnMenu;\r\n context: {\r\n col: col,\r\n isNestedTable: true,\r\n columns: row?.detail.columns\r\n }\r\n \"\r\n ></ng-container>\r\n </div>\r\n <div\r\n class=\"resize-handle\"\r\n (click)=\"$event.stopPropagation()\"\r\n (mousedown)=\"\r\n $event.preventDefault();\r\n onResizeColumn($event, col);\r\n $event.stopPropagation()\r\n \"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/resize-handle.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n </div>\r\n </div>\r\n <ng-template cdkDragPreview>\r\n <div class=\"p-2 border d-flex gap-2\">\r\n <div>\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/arrows-move.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n <div>{{ col.header }}</div>\r\n </div>\r\n </ng-template>\r\n </div>\r\n </div>\r\n </thead>\r\n <div\r\n [style.width.px]=\"nestedHeader.offsetWidth - 10\"\r\n [style.minWidth.px]=\"nestedHeader.offsetWidth - 10\"\r\n >\r\n <cdk-virtual-scroll-viewport\r\n [itemSize]=\"nestedTablerowHeight\"\r\n class=\"viewport\"\r\n [style.height.px]=\"\r\n (row?.detail?.result?.length < 5\r\n ? nestedTablerowHeight * row?.detail?.result?.length + 40\r\n : 300) + (hasHorizontalScroll ? -12 : 1)\r\n \"\r\n [style.width.px]=\"nestedHeader.offsetWidth - 10\"\r\n [style.minWidth.px]=\"nestedHeader.offsetWidth - 10\"\r\n >\r\n <div\r\n class=\"cursor-pointer border-below d-flex tr\"\r\n *cdkVirtualFor=\"let d of row?.detail?.result; trackBy: trackById\"\r\n [style.height.px]=\"nestedTablerowHeight\"\r\n [style.width.px]=\"nestedHeader?.offsetWidth\"\r\n [style.minWidth.px]=\"nestedHeader?.offsetWidth\"\r\n [style.backgroundColor]=\"bodyBackgroundColor\"\r\n (contextmenu)=\"onRightClick($event, d)\"\r\n >\r\n <div\r\n class=\"px-4 py-0 td\"\r\n *ngFor=\"let col of previewNestedCols; let j = index\"\r\n [style.fontSize.px]=\"nestedTablerowFontsize\"\r\n [attr.field]=\"col.field\"\r\n [style.width.px]=\"col?.width || 250\"\r\n [style.minWidth.px]=\"col?.width || 250\"\r\n [style.maxWidth.px]=\"col?.width || 250\"\r\n >\r\n <div\r\n [style.height.px]=\"nestedTablerowHeight - 1\"\r\n [style.max-width.px]=\"col?.width\"\r\n class=\"d-flex align-items-center\"\r\n >\r\n <!-- {{ d[col.field] || (col.is_amount ? 0 : \"-\") }} -->\r\n <div\r\n #cellText\r\n class=\"text-ellipsis flex-grow-1\"\r\n [title]=\"\r\n col?.type === 'date'\r\n ? (getNestedValue(d, col.field) | date : dateFormat)\r\n : getNestedValue(d, col.field) || '-'\r\n \"\r\n >\r\n <ng-container *ngIf=\"col?.type !== 'image'\">\r\n <ng-container *ngIf=\"col.is_amount\">{{\r\n currencySymbol\r\n }}</ng-container>\r\n {{\r\n !isNestedValueArray(d, col.field)\r\n ? col?.type === 'date'\r\n ? (isDate(getNestedValue(d, col.field))\r\n ? (getNestedValue(d, col.field) | date: dateFormat)\r\n : (getNestedValue(d, col.field)?.value ||\r\n getNestedValue(d, col.field)?.name ||\r\n getNestedValue(d, col.field) ||\r\n '-'))\r\n : (getNestedValue(d, col.field)?.value ||\r\n getNestedValue(d, col.field)?.name ||\r\n getNestedValue(d, col.field) ||\r\n (col.is_amount ? 0: '-'))\r\n : (getNestedValue(d, col.field)?.[0]?.department_name ||\r\n getNestedValue(d, col.field)?.[0]?.roleName || getNestedValue(d, col.field)?.[0]?.full_name ||\r\n '-')\r\n }}\r\n </ng-container>\r\n <ng-container *ngIf=\"false\">\r\n {{ getTotalAmount(col) }}\r\n </ng-container>\r\n <ng-container *ngIf=\"col?.type == 'image'\">\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n defaultImagePlaceholder;\r\n context: {\r\n row: d,\r\n col: col,\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </cdk-virtual-scroll-viewport>\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template #leftRightNestedPlaceholder let-row>\r\n <table\r\n class=\"nested-table table table-sm w-100 mb-0\"\r\n [style.backgroundColor]=\"bodyBackgroundColor\"\r\n [style.height.px]=\"\r\n gridType == 'Assets'\r\n ? (nestedTableContainer?.nativeElement?.offsetHeight ?? 0) + 12\r\n : (taskManagementContainer?.nativeElement?.offsetHeight ?? 0)\r\n \"\r\n >\r\n <!-- <div class=\"thead\">\r\n <div\r\n class=\"tr d-flex border-below\"\r\n [style.height.px]=\"nestedTableHeaderRowHeight\"\r\n [style.backgroundColor]=\"headerBackgroundColor\"\r\n >\r\n <div class=\"th\" *ngFor=\"let _ of [1, 2, 3, 4, 5]\"></div>\r\n </div>\r\n </div> -->\r\n <!-- <div class=\"tbody\">\r\n <div\r\n class=\"tr border-below\"\r\n [style.height.px]=\"nestedTablerowHeight\"\r\n *ngFor=\"let _ of row?.detail?.result\"\r\n [style.backgroundColor]=\"headerBackgroundColor\"\r\n >\r\n <div class=\"td\" *ngFor=\"let __ of [1, 2, 3, 4, 5]\" class=\"py-0\">\r\n <span\r\n [style.height.px]=\"nestedTablerowHeight\"\r\n [style.max-width.px]=\"nestedTablerowHeight\"\r\n ></span>\r\n </div>\r\n </div>\r\n </div> -->\r\n </table>\r\n</ng-template>\r\n\r\n<ng-template #taskManagementTemplate let-taskDetails=\"taskDetails\">\r\n <div\r\n class=\"p-4\"\r\n #taskManagementContainer\r\n [style.backgroundColor]=\"nestedTableHeaderBackgroundColor\"\r\n [style.fontFaimly]=\"fontFaimly\"\r\n >\r\n <div class=\"d-flex justify-content-between\">\r\n <div class=\"col-4\">\r\n <div class=\"item-title\">Description</div>\r\n <!-- <div class=\"item-content firstDiv\">\r\n {{ taskDetails.description }}\r\n </div> -->\r\n <p\r\n [style.fontSize]=\"bodyTextFontsSize\"\r\n class=\"item-content firstDiv taskDescription pe-4\"\r\n [innerHTML]=\"getSafeComment(taskDetails?.editor_description)\"\r\n (click)=\"openFullImage($event)\"\r\n ></p>\r\n </div>\r\n <div class=\"col-4\">\r\n <div class=\"item-title\">Attachments</div>\r\n <h5 *ngIf=\"taskDetails?.attachments?.length == 0\">\r\n No Attachments found\r\n </h5>\r\n <div\r\n *ngIf=\"taskDetails?.attachments?.length\"\r\n class=\"item-content d-flex flex-wrap\"\r\n style=\"gap: 10px\"\r\n >\r\n <a\r\n *ngFor=\"let attachement of taskDetails?.attachments; let i = index\"\r\n class=\"symbol-label fs-2 fw-semibold text-success cursor-pointer\"\r\n >\r\n <span\r\n title=\"{{ taskDetails?.attachments_name[i] || 'Attachment' }}\"\r\n (click)=\"downloadAttchment(attachement)\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath +\r\n 'data-grid/document-icons/' +\r\n getExtention(attachement) +\r\n '.svg'\r\n \"\r\n >\r\n </span>\r\n </a>\r\n </div>\r\n </div>\r\n <div class=\"col-4\">\r\n <div class=\"item-title\">\r\n Comments ({{ taskDetails?.comments?.length }})\r\n </div>\r\n <h5 *ngIf=\"taskDetails?.comments?.length == 0\">No Comments found</h5>\r\n <div *ngIf=\"taskDetails?.comments?.length\" class=\"item-content\">\r\n <div class=\"comment\" *ngFor=\"let comment of taskDetails.comments\">\r\n <div class=\"d-flex align-items-center pe-3\">\r\n <img\r\n class=\"pic image-input-wrapper\"\r\n [style.width.px]=\"rowHeight - 12\"\r\n [style.height.px]=\"rowHeight - 12\"\r\n *ngIf=\"comment?.comment_by.logo\"\r\n src=\"{{ comment?.comment_by.logo }}\"\r\n alt=\"{{ comment.comment_by.full_name }}\"\r\n />\r\n <!-- <app-default-image-placeholder *ngIf=\"!comment?.comment_by.logo\" title=\"{{ comment.comment_by.full_name }}\" [name]=\"comment.comment_by.full_name\"></app-default-image-placeholder> -->\r\n <span\r\n *ngIf=\"!comment?.comment_by.logo\"\r\n [ngClass]=\"getDynamicClass(comment.comment_by.full_name)\"\r\n class=\"pic d-flex align-items-center rounded-circle\"\r\n [style.width.px]=\"rowHeight - 12\"\r\n [style.height.px]=\"rowHeight - 12\"\r\n [style.fontSize.px]=\"rowHeight / 3\"\r\n title=\"{{ comment.comment_by.full_name }}\"\r\n >\r\n {{ getInitials(comment.comment_by.full_name) }}\r\n </span>\r\n </div>\r\n <div>\r\n <div class=\"comment-author fs-14px\">\r\n {{ comment?.comment_by.full_name }}\r\n </div>\r\n <div\r\n class=\"comment-content forCommentImg\"\r\n [innerHTML]=\"getSafeComment(comment.comment)\"\r\n ></div>\r\n <div class=\"comment-timestamp\">\r\n {{ comment.comment_date | date }}\r\n </div>\r\n <div class=\"comment-timestamp\">\r\n Replies: ({{ comment.replies.length }})\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n</ng-template>\r\n", styles: ["@charset \"UTF-8\";@import\"bootstrap/dist/css/bootstrap.min.css\";.data-grid-table-wrapper{height:100%;width:100%;border:1px solid #d9d9db;border-radius:12px;position:relative}.data-grid-header{position:sticky;top:0}.data-grid-header{display:flex}.header-row{display:grid;width:100%}.header-cell{display:flex;align-items:center;position:relative;width:100%;padding:8px 0 8px 8px;font-weight:700;border-bottom:1px solid #d9d9db;white-space:nowrap;min-width:80px;font-weight:600}.header-cell .filter-applied-on-text{color:#5d9cff!important}.filter-cell{padding:4px!important;display:flex;align-items:center;gap:8px;width:100%}.filter-cell .filter-applied{background-color:#bddef9}.border-right{border-right:1px solid #d9d9db}.merged-grid{display:grid;grid-auto-rows:40px;border-bottom:1px solid #ccc}.span-two-rows{grid-row:span 2;display:flex;justify-content:space-between;align-items:center}.group-header{display:flex;justify-content:space-between;position:relative}.group-header-content{position:sticky;left:10px;overflow:hidden;text-overflow:ellipsis}.resize-handle{width:6px;cursor:e-resize;right:0;top:0;color:#00000026;margin-right:4px}.group-header .resize-handle{top:25%}.h-100{height:100%}.data-grid-body{position:relative;overflow-y:auto;overflow-x:hidden}.cell{padding:8px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;height:100%;display:flex;align-items:center}.data-grid-row{display:flex;width:100%;min-width:max-content;align-items:center;border-bottom:1px solid #d9d9db}.hovered-row{background-color:#ccc}.checkbox-row{border-bottom:#d9d9db}.w-100{width:100%}.data-grid-header-wrapper{display:flex;position:relative;overflow:hidden;-webkit-user-select:none;user-select:none}.data-grid-header{display:flex;position:relative;z-index:1}.left-pinned,.right-pinned{position:sticky;top:0}.right-pinned-header{position:absolute;right:0;border-left:1px solid #d9d9db;z-index:unset}.left-pinned{left:0}.right-pinned{right:0;border-left:1px solid #d9d9db}.center-scrollable{z-index:unset!important;overflow-x:auto;overflow-y:visible;white-space:nowrap;scrollbar-width:none;-ms-overflow-style:none}.center-scrollable::-webkit-scrollbar{display:none}.data-grid-body-wrapper{-webkit-user-select:none;user-select:none;display:flex}.center-scrollable-body{overflow-x:auto;scrollbar-width:none;-ms-overflow-style:none}.center-scrollable-body::-webkit-scrollbar{display:none}.left-pinned-body,.right-pinned-body{position:sticky;top:0;z-index:unset;background:#fff;scrollbar-width:none;-ms-overflow-style:none}.left-pinned-body::-webkit-scrollbar,.right-pinned-body::-webkit-scrollbar{display:none}.left-pinned-body{left:0}.border-end{border-right:1px solid #d9d9db!important}.right-pinned-body{right:0;border-left:1px solid #d9d9db}.fake-scroll-bar{height:14px;overflow:scroll;margin-bottom:10px}.text-ellipsis{overflow:hidden;text-overflow:ellipsis}.select-all-checkbox-cell{width:50px;display:flex;justify-content:center;align-items:center;height:100%;border-right:1px solid #d9d9db}.select-all-checkbox-cell input{width:16px;height:14px}.border-below{border-bottom:1px solid #d9d9db!important}.three-dots{width:22px;height:22px;display:flex;justify-content:center;align-items:center;border-radius:3px;margin-right:8px;cursor:pointer}.three-dots:hover{background-color:#ccc!important}.filter-icon-wrapper{min-height:22px;max-height:22px;min-width:22px;max-width:22px;display:flex;justify-content:center;align-items:center;border-radius:3px;cursor:pointer;transition:background-color .3s ease}.filter-icon-wrapper:hover{background-color:#ccc}.column-menu,.filter-menu{box-shadow:0 0 16px #00000026;border-radius:4px}.column-menu{background:#fff;width:100%;width:240px;border:1px solid #ddd;box-shadow:0 0 16px #00000026;border:1px solid #d9d9db;padding:4px 0;font-size:14px;position:fixed}.column-menu-item{padding:8px 12px;cursor:pointer;display:flex;align-items:center;transition:background-color .2s ease}.column-menu-item:hover{background-color:#deebf7}.pin-parent{position:relative;width:100%!important}.column-submenu{position:absolute;top:0;left:100%;background:#fff;border:1px solid #ddd;width:130px;box-shadow:0 0 16px #00000026;border:1px solid #d9d9db;display:none;padding:4px 0;z-index:10;border-radius:4px}.pin-parent:hover .column-submenu{display:block}.filter-menu-container{position:fixed;width:210px;background:#fff;border:1px solid #ddd;border-radius:4px;padding:12px;box-shadow:0 0 16px #00000026;border:1px solid #d9d9db;z-index:1000;font-size:14px}.filter-menu-header{font-weight:600;margin-bottom:10px}.filter-dropdown-section{max-height:350px;overflow-y:auto}.dropdown-options{overflow-y:auto;scrollbar-width:thin;height:100%}.filter-text-section select,.filter-text-section input{width:100%}.filter-radio-inputs{width:14px!important;height:14px!important}.right-menu{border-left:1px solid #d9d9db;font-size:14px}.border-start{border-left:1px solid #d9d9db!important}.column-panel-item{font-size:.875rem;color:#333}.toggle-icon{cursor:pointer;transition:transform .2s ease}.toggle-icon.rotate{transform:rotate(90deg)}.grab-icon{cursor:grab;color:#6c757d}.text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.cursor-pointer{cursor:pointer}.pivot-mode{height:48px}.chevron-wrapper{width:30px;height:20px;cursor:pointer;border-radius:3px;display:flex;justify-content:center;align-items:center;transition:background-color .3s ease;margin-right:8px}.chevron-wrapper:hover{background-color:#cac7c7}.chevron-wrapper i{font-size:14px}.column-panel-body{height:70%;overflow:auto;scrollbar-width:thin}.side-menue-text{transform:rotate(90deg);position:relative;font-weight:700;margin-top:40px}.columns-button{padding-top:20px;padding-bottom:35px;width:29px}.fake-scroll-content{height:12px}.fake-scrollbar{width:25px}.fake-scrollbar div{min-width:1px}.fake-horizintal-scrollbar div{min-height:1px}.side-filter-columns-wrapper{height:calc(100% - 25px)}.custom-modal-overlay{position:fixed;top:0;left:0;width:100%;height:100%;overflow:hidden;display:flex;justify-content:center;align-items:center;z-index:1050}.custom-modal-overlay .moda-header{background-color:#f8f8f8}.custom-modal-content{background-color:#fff;border-radius:8px;min-width:300px;max-width:400px;box-shadow:0 5px 20px #0000004d}.overlay-scrollable{height:250px;overflow:auto}.footer-row{border-top:1px solid #d9d9db;padding-left:32px}.fake-horizintal-scrollbar{position:relative;bottom:17px;overflow-x:auto;overflow-y:hidden;height:17px}.border-dashed{border:1px dashed #d9d9db}.cdk-drag-preview{box-sizing:border-box!important;border-radius:4px!important;box-shadow:0 5px 5px -3px #0003,0 8px 10px 1px #00000024,0 3px 14px 2px #0000001f!important;background-color:#f3f4f5!important;border:1px solid #d9d9db!important;z-index:9999!important}.data-grid-header-wrapper ::ng-deep .cdk-drag-placeholder{display:block!important;background:#fff!important;opacity:1!important}.cdk-drag-animating{transition:transform .25s cubic-bezier(0,0,.2,1)!important}.top-row-grouping-placeholder{display:flex;align-items:center;border-radius:12px;font-size:14px;padding-inline:6px;border:1px solid #d9d9db}.top-row-grouping-placeholder .bi-x{cursor:pointer;color:#7a7a7a}.top-row-grouping-placeholder .bi-x:hover{color:#111}.right-pinned-body-wrapper{position:absolute;right:0}.actions-dropdown{position:absolute;right:200px;z-index:1050;background-color:#fff;border-radius:8px!important;cursor:default}.bg-fff{background-color:#fff}.actions-dropdown-setting{right:250px}.action-button{background-color:#007cf5!important;border-radius:8px!important;padding:8px 16px!important;font-size:14px;height:32px;align-items:center}.global-search{max-width:380px!important;display:flex!important;align-items:center!important}.global-search span{margin-top:-4px!important}.global-search input{padding-left:28px;border-radius:8px!important}.global-search input:focus{outline:none!important;box-shadow:none!important}.active .top-icon ::ng-deep svg path{stroke:#007cf5!important}.dropdown-menu{background-color:#fff!important;border:1px solid #d9d9db!important;border-radius:8px!important}.custom-menu{width:220px;border-radius:8px;padding:4px 0;background-color:#fff}.custom-menu .dropdown-item{font-size:14px;padding:8px 14px}.custom-menu .dropdown-item:hover{background-color:#f5f5f5;border-radius:6px}.table-layout{right:0;background:#fff;border-radius:8px!important}.actions-dropdown,.table-layout,.custom-menu,.dropdown-menu{background:#fff;border-radius:8px!important;border:1px solid #ccc!important;background-color:#fff}.preview-box{width:40px;height:10px;border-radius:3px;background-color:transparent;transition:background-color .2s ease-in-out}.btn-check:checked+label .preview-box{background-color:var(--bs-primary)}.preview-box{width:40px;height:10px;border-radius:3px;border:2px solid transparent;transition:border-color .2s ease-in-out}#small:checked+label .preview-box{border-color:#007cf5!important;background-color:transparent!important}#medium:checked+label .preview-box{border-color:#007cf5!important;background-color:transparent!important}#large:checked+label .preview-box{border-color:#007cf5!important;background-color:transparent!important}.btn-check:checked+.btn{background-color:transparent!important;border-color:#007cf5!important}.layout-button{padding:8px 28px!important;width:82px;border-radius:8px!important}.show-hide-table-label{position:sticky;top:0;z-index:99;background:#fff}.cursor-grap{cursor:grabbing}.pagination-container{display:flex;align-items:center;gap:12px;font-size:13px;color:#333}.page-size select{padding:3px 6px;border:1px solid #ccc;border-radius:6px;background:#fff;font-size:13px}.page-info{margin-left:10px}.page-buttons{display:flex;gap:4px;margin-left:auto;align-items:center}.page-buttons button{padding:3px 8px;border:1px solid #ccc;background:#fff;border-radius:4px;cursor:pointer;font-size:13px;line-height:1.2}.page-buttons button.active{background:#eee;font-weight:600}.page-buttons button:disabled{opacity:.5;cursor:not-allowed}.page-buttons span{padding:0 6px;color:#666}.page-size .separator{padding:0 8px;border-right:1px solid #ccc;margin-right:8px}.page-size .separator .actions-dropdown{position:fixed;right:200px;z-index:1050;background-color:#fff}.fs-14px{font-size:14px}.fs-12px{font-size:12px!important}.save-preset-dropdown{background:#fff;color:#111!important;right:0;font-weight:400!important;text-align:left!important;max-width:250px!important;text-wrap:auto!important;top:14px;font-size:14px!important}.add-filter-button{height:28px;cursor:pointer;border-radius:4px}.add-filter-button:hover,.button-filter:hover{color:#000!important}.button-filter:hover ::ng-deep svg path{stroke:#000!important}.table-layout .dropdown-item{border-radius:0!important;padding-inline:16px!important;font-size:14px;padding-block:6px!important}.table-layout .dropdown-item:hover{background-color:transparent!important}.filter-serach-inpt{max-height:230px!important;overflow:auto;scrollbar-width:thin;padding-top:4px;background-color:#f7f7f7;border-color:#dedede;border-radius:8px}.filter-serach-inpt .badge{color:#007cf5!important;background-color:#e6f2ff!important;border-radius:8px!important;padding:8px!important;font-weight:500!important;font-size:12px!important;height:24px!important}.filter-serach-inpt .badge ::ng-deep svg{cursor:pointer}.filter-serach-inpt .badge ::ng-deep svg:hover path{stroke:#040081!important}.filter-serach-inpt input{background-color:#f7f7f7;padding:0;height:26px;margin-top:-5px}.text-filter select{border:0}.text-filter select option{font-size:14px;font-weight:500}.text-filter select:focus{border:0}.text-filter input:focus,.text-filter select:focus{box-shadow:none!important}.active-filters{background-color:#f7f7f7;white-space:nowrap;background:#f7f7f7;padding-inline:8px;height:28px;font-size:14px;font-weight:500;border-radius:8px;box-shadow:none}.active-filters .header-tag{white-space:nowrap}.filter-tags .active{background-color:#e6f2ff}.filter-tags .active .header-tag{color:#007cf5!important}.table-cell{cursor:pointer;width:100%}.table-cell input:focus{outline:0!important;border:0!important;width:100%!important;box-shadow:none!important}.active-for-editing{outline:2.5px solid #007cf5!important;border-radius:4px;border:0!important;width:100%!important}.active-cell{outline:none!important;box-shadow:inset 0 0 0 1.5px #007cf5}span[inlineSVG]{width:16px;height:16px;display:inline-block}.cell .dropdown-menu{min-width:unset!important}.cell .dropdown-menu .item{transition:background-color .3s ease;display:flex;align-items:center;-webkit-user-select:none;user-select:none}.cell .dropdown-menu .item:hover{background-color:#f0f8ff}.cell .cell-editin-dropdown{scrollbar-width:thin!important;-webkit-user-select:none;user-select:none}.fw-semibold{font-weight:500!important}:host ::ng-deep .three-dots-col-menu svg,:host ::ng-deep .three-dots-col-menu svg path{stroke:#000!important}.fs-7{font-size:12px!important}.fs-8{font-size:10px!important}.all-filters-reset-button:hover{opacity:.7}.full-text-box{background:#fff;position:relative;display:flex;align-items:center;z-index:1050;border:1px solid #dedede;border-radius:8px;padding:12px 14px;box-shadow:0 2px 8px #00000026;max-height:400px;overflow:auto}.full-text-box ul{max-height:400px}.full-text-content{border-radius:8px;max-height:70vh;overflow:auto;white-space:pre-wrap}.pic{border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:22px}.pic-comb2{background-color:#fbe7bf;color:#fd7f31}.pic-comb1{background-color:#d9ecbf;color:#65b500}.pic-comb4{background-color:#fdd3d7;color:#f64e60}.w-40px{width:40px}.h-40px{height:40px}.pic{border-radius:50%;overflow:hidden}.image-placeholder .pic{font-size:14px;font-weight:600;letter-spacing:.5px}.header-cell{font-weight:600}.header-cell,.cell{box-sizing:border-box}.transparent-border-right{border-right:1px solid transparent!important}.resizing-highlight{position:relative}.resizing-highlight:before{content:\"\";position:absolute;top:-1px;right:-1px;width:2px;height:calc(100% + 2px);background:#7cb9f6;z-index:1000;pointer-events:none}.resizing-highlight-right{position:relative}.resizing-highlight-right:before{content:\"\";position:absolute;top:-1px;left:-1px;width:2px;height:calc(100% + 2px);background:#7cb9f6;z-index:1000;pointer-events:none}.resizing-highlight-right:first-child{width:1px}.editable-header{border-bottom:1px dashed #666}.muted-text{color:#727272!important}.context-menu{position:fixed;display:none;background:#fff;border:1px solid #dcdcdc;box-shadow:#0000003d 0 3px 8px;z-index:1000;width:150px;border-radius:8px;font-weight:600}.context-menu.show{display:block}.context-menu ul{list-style:none;margin:0;padding:0}.context-menu li{padding:10px;cursor:pointer;color:#99a1b7}.context-menu li ::ng-deep svg{width:16px;height:16px;display:inline-block;color:#727272}.context-menu li ::ng-deep svg path{stroke:#727272}.context-menu li:hover{background-color:#f0f0f5!important}.invisible{visibility:hidden!important}.fw-500{font-weight:500!important}.taskbar{position:fixed;display:flex;justify-content:center;z-index:1000}.taskbar .action-btn{transition:opacity text-decoration .3s ease}.taskbar .action-btn:hover{text-decoration:underline;opacity:.8}.taskbar .delete{color:#ea0000}.selected-count,.action-btn,.dropdown-content a{font-weight:500;font-size:14px}.selected-rows-action-bar{background-color:#1a1a1a;color:#fff;padding:4px 24px;border-radius:8px;display:flex;align-items:center;justify-content:space-between;gap:24px;box-shadow:0 -4px 12px #00000026}.selected-rows-action-bar .btn:active,.selected-rows-action-bar .btn:focus{outline:0!important;border:0!important;border-color:transparent!important}.selected-rows-action-bar .action-btn{color:#fff!important}.cell .dropdown-menu,.cell .form-select,.cell input{color:#000!important}.cell input::placeholder{color:#727272!important}.cell .badge{border-radius:50px!important;height:26px;align-items:center}.cell .badge-danger{color:#ea5353!important;border:1px solid #ea5353!important;background-color:#ff00000d!important}.cell .badge-success{background-color:#84ca8130!important;border:1.5px solid rgb(70,227,114)!important;color:#46e372!important}.cell .badge-warning{background-color:#fff3dc!important;color:orange!important;border:1px solid #ffa000!important}.cell .badge-info{color:#00bad1;background-color:#e8fbfd;border:1px solid #00bad1}.cell .badge-secondary{color:#6c757d;background-color:#f1f3f5;border:1px solid #6c757d}.header-tag ::ng-deep svg path{stroke:#727272!important}.cross-secondary:hover ::ng-deep svg path{stroke:#000!important}.disable-sorting{pointer-events:none;opacity:.5}.rows-grouping-top-container ::ng-deep .cdk-drag-placeholder{background-color:transparent!important}input.is-invalid:focus{border:2.5px solid red!important;outline:none}.table-cell input.is-invalid:focus{border:2.5px solid red!important;outline-color:red!important;outline:none!important;box-shadow:none!important}.active-for-editing:has(input.is-invalid:focus){outline:none!important;box-shadow:none!important;border:0!important}.selected-cell,.row-selected{background-color:#c2e0fe}.first-row-selected{border-top:2px solid #2196f3!important}.last-row-selected{border-bottom:2px solid #2196f3!important}.left-selection-border{border-left:2px solid #2196f3!important}.s-no{font-size:14px;font-weight:500}.top-border{border-top:2px solid #2196f3!important}.bottom-border{border-bottom:2px solid #2196f3!important}.left-border{border-left:2px solid #2196f3!important}.border-left{border-left:1px solid #d9d9db}.right-border{border-right:2px solid #2196f3!important}.top-left-corner{border-top-left-radius:4px}.top-right-corner{border-top-right-radius:4px}.bottom-left-corner{border-bottom-left-radius:4px}.bottom-right-corner{border-bottom-right-radius:4px}.flash-bg{animation:flashAnim 1000s ease}@keyframes flashAnim{0%{background-color:#48a2fc}50%{background-color:#c2e0fe}to{background-color:#c2e0fe}}.cut-flash-bg{animation:cut-flash .8s ease}@keyframes cut-flash{0%{background-color:#f006}50%{background-color:#f00c}to{background-color:#c2e0fe}}.accordion-details .center-section .table .tbody .tr:hover .td{background-color:#f0f8ff!important}.editing-dropdown-search-input input:focus{border:1px solid #86b7fe!important}.nested-table .thead{position:sticky;top:0}.dropdown-wrapper{position:relative;display:inline-block}.btn-icon{background:transparent;border:0;padding:.25rem .5rem;cursor:pointer}.custom-dropdown-menu{position:absolute;right:0;top:calc(100% + 6px);min-width:200px;list-style:none;margin:0;padding:.25rem 0;background:#fff!important;border:1px solid rgba(0,0,0,.08);box-shadow:0 6px 18px #00000014;border-radius:.35rem;z-index:1200}.custom-dropdown-menu .dropdown-item{display:block;width:100%;padding:.5rem 1rem;text-align:left;background:transparent;border:none}.custom-dropdown-menu .dropdown-item:hover{background:#00000008}.cell-editing-dropdown-menu .dropdown-item{width:99%}.cell-editing-dropdown-menu .selected{background-color:#f0f8ff}.confirm-block{padding:0}.center-nested-table .tr:hover .td{background-color:#f0f8ff}.table ::ng-deep .cdk-drag-placeholder{background-color:#fff!important}.assets-pic{border-radius:8px!important}.fullscreen-overlay{position:fixed;top:0;left:0;width:100vw;height:100vh;background:#000c;display:flex;align-items:center;justify-content:center;z-index:1000;cursor:zoom-out}.fullscreen-img{max-width:90%;max-height:90%;border-radius:8px;box-shadow:0 0 15px #00000080}.position-sticky{z-index:2}.viewport{display:block!important;overflow:visible!important}.nested-table ::ng-deep .cdk-virtual-scroll-content-wrapper{padding:0!important}.nested-table ::ng-deep .cdk-virtual-scroll-viewport{overflow-x:hidden!important}.disabled-search-input{background-color:#f5f5f5;cursor:pointer!important}.right-click-menu-icons ::ng-deep svg path{stroke-width:2!important}.loader{animation:rotate 1s infinite;height:50px;width:50px}.loader:before,.loader:after{border-radius:50%;content:\"\";display:block;height:20px;width:20px}.loader:before{animation:ball1 1s infinite;background-color:#fff;box-shadow:30px 0 #ff3d00;margin-bottom:10px}.loader:after{animation:ball2 1s infinite;background-color:#ff3d00;box-shadow:30px 0 #fff}@keyframes rotate{0%{transform:rotate(0) scale(.8)}50%{transform:rotate(360deg) scale(1.2)}to{transform:rotate(720deg) scale(.8)}}@keyframes ball1{0%{box-shadow:30px 0 #ff3d00}50%{box-shadow:0 0 #ff3d00;margin-bottom:0;transform:translate(15px,15px)}to{box-shadow:30px 0 #ff3d00;margin-bottom:10px}}@keyframes ball2{0%{box-shadow:30px 0 #fff}50%{box-shadow:0 0 #fff;margin-top:-20px;transform:translate(15px,15px)}to{box-shadow:30px 0 #fff;margin-top:0}}.rows-grouping-top-container ::ng-deep .cdk-drag-placeholder{opacity:.7!important}.action-button{background-color:#6f61cf!important;color:#fff!important;border-radius:6px!important;font-weight:500!important;margin-top:-4px}.action-button:hover{background-color:#6a5fb3!important}.action-buttons-row .button{display:inline-flex;align-items:center;justify-content:center;overflow:hidden;color:#fff;border-radius:6px;height:34px;padding:0 10px;white-space:nowrap;transition:max-width .4s ease,background-color .3s ease;max-width:40px;background-color:transparent;border:1px solid #6F61CF}.action-buttons-row .button .label-hidden{opacity:0;margin-left:8px;transition:opacity .3s ease;pointer-events:none;display:none}.action-buttons-row .button:hover{max-width:200px;background-color:#6f61cf}.action-buttons-row .button:hover .label-hidden{opacity:1;pointer-events:auto;margin-left:8px!important;display:block}.action-buttons-row ::ng-deep .button .svg-icon svg path{stroke:#6f61cf;transition:fill .3s ease,stroke .3s ease}.action-buttons-row ::ng-deep .button:hover .svg-icon svg path{stroke:#fff!important}::ng-deep .nav-tabs .nav-link{border:none!important;border-bottom:2px solid transparent!important;border-radius:0!important;background:transparent!important}::ng-deep .nav-tabs .nav-link:hover,::ng-deep .nav-tabs .nav-link:focus{border:none!important;border-bottom:2px solid transparent!important;outline:none!important;background:transparent!important}::ng-deep .nav-tabs .nav-link.active{border:none!important;border-bottom:2px solid var(--bs-primary)!important;background:transparent!important;color:var(--bs-primary)!important}.open-top{top:-150%!important}.muted{color:#7a7a7a!important}.item-title{font-size:1.2em;font-weight:700;margin-bottom:10px}.item-image{width:100%;border-radius:10px}.comment{display:flex;align-items:center;margin-bottom:10px}.comment-avatar{width:40px;height:40px;border-radius:50%;margin-right:10px}.comment-author{font-weight:700}.comment-content{font-size:.9em;line-height:1.4}.comment-timestamp{font-size:.8em;color:#888;margin-left:auto}.des_low{text-overflow:ellipsis;white-space:nowrap;overflow:hidden;width:242px;display:block;text-transform:capitalize!important}.firstDiv{word-break:break-word;overflow-wrap:break-word;white-space:normal}.container{display:flex;flex-wrap:wrap;margin:20px;gap:20px;background-color:#fff;padding:20px;border-radius:10px}.item{width:calc(33.33% - 20px);background-color:#fff;padding:20px;border-radius:10px;box-shadow:0 2px 5px #0000001a}.forCommentImg{width:70px;border-radius:16px;margin:8px 0;cursor:pointer}.image-modal img{max-width:90%;max-height:90%;border-radius:8px;box-shadow:0 4px 10px #00000080}.full-image-modal{position:fixed;background:#000c;display:flex;justify-content:center;align-items:center;z-index:1000}.full-image-modal .full-image{max-width:90%;max-height:90%;border-radius:8px;box-shadow:0 0 10px #fff3}.item-content{font-size:14px;line-height:1.5;max-height:220px;overflow-y:auto}.image-modal.full-image-modal{position:fixed;width:100vw;height:100vh;background-color:#000c;display:flex;justify-content:center;align-items:center;z-index:9999;overflow:hidden;cursor:zoom-out}.image-modal.full-image-modal img{border-radius:8px;box-shadow:0 4px 20px #0006;object-fit:contain;transition:transform .3s ease}.image-modal.full-image-modal img:hover{transform:scale(1.02)}::ng-deep .custom-overlay-wrapper .custom-overlay{position:fixed;top:0;left:0;width:100vw;height:100vh;background:#000000d9;display:flex;align-items:center;justify-content:center;z-index:9999}::ng-deep .custom-overlay-wrapper .custom-modal{background:#fff;border-radius:12px;box-shadow:0 8px 25px #0003;width:360px;max-width:90%;padding:24px;text-align:center;animation:fadeInScale .25s ease}::ng-deep .custom-overlay-wrapper .custom-modal-body .modal-message{font-size:16px;margin-bottom:20px;color:#333}::ng-deep .custom-overlay-wrapper .modal-actions{display:flex;justify-content:center;gap:12px}::ng-deep .custom-overlay-wrapper .modal-actions button{min-width:90px;padding:8px 14px;border-radius:6px;border:none;font-weight:500;cursor:pointer;transition:background-color .2s ease}::ng-deep .custom-overlay-wrapper .btn-confirm{background-color:#007bff;color:#fff}::ng-deep .custom-overlay-wrapper .btn-confirm:hover{background-color:#0069d9}::ng-deep .custom-overlay-wrapper .btn-cancel{background-color:#e4e4e4;color:#333}::ng-deep .custom-overlay-wrapper .btn-cancel:hover{background-color:#d6d6d6}@keyframes fadeInScale{0%{opacity:0;transform:scale(.95)}to{opacity:1;transform:scale(1)}}.clear-btn{background:linear-gradient(135deg,#f53545,#f53545);border:none;color:#fff;font-size:13px;padding:3px 6px;border-radius:20px;font-weight:500;display:inline-flex;align-items:center;gap:6px;cursor:pointer;transition:all .3s ease;box-shadow:0 2px 6px #ff5f6d66;position:relative;bottom:4px}.clear-btn:hover{transform:translateY(-2px);box-shadow:0 4px 10px #ff5f6d99;background:linear-gradient(135deg,#f53545,#f53545)}.clear-btn i{font-size:16px;vertical-align:middle}.cell-editin-dropdown .deopdown-item{width:100%!important;box-shadow:none!important;border-radius:4px;cursor:pointer;padding-block:8px!important}.cell-editin-dropdown .deopdown-item:hover{background-color:#f1f1f1}\n"] }]
|
|
6344
6549
|
}], ctorParameters: function () { return [{ type: SplitColumnsService }, { type: i0.ChangeDetectorRef }, { type: CommonService }, { type: i0.ElementRef }, { type: i0.NgZone }, { type: CopyServiceService }, { type: i0.Renderer2 }, { type: i4.DomSanitizer }, { type: ExportService }, { type: i6.DatePipe }, { type: FormatCurrencyPipe }]; }, propDecorators: { rowAnimation: [{
|
|
6345
6550
|
type: Input
|
|
6346
6551
|
}], paginationConfig: [{
|
|
@@ -6503,6 +6708,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
|
|
|
6503
6708
|
type: Input
|
|
6504
6709
|
}], resetAllFilters: [{
|
|
6505
6710
|
type: Input
|
|
6711
|
+
}], defaultConfig: [{
|
|
6712
|
+
type: Input
|
|
6506
6713
|
}], columnThreedotsMunuConfig: [{
|
|
6507
6714
|
type: Input
|
|
6508
6715
|
}], cellHosts: [{
|
|
@@ -6555,6 +6762,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
|
|
|
6555
6762
|
}], rightPinnedHeader: [{
|
|
6556
6763
|
type: ViewChild,
|
|
6557
6764
|
args: ['rightPinnedHeader']
|
|
6765
|
+
}], globalSearchInput: [{
|
|
6766
|
+
type: ViewChild,
|
|
6767
|
+
args: ['globalSearchInput']
|
|
6558
6768
|
}], columnsGroupedBox: [{
|
|
6559
6769
|
type: ViewChild,
|
|
6560
6770
|
args: ['columnsGroupedBox']
|