ms-data-grid 0.0.93 → 0.0.94
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/README.md +323 -323
- package/esm2022/lib/data-grid/data-grid.component.mjs +213 -396
- package/esm2022/lib/data-grid/statuses.mjs +1 -1
- package/esm2022/lib/data-grid.module.mjs +1 -1
- package/esm2022/lib/directives/cell-editor.directive.mjs +1 -1
- package/esm2022/lib/directives/cell-render-init.directive.mjs +1 -1
- package/esm2022/lib/directives/cellHost.directive.mjs +1 -1
- package/esm2022/lib/pipes/filter.pipe.mjs +1 -1
- package/esm2022/lib/pipes/format-currency.pipe.mjs +1 -1
- package/esm2022/lib/pipes/format-index.pipe.mjs +1 -1
- package/esm2022/lib/services/common.service.mjs +8 -8
- package/esm2022/lib/services/copy-service.service.mjs +1 -1
- package/esm2022/lib/services/export.service.mjs +1 -1
- package/esm2022/lib/services/split-columns.service.mjs +2 -2
- package/esm2022/public-api.mjs +2 -1
- package/fesm2022/ms-data-grid.mjs +293 -616
- package/fesm2022/ms-data-grid.mjs.map +1 -1
- package/lib/data-grid/data-grid.component.d.ts +24 -49
- package/lib/styles/font-style.css +34 -0
- package/package.json +1 -1
- package/esm2022/lib/services/row-action.service.mjs +0 -145
- package/lib/services/row-action.service.d.ts +0 -21
|
@@ -1,20 +1,19 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
2
|
import { Directive, Injectable, inject, Pipe, EventEmitter, Injector, Input, Output, Component, ChangeDetectionStrategy, ViewChildren, ViewChild, HostListener, NgModule } from '@angular/core';
|
|
3
|
-
import * as
|
|
3
|
+
import * as i9 from '@angular/cdk/drag-drop';
|
|
4
4
|
import { moveItemInArray, DragDropModule } from '@angular/cdk/drag-drop';
|
|
5
5
|
import { trigger, transition, query, style, animate, stagger, state } from '@angular/animations';
|
|
6
|
-
import {
|
|
7
|
-
import 'bootstrap/dist/js/bootstrap.bundle.min.js';
|
|
6
|
+
import { take } from 'rxjs';
|
|
8
7
|
import * as i6 from '@angular/common';
|
|
9
8
|
import { DatePipe, CommonModule, TitleCasePipe } from '@angular/common';
|
|
10
9
|
import * as i4 from '@angular/platform-browser';
|
|
11
10
|
import * as XLSX from 'xlsx-js-style';
|
|
12
11
|
import { saveAs } from 'file-saver';
|
|
13
|
-
import * as
|
|
12
|
+
import * as i8 from '@angular/forms';
|
|
14
13
|
import { FormsModule } from '@angular/forms';
|
|
15
|
-
import * as
|
|
14
|
+
import * as i10 from 'ng-inline-svg';
|
|
16
15
|
import { InlineSVGModule } from 'ng-inline-svg';
|
|
17
|
-
import * as
|
|
16
|
+
import * as i11 from '@angular/cdk/scrolling';
|
|
18
17
|
import { ScrollingModule } from '@angular/cdk/scrolling';
|
|
19
18
|
|
|
20
19
|
const STATUSES_BADGE_MAP = {
|
|
@@ -169,7 +168,7 @@ class SplitColumnsService {
|
|
|
169
168
|
// ✅ Total width already consumed
|
|
170
169
|
const usedWidth = fixedCols.reduce((sum, col) => sum + col.width, 0);
|
|
171
170
|
// ✅ Remaining width after fixed columns
|
|
172
|
-
let remainingWidth = containerWidth -
|
|
171
|
+
let remainingWidth = containerWidth - usedWidth;
|
|
173
172
|
if (remainingWidth < 0)
|
|
174
173
|
remainingWidth = 0;
|
|
175
174
|
// ✅ Average width for columns without width
|
|
@@ -230,7 +229,7 @@ class CommonService {
|
|
|
230
229
|
}
|
|
231
230
|
gethasVisibleColumns(columns) {
|
|
232
231
|
const checkVisible = (columns) => {
|
|
233
|
-
return columns
|
|
232
|
+
return columns?.some((col) => {
|
|
234
233
|
if (col?.is_visible)
|
|
235
234
|
return true;
|
|
236
235
|
if (col?.children?.length) {
|
|
@@ -243,7 +242,7 @@ class CommonService {
|
|
|
243
242
|
}
|
|
244
243
|
gethasInVisibleColumns(columns) {
|
|
245
244
|
const checkVisible = (columns) => {
|
|
246
|
-
return columns
|
|
245
|
+
return columns?.some((col) => {
|
|
247
246
|
if (!col?.is_visible)
|
|
248
247
|
return true;
|
|
249
248
|
if (col?.children?.length) {
|
|
@@ -256,7 +255,7 @@ class CommonService {
|
|
|
256
255
|
}
|
|
257
256
|
getTotalColumnsLength(columns) {
|
|
258
257
|
let count = 0;
|
|
259
|
-
columns
|
|
258
|
+
columns?.forEach(col => {
|
|
260
259
|
if (col.children && Array.isArray(col.children) && col.children.length) {
|
|
261
260
|
count += col.children.length; // count children instead of parent
|
|
262
261
|
}
|
|
@@ -268,7 +267,7 @@ class CommonService {
|
|
|
268
267
|
}
|
|
269
268
|
gethasRightPinnedColumns(columns) {
|
|
270
269
|
const checkPinnedRight = (columns) => {
|
|
271
|
-
return columns
|
|
270
|
+
return columns?.some((col) => {
|
|
272
271
|
if (col?.pinned === 'right' && col?.is_visible)
|
|
273
272
|
return true;
|
|
274
273
|
if (col?.children?.length) {
|
|
@@ -281,7 +280,7 @@ class CommonService {
|
|
|
281
280
|
}
|
|
282
281
|
gethasLeftPinnedColumns(columns) {
|
|
283
282
|
const checkPinnedRight = (columns) => {
|
|
284
|
-
return columns
|
|
283
|
+
return columns?.some((col) => {
|
|
285
284
|
if (col?.pinned === 'left' && col?.is_visible)
|
|
286
285
|
return true;
|
|
287
286
|
if (col?.children?.length) {
|
|
@@ -295,7 +294,7 @@ class CommonService {
|
|
|
295
294
|
getExpandedRowCount(data) {
|
|
296
295
|
let groupCount = 0;
|
|
297
296
|
let rowCount = 0;
|
|
298
|
-
data
|
|
297
|
+
data?.forEach(group => {
|
|
299
298
|
if (group?.isGroup) {
|
|
300
299
|
groupCount++;
|
|
301
300
|
if (group?.isExpand && Array.isArray(group?.children)) {
|
|
@@ -348,7 +347,7 @@ class CommonService {
|
|
|
348
347
|
col.query = {
|
|
349
348
|
first_value: null,
|
|
350
349
|
second_value: null,
|
|
351
|
-
first_condition: col.type !== 'date' && col.type !== 'number'
|
|
350
|
+
first_condition: col.type !== 'date' && col.type !== 'number' ? 'contain' : 'equal',
|
|
352
351
|
second_condition: null,
|
|
353
352
|
condition: 'none',
|
|
354
353
|
_ids: []
|
|
@@ -967,149 +966,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
|
|
|
967
966
|
}]
|
|
968
967
|
}] });
|
|
969
968
|
|
|
970
|
-
class RowActionService {
|
|
971
|
-
constructor() {
|
|
972
|
-
this.STATUS_SETS = {
|
|
973
|
-
EDIT_BLOCKED: [
|
|
974
|
-
'expired', 'closed', 'Assigning Stop', 'Evaluation Start',
|
|
975
|
-
'Evaluation Stop', 'Completed', 'approved', 'rejected',
|
|
976
|
-
'partially', 'accepted'
|
|
977
|
-
],
|
|
978
|
-
ARCHIVE_BLOCKED: [
|
|
979
|
-
'approved', 'partially', 'Assigning Start',
|
|
980
|
-
'Completed', 'Evaluation Start'
|
|
981
|
-
],
|
|
982
|
-
DISPOSED: ['scrap', 'trashed', 'disposed'],
|
|
983
|
-
SEPARATED: ['termination', 'resignation', 'retirement', 'separated'],
|
|
984
|
-
UNAVAILABLE: ['unavailable', 'unAvailable']
|
|
985
|
-
};
|
|
986
|
-
this.ACTION_ALIASES = {
|
|
987
|
-
accept: 'view',
|
|
988
|
-
achive: 'unactive'
|
|
989
|
-
};
|
|
990
|
-
this.rules = {
|
|
991
|
-
assigningstart: (r) => r.status === 'To be start Assigning' && !r.isDeleted,
|
|
992
|
-
assigningstop: (r) => r.status === 'Assigning Start' && !r.isDeleted,
|
|
993
|
-
evaluationstart: (r) => r.status === 'Assigning Stop' && !r.isDeleted,
|
|
994
|
-
completed: (r) => r.status === 'Evaluation Start' && !r.isDeleted,
|
|
995
|
-
archive: (r) => this.canArchiveOrDelete(r),
|
|
996
|
-
unactive: (r) => this.canArchiveOrDelete(r),
|
|
997
|
-
delete: (r) => this.canArchiveOrDelete(r),
|
|
998
|
-
unarchive: (r) => r.isDeleted && r.availStatus !== 'disposed',
|
|
999
|
-
active: (r) => r.isDeleted && r.availStatus !== 'disposed',
|
|
1000
|
-
link: (r) => !this.STATUS_SETS.UNAVAILABLE.includes(r.status) &&
|
|
1001
|
-
!r.isDeleted &&
|
|
1002
|
-
r.availStatus !== 'disposed' &&
|
|
1003
|
-
r.status !== 'linked',
|
|
1004
|
-
unlink: (r, ctx) => ctx.showUnLink === true && r.status === 'linked',
|
|
1005
|
-
rejoin: (r) => this.STATUS_SETS.SEPARATED.includes(r.accountStatus),
|
|
1006
|
-
settlementinfo: (r) => this.STATUS_SETS.SEPARATED.includes(r.accountStatus),
|
|
1007
|
-
assign: (r) => r.status !== 'assigned',
|
|
1008
|
-
edit: (r, ctx) => this.canEdit(r, ctx),
|
|
1009
|
-
trash: (r) => !this.STATUS_SETS.DISPOSED.includes(r.availStatus),
|
|
1010
|
-
scrap: (r) => !this.STATUS_SETS.DISPOSED.includes(r.availStatus),
|
|
1011
|
-
retain: (r) => !this.STATUS_SETS.DISPOSED.includes(r.availStatus),
|
|
1012
|
-
defaultgrade: (r) => r.isCustomGrade !== 'Active',
|
|
1013
|
-
subscribe: (r, ctx) => !r.assignedToIds.includes(ctx.currentUserId),
|
|
1014
|
-
unsubscribe: (r, ctx) => r.assignedToIds.includes(ctx.currentUserId),
|
|
1015
|
-
changestatus: (r) => !r.isDeleted,
|
|
1016
|
-
download: (r) => r.offerLetter !== null,
|
|
1017
|
-
view: (r) => r.offerLetter !== null
|
|
1018
|
-
};
|
|
1019
|
-
}
|
|
1020
|
-
normalizeRow(element) {
|
|
1021
|
-
return {
|
|
1022
|
-
isDeleted: element.is_deleted === true || element.is_deleted === 'true',
|
|
1023
|
-
status: element.status || '',
|
|
1024
|
-
availStatus: element.availStatus || '',
|
|
1025
|
-
accountStatus: (element.account_status || '').toLowerCase(),
|
|
1026
|
-
assigneeCount: element.assignee?.length ?? 0,
|
|
1027
|
-
assignedToIds: element.assigned_to?.map((x) => x.id) ?? [],
|
|
1028
|
-
settlementCompleted: element.settlement_completed === true,
|
|
1029
|
-
finalSettlementCompleted: element.final_settlement_completed === true,
|
|
1030
|
-
storeEdit: element.store_edit !== false,
|
|
1031
|
-
isOwner: element.is_owner ?? true,
|
|
1032
|
-
isCustomGrade: element.is_custom_grade || '',
|
|
1033
|
-
parent: element.parent,
|
|
1034
|
-
offerLetter: element.offer_letter,
|
|
1035
|
-
typename: element.__typename || ''
|
|
1036
|
-
};
|
|
1037
|
-
}
|
|
1038
|
-
normalizeAction(action, ctx) {
|
|
1039
|
-
let normalized = this.ACTION_ALIASES[action] || action;
|
|
1040
|
-
if (ctx.packageData) {
|
|
1041
|
-
if (action === 'unarchive')
|
|
1042
|
-
return 'active';
|
|
1043
|
-
if (action === 'archive')
|
|
1044
|
-
return 'unactive';
|
|
1045
|
-
}
|
|
1046
|
-
return normalized.toLowerCase();
|
|
1047
|
-
}
|
|
1048
|
-
canArchiveOrDelete(r) {
|
|
1049
|
-
return (!r.isDeleted &&
|
|
1050
|
-
!r.settlementCompleted &&
|
|
1051
|
-
!r.finalSettlementCompleted &&
|
|
1052
|
-
r.availStatus !== 'reserved' &&
|
|
1053
|
-
r.assigneeCount === 0 &&
|
|
1054
|
-
r.availStatus !== 'disposed' &&
|
|
1055
|
-
r.availStatus !== 'maintenance' &&
|
|
1056
|
-
r.availStatus !== 'assigned' &&
|
|
1057
|
-
!this.STATUS_SETS.ARCHIVE_BLOCKED.includes(r.status) &&
|
|
1058
|
-
r.parent !== null);
|
|
1059
|
-
}
|
|
1060
|
-
canEdit(r, ctx) {
|
|
1061
|
-
const isBlocked = this.STATUS_SETS.EDIT_BLOCKED.includes(r.status) ||
|
|
1062
|
-
r.isDeleted ||
|
|
1063
|
-
!r.storeEdit ||
|
|
1064
|
-
r.availStatus === 'disposed' ||
|
|
1065
|
-
r.settlementCompleted ||
|
|
1066
|
-
r.finalSettlementCompleted;
|
|
1067
|
-
if (isBlocked)
|
|
1068
|
-
return false;
|
|
1069
|
-
if (ctx.tableType === 'BusinessExpenseListing') {
|
|
1070
|
-
return true;
|
|
1071
|
-
}
|
|
1072
|
-
return r.status !== 'accepted' && r.isOwner;
|
|
1073
|
-
}
|
|
1074
|
-
isActionValid(action, element, ctx = {}) {
|
|
1075
|
-
const row = this.normalizeRow(element);
|
|
1076
|
-
const normalizedAction = this.normalizeAction(action, ctx);
|
|
1077
|
-
const rule = this.rules[normalizedAction];
|
|
1078
|
-
if (rule) {
|
|
1079
|
-
return rule(row, ctx);
|
|
1080
|
-
}
|
|
1081
|
-
return row.availStatus !== 'disposed' || row.typename === 'Alert';
|
|
1082
|
-
}
|
|
1083
|
-
getValidActions(actions, element, ctx = {}) {
|
|
1084
|
-
if (!actions?.length)
|
|
1085
|
-
return [];
|
|
1086
|
-
let validActions = actions.filter(action => this.isActionValid(action, element, ctx));
|
|
1087
|
-
if (ctx.tableType === 'recruitmentListing') {
|
|
1088
|
-
validActions = this.applyRecruitmentFilters(validActions, element);
|
|
1089
|
-
}
|
|
1090
|
-
return validActions;
|
|
1091
|
-
}
|
|
1092
|
-
applyRecruitmentFilters(actions, element) {
|
|
1093
|
-
let filtered = [...actions];
|
|
1094
|
-
if (element?.status === 'hired' && !element?.is_deleted) {
|
|
1095
|
-
filtered = filtered.filter(action => !['changestatus', 'unarchive', 'archive', 'edit'].includes(action));
|
|
1096
|
-
}
|
|
1097
|
-
if (element?.is_deleted) {
|
|
1098
|
-
filtered = filtered.filter(action => action !== 'changestatus');
|
|
1099
|
-
}
|
|
1100
|
-
if (element?.offer_letter === null) {
|
|
1101
|
-
filtered = filtered.filter(action => !['download', 'view'].includes(action));
|
|
1102
|
-
}
|
|
1103
|
-
return filtered;
|
|
1104
|
-
}
|
|
1105
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: RowActionService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
1106
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: RowActionService, providedIn: 'root' }); }
|
|
1107
|
-
}
|
|
1108
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: RowActionService, decorators: [{
|
|
1109
|
-
type: Injectable,
|
|
1110
|
-
args: [{ providedIn: 'root' }]
|
|
1111
|
-
}] });
|
|
1112
|
-
|
|
1113
969
|
class CellRenderInitDirective {
|
|
1114
970
|
constructor(vcr, injector) {
|
|
1115
971
|
this.vcr = vcr;
|
|
@@ -1175,79 +1031,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
|
|
|
1175
1031
|
type: Output
|
|
1176
1032
|
}] } });
|
|
1177
1033
|
|
|
1178
|
-
class CellEditorDirective {
|
|
1179
|
-
constructor(vcr, injector) {
|
|
1180
|
-
this.vcr = vcr;
|
|
1181
|
-
this.injector = injector;
|
|
1182
|
-
// Parent component listens using:
|
|
1183
|
-
// (editorEvent)="finishEdit($event)"
|
|
1184
|
-
this.editorEvent = new EventEmitter();
|
|
1185
|
-
}
|
|
1186
|
-
ngOnInit() {
|
|
1187
|
-
if (!this.componentType)
|
|
1188
|
-
return;
|
|
1189
|
-
// ✅ Dynamically create the editor component
|
|
1190
|
-
const componentRef = this.vcr.createComponent(this.componentType, {
|
|
1191
|
-
injector: Injector.create({
|
|
1192
|
-
providers: [
|
|
1193
|
-
{ provide: 'rowData', useValue: this.rowData },
|
|
1194
|
-
{ provide: 'colData', useValue: this.colData },
|
|
1195
|
-
{ provide: 'cellValue', useValue: this.cellValue }
|
|
1196
|
-
],
|
|
1197
|
-
parent: this.injector
|
|
1198
|
-
})
|
|
1199
|
-
});
|
|
1200
|
-
// -----------------------------------------------
|
|
1201
|
-
// 1️⃣ Call custom lifecycle hook if it exists
|
|
1202
|
-
// -----------------------------------------------
|
|
1203
|
-
if (typeof componentRef.instance.editorInit === 'function') {
|
|
1204
|
-
componentRef.instance.editorInit({
|
|
1205
|
-
row: this.rowData,
|
|
1206
|
-
col: this.colData,
|
|
1207
|
-
value: this.cellValue
|
|
1208
|
-
});
|
|
1209
|
-
}
|
|
1210
|
-
// -----------------------------------------------
|
|
1211
|
-
// 2️⃣ Auto-detect all @Output() EventEmitters
|
|
1212
|
-
// -----------------------------------------------
|
|
1213
|
-
for (const key of Object.keys(componentRef.instance)) {
|
|
1214
|
-
const property = componentRef.instance[key];
|
|
1215
|
-
// Check if any property is an EventEmitter
|
|
1216
|
-
if (property instanceof EventEmitter) {
|
|
1217
|
-
property.subscribe((value) => {
|
|
1218
|
-
this.editorEvent.emit({
|
|
1219
|
-
eventName: key,
|
|
1220
|
-
data: {
|
|
1221
|
-
row: this.rowData,
|
|
1222
|
-
col: this.colData,
|
|
1223
|
-
value
|
|
1224
|
-
}
|
|
1225
|
-
});
|
|
1226
|
-
});
|
|
1227
|
-
}
|
|
1228
|
-
}
|
|
1229
|
-
}
|
|
1230
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: CellEditorDirective, deps: [{ token: i0.ViewContainerRef }, { token: i0.Injector }], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
1231
|
-
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: CellEditorDirective, selector: "[cellEditor]", inputs: { componentType: ["cellEditor", "componentType"], rowData: "rowData", colData: "colData", cellValue: "cellValue" }, outputs: { editorEvent: "editorEvent" }, ngImport: i0 }); }
|
|
1232
|
-
}
|
|
1233
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: CellEditorDirective, decorators: [{
|
|
1234
|
-
type: Directive,
|
|
1235
|
-
args: [{
|
|
1236
|
-
selector: '[cellEditor]'
|
|
1237
|
-
}]
|
|
1238
|
-
}], ctorParameters: function () { return [{ type: i0.ViewContainerRef }, { type: i0.Injector }]; }, propDecorators: { componentType: [{
|
|
1239
|
-
type: Input,
|
|
1240
|
-
args: ['cellEditor']
|
|
1241
|
-
}], rowData: [{
|
|
1242
|
-
type: Input
|
|
1243
|
-
}], colData: [{
|
|
1244
|
-
type: Input
|
|
1245
|
-
}], cellValue: [{
|
|
1246
|
-
type: Input
|
|
1247
|
-
}], editorEvent: [{
|
|
1248
|
-
type: Output
|
|
1249
|
-
}] } });
|
|
1250
|
-
|
|
1251
1034
|
class FilterPipe {
|
|
1252
1035
|
transform(items, searchText, key) {
|
|
1253
1036
|
if (!items || !searchText)
|
|
@@ -1302,7 +1085,7 @@ const sortingAnimation = trigger('listSort', [
|
|
|
1302
1085
|
])
|
|
1303
1086
|
]);
|
|
1304
1087
|
class DataGridComponent {
|
|
1305
|
-
constructor(columnService, cdr, commonSevice, elementRef, ngZone, copyService, renderer, sanitizer, exportService, datePipe, formatCurrency
|
|
1088
|
+
constructor(columnService, cdr, commonSevice, elementRef, ngZone, copyService, renderer, sanitizer, exportService, datePipe, formatCurrency) {
|
|
1306
1089
|
this.columnService = columnService;
|
|
1307
1090
|
this.cdr = cdr;
|
|
1308
1091
|
this.commonSevice = commonSevice;
|
|
@@ -1314,7 +1097,6 @@ class DataGridComponent {
|
|
|
1314
1097
|
this.exportService = exportService;
|
|
1315
1098
|
this.datePipe = datePipe;
|
|
1316
1099
|
this.formatCurrency = formatCurrency;
|
|
1317
|
-
this.actionValidator = actionValidator;
|
|
1318
1100
|
// **************************************//
|
|
1319
1101
|
// **************************************//
|
|
1320
1102
|
// ********** Input Goes Here *********** //
|
|
@@ -1322,56 +1104,56 @@ class DataGridComponent {
|
|
|
1322
1104
|
// **************************************//
|
|
1323
1105
|
this.rowAnimation = RowAnimationType.None;
|
|
1324
1106
|
// Pagination Config Store Here
|
|
1325
|
-
this.paginationConfig =
|
|
1107
|
+
this.paginationConfig = {};
|
|
1326
1108
|
// The dataset store here;
|
|
1327
1109
|
this.dataSet = [];
|
|
1328
1110
|
// The columns Store Here
|
|
1329
1111
|
this.columns = [];
|
|
1330
1112
|
// Row Height;
|
|
1331
|
-
this.rowHeight =
|
|
1113
|
+
this.rowHeight = 50;
|
|
1332
1114
|
// Header Row Height;
|
|
1333
|
-
this.headerRowHeight =
|
|
1115
|
+
this.headerRowHeight = 40;
|
|
1334
1116
|
// Show Vertical Borders;
|
|
1335
1117
|
this.showVerticalBorder = false;
|
|
1336
1118
|
// Even Rows Background Color;
|
|
1337
1119
|
this.evenRowsBackgroundColor = '';
|
|
1338
1120
|
// Even Rows Background Color;
|
|
1339
|
-
this.oddRowsBackgroundColor = '#
|
|
1121
|
+
this.oddRowsBackgroundColor = '#F5F5F5';
|
|
1340
1122
|
// Header Rows Background Color;
|
|
1341
|
-
this.headerBackgroundColor = '#
|
|
1123
|
+
this.headerBackgroundColor = '#F5F5F5';
|
|
1342
1124
|
// Header Rows Background Color;
|
|
1343
|
-
this.checkboxesBackgroundColor = '#
|
|
1125
|
+
this.checkboxesBackgroundColor = '#FFFFFF';
|
|
1344
1126
|
// Show Columns Grouping;
|
|
1345
1127
|
this.showColumnsGrouping = false;
|
|
1346
1128
|
// Row Hovered Background color;
|
|
1347
|
-
this.rowHoverColor = '
|
|
1129
|
+
this.rowHoverColor = '#F5F5F5';
|
|
1348
1130
|
// Left PinnedBackground color;
|
|
1349
|
-
this.leftPinnedBackgroundColor = '#
|
|
1131
|
+
this.leftPinnedBackgroundColor = '#FFFFFF';
|
|
1350
1132
|
// Body Background color;
|
|
1351
|
-
this.bodyBackgroundColor = '#
|
|
1133
|
+
this.bodyBackgroundColor = '#FFFFFF';
|
|
1352
1134
|
// Right Pinned Background color;
|
|
1353
|
-
this.rightPinnedBackgroundColor = '#
|
|
1135
|
+
this.rightPinnedBackgroundColor = '#FFFFFF';
|
|
1354
1136
|
// Side Menu Background color;
|
|
1355
|
-
this.sidemenuBackgroundColor = '#
|
|
1137
|
+
this.sidemenuBackgroundColor = '#FFFFFF';
|
|
1356
1138
|
// Body text color;
|
|
1357
|
-
this.bodyTextColor = '#
|
|
1139
|
+
this.bodyTextColor = '#1B1F22';
|
|
1358
1140
|
// Header text color;
|
|
1359
|
-
this.headerTextColor = '#
|
|
1141
|
+
this.headerTextColor = '#6A6B6D';
|
|
1360
1142
|
// Header text color;
|
|
1361
|
-
this.checkboxesColor = '#
|
|
1143
|
+
this.checkboxesColor = '#FFFFFF';
|
|
1362
1144
|
// Header text size;
|
|
1363
|
-
this.headerTextFontsSize =
|
|
1145
|
+
this.headerTextFontsSize = 13;
|
|
1364
1146
|
// Body text color;
|
|
1365
1147
|
this.bodyTextFontsSize = 14;
|
|
1366
1148
|
// Header font weight;
|
|
1367
|
-
this.headerFontWeight =
|
|
1149
|
+
this.headerFontWeight = 600; // basit said
|
|
1368
1150
|
// Body Font Weight;
|
|
1369
1151
|
this.bodyFontWeight = 400;
|
|
1370
1152
|
// Checked Row Background Color;
|
|
1371
|
-
this.checkedRowBackgroundColor = '
|
|
1153
|
+
this.checkedRowBackgroundColor = '#0084FF1A';
|
|
1372
1154
|
// dropdowns Background Color;
|
|
1373
|
-
this.dropdownsBackgroundColor = '#
|
|
1374
|
-
this.footerRowBackgroundColor = '';
|
|
1155
|
+
this.dropdownsBackgroundColor = '#FFFFFF';
|
|
1156
|
+
this.footerRowBackgroundColor = '#FFFFFF';
|
|
1375
1157
|
// Footer row Height;
|
|
1376
1158
|
this.footerRowHeight = 46;
|
|
1377
1159
|
// Footer row Height;
|
|
@@ -1423,7 +1205,7 @@ class DataGridComponent {
|
|
|
1423
1205
|
// Taskbar actions
|
|
1424
1206
|
this.taskbarActions = [];
|
|
1425
1207
|
// Sorting Config to show sort icons
|
|
1426
|
-
this.sortingConfig =
|
|
1208
|
+
this.sortingConfig = { field: '', order_by: '' };
|
|
1427
1209
|
this.tableFilterViewId = '';
|
|
1428
1210
|
this.selectedTableLayout = 'medium';
|
|
1429
1211
|
this.closeDropdown = { preset: { closed: false, loading: false } };
|
|
@@ -1436,12 +1218,11 @@ class DataGridComponent {
|
|
|
1436
1218
|
this.nestedTableHeaderRowHeight = 40;
|
|
1437
1219
|
// Nested Table row height
|
|
1438
1220
|
this.nestedTablerowHeight = 45;
|
|
1439
|
-
this.packageData = false;
|
|
1440
1221
|
this.gridType = '';
|
|
1441
1222
|
this.currencySymbol = '';
|
|
1442
1223
|
this.currencyFormat = '';
|
|
1443
|
-
this.leftPinnedBoxshadow = '';
|
|
1444
|
-
this.rightPinnedBoxshadow = '';
|
|
1224
|
+
this.leftPinnedBoxshadow = '1px 0px 4px 0px rgba(18, 19, 20, 0.1)';
|
|
1225
|
+
this.rightPinnedBoxshadow = '-1px 0px 4px 0px rgba(18, 19, 20, 0.1)';
|
|
1445
1226
|
// GlobalSearch
|
|
1446
1227
|
this.selectedRowsBackgroundColor = '#8ac5ff';
|
|
1447
1228
|
// GlobalSearch
|
|
@@ -1458,9 +1239,9 @@ class DataGridComponent {
|
|
|
1458
1239
|
this.enableCut = false;
|
|
1459
1240
|
this.tabs = [];
|
|
1460
1241
|
this.showCheckboxes = true;
|
|
1461
|
-
this.
|
|
1462
|
-
this.resetAllFilters = { resetAll: false };
|
|
1242
|
+
this.consumerFont = null;
|
|
1463
1243
|
this.defaultConfig = null;
|
|
1244
|
+
this.resetAllFilters = { resetAll: false };
|
|
1464
1245
|
this.columnThreedotsMunuConfig = {
|
|
1465
1246
|
showPinleft: true,
|
|
1466
1247
|
showPinright: true,
|
|
@@ -1473,8 +1254,6 @@ class DataGridComponent {
|
|
|
1473
1254
|
showChoseColumns: false,
|
|
1474
1255
|
showResetColumns: false,
|
|
1475
1256
|
};
|
|
1476
|
-
// for action validation;
|
|
1477
|
-
this.validateIcon = false;
|
|
1478
1257
|
this.changeLayout = new EventEmitter();
|
|
1479
1258
|
this.customCellEvent = new EventEmitter();
|
|
1480
1259
|
// Filter Apply event;
|
|
@@ -1483,7 +1262,6 @@ class DataGridComponent {
|
|
|
1483
1262
|
this.tablePresetConfig = new EventEmitter();
|
|
1484
1263
|
this.sortingOrderOptions = new EventEmitter();
|
|
1485
1264
|
this.createUpdateConfigListing = new EventEmitter();
|
|
1486
|
-
this.storePresetName = '';
|
|
1487
1265
|
this.isFullScreen = false;
|
|
1488
1266
|
this.activeTab = null;
|
|
1489
1267
|
this.groupedColumns = [];
|
|
@@ -1501,6 +1279,7 @@ class DataGridComponent {
|
|
|
1501
1279
|
this.filterColumnsList = [];
|
|
1502
1280
|
this.groupBoxPadding = 200;
|
|
1503
1281
|
this.presetName = '';
|
|
1282
|
+
this.storePresetName = '';
|
|
1504
1283
|
this.presetFilter = false;
|
|
1505
1284
|
this.searchTextPresetTable = '';
|
|
1506
1285
|
this.addFilterColumnInput = '';
|
|
@@ -1582,7 +1361,6 @@ class DataGridComponent {
|
|
|
1582
1361
|
];
|
|
1583
1362
|
this.hasScroll = false;
|
|
1584
1363
|
this.injector = inject(Injector);
|
|
1585
|
-
this.shouldRestoreScroll = false;
|
|
1586
1364
|
// private getDecrypt(key:string){
|
|
1587
1365
|
// const value = localStorage.getItem(key)
|
|
1588
1366
|
// try {
|
|
@@ -1622,6 +1400,7 @@ class DataGridComponent {
|
|
|
1622
1400
|
// Row Hover Logic Here
|
|
1623
1401
|
this.hoveredRowId = null;
|
|
1624
1402
|
this.isMenueHidden = false;
|
|
1403
|
+
this.clickedOnSortIcon = false;
|
|
1625
1404
|
this.getVisibleLeafColumns = (columns) => {
|
|
1626
1405
|
const result = [];
|
|
1627
1406
|
for (const column of columns) {
|
|
@@ -1787,38 +1566,37 @@ class DataGridComponent {
|
|
|
1787
1566
|
moveItemInArray(this.columns, prevColIndexInColumns, currColIndexInColumns);
|
|
1788
1567
|
// await this.refreshPreviewColumns();
|
|
1789
1568
|
this.cdr.detectChanges();
|
|
1790
|
-
|
|
1791
|
-
|
|
1792
|
-
|
|
1793
|
-
|
|
1794
|
-
|
|
1795
|
-
|
|
1796
|
-
|
|
1797
|
-
|
|
1798
|
-
|
|
1799
|
-
|
|
1800
|
-
|
|
1801
|
-
|
|
1802
|
-
|
|
1803
|
-
|
|
1804
|
-
|
|
1805
|
-
|
|
1806
|
-
|
|
1807
|
-
|
|
1808
|
-
|
|
1809
|
-
|
|
1810
|
-
|
|
1811
|
-
|
|
1812
|
-
|
|
1813
|
-
|
|
1814
|
-
|
|
1815
|
-
|
|
1816
|
-
|
|
1817
|
-
}
|
|
1569
|
+
this.ngZone.runOutsideAngular(() => {
|
|
1570
|
+
// Wait a tick to make sure elements are rendered
|
|
1571
|
+
requestAnimationFrame(() => {
|
|
1572
|
+
allFields.forEach((field) => {
|
|
1573
|
+
const updatedCells = Array.from(document.querySelectorAll(`[field="${field}"]`));
|
|
1574
|
+
updatedCells.forEach((el) => {
|
|
1575
|
+
const oldLeft = firstPositions.get(el);
|
|
1576
|
+
if (oldLeft == null)
|
|
1577
|
+
return; // skip if old position not available
|
|
1578
|
+
const newLeft = el.getBoundingClientRect().left;
|
|
1579
|
+
const deltaX = oldLeft - newLeft;
|
|
1580
|
+
if (deltaX !== 0) {
|
|
1581
|
+
el.style.willChange = 'transform';
|
|
1582
|
+
el.style.transition = 'none';
|
|
1583
|
+
el.style.transform = `translateX(${deltaX}px)`;
|
|
1584
|
+
// Force reflow
|
|
1585
|
+
void el.offsetWidth;
|
|
1586
|
+
el.style.transition = 'transform 300ms cubic-bezier(0.4, 0, 0.2, 1)';
|
|
1587
|
+
el.style.transform = 'translateX(0)';
|
|
1588
|
+
const handle = () => {
|
|
1589
|
+
el.style.transition = '';
|
|
1590
|
+
el.style.transform = '';
|
|
1591
|
+
el.style.willChange = '';
|
|
1592
|
+
el.removeEventListener('transitionend', handle);
|
|
1593
|
+
};
|
|
1594
|
+
el.addEventListener('transitionend', handle);
|
|
1595
|
+
}
|
|
1596
|
+
});
|
|
1818
1597
|
});
|
|
1819
1598
|
});
|
|
1820
1599
|
});
|
|
1821
|
-
// });
|
|
1822
1600
|
};
|
|
1823
1601
|
// onChildDragStart() {
|
|
1824
1602
|
// debugger;
|
|
@@ -1883,7 +1661,6 @@ class DataGridComponent {
|
|
|
1883
1661
|
moveItemInArray(this[section]?.[groupInSectionIndex].children, event.previousIndex, event.currentIndex);
|
|
1884
1662
|
// await this.refreshPreviewColumns();
|
|
1885
1663
|
this.cdr.detectChanges();
|
|
1886
|
-
await firstValueFrom(this.ngZone.onStable);
|
|
1887
1664
|
// allFields.forEach((field) => {
|
|
1888
1665
|
// const updatedCells = Array.from(
|
|
1889
1666
|
// document.querySelectorAll(`[field="${field}"]`)
|
|
@@ -1924,7 +1701,7 @@ class DataGridComponent {
|
|
|
1924
1701
|
el.style.transform = `translateX(${deltaX}px)`;
|
|
1925
1702
|
// Force reflow
|
|
1926
1703
|
void el.offsetWidth;
|
|
1927
|
-
el.style.transition = 'transform
|
|
1704
|
+
el.style.transition = 'transform 400ms cubic-bezier(0.4, 0, 0.2, 1)';
|
|
1928
1705
|
el.style.transform = 'translateX(0)';
|
|
1929
1706
|
const handle = () => {
|
|
1930
1707
|
el.style.transition = '';
|
|
@@ -1941,6 +1718,7 @@ class DataGridComponent {
|
|
|
1941
1718
|
};
|
|
1942
1719
|
this.isActiveFilterOpen = false;
|
|
1943
1720
|
this.activeSubButton = '';
|
|
1721
|
+
this.pageSizeOptions = [10, 25, 50, 75, 100, 150, 200, 250, 300, 500];
|
|
1944
1722
|
this.searchTextForFilterDropDown = '';
|
|
1945
1723
|
this.isFilterOpen = false;
|
|
1946
1724
|
this.showFilters = this.showSideMenu ? false : false;
|
|
@@ -2077,6 +1855,7 @@ class DataGridComponent {
|
|
|
2077
1855
|
'.svg');
|
|
2078
1856
|
},
|
|
2079
1857
|
};
|
|
1858
|
+
this.activeFilterType = '';
|
|
2080
1859
|
}
|
|
2081
1860
|
ngAfterViewInit() {
|
|
2082
1861
|
this.ngZone.onStable.pipe(take(1)).subscribe(async () => {
|
|
@@ -2133,23 +1912,20 @@ class DataGridComponent {
|
|
|
2133
1912
|
this.addStylesToImages();
|
|
2134
1913
|
this.hasScroll = this.hasHorizontalScrollbar();
|
|
2135
1914
|
this.cdr.detectChanges();
|
|
2136
|
-
if (this.shouldRestoreScroll &&
|
|
2137
|
-
this.centerScrollableBody?.nativeElement) {
|
|
2138
|
-
setTimeout(() => {
|
|
2139
|
-
const left = this.commonSevice.mainContainerLeft;
|
|
2140
|
-
this.centerScrollableBody.nativeElement.scrollLeft = left;
|
|
2141
|
-
this.centerPinnedHeader.nativeElement.scrollLeft = left;
|
|
2142
|
-
this.shouldRestoreScroll = false;
|
|
2143
|
-
}, 1000);
|
|
2144
|
-
}
|
|
2145
1915
|
}
|
|
2146
1916
|
ngOnInit() {
|
|
2147
1917
|
// if (this.tabs?.length) {
|
|
2148
1918
|
// this.activeTab = this.tabs[0];
|
|
2149
1919
|
// }
|
|
2150
1920
|
// this.autosizeAllColumns();
|
|
1921
|
+
if (this.consumerFont) {
|
|
1922
|
+
if (!this.fontFamilies.includes(this.consumerFont)) {
|
|
1923
|
+
this.fontFamilies.unshift(this.consumerFont);
|
|
1924
|
+
}
|
|
1925
|
+
this.fontFaimly = this.consumerFont;
|
|
1926
|
+
}
|
|
2151
1927
|
if (!this.curretaTablePresetForUpdate) {
|
|
2152
|
-
|
|
1928
|
+
this.autosizeAllColumns();
|
|
2153
1929
|
}
|
|
2154
1930
|
// const user = this.getDecrypt('user');
|
|
2155
1931
|
// this.currencyFormat = user?.currency_format;
|
|
@@ -2157,21 +1933,15 @@ class DataGridComponent {
|
|
|
2157
1933
|
// this.dateFormat = user?.date_format;
|
|
2158
1934
|
if (!this.dateFormat) {
|
|
2159
1935
|
const storedDateFormat = localStorage.getItem('dateformat');
|
|
2160
|
-
|
|
2161
|
-
this.dateFormat = storedDateFormat ? JSON.parse(storedDateFormat) : 'dd/MM/yyyy';
|
|
2162
|
-
}
|
|
1936
|
+
this.dateFormat = storedDateFormat ? JSON.parse(storedDateFormat) : 'dd/MM/yyyy';
|
|
2163
1937
|
}
|
|
2164
1938
|
if (!this.currencyFormat) {
|
|
2165
1939
|
const storedCurrencyFormat = localStorage.getItem('currencyFormat');
|
|
2166
|
-
|
|
2167
|
-
this.currencyFormat = storedCurrencyFormat ? JSON.parse(storedCurrencyFormat) : '1,234,567.89';
|
|
2168
|
-
}
|
|
1940
|
+
this.currencyFormat = storedCurrencyFormat ? JSON.parse(storedCurrencyFormat) : '1,234,567.89';
|
|
2169
1941
|
}
|
|
2170
1942
|
if (!this.currencySymbol) {
|
|
2171
1943
|
const storedCurrencySymbol = localStorage.getItem('currencySymbol');
|
|
2172
|
-
|
|
2173
|
-
this.currencySymbol = storedCurrencySymbol ? JSON.parse(storedCurrencySymbol) : '$';
|
|
2174
|
-
}
|
|
1944
|
+
this.currencySymbol = storedCurrencySymbol ? JSON.parse(storedCurrencySymbol) : '$';
|
|
2175
1945
|
}
|
|
2176
1946
|
}
|
|
2177
1947
|
async ngOnChanges(changes) {
|
|
@@ -2182,15 +1952,10 @@ class DataGridComponent {
|
|
|
2182
1952
|
if (changes['tabs']) {
|
|
2183
1953
|
const allTabs = JSON.parse(localStorage.getItem('activeTabs') || '{}');
|
|
2184
1954
|
const savedTab = allTabs[this.tableType];
|
|
2185
|
-
|
|
2186
|
-
|
|
2187
|
-
|
|
2188
|
-
else {
|
|
2189
|
-
this.activeTab = savedTab || this.tabs?.[0];
|
|
1955
|
+
this.activeTab = savedTab || this.tabs?.[0];
|
|
1956
|
+
if (this.tableType) {
|
|
1957
|
+
this.setActiveTab(this.activeTab);
|
|
2190
1958
|
}
|
|
2191
|
-
// if (this.tableType) {
|
|
2192
|
-
// this.setActiveTab(this.activeTab);
|
|
2193
|
-
// }
|
|
2194
1959
|
}
|
|
2195
1960
|
}
|
|
2196
1961
|
if (changes['filtersConfig']) {
|
|
@@ -2227,13 +1992,11 @@ class DataGridComponent {
|
|
|
2227
1992
|
this.ngZone.onStable.pipe(take(1)).subscribe(() => {
|
|
2228
1993
|
this.computeViewportRows();
|
|
2229
1994
|
this.updateVisibleRows(0);
|
|
2230
|
-
if (this.commonSevice?.mainContainerLeft > 200)
|
|
2231
|
-
this.shouldRestoreScroll = true;
|
|
2232
1995
|
this.cdr.detectChanges();
|
|
2233
1996
|
});
|
|
2234
1997
|
if (this.centerPinnedHeader?.nativeElement) {
|
|
2235
1998
|
void this.centerPinnedHeader.nativeElement.offsetWidth;
|
|
2236
|
-
this.dataSetLoading = true;
|
|
1999
|
+
// this.dataSetLoading = true;
|
|
2237
2000
|
setTimeout(() => {
|
|
2238
2001
|
if (this.centerScrollableBody?.nativeElement) {
|
|
2239
2002
|
this.centerScrollableBody.nativeElement.scrollLeft =
|
|
@@ -2310,11 +2073,6 @@ class DataGridComponent {
|
|
|
2310
2073
|
this.globalSearchText = temprorySelected.config.globalSearch;
|
|
2311
2074
|
this.setTableLayout(this.selectedTableLayout);
|
|
2312
2075
|
this.oddRowsBackgroundColor = temprorySelected?.config?.oddRowsBackgroundColor || '#f1f1f1';
|
|
2313
|
-
const groupedColumns = temprorySelected?.config?.groupedColumns;
|
|
2314
|
-
if (groupedColumns?.length) {
|
|
2315
|
-
this.groupedColumns = structuredClone(groupedColumns);
|
|
2316
|
-
this.groupDataAsync(this.dataSet, this.groupedColumns);
|
|
2317
|
-
}
|
|
2318
2076
|
this.cdr.detectChanges();
|
|
2319
2077
|
}
|
|
2320
2078
|
else if (this.defaultConfig) {
|
|
@@ -2325,13 +2083,12 @@ class DataGridComponent {
|
|
|
2325
2083
|
this.selectedTableLayout = this.defaultConfig.selectedTableLayout;
|
|
2326
2084
|
this.bodyTextFontsSize = this.defaultConfig.bodyTextFontsSize;
|
|
2327
2085
|
this.globalSearchText = this.defaultConfig.globalSearch;
|
|
2328
|
-
this.setTableLayout(this.selectedTableLayout);
|
|
2329
2086
|
}
|
|
2330
2087
|
else {
|
|
2331
2088
|
this.rowShadingEnabled = false;
|
|
2332
2089
|
this.showVerticalBorder = false;
|
|
2333
2090
|
this.fontFaimly = 'Inter';
|
|
2334
|
-
this.headerTextFontsSize =
|
|
2091
|
+
this.headerTextFontsSize = 13;
|
|
2335
2092
|
this.selectedTableLayout = 'medium';
|
|
2336
2093
|
this.bodyTextFontsSize = 14;
|
|
2337
2094
|
this.globalSearchText = '';
|
|
@@ -2339,7 +2096,7 @@ class DataGridComponent {
|
|
|
2339
2096
|
this.presetName = '';
|
|
2340
2097
|
}
|
|
2341
2098
|
this.cdr.detectChanges();
|
|
2342
|
-
},
|
|
2099
|
+
}, 500);
|
|
2343
2100
|
}
|
|
2344
2101
|
if (changes['pageSizeOptions'] && changes['pageSizeOptions']?.currentValue) {
|
|
2345
2102
|
this.buildPageSizeKeyMap();
|
|
@@ -2348,7 +2105,6 @@ class DataGridComponent {
|
|
|
2348
2105
|
async setColumnsColumnDropdownValus() {
|
|
2349
2106
|
if (!this.columns)
|
|
2350
2107
|
return;
|
|
2351
|
-
// Just removed temporary for super admin will set it again
|
|
2352
2108
|
if (this.columns?.length) {
|
|
2353
2109
|
this.columns = this.columns?.filter(c => c?.field?.trim() !== 'is_deleted');
|
|
2354
2110
|
}
|
|
@@ -2514,22 +2270,9 @@ class DataGridComponent {
|
|
|
2514
2270
|
columns: this.cleanColumns(this.columns),
|
|
2515
2271
|
filters: this.cleanFilterdColumns(),
|
|
2516
2272
|
no_of_records: this.paginationConfig.pageSize,
|
|
2517
|
-
table_config: {
|
|
2518
|
-
rowShadingEnabled: this.rowShadingEnabled,
|
|
2519
|
-
showVerticalBorder: this.showVerticalBorder,
|
|
2520
|
-
fontFaimly: this.fontFaimly,
|
|
2521
|
-
headerTextFontsSize: this.headerTextColor,
|
|
2522
|
-
selectedTableLayout: this.selectedTableLayout,
|
|
2523
|
-
bodyTextFontsSize: this.bodyTextFontsSize,
|
|
2524
|
-
globalSearch: this.globalSearchText,
|
|
2525
|
-
filterNames: '',
|
|
2526
|
-
totalCount: 0,
|
|
2527
|
-
activeFilters: true,
|
|
2528
|
-
oddRowsBackgroundColor: '#f1f1f1'
|
|
2529
|
-
},
|
|
2530
2273
|
type: this.tableType,
|
|
2531
2274
|
};
|
|
2532
|
-
this.createUpdateConfigListing.emit(
|
|
2275
|
+
this.createUpdateConfigListing.emit(sendData);
|
|
2533
2276
|
};
|
|
2534
2277
|
window.addEventListener('mousemove', onMouseMove);
|
|
2535
2278
|
window.addEventListener('mouseup', onMouseUp);
|
|
@@ -2548,27 +2291,6 @@ class DataGridComponent {
|
|
|
2548
2291
|
update(this.columns);
|
|
2549
2292
|
this.cdr.detectChanges();
|
|
2550
2293
|
}
|
|
2551
|
-
get createUpdateColumnConfig() {
|
|
2552
|
-
return {
|
|
2553
|
-
columns: this.cleanColumns(this.columns),
|
|
2554
|
-
filters: this.cleanFilterdColumns(),
|
|
2555
|
-
no_of_records: this.paginationConfig.pageSize,
|
|
2556
|
-
table_config: {
|
|
2557
|
-
rowShadingEnabled: this.rowShadingEnabled,
|
|
2558
|
-
showVerticalBorder: this.showVerticalBorder,
|
|
2559
|
-
fontFaimly: this.fontFaimly,
|
|
2560
|
-
headerTextFontsSize: Number(this.headerTextFontsSize),
|
|
2561
|
-
selectedTableLayout: this.selectedTableLayout,
|
|
2562
|
-
bodyTextFontsSize: Number(this.bodyTextFontsSize),
|
|
2563
|
-
globalSearch: this.globalSearchText,
|
|
2564
|
-
filterNames: '',
|
|
2565
|
-
totalCount: 0,
|
|
2566
|
-
activeFilters: true,
|
|
2567
|
-
oddRowsBackgroundColor: '#f1f1f1'
|
|
2568
|
-
},
|
|
2569
|
-
type: this.tableType,
|
|
2570
|
-
};
|
|
2571
|
-
}
|
|
2572
2294
|
cleanColumns(columns) {
|
|
2573
2295
|
return columns.map((col) => {
|
|
2574
2296
|
const { __typename, _id, column_dropdown_value, filterValue, expandedFilter, query, isRowGrouped, ...rest } = col;
|
|
@@ -2588,6 +2310,7 @@ class DataGridComponent {
|
|
|
2588
2310
|
...rest,
|
|
2589
2311
|
column_dropdown_value: cleanedDropdown,
|
|
2590
2312
|
query: cleanedQuery,
|
|
2313
|
+
is_groupable: rest.type !== 'image',
|
|
2591
2314
|
};
|
|
2592
2315
|
});
|
|
2593
2316
|
}
|
|
@@ -2638,7 +2361,7 @@ class DataGridComponent {
|
|
|
2638
2361
|
no_of_records: this.paginationConfig.pageSize,
|
|
2639
2362
|
type: this.tableType,
|
|
2640
2363
|
};
|
|
2641
|
-
this.createUpdateConfigListing.emit(
|
|
2364
|
+
this.createUpdateConfigListing.emit(sendData);
|
|
2642
2365
|
matchingEls.forEach((el) => {
|
|
2643
2366
|
el.classList.remove('resizing-highlight');
|
|
2644
2367
|
el.classList.remove('resizing-highlight-right');
|
|
@@ -2762,7 +2485,8 @@ class DataGridComponent {
|
|
|
2762
2485
|
}
|
|
2763
2486
|
return false;
|
|
2764
2487
|
}
|
|
2765
|
-
openThreeDotsMenu(event, child,
|
|
2488
|
+
openThreeDotsMenu(event, child, clickedOnSortIcon) {
|
|
2489
|
+
this.clickedOnSortIcon = clickedOnSortIcon || false;
|
|
2766
2490
|
event.preventDefault();
|
|
2767
2491
|
event.stopPropagation();
|
|
2768
2492
|
this.isMenueHidden = true;
|
|
@@ -2792,6 +2516,8 @@ class DataGridComponent {
|
|
|
2792
2516
|
sortAsc(col) {
|
|
2793
2517
|
if (!col.is_sortable)
|
|
2794
2518
|
return;
|
|
2519
|
+
this.sortingConfig['order_by'] = 'asc';
|
|
2520
|
+
this.sortingConfig['field'] = col.field;
|
|
2795
2521
|
col.order_by = 'asc';
|
|
2796
2522
|
const event = {
|
|
2797
2523
|
order: 'asc',
|
|
@@ -2803,6 +2529,8 @@ class DataGridComponent {
|
|
|
2803
2529
|
sortDesc(col) {
|
|
2804
2530
|
if (!col.is_sortable)
|
|
2805
2531
|
return;
|
|
2532
|
+
this.sortingConfig['order_by'] = 'desc';
|
|
2533
|
+
this.sortingConfig['field'] = col.field;
|
|
2806
2534
|
col.order_by = 'desc';
|
|
2807
2535
|
const event = {
|
|
2808
2536
|
order: 'desc',
|
|
@@ -2818,7 +2546,6 @@ class DataGridComponent {
|
|
|
2818
2546
|
this.sortingOrderOptions.emit(event);
|
|
2819
2547
|
}
|
|
2820
2548
|
async updateColumnPinInSourceByField(column, pinned, isNestedTable = false, columns) {
|
|
2821
|
-
debugger;
|
|
2822
2549
|
if (isNestedTable) {
|
|
2823
2550
|
this.pinUnpinColum(column, pinned, columns);
|
|
2824
2551
|
return;
|
|
@@ -2844,7 +2571,7 @@ class DataGridComponent {
|
|
|
2844
2571
|
no_of_records: this.paginationConfig.pageSize,
|
|
2845
2572
|
type: this.tableType,
|
|
2846
2573
|
};
|
|
2847
|
-
this.createUpdateConfigListing.emit(
|
|
2574
|
+
this.createUpdateConfigListing.emit(sendData);
|
|
2848
2575
|
}
|
|
2849
2576
|
autosizeColumn(cols) {
|
|
2850
2577
|
this.activeCol = null;
|
|
@@ -2879,7 +2606,7 @@ class DataGridComponent {
|
|
|
2879
2606
|
no_of_records: this.paginationConfig.pageSize,
|
|
2880
2607
|
type: this.tableType,
|
|
2881
2608
|
};
|
|
2882
|
-
this.createUpdateConfigListing.emit(
|
|
2609
|
+
this.createUpdateConfigListing.emit(sendData);
|
|
2883
2610
|
}, 1000);
|
|
2884
2611
|
this.refreshPreviewColumns();
|
|
2885
2612
|
}
|
|
@@ -2930,7 +2657,7 @@ class DataGridComponent {
|
|
|
2930
2657
|
no_of_records: this.paginationConfig.pageSize,
|
|
2931
2658
|
type: this.tableType,
|
|
2932
2659
|
};
|
|
2933
|
-
this.createUpdateConfigListing.emit(
|
|
2660
|
+
this.createUpdateConfigListing.emit(sendData);
|
|
2934
2661
|
}, 1000);
|
|
2935
2662
|
}
|
|
2936
2663
|
markColumnAsGrouped(columns, field) {
|
|
@@ -3122,7 +2849,7 @@ class DataGridComponent {
|
|
|
3122
2849
|
no_of_records: this.paginationConfig.pageSize,
|
|
3123
2850
|
type: this.tableType,
|
|
3124
2851
|
};
|
|
3125
|
-
this.createUpdateConfigListing.emit(
|
|
2852
|
+
this.createUpdateConfigListing.emit(sendData);
|
|
3126
2853
|
setTimeout(() => {
|
|
3127
2854
|
this.updateColumnWidthsAndGroups();
|
|
3128
2855
|
this.refreshPreviewColumns();
|
|
@@ -3161,7 +2888,7 @@ class DataGridComponent {
|
|
|
3161
2888
|
}
|
|
3162
2889
|
async toggleColumnVisibility(column, isVisible) {
|
|
3163
2890
|
if (isVisible) {
|
|
3164
|
-
if (this.visibleColumns()?.length <= 2 && column.is_visible
|
|
2891
|
+
if (this.visibleColumns()?.length <= 2 && column.is_visible) {
|
|
3165
2892
|
return;
|
|
3166
2893
|
}
|
|
3167
2894
|
}
|
|
@@ -3177,7 +2904,7 @@ class DataGridComponent {
|
|
|
3177
2904
|
no_of_records: this.paginationConfig.pageSize,
|
|
3178
2905
|
type: this.tableType,
|
|
3179
2906
|
};
|
|
3180
|
-
this.createUpdateConfigListing.emit(
|
|
2907
|
+
this.createUpdateConfigListing.emit(sendData);
|
|
3181
2908
|
if (this.tableFilterViewId) {
|
|
3182
2909
|
this.savePreset('mouseUp');
|
|
3183
2910
|
}
|
|
@@ -3221,7 +2948,7 @@ class DataGridComponent {
|
|
|
3221
2948
|
no_of_records: this.paginationConfig.pageSize,
|
|
3222
2949
|
type: this.tableType,
|
|
3223
2950
|
};
|
|
3224
|
-
this.createUpdateConfigListing.emit(
|
|
2951
|
+
this.createUpdateConfigListing.emit(sendData);
|
|
3225
2952
|
}
|
|
3226
2953
|
finally {
|
|
3227
2954
|
this.loading = false;
|
|
@@ -3392,7 +3119,7 @@ class DataGridComponent {
|
|
|
3392
3119
|
no_of_records: this.paginationConfig.pageSize,
|
|
3393
3120
|
type: this.tableType,
|
|
3394
3121
|
};
|
|
3395
|
-
this.createUpdateConfigListing.emit(
|
|
3122
|
+
this.createUpdateConfigListing.emit(sendData);
|
|
3396
3123
|
}, 400);
|
|
3397
3124
|
}
|
|
3398
3125
|
async refreshHeaders() {
|
|
@@ -3759,7 +3486,7 @@ class DataGridComponent {
|
|
|
3759
3486
|
no_of_records: this.paginationConfig.pageSize,
|
|
3760
3487
|
type: this.tableType,
|
|
3761
3488
|
};
|
|
3762
|
-
this.createUpdateConfigListing.emit(
|
|
3489
|
+
this.createUpdateConfigListing.emit(sendData);
|
|
3763
3490
|
this.cdr.detectChanges();
|
|
3764
3491
|
}
|
|
3765
3492
|
deepCloneColumns(columns) {
|
|
@@ -3881,7 +3608,7 @@ class DataGridComponent {
|
|
|
3881
3608
|
no_of_records: this.paginationConfig.pageSize,
|
|
3882
3609
|
type: this.tableType,
|
|
3883
3610
|
};
|
|
3884
|
-
this.createUpdateConfigListing.emit(
|
|
3611
|
+
this.createUpdateConfigListing.emit(sendData);
|
|
3885
3612
|
setTimeout(() => {
|
|
3886
3613
|
this.cdr.detectChanges();
|
|
3887
3614
|
}, 2);
|
|
@@ -3923,6 +3650,10 @@ class DataGridComponent {
|
|
|
3923
3650
|
// const dateObj = new Date(keyValue);
|
|
3924
3651
|
// groupKey = this.commonSevice.formatDateValue(dateObj, this.dateFormat || 'dd/MM/yyyy');
|
|
3925
3652
|
// }
|
|
3653
|
+
if (typeof keyValue === 'string' && !isNaN(Date.parse(keyValue))) {
|
|
3654
|
+
const dateObj = new Date(keyValue);
|
|
3655
|
+
groupKey = this.commonSevice.formatDateValue(dateObj, this.dateFormat || 'dd/MM/yyyy');
|
|
3656
|
+
}
|
|
3926
3657
|
if (!groupedMap.has(groupKey))
|
|
3927
3658
|
groupedMap.set(groupKey, []);
|
|
3928
3659
|
groupedMap.get(groupKey).push(item);
|
|
@@ -3987,27 +3718,24 @@ class DataGridComponent {
|
|
|
3987
3718
|
this.onFontChange();
|
|
3988
3719
|
}
|
|
3989
3720
|
setTableLayout(layoutType) {
|
|
3990
|
-
if (!layoutType)
|
|
3991
|
-
return;
|
|
3992
3721
|
if (layoutType === 'small') {
|
|
3993
|
-
this.rowHeight =
|
|
3722
|
+
this.rowHeight = 50;
|
|
3994
3723
|
this.headerRowHeight = 40;
|
|
3995
|
-
this.bodyTextFontsSize =
|
|
3996
|
-
this.headerTextFontsSize =
|
|
3724
|
+
this.bodyTextFontsSize = 10;
|
|
3725
|
+
this.headerTextFontsSize = 10;
|
|
3997
3726
|
}
|
|
3998
3727
|
else if (layoutType === 'medium') {
|
|
3999
|
-
this.rowHeight =
|
|
4000
|
-
this.headerRowHeight =
|
|
4001
|
-
this.bodyTextFontsSize =
|
|
4002
|
-
this.headerTextFontsSize =
|
|
3728
|
+
this.rowHeight = 60;
|
|
3729
|
+
this.headerRowHeight = 40;
|
|
3730
|
+
this.bodyTextFontsSize = 14;
|
|
3731
|
+
this.headerTextFontsSize = 13;
|
|
4003
3732
|
}
|
|
4004
3733
|
else {
|
|
4005
|
-
this.rowHeight =
|
|
4006
|
-
this.headerRowHeight =
|
|
4007
|
-
this.bodyTextFontsSize =
|
|
4008
|
-
this.headerTextFontsSize =
|
|
3734
|
+
this.rowHeight = 72;
|
|
3735
|
+
this.headerRowHeight = 40;
|
|
3736
|
+
this.bodyTextFontsSize = 16;
|
|
3737
|
+
this.headerTextFontsSize = 16;
|
|
4009
3738
|
}
|
|
4010
|
-
// this.createUpdateConfigListing.emit(this.createUpdateColumnConfig);
|
|
4011
3739
|
}
|
|
4012
3740
|
get startIndexData() {
|
|
4013
3741
|
return (this.paginationConfig.page - 1) * this.paginationConfig.limit;
|
|
@@ -4051,27 +3779,27 @@ class DataGridComponent {
|
|
|
4051
3779
|
}
|
|
4052
3780
|
}
|
|
4053
3781
|
openFilteronThreeDotsClick(col) {
|
|
4054
|
-
if (col.type == 'image' || !col?.type
|
|
3782
|
+
if (col.type == 'image' || !col?.type)
|
|
4055
3783
|
return;
|
|
4056
3784
|
this.selectedColumnForFilter = col;
|
|
4057
3785
|
this.isThreeDotsFilterOpen = true;
|
|
4058
3786
|
this.addFilterColumnInput = '';
|
|
4059
|
-
if (col.type === 'dropdown'
|
|
3787
|
+
if (col.type === 'dropdown') {
|
|
4060
3788
|
this.currentFilterSelectedIds.clear();
|
|
4061
3789
|
const savedIds = col?.query?._ids || [];
|
|
4062
3790
|
savedIds.forEach((id) => this.currentFilterSelectedIds.add(id));
|
|
4063
|
-
this.selectedFilterOptions = this.selectedColumnForFilter?.column_dropdown_value
|
|
3791
|
+
this.selectedFilterOptions = this.selectedColumnForFilter?.column_dropdown_value.filter((option) => this.currentFilterSelectedIds.has(option?.id || option?._id || option));
|
|
4064
3792
|
setTimeout(() => {
|
|
4065
3793
|
if (this.filterMenueSearchInput) {
|
|
4066
3794
|
this.filterMenueSearchInput.nativeElement.focus();
|
|
4067
3795
|
}
|
|
4068
3796
|
}, 100);
|
|
4069
3797
|
}
|
|
4070
|
-
else if (['string', 'number', 'date'
|
|
4071
|
-
this.firstCondition = col.query.first_condition ? col.query.first_condition : (
|
|
3798
|
+
else if (['string', 'number', 'date'].includes(col.type)) {
|
|
3799
|
+
this.firstCondition = col.query.first_condition ? col.query.first_condition : (col.type == 'date' ? 'equal' : 'contain');
|
|
4072
3800
|
this.firstValue = col?.query?.first_value || '';
|
|
4073
3801
|
this.condition = col?.query?.condition || 'none';
|
|
4074
|
-
this.secondCondition = col.query.first_condition ? col.query.first_condition : (
|
|
3802
|
+
this.secondCondition = col.query.first_condition ? col.query.first_condition : (col.type == 'date' ? 'equal' : 'contain');
|
|
4075
3803
|
this.secondValue = col?.query?.second_value || '';
|
|
4076
3804
|
setTimeout(() => {
|
|
4077
3805
|
this.filterMenueTextchInput.nativeElement.focus();
|
|
@@ -4080,30 +3808,28 @@ class DataGridComponent {
|
|
|
4080
3808
|
this.cdr.detectChanges();
|
|
4081
3809
|
}
|
|
4082
3810
|
openFilterFromDisabledSearchedInput(col) {
|
|
4083
|
-
if (col.type !== 'dropdown'
|
|
3811
|
+
if (col.type !== 'dropdown')
|
|
4084
3812
|
return;
|
|
4085
3813
|
this.openFilter(col);
|
|
4086
3814
|
}
|
|
4087
3815
|
openFilter(col) {
|
|
4088
|
-
if (!col.is_search_able)
|
|
4089
|
-
return;
|
|
4090
3816
|
this.activeFilterCell = col;
|
|
4091
3817
|
this.activeCol = null;
|
|
4092
3818
|
this.isFilterOpen = true;
|
|
4093
3819
|
this.searchTextForFilterDropDown = '';
|
|
4094
3820
|
this.addFilterColumnInput = '';
|
|
4095
3821
|
this.selectedColumnForFilter = col;
|
|
4096
|
-
if (col.type === 'dropdown'
|
|
3822
|
+
if (col.type === 'dropdown') {
|
|
4097
3823
|
this.currentFilterSelectedIds.clear();
|
|
4098
3824
|
const savedIds = col?.query?._ids || [];
|
|
4099
3825
|
savedIds.forEach((id) => this.currentFilterSelectedIds.add(id));
|
|
4100
3826
|
this.selectedFilterOptions = this.selectedColumnForFilter?.column_dropdown_value?.filter((option) => this.currentFilterSelectedIds.has(option?.id || option?._id || option));
|
|
4101
3827
|
}
|
|
4102
|
-
else if (['string', 'number', 'date'
|
|
4103
|
-
this.firstCondition = col?.query?.first_condition ||
|
|
3828
|
+
else if (['string', 'number', 'date'].includes(col.type)) {
|
|
3829
|
+
this.firstCondition = col?.query?.first_condition || 'contain';
|
|
4104
3830
|
this.firstValue = col?.query?.first_value || '';
|
|
4105
3831
|
this.condition = col?.query?.condition || 'none';
|
|
4106
|
-
this.secondCondition = col?.query?.second_condition ||
|
|
3832
|
+
this.secondCondition = col?.query?.second_condition || 'contain';
|
|
4107
3833
|
this.secondValue = col?.query?.second_value || '';
|
|
4108
3834
|
}
|
|
4109
3835
|
this.cdr.detectChanges();
|
|
@@ -4161,7 +3887,7 @@ class DataGridComponent {
|
|
|
4161
3887
|
};
|
|
4162
3888
|
const column = findColumn(this.columns, this.selectedColumnForFilter.field);
|
|
4163
3889
|
if (column) {
|
|
4164
|
-
if (column.type === 'dropdown'
|
|
3890
|
+
if (column.type === 'dropdown') {
|
|
4165
3891
|
column.query = column.query || {};
|
|
4166
3892
|
column.query._ids = column.query._ids || [];
|
|
4167
3893
|
// Remove stale IDs (not present in Set)
|
|
@@ -4174,7 +3900,7 @@ class DataGridComponent {
|
|
|
4174
3900
|
}
|
|
4175
3901
|
});
|
|
4176
3902
|
}
|
|
4177
|
-
else if (['string', 'number', 'date'
|
|
3903
|
+
else if (['string', 'number', 'date'].includes(column.type)) {
|
|
4178
3904
|
column.query = {
|
|
4179
3905
|
first_condition: this.firstCondition || 'contain',
|
|
4180
3906
|
first_value: this.firstValue || null,
|
|
@@ -4210,10 +3936,9 @@ class DataGridComponent {
|
|
|
4210
3936
|
no_of_records: Number(this.paginationConfig.limit),
|
|
4211
3937
|
type: this.tableType,
|
|
4212
3938
|
};
|
|
4213
|
-
this.createUpdateConfigListing.emit(
|
|
3939
|
+
this.createUpdateConfigListing.emit(sendData);
|
|
4214
3940
|
const filters = this.cleanFilterdColumns();
|
|
4215
3941
|
setTimeout(() => {
|
|
4216
|
-
this.commonSevice.mainContainerLeft = this.centerScrollableBody.nativeElement.scrollLeft;
|
|
4217
3942
|
this.filterOptions.emit(filters);
|
|
4218
3943
|
}, 200);
|
|
4219
3944
|
}
|
|
@@ -4303,15 +4028,13 @@ class DataGridComponent {
|
|
|
4303
4028
|
no_of_records: Number(this.paginationConfig.limit),
|
|
4304
4029
|
type: this.tableType,
|
|
4305
4030
|
};
|
|
4306
|
-
this.createUpdateConfigListing.emit(
|
|
4031
|
+
this.createUpdateConfigListing.emit(sendData);
|
|
4307
4032
|
const filters = this.cleanFilterdColumns();
|
|
4308
4033
|
setTimeout(() => {
|
|
4309
|
-
this.commonSevice.mainContainerLeft = this.centerScrollableBody.nativeElement.scrollLeft;
|
|
4310
4034
|
this.filterOptions.emit(filters);
|
|
4311
4035
|
}, 200);
|
|
4312
4036
|
}
|
|
4313
|
-
clearAllFilters(
|
|
4314
|
-
this.groupedColumns = [];
|
|
4037
|
+
clearAllFilters() {
|
|
4315
4038
|
this.tableView?.forEach((ele) => { ele.is_temp = false; });
|
|
4316
4039
|
const resetAllRecursively = (columns) => {
|
|
4317
4040
|
for (const column of columns) {
|
|
@@ -4335,13 +4058,13 @@ class DataGridComponent {
|
|
|
4335
4058
|
this.filtersConfig = [];
|
|
4336
4059
|
this.refreshPreviewColumns();
|
|
4337
4060
|
this.cdr.detectChanges();
|
|
4338
|
-
|
|
4339
|
-
|
|
4340
|
-
|
|
4341
|
-
|
|
4342
|
-
|
|
4343
|
-
|
|
4344
|
-
|
|
4061
|
+
this.rowShadingEnabled = false;
|
|
4062
|
+
this.showVerticalBorder = false;
|
|
4063
|
+
this.fontFaimly = 'Inter';
|
|
4064
|
+
this.headerTextFontsSize = 14;
|
|
4065
|
+
this.selectedTableLayout = 'mediumd';
|
|
4066
|
+
this.bodyTextFontsSize = 14;
|
|
4067
|
+
this.globalSearchText = '';
|
|
4345
4068
|
const event = { eventType: 'reset', data: { tableType: this.tableType } };
|
|
4346
4069
|
const sendData = {
|
|
4347
4070
|
columns: this.cleanColumns(this.columns),
|
|
@@ -4349,17 +4072,11 @@ class DataGridComponent {
|
|
|
4349
4072
|
no_of_records: Number(this.paginationConfig.limit),
|
|
4350
4073
|
type: this.tableType,
|
|
4351
4074
|
};
|
|
4352
|
-
|
|
4353
|
-
this.createUpdateConfigListing.emit(this.createUpdateColumnConfig);
|
|
4354
|
-
}
|
|
4355
|
-
this.commonSevice.mainContainerLeft = this.centerScrollableBody.nativeElement.scrollLeft;
|
|
4356
|
-
this.commonSevice.mainContainerLeft = this.centerScrollableBody.nativeElement.scrollLeft;
|
|
4075
|
+
this.createUpdateConfigListing.emit(sendData);
|
|
4357
4076
|
setTimeout(() => {
|
|
4358
4077
|
const filteredColumns = this.cleanFilterdColumns();
|
|
4359
4078
|
this.genericEvent.emit(event);
|
|
4360
|
-
|
|
4361
|
-
this.filterOptions.emit(filteredColumns);
|
|
4362
|
-
}
|
|
4079
|
+
this.filterOptions.emit(filteredColumns);
|
|
4363
4080
|
}, 300);
|
|
4364
4081
|
this.cdr.detectChanges();
|
|
4365
4082
|
}
|
|
@@ -4396,8 +4113,7 @@ class DataGridComponent {
|
|
|
4396
4113
|
no_of_records: Number(this.paginationConfig.limit),
|
|
4397
4114
|
type: this.tableType,
|
|
4398
4115
|
};
|
|
4399
|
-
this.createUpdateConfigListing.emit(
|
|
4400
|
-
this.commonSevice.mainContainerLeft = this.centerScrollableBody.nativeElement.scrollLeft;
|
|
4116
|
+
this.createUpdateConfigListing.emit(sendData);
|
|
4401
4117
|
setTimeout(() => {
|
|
4402
4118
|
const filteredColumns = this.cleanFilterdColumns();
|
|
4403
4119
|
this.filterOptions.emit(filteredColumns);
|
|
@@ -4424,8 +4140,7 @@ class DataGridComponent {
|
|
|
4424
4140
|
no_of_records: Number(this.paginationConfig.limit),
|
|
4425
4141
|
type: this.tableType,
|
|
4426
4142
|
};
|
|
4427
|
-
this.createUpdateConfigListing.emit(
|
|
4428
|
-
this.commonSevice.mainContainerLeft = this.centerScrollableBody.nativeElement.scrollLeft;
|
|
4143
|
+
this.createUpdateConfigListing.emit(sendData);
|
|
4429
4144
|
setTimeout(() => {
|
|
4430
4145
|
const filteredColumns = this.cleanFilterdColumns();
|
|
4431
4146
|
this.filterOptions.emit(filteredColumns);
|
|
@@ -4474,7 +4189,7 @@ class DataGridComponent {
|
|
|
4474
4189
|
if (column.type == 'image' || !column?.is_editable)
|
|
4475
4190
|
return;
|
|
4476
4191
|
this.editingKey = ((row.id || row._id) + '-' + column.field);
|
|
4477
|
-
if (column.type === 'dropdown'
|
|
4192
|
+
if (column.type === 'dropdown') {
|
|
4478
4193
|
setTimeout(() => {
|
|
4479
4194
|
const dropdownMenu = document.querySelector('.cell-editing-dropdown-menu');
|
|
4480
4195
|
if (dropdownMenu) {
|
|
@@ -4510,10 +4225,6 @@ class DataGridComponent {
|
|
|
4510
4225
|
this.rowSelectedIndexes.clear();
|
|
4511
4226
|
if (!this.editingKey)
|
|
4512
4227
|
return;
|
|
4513
|
-
if (control && control.pristine) {
|
|
4514
|
-
this.editingKey = null;
|
|
4515
|
-
return;
|
|
4516
|
-
}
|
|
4517
4228
|
this.checkRowEditAndEmitValue(row, column, row[column.field]);
|
|
4518
4229
|
this.editingKey = null;
|
|
4519
4230
|
this.cdr.detectChanges();
|
|
@@ -4598,7 +4309,6 @@ class DataGridComponent {
|
|
|
4598
4309
|
},
|
|
4599
4310
|
eventType: 'pageChange',
|
|
4600
4311
|
};
|
|
4601
|
-
this.commonSevice.mainContainerLeft = this.centerScrollableBody.nativeElement.scrollLeft;
|
|
4602
4312
|
this.genericEvent.emit(event);
|
|
4603
4313
|
}
|
|
4604
4314
|
onPageSizeChange() {
|
|
@@ -4617,7 +4327,7 @@ class DataGridComponent {
|
|
|
4617
4327
|
no_of_records: Number(this.paginationConfig.limit),
|
|
4618
4328
|
type: this.tableType,
|
|
4619
4329
|
};
|
|
4620
|
-
this.createUpdateConfigListing.emit(
|
|
4330
|
+
this.createUpdateConfigListing.emit(sendData);
|
|
4621
4331
|
setTimeout(() => {
|
|
4622
4332
|
const event = {
|
|
4623
4333
|
obj: {
|
|
@@ -4630,11 +4340,11 @@ class DataGridComponent {
|
|
|
4630
4340
|
}, 700);
|
|
4631
4341
|
}
|
|
4632
4342
|
actionPreset(data, type) {
|
|
4633
|
-
data.columns = data
|
|
4343
|
+
data.columns = data.columns.map(({ _id, filterValue, search, column_dropdown_value, query, __typename, ...rest }) => rest);
|
|
4634
4344
|
this.tableView?.forEach((ele) => { ele.is_temp = false; });
|
|
4635
4345
|
{
|
|
4636
|
-
this.bodyTextFontsSize = data
|
|
4637
|
-
this.fontFaimly = data
|
|
4346
|
+
this.bodyTextFontsSize = data?.config?.bodyTextFontsSize,
|
|
4347
|
+
this.fontFaimly = data?.config?.fontFaimly,
|
|
4638
4348
|
data?.filters?.forEach((element) => {
|
|
4639
4349
|
delete element.__typename;
|
|
4640
4350
|
if (element.query) {
|
|
@@ -4675,9 +4385,9 @@ class DataGridComponent {
|
|
|
4675
4385
|
}));
|
|
4676
4386
|
this.columns = data.columns;
|
|
4677
4387
|
{
|
|
4678
|
-
this.bodyTextFontsSize = data
|
|
4679
|
-
this.fontFaimly = data
|
|
4680
|
-
data
|
|
4388
|
+
this.bodyTextFontsSize = data?.config?.bodyTextFontsSize,
|
|
4389
|
+
this.fontFaimly = data?.config?.fontFaimly,
|
|
4390
|
+
data?.filters?.forEach((element) => {
|
|
4681
4391
|
delete element.__typename;
|
|
4682
4392
|
if (element.query) {
|
|
4683
4393
|
delete element.query.__typename;
|
|
@@ -4689,9 +4399,9 @@ class DataGridComponent {
|
|
|
4689
4399
|
}
|
|
4690
4400
|
});
|
|
4691
4401
|
// this.globalSearch = data.config.bodyTextFontsSize,
|
|
4692
|
-
this.headerTextFontsSize = data
|
|
4693
|
-
this.selectedTableLayout = data
|
|
4694
|
-
this.showVerticalBorder = data
|
|
4402
|
+
this.headerTextFontsSize = data?.config?.headerTextFontsSize,
|
|
4403
|
+
this.selectedTableLayout = data?.config?.selectedTableLayout,
|
|
4404
|
+
this.showVerticalBorder = data?.config?.showVerticalBorder,
|
|
4695
4405
|
this.currentIdForUpdatePreset = data.id;
|
|
4696
4406
|
this.curretaTablePresetForUpdate = structuredClone(data);
|
|
4697
4407
|
this.presetName = data?.name;
|
|
@@ -4770,7 +4480,7 @@ class DataGridComponent {
|
|
|
4770
4480
|
no_of_records: Number(this.paginationConfig.limit),
|
|
4771
4481
|
type: this.tableType,
|
|
4772
4482
|
};
|
|
4773
|
-
this.createUpdateConfigListing.emit(
|
|
4483
|
+
this.createUpdateConfigListing.emit(sendData);
|
|
4774
4484
|
setTimeout(() => {
|
|
4775
4485
|
this.genericEvent.emit(event);
|
|
4776
4486
|
}, 500);
|
|
@@ -4917,12 +4627,9 @@ class DataGridComponent {
|
|
|
4917
4627
|
return (parts[0][0] + (parts[1]?.[0] || '')).toUpperCase();
|
|
4918
4628
|
}
|
|
4919
4629
|
onRightClick(event, deatilsList) {
|
|
4920
|
-
|
|
4921
|
-
|
|
4922
|
-
|
|
4923
|
-
this.actions = this.validateIcon
|
|
4924
|
-
? this.getValidActions(deatilsList)
|
|
4925
|
-
: (deatilsList?.actions?.length ? deatilsList.actions : []);
|
|
4630
|
+
if (deatilsList?.actions?.length) {
|
|
4631
|
+
this.actions = deatilsList.actions;
|
|
4632
|
+
}
|
|
4926
4633
|
if (!(event instanceof MouseEvent)) {
|
|
4927
4634
|
event.preventDefault();
|
|
4928
4635
|
}
|
|
@@ -4943,13 +4650,13 @@ class DataGridComponent {
|
|
|
4943
4650
|
const menuWidth = menuElement.offsetWidth;
|
|
4944
4651
|
const menuHeight = menuElement.offsetHeight;
|
|
4945
4652
|
const viewportWidth = window.innerWidth;
|
|
4946
|
-
const viewportHeight =
|
|
4653
|
+
const viewportHeight = window.innerHeight;
|
|
4947
4654
|
let x = (event instanceof MouseEvent) ? event.clientX : event.touches[0].clientX; //event.clientX;
|
|
4948
4655
|
let y = (event instanceof MouseEvent) ? event.clientY : event.touches[0].clientY; //event.clientY;
|
|
4949
4656
|
if (x + menuWidth > viewportWidth) {
|
|
4950
4657
|
x = viewportWidth - menuWidth - 10;
|
|
4951
4658
|
}
|
|
4952
|
-
if (y + menuHeight >
|
|
4659
|
+
if (y + menuHeight > viewportHeight) {
|
|
4953
4660
|
y = viewportHeight - menuHeight - 10;
|
|
4954
4661
|
}
|
|
4955
4662
|
this.xPos = x;
|
|
@@ -4974,20 +4681,12 @@ class DataGridComponent {
|
|
|
4974
4681
|
this.genericEvent.emit(sendObj);
|
|
4975
4682
|
}
|
|
4976
4683
|
onVerifyClick(type) {
|
|
4684
|
+
const idsArray = Array.from(this.selectedRows);
|
|
4977
4685
|
const text = type?.toLowerCase();
|
|
4978
|
-
if (text == 'archive' || text == 'unarchive'
|
|
4979
|
-
|
|
4980
|
-
|
|
4981
|
-
// || text == 'send to review' || text == 'mark as paid' || text == 'mark as unpaid' || text == 'fulfill' || text == 'unfulfill' || text == 'refund' || text == 'cancel' || text == 'resend' || text == 'chargeback'
|
|
4982
|
-
// || text == 'dispute' || text == 'escalate' || text == 'deescalate' || text == 'flag' || text == 'unflag' || text == 'verify' || text == 'unverify' || text == 'subscribe' || text == 'unsubscribe' || text == 'follow' || text == 'unfollow'
|
|
4983
|
-
// || text == 'like' || text == 'unlike' || text == 'share' || text == 'unshare' || text == 'comment' || text == 'uncomment' || text == 'tag' || text == 'untag' || text == 'assign' || text == 'unassign' || text == 'link' || text == 'unlink'
|
|
4984
|
-
// || text == 'sync' || text == 'unsync' || text == 'backup' || text == 'restore backup' || text == 'migrate' || text == 'import' || text == 'export' || text == 'generate report' || text == 'download report' || text == 'view details'
|
|
4985
|
-
// || 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'
|
|
4986
|
-
) {
|
|
4987
|
-
// this.clearSelectionState(this.tableType);
|
|
4988
|
-
// this.selectedRows.clear();
|
|
4686
|
+
if (text == 'archive' || text == 'unarchive') {
|
|
4687
|
+
this.clearSelectionState(this.tableType);
|
|
4688
|
+
this.selectedRows.clear();
|
|
4989
4689
|
}
|
|
4990
|
-
const idsArray = Array.from(this.selectedRows);
|
|
4991
4690
|
const arrayOfObjectsWithTableType = [];
|
|
4992
4691
|
this.selectedRows.forEach(id => {
|
|
4993
4692
|
arrayOfObjectsWithTableType.push({
|
|
@@ -5006,7 +4705,7 @@ class DataGridComponent {
|
|
|
5006
4705
|
this.genericEvent.emit(sendObj);
|
|
5007
4706
|
}
|
|
5008
4707
|
getCellClasses(column, value) {
|
|
5009
|
-
if (!value || !column?.field
|
|
4708
|
+
if (!value || !column?.field)
|
|
5010
4709
|
return '';
|
|
5011
4710
|
let val = typeof value === 'object' ? value?.value ?? value : value;
|
|
5012
4711
|
const field = column.field.toLowerCase();
|
|
@@ -5035,7 +4734,7 @@ class DataGridComponent {
|
|
|
5035
4734
|
removeColumnFilterFromColumn(column) {
|
|
5036
4735
|
if (!column)
|
|
5037
4736
|
return;
|
|
5038
|
-
if (column.type === 'dropdown'
|
|
4737
|
+
if (column.type === 'dropdown') {
|
|
5039
4738
|
column.query._ids = [];
|
|
5040
4739
|
}
|
|
5041
4740
|
else if (['string', 'number', 'date'].includes(column.type)) {
|
|
@@ -5067,7 +4766,7 @@ class DataGridComponent {
|
|
|
5067
4766
|
no_of_records: Number(this.paginationConfig.limit),
|
|
5068
4767
|
type: this.tableType,
|
|
5069
4768
|
};
|
|
5070
|
-
this.createUpdateConfigListing.emit(
|
|
4769
|
+
this.createUpdateConfigListing.emit(sendData);
|
|
5071
4770
|
setTimeout(() => {
|
|
5072
4771
|
const filteredColumns = cleanedFilteredColumns;
|
|
5073
4772
|
this.filterOptions.emit(filteredColumns);
|
|
@@ -5089,7 +4788,7 @@ class DataGridComponent {
|
|
|
5089
4788
|
no_of_records: this.paginationConfig.pageSize,
|
|
5090
4789
|
type: this.tableType,
|
|
5091
4790
|
};
|
|
5092
|
-
this.createUpdateConfigListing.emit(
|
|
4791
|
+
this.createUpdateConfigListing.emit(sendData);
|
|
5093
4792
|
}
|
|
5094
4793
|
cleanFilterdColumns() {
|
|
5095
4794
|
const filteredColumns = this.commonSevice.getFiltersFromColumns(this.columns, this.filtersConfig);
|
|
@@ -5155,7 +4854,6 @@ class DataGridComponent {
|
|
|
5155
4854
|
eventType: 'config'
|
|
5156
4855
|
};
|
|
5157
4856
|
this.genericEvent.emit(event);
|
|
5158
|
-
this.createUpdateConfigListing.emit(this.createUpdateColumnConfig);
|
|
5159
4857
|
}
|
|
5160
4858
|
onGlobalSearch() {
|
|
5161
4859
|
const event = {
|
|
@@ -5168,7 +4866,6 @@ class DataGridComponent {
|
|
|
5168
4866
|
if (this.tableFilterViewId) {
|
|
5169
4867
|
this.savePreset('mouseUp');
|
|
5170
4868
|
}
|
|
5171
|
-
this.createUpdateConfigListing.emit(this.createUpdateColumnConfig);
|
|
5172
4869
|
}
|
|
5173
4870
|
onSearchInput(event) {
|
|
5174
4871
|
const value = event.target.value;
|
|
@@ -5610,84 +5307,13 @@ class DataGridComponent {
|
|
|
5610
5307
|
this.goToFirstPage();
|
|
5611
5308
|
return;
|
|
5612
5309
|
}
|
|
5613
|
-
// Ctrl + Shift + Arrow Right → Last Page
|
|
5614
|
-
const MIN_HEIGHT = 28;
|
|
5615
|
-
if ((event.ctrlKey || event.metaKey) && event.shiftKey && event.key === 'ArrowUp') {
|
|
5616
|
-
event.preventDefault();
|
|
5617
|
-
this.headerRowHeight += 1;
|
|
5618
|
-
this.rowHeight += 1;
|
|
5619
|
-
return;
|
|
5620
|
-
}
|
|
5621
|
-
// Ctrl + Shift + Arrow Right → Last Page
|
|
5622
|
-
if ((event.ctrlKey || event.metaKey) && event.shiftKey && event.key === 'ArrowDown') {
|
|
5623
|
-
event.preventDefault();
|
|
5624
|
-
this.headerRowHeight = Math.max(MIN_HEIGHT, this.headerRowHeight - 1);
|
|
5625
|
-
this.rowHeight = Math.max(MIN_HEIGHT, this.rowHeight - 1);
|
|
5626
|
-
return;
|
|
5627
|
-
}
|
|
5628
5310
|
if ((event.ctrlKey || event.metaKey) && event.key === '/') {
|
|
5629
5311
|
event.preventDefault();
|
|
5630
5312
|
if (this.globalSearchInput) {
|
|
5631
|
-
|
|
5632
|
-
inputEl.focus();
|
|
5633
|
-
const originalOutline = inputEl.style.outline;
|
|
5634
|
-
const originalBoxShadow = inputEl.style.boxShadow;
|
|
5635
|
-
inputEl.style.setProperty('outline', '2px solid #4f9cff', 'important');
|
|
5636
|
-
inputEl.style.setProperty('box-shadow', '0 0 8px 2px #4f9cff', 'important');
|
|
5637
|
-
setTimeout(() => {
|
|
5638
|
-
inputEl.style.setProperty('outline', originalOutline || '', 'important');
|
|
5639
|
-
inputEl.style.setProperty('box-shadow', originalBoxShadow || '', 'important');
|
|
5640
|
-
}, 1000);
|
|
5313
|
+
this.globalSearchInput?.nativeElement?.focus();
|
|
5641
5314
|
}
|
|
5642
5315
|
return;
|
|
5643
5316
|
}
|
|
5644
|
-
if (event.ctrlKey && event.altKey && event.key.toLowerCase() === 'r') {
|
|
5645
|
-
event.preventDefault();
|
|
5646
|
-
this.autosizeAllColumns();
|
|
5647
|
-
return;
|
|
5648
|
-
}
|
|
5649
|
-
if (event.altKey && event.key?.toLocaleLowerCase() === 'r') {
|
|
5650
|
-
event.preventDefault();
|
|
5651
|
-
this.autoSizeColumnsByRatio();
|
|
5652
|
-
return;
|
|
5653
|
-
}
|
|
5654
|
-
if ((event.ctrlKey || event.metaKey) && event.shiftKey && event.key.toLowerCase() === 'c') {
|
|
5655
|
-
event.preventDefault();
|
|
5656
|
-
this.downloadCsv('csv');
|
|
5657
|
-
return;
|
|
5658
|
-
}
|
|
5659
|
-
if ((event.ctrlKey || event.metaKey) && event.shiftKey && event.key.toLowerCase() === 'e') {
|
|
5660
|
-
event.preventDefault();
|
|
5661
|
-
this.downloadCsv('xlsx');
|
|
5662
|
-
return;
|
|
5663
|
-
}
|
|
5664
|
-
if ((event.ctrlKey || event.metaKey) && event.shiftKey && event.key.toLowerCase() === 'b') {
|
|
5665
|
-
event.preventDefault();
|
|
5666
|
-
this.showVerticalBorder = !this.showVerticalBorder;
|
|
5667
|
-
this.onFontChange();
|
|
5668
|
-
return;
|
|
5669
|
-
}
|
|
5670
|
-
if ((event.ctrlKey || event.metaKey) && event.shiftKey && event.key.toLowerCase() === 'h') {
|
|
5671
|
-
event.preventDefault();
|
|
5672
|
-
this.rowShadingEnabled = !this.rowShadingEnabled;
|
|
5673
|
-
this.onFontChange();
|
|
5674
|
-
return;
|
|
5675
|
-
}
|
|
5676
|
-
if ((event.ctrlKey || event.metaKey) && event.shiftKey && event.key.toLowerCase() === 's') {
|
|
5677
|
-
event.preventDefault();
|
|
5678
|
-
this.setTableLayout('small');
|
|
5679
|
-
return;
|
|
5680
|
-
}
|
|
5681
|
-
if ((event.ctrlKey || event.metaKey) && event.shiftKey && event.key.toLowerCase() === 'm') {
|
|
5682
|
-
event.preventDefault();
|
|
5683
|
-
this.setTableLayout('medium');
|
|
5684
|
-
return;
|
|
5685
|
-
}
|
|
5686
|
-
if ((event.ctrlKey || event.metaKey) && event.shiftKey && event.key.toLowerCase() === 'l') {
|
|
5687
|
-
event.preventDefault();
|
|
5688
|
-
this.setTableLayout('large');
|
|
5689
|
-
return;
|
|
5690
|
-
}
|
|
5691
5317
|
if (event.altKey) {
|
|
5692
5318
|
const newLimit = this.pageSizeKeyMap[event.key];
|
|
5693
5319
|
if (newLimit) {
|
|
@@ -5827,8 +5453,6 @@ class DataGridComponent {
|
|
|
5827
5453
|
}
|
|
5828
5454
|
}
|
|
5829
5455
|
async onPaste(event) {
|
|
5830
|
-
if (!this.enableCut)
|
|
5831
|
-
return;
|
|
5832
5456
|
const target = event.target;
|
|
5833
5457
|
const tag = target?.tagName?.toLowerCase();
|
|
5834
5458
|
if (tag === 'input' || tag === 'textarea' || target?.getAttribute('contenteditable') === 'true') {
|
|
@@ -5861,18 +5485,18 @@ class DataGridComponent {
|
|
|
5861
5485
|
return new Promise(resolve => {
|
|
5862
5486
|
const overlay = document.createElement('div');
|
|
5863
5487
|
overlay.classList.add('custom-overlay-wrapper');
|
|
5864
|
-
overlay.innerHTML = `
|
|
5865
|
-
<div class="custom-overlay">
|
|
5866
|
-
<div class="custom-modal">
|
|
5867
|
-
<div class="custom-modal-body">
|
|
5868
|
-
<p class="modal-message">${message}</p>
|
|
5869
|
-
<div class="modal-actions">
|
|
5870
|
-
<button class="btn-confirm">Confirm</button>
|
|
5871
|
-
<button class="btn-cancel">Cancel</button>
|
|
5872
|
-
</div>
|
|
5873
|
-
</div>
|
|
5874
|
-
</div>
|
|
5875
|
-
</div>
|
|
5488
|
+
overlay.innerHTML = `
|
|
5489
|
+
<div class="custom-overlay">
|
|
5490
|
+
<div class="custom-modal">
|
|
5491
|
+
<div class="custom-modal-body">
|
|
5492
|
+
<p class="modal-message">${message}</p>
|
|
5493
|
+
<div class="modal-actions">
|
|
5494
|
+
<button class="btn-confirm">Confirm</button>
|
|
5495
|
+
<button class="btn-cancel">Cancel</button>
|
|
5496
|
+
</div>
|
|
5497
|
+
</div>
|
|
5498
|
+
</div>
|
|
5499
|
+
</div>
|
|
5876
5500
|
`;
|
|
5877
5501
|
document.body.appendChild(overlay);
|
|
5878
5502
|
const confirmBtn = overlay.querySelector('.btn-confirm');
|
|
@@ -6112,8 +5736,8 @@ class DataGridComponent {
|
|
|
6112
5736
|
setTimeout(() => {
|
|
6113
5737
|
// if (this.isOutsideContainer && this.currentDraggingColumn) {
|
|
6114
5738
|
// this.currentDraggingColumn!.is_visible = false;
|
|
6115
|
-
this.currentDraggingColumn = null;
|
|
6116
|
-
this.isOutsideContainer = false;
|
|
5739
|
+
// this.currentDraggingColumn = null;
|
|
5740
|
+
// this.isOutsideContainer = false;
|
|
6117
5741
|
// this.cdr.detectChanges();
|
|
6118
5742
|
// }
|
|
6119
5743
|
}, 100);
|
|
@@ -6147,7 +5771,7 @@ class DataGridComponent {
|
|
|
6147
5771
|
});
|
|
6148
5772
|
const stringsCurrentPrestCols = JSON.stringify(currentPresetColumns);
|
|
6149
5773
|
const stringColumns = JSON.stringify(columns);
|
|
6150
|
-
const filters = this.filtersConfig
|
|
5774
|
+
const filters = this.filtersConfig?.map((filter) => {
|
|
6151
5775
|
return {
|
|
6152
5776
|
filed: filter.field,
|
|
6153
5777
|
query: {
|
|
@@ -6173,6 +5797,14 @@ class DataGridComponent {
|
|
|
6173
5797
|
// console.log('Current Temp Preset : ', currPreset)
|
|
6174
5798
|
// console.log('Current Temp Preset Cols columns: ', currentPresetColumns)
|
|
6175
5799
|
// console.log('Current columns: ', columns);
|
|
5800
|
+
// this.rowShadingEnabled = temprorySelected.config.rowShadingEnabled;
|
|
5801
|
+
// this.showVerticalBorder = temprorySelected.config.showVerticalBorder;
|
|
5802
|
+
// this.fontFaimly = temprorySelected.config.fontFaimly;
|
|
5803
|
+
// this.headerTextFontsSize = temprorySelected.config.headerTextFontsSize;
|
|
5804
|
+
// this.selectedTableLayout = temprorySelected.config.selectedTableLayout;
|
|
5805
|
+
// this.bodyTextFontsSize = temprorySelected.config.bodyTextFontsSize;
|
|
5806
|
+
// this.globalSearchText = temprorySelected.config.globalSearch;
|
|
5807
|
+
// this.setTableLayout(this.selectedTableLayout);
|
|
6176
5808
|
if (!currentPresetColumns)
|
|
6177
5809
|
return true;
|
|
6178
5810
|
return (currentPresetColumns && (stringsCurrentPrestCols == stringColumns) && (JSON.stringify(filters) == JSON.stringify(currentPresetFilters)) && (this.fontFaimly == currPreset.config.fontFaimly)
|
|
@@ -6198,6 +5830,15 @@ class DataGridComponent {
|
|
|
6198
5830
|
};
|
|
6199
5831
|
this.genericEvent.emit(event);
|
|
6200
5832
|
}
|
|
5833
|
+
createCustomColumn() {
|
|
5834
|
+
const event = {
|
|
5835
|
+
data: {
|
|
5836
|
+
listingType: this.listingType,
|
|
5837
|
+
},
|
|
5838
|
+
eventType: "createCustomColumn",
|
|
5839
|
+
};
|
|
5840
|
+
this.genericEvent.emit(event);
|
|
5841
|
+
}
|
|
6201
5842
|
setActiveTab(tab) {
|
|
6202
5843
|
this.activeTab = tab;
|
|
6203
5844
|
const allTabs = JSON.parse(localStorage.getItem('activeTabs') || '{}');
|
|
@@ -6454,43 +6095,11 @@ class DataGridComponent {
|
|
|
6454
6095
|
first?.full_name ??
|
|
6455
6096
|
'-');
|
|
6456
6097
|
}
|
|
6457
|
-
|
|
6458
|
-
|
|
6459
|
-
}
|
|
6460
|
-
getDynamicRight(col, section, colIndex, subColIndex) {
|
|
6461
|
-
if (section == 'right' && this.previewRightPinnedColumns?.length == 1 && col.width < 200) {
|
|
6462
|
-
return 100;
|
|
6463
|
-
}
|
|
6464
|
-
else if (section == 'right') {
|
|
6465
|
-
return null;
|
|
6466
|
-
}
|
|
6467
|
-
else if (section == 'previewCenterColumns' && colIndex == (this.previewCenterColumns?.length - 1) && col.width < 200) {
|
|
6468
|
-
return 200;
|
|
6469
|
-
}
|
|
6470
|
-
else {
|
|
6471
|
-
return col.width - 45;
|
|
6472
|
-
}
|
|
6473
|
-
}
|
|
6474
|
-
blurInput(event, row, col) {
|
|
6475
|
-
const input = event?.target;
|
|
6476
|
-
input?.blur();
|
|
6477
|
-
this.setActiveCell(row, col);
|
|
6478
|
-
setTimeout(() => {
|
|
6479
|
-
this.editingKey = '';
|
|
6480
|
-
this.cdr.detectChanges();
|
|
6481
|
-
}, 0);
|
|
6482
|
-
}
|
|
6483
|
-
getValidActions(element) {
|
|
6484
|
-
return this.actionValidator.getValidActions(this.actions, // Pass all actions
|
|
6485
|
-
element, {
|
|
6486
|
-
// userId: this.id,
|
|
6487
|
-
tableType: this.tableType,
|
|
6488
|
-
showUnLink: this.showUnLink,
|
|
6489
|
-
packageData: this.packageData
|
|
6490
|
-
});
|
|
6098
|
+
activeFilter(type) {
|
|
6099
|
+
this.activeFilterType = type;
|
|
6491
6100
|
}
|
|
6492
|
-
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 }
|
|
6493
|
-
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", packageData: "packageData", showUnLink: "showUnLink", 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", validateIcon: "validateIcon" }, 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 *ngIf=\"paginationConfig\"\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: i9.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i9.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i9.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: i9.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i9.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i9.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i9.RadioControlValueAccessor, selector: "input[type=radio][formControlName],input[type=radio][formControl],input[type=radio][ngModel]", inputs: ["name", "formControlName", "value"] }, { kind: "directive", type: i9.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i9.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i9.PatternValidator, selector: "[pattern][formControlName],[pattern][formControl],[pattern][ngModel]", inputs: ["pattern"] }, { kind: "directive", type: i9.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i10.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: i10.CdkDropListGroup, selector: "[cdkDropListGroup]", inputs: ["cdkDropListGroupDisabled"], exportAs: ["cdkDropListGroup"] }, { kind: "directive", type: i10.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: i10.CdkDragHandle, selector: "[cdkDragHandle]", inputs: ["cdkDragHandleDisabled"] }, { kind: "directive", type: i10.CdkDragPreview, selector: "ng-template[cdkDragPreview]", inputs: ["data", "matchSize"] }, { kind: "directive", type: i10.CdkDragPlaceholder, selector: "ng-template[cdkDragPlaceholder]", inputs: ["data"] }, { kind: "directive", type: i11.InlineSVGDirective, selector: "[inlineSVG]", inputs: ["inlineSVG", "resolveSVGUrl", "replaceContents", "prepend", "injectComponent", "cacheSVG", "setSVGAttributes", "removeSVGAttributes", "forceEvalStyles", "evalScripts", "fallbackImgUrl", "fallbackSVG", "onSVGLoaded"], outputs: ["onSVGInserted", "onSVGFailed"] }, { kind: "directive", type: i12.CdkFixedSizeVirtualScroll, selector: "cdk-virtual-scroll-viewport[itemSize]", inputs: ["itemSize", "minBufferPx", "maxBufferPx"] }, { kind: "directive", type: i12.CdkVirtualForOf, selector: "[cdkVirtualFor][cdkVirtualForOf]", inputs: ["cdkVirtualForOf", "cdkVirtualForTrackBy", "cdkVirtualForTemplate", "cdkVirtualForTemplateCacheSize"] }, { kind: "component", type: i12.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: [
|
|
6101
|
+
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 }); }
|
|
6102
|
+
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", consumerFont: "consumerFont", defaultConfig: "defaultConfig", 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: "globalSearchInput", first: true, predicate: ["globalSearchInput"], descendants: true }, { 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 card-outer\">\n <div class=\"d-flex justify-content-between mb-3 align-items-center position-relative\">\n <div class=\"d-flex gap-2\">\n <div class=\"nav nav-tabs\" *ngIf=\"true\">\n <div class=\"nav nav-tabs\" id=\"nav-tab\" role=\"tablist\">\n <span\n *ngFor=\"let tab of tabs; let i = index\"\n (click)=\"setActiveTab(tab)\"\n class=\"nav-link cursor-pointer\"\n [class.active]=\"activeTab == tab\"\n >\n {{ tab }}\n </span>\n </div>\n </div>\n <div class=\"new_design_dropdown hide_arrow\">\n <a href=\"JavaScript:void(0)\" (click)=\"activeFilter('all')\" [class.active-filter]=\"activeFilterType === 'all'\"\n class=\"d-flex align-items-center justify-content-center dropdown_main_button\">\n All\n </a>\n </div>\n <div>\n <div class=\"btn-group new_design_dropdown hide_arrow\">\n <a href=\"JavaScript:void(0)\" data-bs-toggle=\"dropdown\" aria-expanded=\"false\" data-bs-auto-close=\"outside\"\n class=\"d-flex align-items-center dropdown-toggle justify-content-center dropdown_main_button\">\n Unfulfilled\n </a>\n <ul class=\"dropdown-menu\">\n <li>\n <a class=\"dropdown-item hover_dropdown_bg d-flex align-items-center\" href=\"javascript:void(0)\">\n <div>\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/resetIconNew.svg'\"\n class=\"svg-icon svg-icon-2\"\n ></span>\n </div>\n <span> Reset</span>\n </a>\n </li>\n <li>\n <a class=\"dropdown-item hover_dropdown_bg d-flex align-items-center\" href=\"javascript:void(0)\">\n <div>\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/updatePresetIconNew.svg'\"\n class=\"svg-icon svg-icon-2\"\n ></span>\n </div>\n <span> Update and Re-save</span>\n </a>\n </li>\n <hr class=\"mt-1\">\n <li>\n <a class=\"dropdown-item hover_dropdown_bg d-flex align-items-center\" href=\"javascript:void(0)\">\n <div>\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/infoIconNew.svg'\"\n class=\"svg-icon svg-icon-2\"\n ></span>\n </div>\n <span> Rename</span>\n </a>\n </li>\n <li>\n <a class=\"dropdown-item hover_dropdown_bg d-flex align-items-center\" href=\"javascript:void(0)\">\n <div>\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/duplicateIconNew.svg'\"\n class=\"svg-icon svg-icon-2\"\n ></span>\n </div>\n <span>Duplicate</span>\n </a>\n </li>\n <li>\n <a class=\"dropdown-item hover_dropdown_bg d-flex align-items-center\" href=\"javascript:void(0)\">\n <div>\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/trashIconNew.svg'\"\n class=\"svg-icon svg-icon-2\"\n ></span>\n </div>\n <span class=\"text-danger\">Delete</span>\n </a>\n </li>\n </ul>\n </div>\n </div>\n <div>\n <div class=\"btn-group new_design_dropdown hide_arrow\">\n <a href=\"JavaScript:void(0)\" data-bs-toggle=\"dropdown\" aria-expanded=\"false\" data-bs-auto-close=\"outside\"\n class=\"d-flex align-items-center dropdown-toggle justify-content-center dropdown_main_button\">\n Unpaid\n </a>\n <ul class=\"dropdown-menu\">\n <li>\n <a class=\"dropdown-item hover_dropdown_bg d-flex align-items-center\" href=\"javascript:void(0)\">\n <div>\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/infoIconNew.svg'\"\n class=\"svg-icon svg-icon-2\"\n ></span>\n </div>\n <span> Test Type</span>\n </a>\n </li>\n </ul>\n </div>\n </div>\n </div>\n <div class=\"d-flex gap-1 align-items-center table-right-top-actions\">\n <div class=\"global-search position-relative\" [style.width.px]=\"350\">\n <span *ngIf=\"enableGlobalSearch\"\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/search.svg'\"\n class=\"data-grid-svg-icon ms-2 mt-0 position-absolute icon\" style=\"top: 8px;\"\n ></span>\n <input #globalSearchInput\n *ngIf=\"enableGlobalSearch\"\n class=\"form-control\"\n placeholder=\"Search\"\n [(ngModel)]=\"tableSearch\"\n (keydown.enter)=\"onGlobalSearch()\"\n (input)=\"onSearchInput($event)\"\n type=\"search\"\n />\n </div>\n <!-- <ng-container *ngFor=\"let button of buttons\">\n <div\n class=\"d-flex align-items-center gap-2 action-buttons-row\"\n *ngIf=\"button?.has_permission\"\n >\n <a\n href=\"JavaScript:void(0)\"\n (click)=\"onActionButtonClick(button.name)\"\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\"\n >\n <span\n *ngIf=\"button.is_showIcon\"\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/' + button.icon + '.svg'\n \"\n class=\"svg-icon svg-icon-2\"\n ></span>\n <span\n class=\"label-hidden text-white\"\n [class.ms-0]=\"button.is_showIcon\"\n >{{ button?.name }}</span\n >\n </a>\n </div>\n </ng-container> -->\n <div *ngIf=\"!showFilterRow\"\n class=\"cursor-pointer position-relative action-buttons-row\"\n (click)=\"toggleOpenFilter()\"\n [class.active]=\"showFilters\">\n <a href=\"JavaScript:void(0)\"\n class=\"p-0 d-flex align-items-center justify-content-center grid-header-icon\">\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/filterIconNew.svg'\" class=\"svg-icon svg-icon-2\"></span>\n </a>\n <span *ngIf=\"activeFilteredColumns?.length\"\n style=\"\n width: 7px;\n height: 7px;\n box-shadow: 0px 0px 3px #0022ff;\n background-color: rgb(0, 60, 255);\n position: absolute;\n right: 8px;\n top: 6px;\n \"\n class=\"rounded-circle d-block\"\n ></span>\n </div>\n <div class=\"cursor-pointer d-none\"\n (click)=\"toggleActions('advance-filter')\"\n [class.active]=\"activeTopButton === 'advance-filter'\">\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/zoom-charge.svg'\"\n class=\"data-grid-svg-icon top-icon me-2\"\n ></span>\n </div>\n <div class=\"cursor-pointer actions-buttons-row\">\n <div class=\"btn-group new_design_dropdown hide_arrow\">\n <a href=\"JavaScript:void(0)\" data-bs-toggle=\"dropdown\" aria-expanded=\"false\" data-bs-auto-close=\"outside\"\n class=\"p-0 d-flex align-items-center dropdown-toggle justify-content-center grid-header-icon\">\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/sortingIconNew.svg'\"\n class=\"svg-icon svg-icon-2\"\n ></span>\n </a>\n <ul class=\"dropdown-menu dropdown-menu-left productSortingDropdownMenu\">\n <li>\n <a class=\"dropdown-item hover_dropdown_bg d-flex align-items-center\" href=\"javascript:void(0)\">\n <div class=\"sorting_icon_input\">\n <input class=\"form-check-input\" type=\"radio\" name=\"exampleRadios\" id=\"productName\" value=\"option1\" checked>\n </div>\n <label class=\"form-check-label mb-0 mt-1\" for=\"productName\">\n Product Name\n </label>\n </a>\n </li>\n <li>\n <a class=\"dropdown-item hover_dropdown_bg d-flex align-items-center\" href=\"javascript:void(0)\">\n <div class=\"sorting_icon_input\">\n <input class=\"form-check-input\" type=\"radio\" name=\"exampleRadios\" id=\"createdDate\" value=\"option1\" checked>\n </div>\n <label class=\"form-check-label mb-0 mt-1\" for=\"createdDate\">\n Created Date\n </label>\n </a>\n </li>\n <li>\n <a class=\"dropdown-item hover_dropdown_bg d-flex align-items-center\" href=\"javascript:void(0)\">\n <div class=\"sorting_icon_input\">\n <input class=\"form-check-input\" type=\"radio\" name=\"exampleRadios\" id=\"updatedDate\" value=\"option1\" checked>\n </div>\n <label class=\"form-check-label mb-0 mt-1\" for=\"updatedDate\">\n Updated Date\n </label>\n </a>\n </li>\n <li>\n <a class=\"dropdown-item hover_dropdown_bg d-flex align-items-center\" href=\"javascript:void(0)\">\n <div class=\"sorting_icon_input\">\n <input class=\"form-check-input\" type=\"radio\" name=\"exampleRadios\" id=\"productType\" value=\"option1\" checked>\n </div>\n <label class=\"form-check-label mb-0 mt-1\" for=\"productType\">\n Product Type\n </label>\n </a>\n </li>\n <hr class=\"my-2\" style=\"border: 1px solid #E0E0E0;\">\n <li class=\"d-flex\" (click)=\"activeFilter('newest')\" [class.active-filter]=\"activeFilterType === 'newest'\">\n <a class=\"dropdown-item hover_dropdown_bg d-flex align-items-center\" href=\"javascript:void(0)\">\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrowupIconNew.svg'\"\n class=\"svg-icon svg-icon-2 mb-1 new_old_filter\"\n ></span>\n <span class=\"mt-1 newest\">Oldest First</span>\n </a>\n <div *ngIf=\"activeFilterType === 'newest'\">\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/tickIconNew.svg'\"\n class=\"svg-icon svg-icon-2 mb-1\"\n ></span>\n </div>\n </li>\n <li class=\"d-flex\" (click)=\"activeFilter('oldest')\" [class.active-filter]=\"activeFilterType === 'oldest'\">\n <a class=\"dropdown-item hover_dropdown_bg d-flex align-items-center\" href=\"javascript:void(0)\">\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrowdownIconNew.svg'\"\n class=\"svg-icon svg-icon-2 mb-1 new_old_filter\"\n ></span>\n <span class=\"mt-1 oldest\">Newest First</span>\n </a>\n <div *ngIf=\"activeFilterType === 'oldest'\">\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/tickIconNew.svg'\"\n class=\"svg-icon svg-icon-2 mb-1\"\n ></span>\n </div>\n </li>\n </ul>\n </div>\n </div>\n <div class=\"cursor-pointer action-buttons-row\"\n (click)=\"toggleActions('setting')\"\n [class.active]=\"\n activeTopButton === 'setting' ||\n activeTopButton === 'table-layout' ||\n activeTopButton === 'table-presets' ||\n activeTopButton === 'show-hide-columns'\">\n <!-- <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/settings-2.svg'\"\n class=\"data-grid-svg-icon top-icon me-2\"\n ></span> -->\n\n <a href=\"JavaScript:void(0)\"\n class=\"p-0 d-flex align-items-center justify-content-center grid-header-icon\">\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/settingIconNew.svg'\"\n class=\"svg-icon svg-icon-2\"\n ></span>\n </a>\n\n <div *ngIf=\"activeTopButton === 'setting'\"\n class=\"actions-dropdown mt-1 actions-dropdown-setting\"\n style=\"position: absolute\">\n <div class=\"dropdown-menu show shadow custom-menu setting_dropdown_menu\">\n <!-- Table Layout -->\n <a class=\"dropdown-item py-0 px-2 d-flex justify-content-between align-items-center cursor-pointer\"\n (click)=\"$event.stopPropagation(); toggleActions('table-layout')\">\n <span class=\"d-flex justify-content-between align-items-center\">\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/layoutIconNew.svg'\n \"\n class=\"data-grid-svg-icon setting_dropdown\"\n ></span>\n Table Layout</span\n >\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\n \"\n class=\"data-grid-svg-icon d-flex align-items-center justify-content-center\"\n ></span>\n </a>\n <!-- Table Presets -->\n <a (click)=\"$event.stopPropagation(); toggleActions('table-presets')\"\n class=\"dropdown-item py-0 px-2 d-flex justify-content-between align-items-center cursor-pointer\">\n <span class=\"d-flex align-items-center justify-content-center\">\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/list-details.svg'\n \"\n class=\"data-grid-svg-icon setting_dropdown d-flex align-items-center justify-content-center\"\n ></span>\n Table Presets</span\n >\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\n \"\n class=\"data-grid-svg-icon d-flex align-items-center justify-content-center\"\n ></span>\n </a>\n\n <!-- Columns -->\n <a *ngIf=\"!showSideMenu\" (click)=\"$event.stopPropagation(); toggleActions('show-hide-columns')\"\n class=\"dropdown-item py-0 px-2 d-flex justify-content-between align-items-center cursor-pointer\">\n <span class=\"d-flex align-items-center justify-content-center\"><span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/eyeIconNew.svg'\"\n class=\"data-grid-svg-icon setting_dropdown me-2\"\n ></span>\n Columns</span>\n <div class=\"d-flex align-items-center gap-2\">\n <span class=\"muted-text\">{{ columnsCount }}</span>\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\n \"\n class=\"data-grid-svg-icon d-flex align-items-center justify-content-center\"\n ></span>\n </div>\n </a>\n\n <a (click)=\"autosizeAllColumns()\" class=\"dropdown-item py-0 px-2 d-flex justify-content-between align-items-center cursor-pointer\">\n <span class=\"d-flex align-items-center justify-content-center\"><span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/resizeIconNew.svg'\"\n class=\"data-grid-svg-icon setting_dropdown me-2\"></span>\n <span>Autosize all columns</span>\n </span>\n <!-- <div class=\"d-flex align-items-center gap-2\">\n <div class=\"form-check form-switch\">\n <input class=\"form-check-input\" type=\"checkbox\" id=\"flexSwitchCheckChecked\">\n <label class=\"form-check-label\" for=\"flexSwitchCheckChecked\"></label>\n </div>\n </div> -->\n </a>\n\n <a class=\"dropdown-item py-0 px-2 d-flex justify-content-between align-items-center cursor-pointer\">\n <span class=\"d-flex align-items-center justify-content-center\"><span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/multicellNew.svg'\"\n class=\"data-grid-svg-icon setting_dropdown me-2\"></span>\n <span>Multi-cell tooltip mode</span>\n </span>\n <!-- <div class=\"d-flex align-items-center gap-2\">\n <div class=\"form-check form-switch\">\n <input class=\"form-check-input\" type=\"checkbox\" id=\"flexSwitchCheckChecked\">\n <label class=\"form-check-label\" for=\"flexSwitchCheckChecked\"></label>\n </div>\n </div> -->\n </a>\n\n <div class=\"dropdown-divider\"></div>\n\n <!-- Filter -->\n <!-- <a class=\"dropdown-item py-0 px-2 d-flex align-items-center cursor-pointer\"\n (click)=\"toggleOpenFilter(); activeTopButton = '';\"\n *ngIf=\"!showFilterRow\">\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/filterIconNew.svg'\n \"\n class=\"data-grid-svg-icon setting_dropdown d-flex align-items-center justify-content-center cursor-pointer\"\n ></span>\n Filter\n </a> -->\n\n <!-- Download -->\n <a class=\"dropdown-item py-0 px-2 d-flex align-items-center cursor-pointer\"\n (click)=\"downloadCsv('csv')\">\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/exportIconNew.svg'\"\n class=\"data-grid-svg-icon setting_dropdown d-flex align-items-center justify-content-center cursor-pointer\"\n ></span>\n CSV Export\n </a>\n <a *ngIf=\"enableExport\"\n class=\"dropdown-item py-0 px-2 d-flex align-items-center cursor-pointer\"\n (click)=\"downloadCsv('xlsx')\">\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/exportIconNew.svg'\n \"\n class=\"data-grid-svg-icon setting_dropdown d-flex align-items-center justify-content-center cursor-pointer\"\n ></span>\n Excel Export\n </a>\n <!-- Font Family & Font Size -->\n <div class=\"px-2 pb-2 pt-2\">\n <div class=\"d-flex gap-2\">\n <!-- <select\n class=\"form-select form-select-sm\"\n [(ngModel)]=\"fontFaimly\"\n (change)=\"onFontChange()\"\n >\n <option *ngFor=\"let font of fontFamilies\" [value]=\"font\">\n {{ font }}\n </option>\n </select> -->\n\n <!-- Font Size -->\n <!-- <select\n class=\"form-select form-select-sm\"\n (change)=\"onFontChange()\"\n [(ngModel)]=\"bodyTextFontsSize\"\n >\n <option *ngFor=\"let size of fontSizes\" [value]=\"size\">\n {{ size }}\n </option>\n </select> -->\n </div>\n </div>\n </div>\n </div>\n\n <!-- Table Layout -->\n\n <ng-container *ngIf=\"activeTopButton === 'table-layout'\">\n <div\n *ngTemplateOutlet=\"tableLayout\"\n class=\"actions-dropdown mt-1\"\n style=\"position: absolute\"\n ></div>\n </ng-container>\n\n <!-- Table Presets -->\n <ng-container *ngIf=\"activeTopButton === 'table-presets'\">\n <div\n *ngTemplateOutlet=\"tablePreset\"\n class=\"actions-dropdown mt-1\"\n style=\"position: absolute\"\n ></div>\n </ng-container>\n\n <!-- Table Presets -->\n <ng-container *ngIf=\"activeTopButton === 'show-hide-columns'\">\n <div\n *ngTemplateOutlet=\"showHideColumns\"\n class=\"actions-dropdown mt-1\"\n style=\"position: absolute\"\n ></div>\n </ng-container>\n </div>\n <div class=\"cursor-pointer actions-buttons-row\">\n <div class=\"btn-group new_design_dropdown\">\n <button type=\"button\" class=\"primary_btn_new common_btn dropdown-toggle consumerDropdownButton px-2\" data-bs-toggle=\"dropdown\" aria-expanded=\"false\">\n Actions\n </button>\n <ul class=\"dropdown-menu\">\n <li>\n <a class=\"dropdown-item hover_dropdown_bg action_dropdown\" (click)=\"createCustomColumn()\">Create custom column</a>\n </li>\n <ng-container *ngFor=\"let button of buttons\">\n <li *ngIf=\"button?.has_permission\">\n <a class=\"dropdown-item hover_dropdown_bg action_dropdown\" \n href=\"javascript:void(0)\" \n (click)=\"onActionButtonClick(button.name)\">\n <!-- <span *ngIf=\"button.is_showIcon\" \n class=\"me-2\">\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/' + button.icon + '.svg'\"\n class=\"svg-icon svg-icon-2\"></span>\n </span> -->\n <span>{{ button?.name }}</span>\n </a>\n </li>\n </ng-container>\n </ul>\n </div>\n </div>\n <!-- <div class=\"cursor-pointer actions-buttons-row\" *ngIf=\"buttons.length == 1\">\n <a href=\"JavaScript:void(0)\"\n (click)=\"onActionButtonClick(buttons[0].name)\"\n class=\"btn btn-primary border border-primary py-1 d-flex align-items-center justify-content-center px-3\">\n <span class=\"text-white\"\n [class.ms-0]=\"buttons[0].is_showIcon\"\n >{{ buttons[0].name }}</span>\n </a>\n </div> -->\n <div class=\"action-buttons-row\" *ngIf=\"showFullScreenButton\">\n <a\n *ngIf=\"!isFullScreen\"\n class=\"button button-small btn btn-active-primary border border-primary expend d-flex justify-content-center align-items-center\"\n (click)=\"toggleFullscreen()\"\n data-bs-toggle=\"tooltip\"\n data-bs-placement=\"top\"\n title=\"Minimise\"\n [ngClass]=\"{ minArrow: !isFullScreen, maxArrow: isFullScreen }\"\n style=\"transition: color 0.2s\"\n >\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/expend.svg'\"\n class=\"svg-icon svg-icon-2 mb-1\"\n ></span>\n </a>\n <a\n *ngIf=\"isFullScreen\"\n class=\"button button-small btn btn-active-primary border border-primary expend d-flex justify-content-center align-items-center\"\n (click)=\"toggleFullscreen()\"\n data-bs-toggle=\"tooltip\"\n data-bs-placement=\"top\"\n title=\"Maximise\"\n [ngClass]=\"{ minArrow: !isFullScreen, maxArrow: isFullScreen }\"\n style=\"transition: color 0.2s\"\n >\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/minimize.svg'\"\n class=\"svg-icon svg-icon-2 mb-1\"\n ></span>\n </a>\n </div>\n <div>\n <!-- Example single danger button -->\n\n <!-- <button\n type=\"button\"\n class=\"btn btn-primary btn-sm d-flex gap-2 action-button\"\n (click)=\"toggleActions('actions')\"\n >\n Action\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/Vector.svg'\"\n class=\"data-grid-svg-icon\"\n ></span>\n </button>\n <div\n *ngIf=\"activeTopButton === 'actions'\"\n class=\"actions-dropdown mt-1\"\n >\n <div class=\"dropdown-menu show\">\n <a class=\"dropdown-item\" href=\"#\">Action</a>\n <a class=\"dropdown-item\" href=\"#\">Another action</a>\n <a class=\"dropdown-item\" href=\"#\">Something else here</a>\n <div class=\"dropdown-divider\"></div>\n <a class=\"dropdown-item\" href=\"#\">Separated link</a>\n </div>\n </div> -->\n </div>\n </div>\n </div>\n\n <div\n *ngIf=\"showFilters && !showFilterRow\"\n class=\"top-filter-row border-top py-2 d-flex justify-content-between align-items-center\"\n [style.height.px]=\"topFilterRowHeight\"\n >\n <!-- LEFT SIDE (Filter tags + Filter button) -->\n <div class=\"d-flex gap-2 align-items-center\">\n <ng-container>\n <div\n *ngFor=\"let col of activeFilteredColumns; trackBy: trackByField\"\n class=\"filter-tags\"\n >\n <div\n (click)=\"\n isActiveFilterOpen = true;\n activeTopButton = 'filter-columns';\n openFilter(col)\n \"\n class=\"d-flex justify-content-center align-items-center muted-text add-filter-button active-filters\"\n style=\"white-space: nowrap\"\n [class.active]=\"\n col?.field == selectedColumnForFilter?.field &&\n isActiveFilterOpen &&\n activeTopButton == 'filter-columns'\n \"\n >\n <span class=\"header-tag mt-0 d-flex align-items-center left-side-pinned\">\n <span\n *ngIf=\"col?.pinned\"\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/pin.svg'\"\n class=\"data-grid-svg-icon me-2\"\n ></span>\n {{ col.header }}: {{col.query.first_value || col.query?._ids[0]}}\n <span\n (click)=\"\n $event.stopPropagation(); removeColumnFilterFromColumn(col)\n \"\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/filterCrossNew.svg'\n \"\n class=\"data-grid-svg-icon cross-secondary ms-2\"\n ></span>\n </span>\n </div>\n\n <ng-container\n *ngIf=\"\n activeTopButton === 'filter-columns' &&\n col?.field == selectedColumnForFilter?.field &&\n isActiveFilterOpen\n \"\n >\n <div\n *ngTemplateOutlet=\"filterColumns; context: { column: col }\"\n class=\"actions-dropdown mt-1\"\n ></div>\n </ng-container>\n </div>\n </ng-container>\n\n <!-- Filter Button -->\n <div class=\"add-filter-button-menu\">\n <div\n (click)=\"toggleActions('filter-columns'); isActiveFilterOpen = false\"\n class=\"d-flex justify-content-center align-items-center muted-text add-filter-button button-filter\"\n style=\"width: 70px\">\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/plus.svg'\"\n class=\"me-2 data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n Filter\n </div>\n\n <ng-container\n *ngIf=\"activeTopButton === 'filter-columns' && !isActiveFilterOpen\"\n >\n <div\n *ngTemplateOutlet=\"filterColumns\"\n class=\"actions-dropdown mt-1\"\n ></div>\n </ng-container>\n </div>\n </div>\n\n <!-- RIGHT SIDE (Update + Reset) -->\n <div class=\"d-flex gap-3 align-items-center\">\n <div\n (click)=\"savePreset()\"\n class=\"text-primary cursor-pointer all-filters-reset-button\"\n *ngIf=\"!checkFilterChangesEffect()\"\n >\n Update View\n </div>\n\n <div\n class=\"text-primary cursor-pointer all-filters-reset-button\"\n *ngIf=\"!tableFilterViewId && activeFilteredColumns?.length\"\n (click)=\"clearAllFilters()\">\n Clear filters\n </div>\n </div>\n </div>\n\n <div\n [style.height]=\"\n showFilters ? 'calc(100% - ' + (topFilterRowHeight + footerRowHeight) + 'px)' : 'calc(100% - ' + footerRowHeight + 'px)'\n \"\n cdkDropListGroup\n class=\"data-grid-table-wrapper overflow-hidden\"\n #dataGridContainer\n [style.fontFamily]=\"fontFaimly\"\n [style.backgroundColor]=\"bodyBackgroundColor\"\n id=\"data-grid-main-container\"\n >\n <div\n *ngIf=\"showRowsGrouping\"\n [style.height.px]=\"headerRowHeight\"\n [cdkDropListData]=\"columns\"\n [style.backgroundColor]=\"\n topGroupedBadgesBackgroundColor || headerBackgroundColor\n \"\n cdkDropList\n (cdkDropListEntered)=\"enterToTopRowGrouping($event)\"\n (cdkDropListExited)=\"exitedFromTheTopRow($event)\"\n (cdkDropListDropped)=\"onDropTopGroup($event)\"\n [cdkDropListEnterPredicate]=\"canEnterToRowsGrouping\"\n id=\"rows-grouping-top-container\"\n class=\"border-below d-flex px-4 align-items-center\"\n >\n <div\n class=\"d-flex gap-2 align-items-center\"\n [style.color]=\"headerTextColor\"\n >\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/justify.svg'\"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n <div *ngIf=\"!draggingInGroupArea && !groupedColumns?.length\">\n Drag here to set row groups\n </div>\n <div\n cdkDropListOrientation=\"horizontal\"\n cdkDropList\n (cdkDropListDropped)=\"onGroupReorder($event)\"\n class=\"d-flex\"\n >\n <div\n cdkDrag\n [cdkDragLockAxis]=\"'x'\"\n *ngFor=\"\n let child of groupedColumns;\n let i = index;\n trackBy: trackByField\n \"\n class=\"d-flex align-items-center\"\n >\n <ng-container\n *ngTemplateOutlet=\"\n topGroupingRowPlaceholder;\n context: {\n $implicit: child,\n showChevron:\n groupedColumns.length > 1 && i != groupedColumns.length - 1\n }\n \"\n ></ng-container>\n <ng-template cdkDragPreview\n ><div class=\"p-2 border d-flex gap-2\">\n <div>\n <span\n *ngIf=\"!draggingInGroupArea\"\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/arrows-move.svg'\n \"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n </div>\n <div>{{ child.header }}</div>\n </div>\n </ng-template>\n </div>\n </div>\n </div>\n </div>\n <div\n class=\"d-flex overflow-hidden\"\n [style.height]=\"\n 'calc(100% - ' +\n (showRowsGrouping\n ? headerRowHeight + footerRowHeight\n : footerRowHeight) +\n 'px)'\n \"\n >\n <div\n class=\"h-100\"\n [style.width]=\"\n !showSideMenu\n ? '100%'\n : sideMenuVisible\n ? 'calc(100% - 280px)'\n : 'calc(100% - 30px)'\n \"\n >\n <div class=\"h-100 transition position-relative w-100\">\n <!-- ##################################################################################################################################################################################### -->\n <!-- ##################################################################################################################################################################################### -->\n <!-- Data Grid Header starts here -->\n <!-- ##################################################################################################################################################################################### -->\n <!-- ##################################################################################################################################################################################### -->\n <!-- [style.backgroundColor]=\"headerBackgroundColor\" -->\n <div\n class=\"data-grid-header-wrapper w-100\"\n [style.color]=\"headerTextColor\"\n [style.backgroundColor]=\"headerBackgroundColor\"\n [style.fontSize.px]=\"headerTextFontsSize\"\n [class.border-below]=\"!hasAnyVisibleColumn\"\n [style.height.px]=\"\n showColumnsGrouping && showFilterRow\n ? headerRowHeight * 3\n : showColumnsGrouping || showFilterRow\n ? headerRowHeight * 2\n : headerRowHeight\n \"\n >\n <!-- ********************************************************************************* -->\n <!-- ********************************************************************************* -->\n <!-- Data Grid Left Pinned Header starts here -->\n <!-- ********************************************************************************* -->\n <!-- ********************************************************************************* -->\n <div\n class=\"data-grid-header left-pinned\"\n #leftPinnedHeader\n [class.border-right]=\"hasLeftPinnedColumns\">\n <div *ngIf=\"showSerialNumber\"\n [style.backgroundColor]=\"checkboxesBackgroundColor\"\n class=\"select-all-checkbox-cell border-below\"\n [style.width.px]=\"55\"\n [style.height.px]=\"\n showColumnsGrouping && showFilterRow\n ? headerRowHeight * 3\n : showColumnsGrouping || showFilterRow\n ? headerRowHeight * 2\n : headerRowHeight\n \"\n >\n S.No\n </div>\n <div *ngIf=\"showCheckboxes\"\n class=\"select-all-checkbox-cell border-below\"\n [style.height.px]=\"\n showColumnsGrouping && showFilterRow\n ? headerRowHeight * 3\n : showColumnsGrouping || showFilterRow\n ? headerRowHeight * 2\n : headerRowHeight\n \"\n >\n <input class=\"serialNoCheckbox\"\n *ngIf=\"hasAnyVisibleColumn\"\n style=\"width: 16px; height: 16px\"\n type=\"checkbox\"\n [indeterminate]=\"isIndeterminateState(dataSet)\"\n [checked]=\"isAllSelected(dataSet)\"\n (change)=\"toggleSelectAll(dataSet)\"\n />\n </div>\n <div\n [style.backgroundColor]=\"headerBackgroundColor\"\n class=\"d-flex\"\n cdkDropList\n id=\"left-pinned-header\"\n cdkDropListOrientation=\"horizontal\"\n [cdkDropListData]=\"leftPinnedColumns\"\n (cdkDropListEntered)=\"onDropListEnter($event, 'left')\"\n (cdkDropListSorted)=\"\n onSortGroup($event, 'previewLeftPinnedColumns')\n \"\n (cdkDropListDropped)=\"onDropGroup()\"\n style=\"min-width: 1px\"\n >\n <div\n class=\"dragable-header\"\n cdkDrag\n [cdkDragData]=\"col\"\n *ngFor=\"\n let col of leftPinnedColumns;\n let i = index;\n trackBy: trackByField\n \"\n >\n <ng-container\n *ngTemplateOutlet=\"\n headerCell;\n context: {\n $implicit: col,\n index: i,\n section: 'previewLeftPinnedColumns'\n }\n \"\n ></ng-container>\n <ng-template cdkDragPreview\n ><div class=\"p-2 border d-flex gap-2\">\n <div>\n <span\n *ngIf=\"!draggingInGroupArea\"\n [inlineSVG]=\"\n singleSpaAssetsPath +\n 'data-grid/icons/arrows-move.svg'\n \"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n </div>\n <div>{{ col.header }}</div>\n </div>\n </ng-template>\n <ng-template cdkDragPlaceholder>\n <div *ngIf=\"!draggingInGroupArea\">\n <div\n *ngTemplateOutlet=\"\n headerCell;\n context: {\n $implicit: col,\n index: i,\n section: ''\n }\n \"\n ></div>\n </div>\n <div\n *ngIf=\"draggingInGroupArea\"\n class=\"d-flex gap-2 ms-2\"\n style=\"opacity: 0.6\"\n >\n <ng-container\n *ngIf=\"col?.children?.length; else singleCol\"\n >\n <ng-container\n *ngFor=\"\n let child of col.children;\n let i = index;\n trackBy: trackByField\n \"\n >\n <ng-container\n *ngTemplateOutlet=\"\n topGroupingRowPlaceholder;\n context: {\n $implicit: child,\n showChevron:\n col.children.length > 1 &&\n i != col.children.length - 1\n }\n \"\n ></ng-container>\n </ng-container>\n </ng-container>\n\n <ng-template #singleCol>\n <ng-container\n *ngTemplateOutlet=\"\n topGroupingRowPlaceholder;\n context: {\n $implicit: col,\n showChevron: col?.children?.length > 1\n }\n \"\n ></ng-container>\n </ng-template>\n </div>\n </ng-template>\n </div>\n </div>\n </div>\n\n <!-- ********************************************************************************* -->\n <!-- ********************************************************************************* -->\n <!-- Data Grid Center Pinned Header starts here -->\n <!-- ********************************************************************************* -->\n <!-- ********************************************************************************* -->\n <div\n class=\"data-grid-header center-scrollable\"\n #centerPinnedHeader\n (scroll)=\"onCenterBodyScroll($event)\"\n id=\"center-pinned-header\"\n cdkDropList\n [cdkDropListConnectedTo]=\"\n showRowsGrouping ? ['rows-grouping-top-container'] : []\n \"\n [cdkDropListData]=\"centerColumns\"\n cdkDropListOrientation=\"horizontal\"\n [cdkDropListSortingDisabled]=\"\n isDisableColumnGrouping && draggingInGroupArea\n \"\n (cdkDropListEntered)=\"onDropListEnter($event, 'center')\"\n (cdkDropListSorted)=\"onSortGroup($event, 'previewCenterColumns')\"\n (cdkDropListDropped)=\"onDropGroup()\"\n [style.maxWidth]=\"\n 'calc(100% - ' +\n (rightPinnedHeader.offsetWidth + leftPinnedHeader.offsetWidth) +\n 'px)'\n \"\n >\n <div\n *ngIf=\"groupedColumns?.length\"\n style=\"min-width: 200px\"\n class=\"h-100 align-items-center\"\n #columnsGroupedBox\n id=\"groupBoxHeaderDiv\"\n >\n <div\n class=\"d-flex w-100 justify-content-between align-items-center border-below\"\n [style.height.px]=\"\n showFilterRow ? headerRowHeight * 2 : headerRowHeight\n \"\n >\n <div class=\"ps-3\">Group</div>\n <div class=\"d-flex\">\n <div\n class=\"three-dots cursor-pointer\"\n (click)=\"\n openThreeDotsMenu($event, 'group');\n isThreeDotsFilterOpen = false\n \"\n >\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath +\n 'data-grid/icons/three-dots-vertical.svg'\n \"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n </div>\n <div\n (mousedown)=\"\n $event.stopPropagation(); onResizeGroupBox($event)\n \"\n class=\"resize-handle\"\n style=\"margin-right: -2px\"\n >\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath +\n 'data-grid/icons/resize-handle1.svg'\n \"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n </div>\n </div>\n </div>\n\n <div\n [style.height.px]=\"headerRowHeight\"\n class=\"border-below\"\n ></div>\n </div>\n <span\n class=\"d-flex align-items-center justify-content-center cursor-pointer border-below\"\n style=\"min-width: 30px; height: 100%\"\n *ngIf=\"gridType === 'Assets' || gridType === 'Tasks'\"\n >\n </span>\n <div\n class=\"dragable-header\"\n (cdkDragStarted)=\"\n checkColumnGroupingStatus(col);\n dragStartOnGroup(col);\n onDragStarted(col)\n \"\n (cdkDragMoved)=\"onDragMoved($event)\"\n (cdkDragEnded)=\"onDragEnded()\"\n cdkDrag\n [cdkDragData]=\"col\"\n *ngFor=\"\n let col of centerColumns;\n let i = index;\n trackBy: trackById\n \"\n >\n <ng-container\n *ngTemplateOutlet=\"\n headerCell;\n context: {\n $implicit: col,\n index: i,\n section: 'previewCenterColumns'\n }\n \"\n >\n </ng-container>\n <ng-template cdkDragPreview\n ><div class=\"p-2 border d-flex gap-2\">\n <div>\n <span\n *ngIf=\"!isOutsideContainer\"\n [inlineSVG]=\"\n singleSpaAssetsPath +\n (draggingInGroupArea\n ? 'data-grid/icons/justify.svg'\n : 'data-grid/icons/arrows-move.svg')\n \"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n >\n </span>\n <span\n *ngIf=\"isOutsideContainer\"\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/eye-cross.svg'\n \"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n >\n </span>\n </div>\n <div>{{ col.header }}</div>\n </div>\n </ng-template>\n <ng-template cdkDragPlaceholder>\n <div *ngIf=\"!draggingInGroupArea\">\n <div\n *ngTemplateOutlet=\"\n headerCell;\n context: {\n $implicit: col,\n index: i,\n section: 'centerColumns'\n }\n \"\n ></div>\n </div>\n <div\n *ngIf=\"draggingInGroupArea && !isOutsideContainer\"\n class=\"d-flex gap-2 ms-2\"\n style=\"opacity: 0.6\"\n >\n <ng-container *ngIf=\"col?.children?.length; else singleCol\">\n <ng-container\n *ngFor=\"\n let child of col.children;\n let i = index;\n trackBy: trackById\n \"\n >\n <ng-container *ngIf=\"child?.is_groupable\">\n <ng-container\n *ngTemplateOutlet=\"\n topGroupingRowPlaceholder;\n context: {\n $implicit: child,\n showChevron:\n col.children.length > 1 &&\n i != col.children.length - 1\n }\n \"\n ></ng-container>\n </ng-container>\n </ng-container>\n </ng-container>\n\n <ng-template #singleCol>\n <ng-container *ngIf=\"col?.is_groupable\">\n <ng-container\n *ngTemplateOutlet=\"\n topGroupingRowPlaceholder;\n context: {\n $implicit: col,\n showChevron: col?.children?.length > 1\n }\n \"\n ></ng-container>\n </ng-container>\n </ng-template>\n </div>\n </ng-template>\n </div>\n </div>\n\n <!-- ********************************************************************************* -->\n <!-- ********************************************************************************* -->\n <!-- Data Grid Right Pinned Header starts here -->\n <!-- ********************************************************************************* -->\n <!-- ********************************************************************************* -->\n <div\n [style.backgroundColor]=\"headerBackgroundColor\"\n cdkDropList\n id=\"right-pinned-header\"\n [cdkDropListConnectedTo]=\"\n showRowsGrouping ? ['rows-grouping-top-container'] : []\n \"\n cdkDropListOrientation=\"horizontal\"\n class=\"data-grid-header right-pinned\"\n (cdkDropListSorted)=\"\n onSortGroup($event, 'previewRightPinnedColumns')\n \"\n (cdkDropListEntered)=\"onDropListEnter($event, 'right')\"\n (cdkDropListDropped)=\"onDropGroup()\"\n #rightPinnedHeader\n class=\"right-pinned-header d-flex\"\n style=\"min-width: 0.2px\"\n >\n <div\n class=\"dragable-header\"\n cdkDrag\n [cdkDragData]=\"col\"\n *ngFor=\"\n let col of rightPinnedColumns;\n let i = index;\n trackBy: trackById\n \"\n >\n <ng-container\n *ngTemplateOutlet=\"\n headerCell;\n context: {\n $implicit: col,\n pinnedRight: true,\n index: i,\n section: 'right'\n }\n \"\n ></ng-container>\n <ng-template cdkDragPreview\n ><div class=\"p-2 border d-flex gap-2\">\n <div>\n <span\n *ngIf=\"!draggingInGroupArea\"\n [inlineSVG]=\"\n singleSpaAssetsPath +\n 'data-grid/icons/arrows-move.svg'\n \"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n </div>\n <div>{{ col.header }}</div>\n </div>\n </ng-template>\n <ng-template cdkDragPlaceholder>\n <div *ngIf=\"!draggingInGroupArea\">\n <div\n *ngTemplateOutlet=\"\n headerCell;\n context: {\n $implicit: col,\n index: i,\n section: 'right'\n }\n \"\n ></div>\n </div>\n <div\n *ngIf=\"draggingInGroupArea\"\n class=\"d-flex gap-2 ms-2\"\n style=\"opacity: 0.6\"\n >\n <ng-container *ngIf=\"col?.children?.length; else singleCol\">\n <ng-container\n *ngFor=\"\n let child of col.children;\n let i = index;\n trackBy: trackById\n \"\n >\n <ng-container\n *ngTemplateOutlet=\"\n topGroupingRowPlaceholder;\n context: {\n $implicit: child,\n showChevron:\n col.children.length > 1 &&\n i != col.children.length - 1\n }\n \"\n ></ng-container>\n </ng-container>\n </ng-container>\n\n <ng-template #singleCol>\n <ng-container\n *ngTemplateOutlet=\"\n topGroupingRowPlaceholder;\n context: {\n $implicit: col,\n showChevron: col?.children?.length > 1\n }\n \"\n ></ng-container>\n </ng-template>\n </div>\n </ng-template>\n </div>\n </div>\n </div>\n\n <!--########################################################################################################################################################################################################################### -->\n <!--########################################################################################################################################################################################################################### -->\n <!-- Data Grid Body starts here -->\n <!--########################################################################################################################################################################################################################### -->\n <!--########################################################################################################################################################################################################################### -->\n <div\n class=\"h-100 d-flex justify-content-center align-items-center\"\n *ngIf=\"!dataSet?.length && !loading && !dataSetLoading\">\n <!-- <div\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/record-not-found.svg'\n \"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></div> -->\n <div class=\"d-flex flex-column justify-content-center align-items-center\">\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/no-data-image.svg'\"\n class=\"data-grid-svg-icon mb-3 d-flex justify-content-center align-items-center\">\n </span>\n <p class=\"text_common_16px mb-0\">No data available</p>\n <p class=\"page_refresh mb-0\">Try adjusting filters or refresh the page</p>\n </div>\n </div>\n\n <div\n class=\"position-absolute w-100 h-100 d-flex justify-content-center align-items-center loading-overlay\"\n *ngIf=\"loading || dataSetLoading\"\n style=\"\n z-index: 999;\n backdrop-filter: blur(1px);\n \"\n [style.backgroundColor]=\"bodyBackgroundColor\"\n >\n <div class=\"spinner-border text-primary\" role=\"status\">\n <!-- <span class=\"loader\"></span> -->\n <!-- <span class=\"visually-hidden\">Loading...</span> -->\n <!-- </div> -->\n </div>\n </div>\n\n <div\n class=\"data-grid-body-wrapper position-relative d-flex\"\n [style.height]=\"bodyWrapperHeight\"\n style=\"overflow-y: auto; overflow-x: hidden\"\n #mainScroll\n (scroll)=\"onMainScroll($event)\"\n [style.scrollbarWidth]=\"verticalScrollbarWidth\"\n >\n <!-- LEFT PINNED -->\n <div\n [style.height.px]=\"\n !groupedColumns.length ? originalDataSet.length * rowHeight : 0\n \"\n ></div>\n <!-- [class.transparent-border-right]=\"!hasLeftPinnedColumns\" -->\n <div [class.h-100]=\"originalDataSet.length < 8\">\n <div\n class=\"data-grid-body left-pinned-body w-100\"\n style=\"overflow-y: hidden\"\n [class.border-right]=\"hasLeftPinnedColumns\"\n [class.transparent-border-right]=\"!hasLeftPinnedColumns\"\n [style.boxShadow]=\"leftPinnedBoxshadow\"\n [style.transform]=\"'translateY(' + translateY + 'px)'\"\n [style.backgroundColor]=\"leftPinnedBackgroundColor\"\n [class.h-100]=\"originalDataSet.length < 8\"\n *ngIf=\"!loading && !dataSetLoading\"\n [@rowDynamic]=\"rowAnimation\"\n\n \n >\n <ng-container\n *ngFor=\"\n let row of visibleRows;\n let i = index;\n trackBy: trackById\n \"\n >\n <ng-container\n *ngTemplateOutlet=\"\n rowCell;\n context: {\n $implicit: row,\n columns: previewLeftPinnedColumns,\n isEven: (startIndex + i) % 2 === 0,\n isOdd: (startIndex + i) % 2 !== 0,\n isLeft: true,\n section: 'left',\n isTotalRow: false\n }\n \"\n ></ng-container>\n </ng-container>\n <ng-container *ngIf=\"showTotalAmountRow && originalDataSet?.length\">\n <ng-container\n *ngTemplateOutlet=\"\n rowCell;\n context: {\n $implicit: { __virtualIndex: 0 },\n columns: previewLeftPinnedColumns,\n isEven: false,\n isOdd: false,\n section: 'left',\n isTotalRow: true\n }\n \"\n ></ng-container>\n </ng-container>\n </div>\n </div>\n\n <!-- CENTER -->\n <div\n class=\"h-100\"\n [style.width.px]=\"centerPinnedHeader.clientWidth\"\n [style.backgroundColor]=\"bodyBackgroundColor\"\n >\n <div\n class=\"data-grid-body center-scrollable\"\n [class.h-100]=\"originalDataSet.length < 8\"\n style=\"overflow-y: hidden; overflow-x: auto\"\n [style.transform]=\"'translateY(' + translateY + 'px)'\"\n [style.backgroundColor]=\"bodyBackgroundColor\"\n #centerScrollableBody\n (scroll)=\"onCenterBodyScroll($event)\"\n [style.boxShadow]=\"leftPinnedBoxshadow\"\n \n >\n <div [@rowDynamic]=\"rowAnimation\" *ngIf=\"!loading && !dataSetLoading\">\n <ng-container\n *ngFor=\"\n let row of visibleRows;\n let i = index;\n trackBy: trackById\n \"\n >\n <ng-container\n *ngTemplateOutlet=\"\n rowCell;\n context: {\n $implicit: row,\n columns: previewCenterColumns,\n isEven: (startIndex + i) % 2 === 0,\n isOdd: (startIndex + i) % 2 !== 0,\n section: 'center',\n isTotalRow: false\n }\n \"\n ></ng-container>\n </ng-container>\n </div>\n <ng-container *ngIf=\"showTotalAmountRow && originalDataSet?.length\">\n <ng-container\n *ngTemplateOutlet=\"\n rowCell;\n context: {\n $implicit: { __virtualIndex: 0 },\n columns: previewCenterColumns,\n isEven: false,\n isOdd: false,\n section: 'center',\n isTotalRow: true\n }\n \"\n ></ng-container>\n </ng-container>\n </div>\n </div>\n\n <!-- RIGHT PINNED -->\n <div\n class=\"right-pinned-body-wrapper\"\n *ngIf=\"true\"\n [class.h-100]=\"originalDataSet.length < 8\"\n [style.maxWidth.px]=\"\n isScrollbarVisible\n ? rightPinnedHeader.offsetWidth - 15\n : rightPinnedHeader.offsetWidth\n \"\n [style.backgroundColor]=\"rightPinnedBackgroundColor\"\n [@rowDynamic]=\"rowAnimation\"\n >\n <div\n class=\"data-grid-body right-pinned-body w-100 h-100\"\n style=\"overflow-y: hidden\"\n [style.transform]=\"'translateY(' + translateY + 'px)'\"\n [style.boxShadow]=\"rightPinnedBoxshadow\"\n [style.backgroundColor]=\"rightPinnedBackgroundColor\"\n *ngIf=\"!loading && !dataSetLoading && hasRightPinnedColumns\"\n >\n <ng-container\n *ngFor=\"\n let row of visibleRows;\n let i = index;\n trackBy: trackById\n \"\n >\n <ng-container\n *ngTemplateOutlet=\"\n rowCell;\n context: {\n $implicit: row,\n columns: previewRightPinnedColumns,\n isEven: (startIndex + i) % 2 === 0,\n isOdd: (startIndex + i) % 2 !== 0,\n section: 'right',\n isTotalRow: false\n }\n \"\n ></ng-container>\n </ng-container>\n <ng-container *ngIf=\"showTotalAmountRow && originalDataSet?.length\">\n <ng-container\n *ngTemplateOutlet=\"\n rowCell;\n context: {\n $implicit: { __virtualIndex: 0 },\n columns: previewRightPinnedColumns,\n isEven: false,\n isOdd: false,\n section: 'right',\n isTotalRow: true\n }\n \"\n ></ng-container>\n </ng-container>\n </div>\n </div>\n\n <div\n style=\"top: auto; left: auto\"\n (click)=\"\n $event.stopPropagation();\n fullscreenImage = null;\n cdr.detectChanges()\n \"\n [style.width.px]=\"dataGridContainer.offsetWidth\"\n [style.height.px]=\"\n dataGridContainer.offsetHeight - (footerRowHeight + 100)\n \"\n class=\"image-modal full-image-modal\"\n *ngIf=\"fullscreenImage\"\n >\n <img\n (click)=\"$event.stopPropagation()\"\n [src]=\"fullscreenImage\"\n alt=\"Fullscreen Image\"\n />\n </div>\n <div\n *ngIf=\"selectedRows.size > 0 && showTaskbar\"\n class=\"taskbar w-100\"\n [style.bottom.px]=\"85\"\n >\n <div class=\"selected-rows-action-bar\" [@slideUp]>\n <span class=\"selected-count\">\n {{ selectedRows.size }} selected of\n {{\n paginationConfig.totalResults ||\n config?.paginationParams?.totalItems\n }}\n Total\n </span>\n <div class=\"action-buttons d-flex align-items-center\">\n <ng-container\n *ngFor=\"let action of taskbarActions; let i = index\"\n >\n <ng-container *ngIf=\"action?.has_permission\">\n <span\n class=\"action-btn verified btn {{ action }}\"\n (click)=\"onVerifyClick(action?.actionName)\"\n >{{ action?.actionName }}</span\n >\n <span\n *ngIf=\"\n taskbarActions.length > 1 &&\n i !== taskbarActions.length - 1 &&\n taskbarActions[i + 1]?.has_permission\n \"\n class=\"\"\n >|</span\n >\n </ng-container>\n </ng-container>\n <button (click)=\"clearSelectionState(tableType);selectedRows.clear();\" class=\"clear-btn ms-2 mt-2\">\n <i class=\"bi bi-x-circle\"></i> Clear Selection\n </button>\n </div>\n </div>\n </div>\n </div>\n <!-- Vertical Fake scroll Bar -->\n <!-- <div\n (scroll)=\"onMainFakeScroll($event)\"\n class=\"fake-scrollbar fake-scrollbar-vertical d-none\"\n [style.scrollbarWidth]=\"verticalScrollbarWidth\"\n [style.top.px]=\"\n showColumnsGrouping && showFilterRow\n ? headerRowHeight * 3\n : showColumnsGrouping || showFilterRow\n ? headerRowHeight * 2\n : headerRowHeight\n \"\n #fakeScroll\n [style.height]=\"bodyWrapperHeight\"\n style=\"\n overflow-y: auto;\n overflow-x: hidden;\n width: 17px;\n position: absolute;\n right: 0;\n background-color: f1f2f3;\n z-index: 10;\n \"\n >\n <div [style.height.px]=\"rowHeight * dataSetLength\"></div>\n </div> -->\n </div>\n\n <!-- Horizintal Fake Scrollbars -->\n <div\n class=\"d-flex justify-content-between\"\n *ngIf=\"hasScroll\"\n >\n <div\n [style.scrollbarWidth]=\"horizintalScrollbarWidth\"\n class=\"fake-horizintal-scrollbar\"\n #fakeScroll\n [style.width.px]=\"leftPinnedHeader.offsetWidth\"\n style=\"overflow-x: scroll\"\n ></div>\n <div\n [style.scrollbarWidth]=\"horizintalScrollbarWidth\"\n (scroll)=\"onCenterBodyScroll($event)\"\n class=\"fake-horizintal-scrollbar\"\n #horizintalFakeScroll\n [style.width.px]=\"centerPinnedHeader.offsetWidth\"\n >\n <div [style.width.px]=\"centerPinnedHeader.scrollWidth - 10\"></div>\n </div>\n <div\n [style.scrollbarWidth]=\"horizintalScrollbarWidth\"\n class=\"fake-horizintal-scrollbar\"\n #fakeScroll\n [style.width.px]=\"rightPinnedHeader.offsetWidth\"\n style=\"overflow-x: scroll\"\n ></div>\n </div>\n </div>\n\n <!-- Side Menu Implemented Here -->\n <div\n *ngIf=\"showSideMenu\"\n [style.width.px]=\"sideMenuVisible ? 280 : 30\"\n class=\"right-menu h-100\"\n [style.backgroundColor]=\"sidemenuBackgroundColor\"\n >\n <div class=\"h-100 d-flex flex-row-reverse\">\n <div\n style=\"width: 30px\"\n class=\"d-flex flex-column align-items-center cursor-pointer\"\n [class.border-start]=\"sideMenuVisible\"\n >\n <div\n (click)=\"toggleSideMenu('cols')\"\n [class.bg-fff]=\"\n currentOpenedSideMenue == 'cols' && sideMenuVisible\n \"\n [class.border-below]=\"sideMenuVisible\"\n class=\"columns-button d-flex flex-column align-items-center\"\n >\n <div>\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/ui-checks-grid.svg'\n \"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n </div>\n <div class=\"side-menue-text\">Columns</div>\n </div>\n\n <div\n (click)=\"toggleSideMenu('filtrs')\"\n [class.bg-fff]=\"\n currentOpenedSideMenue == 'filtrs' && sideMenuVisible\n \"\n [class.border-below]=\"\n sideMenuVisible && currentOpenedSideMenue == 'filtrs'\n \"\n class=\"columns-button d-flex flex-column align-items-center\"\n >\n <div>\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\n \"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n </div>\n <div class=\"side-menue-text\">Filter</div>\n </div>\n </div>\n <div\n class=\"h-100\"\n *ngIf=\"sideMenuVisible\"\n [ngStyle]=\"{ width: sideMenuVisible ? '250px' : '' }\"\n >\n <div class=\"h-100\">\n <ng-container\n *ngIf=\"currentOpenedSideMenue == 'cols' && sideMenuVisible\"\n >\n <ng-container *ngTemplateOutlet=\"columnPannel\"></ng-container>\n <!-- Column Items -->\n <div class=\"column-panel-body px-3\">\n <ng-container\n *ngFor=\"let col of columns; trackBy: trackByField\"\n >\n <ng-container\n *ngTemplateOutlet=\"columnPanelItem; context: { col: col }\"\n ></ng-container>\n </ng-container>\n </div>\n <hr />\n\n <div class=\"side-menu-row-groups\" style=\"height: 30%\">\n <ng-container\n *ngTemplateOutlet=\"sideMenuRowGroups\"\n ></ng-container>\n </div>\n </ng-container>\n <ng-container\n *ngIf=\"currentOpenedSideMenue == 'filtrs' && sideMenuVisible\"\n >\n <ng-container *ngTemplateOutlet=\"sideFilters\"></ng-container>\n </ng-container>\n </div>\n </div>\n </div>\n </div>\n </div>\n <div\n [style.height.px]=\"footerRowHeight\"\n class=\"border-top\"\n [style.backgroundColor]=\"footerRowBackgroundColor\"\n >\n <!-- Rows: <span class=\"fw-500 ms-1\">{{ dataSet.length }}</span> -->\n\n <div class=\"pagination-container\"\n [style.height.px]=\"footerRowHeight\"\n [style.padding.px]=\"footerPadding\">\n <div class=\"page-size\">\n <select\n [(ngModel)]=\"paginationConfig.limit\"\n (change)=\"onPageSizeChange()\"\n >\n <option *ngFor=\"let size of pageSizeOptions\" [value]=\"size\">\n {{ size }}\n </option>\n </select>\n <span class=\"separator\"> per page </span>\n </div>\n\n <div class=\"page-info\">\n \n {{ (paginationConfig.page - 1) * paginationConfig.limit + 1 }}-{{\n paginationConfig.page * paginationConfig.limit <\n paginationConfig.totalResults\n ? paginationConfig.page * paginationConfig.limit\n : paginationConfig.totalResults\n }}\n of\n {{ paginationConfig.totalResults }}\n results\n </div>\n\n <div class=\"page-buttons\">\n <button\n (click)=\"goToPage(paginationConfig.page - 1)\"\n [disabled]=\"paginationConfig.page === 1\">\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/chevron-left.svg'\"\n class=\"d-flex justify-content-center align-items-center\"\n ></span>\n </button>\n\n <ng-container *ngFor=\"let page of visiblePages\">\n <button\n *ngIf=\"page !== '...'\"\n (click)=\"goToPage(page)\"\n [class.active]=\"page === paginationConfig.page\"\n >\n {{ page }}\n </button>\n <span *ngIf=\"page === '...'\">...</span>\n </ng-container>\n\n <button\n (click)=\"goToPage(paginationConfig.page + 1)\"\n [disabled]=\"paginationConfig.page === paginationConfig.totalResults\">\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\"\n class=\"d-flex justify-content-center align-items-center\"\n ></span>\n </button>\n </div>\n </div>\n </div>\n </div>\n</div>\n\n<!-- ------------------------------------------------------------------------------------------------------------------------ -->\n<!-- ------------------------------------------------------------------------------------------------------------------------ -->\n<!-- Header Cell Template -->\n<!-- ------------------------------------------------------------------------------------------------------------------------ -->\n<!-- ------------------------------------------------------------------------------------------------------------------------ -->\n\n<ng-template\n #headerCell\n let-col\n let-pinnedRight=\"pinnedRight\"\n let-i=\"index\"\n let-sections=\"section\"\n let-calledFromNestedPlaceholder=\"calledFromNestedPlaceholder\"\n>\n <div>\n <!-- Group Header -->\n <ng-container *ngIf=\"col.children?.length > 0; else flatHeader\">\n <div cdkDroplistGroup class=\"group-column-wrapper\">\n <!-- Parent Header -->\n <div\n *ngIf=\"shouldTheGroupHeaderShow(col)\"\n class=\"header-cell group-header\"\n [style.height.px]=\"headerRowHeight\"\n [style.min-height.px]=\"headerRowHeight\"\n [style.max-height.px]=\"headerRowHeight\"\n [class.border-right]=\"showVerticalBorder\"\n [style.gridColumn]=\"'span ' + col.children.length\"\n [style.fontWeight]=\"headerFontWeight\"\n [class.flex-row-reverse]=\"pinnedRight\"\n [class.justify-content-end]=\"pinnedRight\"\n style=\"grid-row: 1\"\n >\n <div\n class=\"group-header-content\"\n [title]=\"col.header\"\n [class.ms-2]=\"pinnedRight\"\n >\n {{ col.header }}\n </div>\n <div\n class=\"resize-handle\"\n (dblclick)=\"autosizeColumn(col.children)\"\n (mousedown)=\"\n $event.stopPropagation(); onResizeGroup($event, col, pinnedRight)\n \"\n >\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/resize-handle1.svg'\n \"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n </div>\n </div>\n\n <!-- Child Headers and Filters -->\n\n <div\n class=\"d-flex\"\n cdkDropList\n cdkDropListOrientation=\"horizontal\"\n [cdkDropListData]=\"col.children\"\n (cdkDropListSorted)=\"onChildDroplistSorted($event, sections)\"\n (cdkDropListDropped)=\"onChildDroplistDroped($event)\"\n [cdkDropListSortingDisabled]=\"false\"\n [cdkDropListConnectedTo]=\"\n showRowsGrouping ? ['rows-grouping-top-container'] : []\n \"\n >\n <div\n cdkDrag\n [cdkDragData]=\"child\"\n *ngFor=\"let child of col.children; let i = index\"\n >\n <!-- Child Header -->\n <ng-container *ngIf=\"child.is_visible && !child['isRowGrouped']\">\n <div\n cdkDragHandle\n class=\"header-cell one-row-header-cells cursor-pointer\"\n [class.border-right]=\"showVerticalBorder\"\n [attr.field]=\"child.field\"\n [style.width.px]=\"child.width\"\n [style.min-width.px]=\"child.width\"\n [style.min-height.px]=\"headerRowHeight\"\n [style.max-height.px]=\"headerRowHeight\"\n [style.fontWeight]=\"headerFontWeight\"\n style=\"grid-row: 2\"\n [class.filter-applied-on-text]=\"isFilterAppliedOnColumn(child)\"\n >\n <div\n class=\"d-flex justify-content-between h-100 align-items-center w-100\"\n >\n <div\n class=\"d-flex justify-content-between align-items-center w-100\"\n [class.flex-row-reverse]=\"pinnedRight\"\n >\n <div\n class=\"text-ellipsis h-100 d-flex align-items-center w-100\"\n [title]=\"col.header\"\n [class.w-100]=\"pinnedRight\"\n >\n <div\n class=\"text-ellipsis h-100\"\n [class.editable-header]=\"child?.is_editable\"\n (click)=\"\n openThreeDotsMenu($event, child);\n openFilteronThreeDotsClick(child)\n \"\n >\n {{ child.header }}\n </div>\n </div>\n\n <div\n class=\"position-relative d-flex\"\n [class.flex-row-reverse]=\"pinnedRight\"\n >\n <div\n [class.me-2]=\"pinnedRight\"\n class=\"d-flex align-items-center\"\n *ngIf=\"child.pinned\"\n >\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/pin.svg'\n \"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n </div>\n <div\n class=\"three-dots p-1 zaid-test\"\n (click)=\"\n openThreeDotsMenu($event, child);\n isThreeDotsFilterOpen = false\n \"\n style=\"cursor: pointer\"\n >\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath +\n 'data-grid/icons/three-dots-vertical.svg'\n \"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n </div>\n\n <!-- Only show menu if this column is active -->\n <div\n class=\"position-absolute\"\n *ngIf=\"activeCol === child\"\n style=\"top: -50%; z-index: 21\"\n [style.left.px]=\"\n -(!child?.pinned ? centerPinnedHeader.scrollLeft : 0)\n \"\n [style.top.px]=\"\n isThreeDotsFilterOpen\n ? showFilterRow || showColumnsGrouping\n ? headerRowHeight * 2 - 10\n : headerRowHeight - 10\n : 0\n \"\n >\n <ng-container\n *ngTemplateOutlet=\"\n columnMenu;\n context: {\n col: child,\n isNestedTable: false,\n section: sections\n }\n \"\n ></ng-container>\n </div>\n\n <div\n class=\"resize-handle\"\n (dblclick)=\"autosizeColumn(child)\"\n (mousedown)=\"\n $event.stopPropagation();\n onResizeColumn($event, child)\n \"\n >\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath +\n 'data-grid/icons/resize-handle1.svg'\n \"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n </div>\n </div>\n </div>\n </div>\n </div>\n\n <!-- Filter Cell -->\n <div\n *ngIf=\"showFilterRow\"\n [style.backgroundColor]=\"headerBackgroundColor\"\n class=\"header-cell filter-cell\"\n [class.border-right]=\"showVerticalBorder\"\n [attr.field]=\"child.field\"\n [style.width.px]=\"child.width\"\n [style.min-width.px]=\"child.width\"\n [style.height.px]=\"headerRowHeight\"\n [style.min-height.px]=\"headerRowHeight\"\n [style.max-height.px]=\"headerRowHeight\"\n [class.border-right]=\"showVerticalBorder\"\n style=\"grid-row: 3\"\n >\n <div\n class=\"header-cell filter-cell\"\n [attr.field]=\"col.field\"\n [style.width.px]=\"col.width\"\n [style.min-width.px]=\"col.width\"\n [style.height.px]=\"headerRowHeight\"\n [style.min-height.px]=\"headerRowHeight\"\n [style.max-height.px]=\"headerRowHeight\"\n >\n <input\n type=\"text\"\n class=\"form-control form-control-sm\"\n placeholder=\"Filter\"\n [(ngModel)]=\"child.filterValue\"\n (ngModelChange)=\"onFilterChange(child)\"\n (paste)=\"onFilterChange(child); applyDropdownFilter()\"\n [readonly]=\"\n child?.type == 'dropdown' || child?.type == 'image'\n \"\n [class.disabled-search-input]=\"\n child?.type == 'dropdown' || child?.type == 'image'\n \"\n (click)=\"\n $event.stopPropagation();\n openFilterFromDisabledSearchedInput(child)\n \"\n (keydown.enter)=\"applyDropdownFilter()\"\n (mousedown)=\"$event.stopPropagation()\"\n />\n <span\n class=\"filter-icon-wrapper\"\n (click)=\"$event.stopPropagation(); openFilter(child)\"\n [class.filter-applied]=\"isFilterAppliedOnColumn(child)\"\n [class.pe-none]=\"child?.type == 'image'\"\n ><span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\n \"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n <span\n *ngIf=\"isFilterAppliedOnColumn(child)\"\n style=\"\n width: 7px;\n height: 7px;\n box-shadow: 0px 0px 3px #7486ff;\n background-color: rgb(0 163 233);\n position: absolute;\n right: 4px;\n top: 12px;\n \"\n class=\"rounded-circle d-block\"\n ></span\n ></span>\n\n <div\n class=\"position-absolute filter-row-filter-wrapper\"\n *ngIf=\"activeFilterCell?.field == child?.field\"\n style=\"top: 100%; right: 0; z-index: 99\"\n [style.left.px]=\"\n child?.pinned ? 0 : -centerPinnedHeader.scrollLeft\n \"\n >\n <ng-container\n *ngTemplateOutlet=\"filterMenu; context: { col: child }\"\n ></ng-container>\n </div>\n </div>\n </div>\n </ng-container>\n <ng-template cdkDragPreview\n ><div class=\"p-2 border d-flex gap-2\">\n <div\n *ngIf=\"\n !draggingInGroupArea ||\n (child.is_groupable && draggingInGroupArea)\n \"\n >\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/arrows-move.svg'\n \"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n </div>\n <div *ngIf=\"draggingInGroupArea && !child.is_groupable\">\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/ban.svg'\n \"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n </div>\n <div>{{ child.header }}</div>\n </div>\n </ng-template>\n <ng-template cdkDragPlaceholder>\n <div *ngIf=\"!draggingInGroupArea\" class=\"position-relative\">\n <div\n *ngTemplateOutlet=\"\n childHeaderPlaceholder;\n context: {\n $implicit: child,\n index: i,\n sections: sections,\n calledFromNestedPlaceholder: true,\n }\n \"\n ></div>\n </div>\n <div\n *ngIf=\"draggingInGroupArea && child?.is_groupable\"\n class=\"d-flex gap-2 ms-2\"\n style=\"opacity: 0.6\"\n >\n <ng-container\n *ngTemplateOutlet=\"\n topGroupingRowPlaceholder;\n context: {\n $implicit: child,\n showChevron: false,\n pinnedRight: pinnedRight,\n sections: sections,\n index: i\n }\n \"\n ></ng-container>\n </div>\n </ng-template>\n </div>\n </div>\n </div>\n </ng-container>\n\n <!-- Flat Header || Single Header Cell-->\n <ng-template #flatHeader>\n <div\n class=\"group-column-wrapper\"\n *ngIf=\"col.is_visible && !col['isRowGrouped']\"\n >\n <!-- Full-height Header Cell (spans 2 rows visually) -->\n <div\n class=\"header-cell one-row-header-cells\"\n [attr.field]=\"col.field\"\n [style.width.px]=\"col.width\"\n [style.min-width.px]=\"col.width\"\n [class.border-right]=\"showVerticalBorder\"\n [style.min-height.px]=\"\n showColumnsGrouping ? headerRowHeight * 2 : headerRowHeight\n \"\n [style.height.px]=\"\n showColumnsGrouping ? headerRowHeight * 2 : headerRowHeight\n \"\n [style.fontWeight]=\"headerFontWeight\"\n style=\"grid-row: 1 / span 2\"\n >\n <div\n class=\"d-flex justify-content-between h-100 align-items-center w-100\"\n >\n <div\n class=\"d-flex justify-content-between w-100 align-items-center\"\n [class.flex-row-reverse]=\"pinnedRight\"\n >\n <div\n class=\"text-ellipsis h-100 d-flex align-items-center w-100\"\n [title]=\"col.header\"\n >\n <div\n class=\"text-ellipsis h-100 cursor-pointer\"\n [class.editable-header]=\"col?.is_editable\"\n [class.filter-applied-on-text]=\"isFilterAppliedOnColumn(col)\"\n (click)=\"\n openThreeDotsMenu($event, col);\n openFilteronThreeDotsClick(col)\n \"\n >\n {{ col.header }}\n </div>\n </div>\n\n <div\n class=\"position-relative d-flex align-items-center\"\n [class.flex-row-reverse]=\"pinnedRight\"\n >\n <div\n [class.me-2]=\"pinnedRight\" [class.threeDotActive]=\"activeCol === col && !clickedOnSortIcon\"\n class=\"d-flex align-items-center three-dots\"\n *ngIf=\"col?.pinned\">\n <span (click)=\"\n openThreeDotsMenu($event, col, false);\n isThreeDotsFilterOpen = false\n \"\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/pin.svg'\n \"\n class=\"data-grid-svg-icon setting_dropdown d-flex justify-content-center align-items-center pin_blue_icon\"\n ></span>\n </div>\n <!-- <div\n [class.me-2]=\"col.order_by\"\n class=\"d-flex align-items-center\"\n *ngIf=\"sortingConfig?.field == col.field\">\n <span\n *ngIf=\"sortingConfig?.order_by == 'asc'\"\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/selectedAscIcon.svg'\n \"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center mt-1 cursor-pointer\"\n (click)=\"sortDesc(col)\"\n [class.active]=\"sortingConfig?.order_by === 'asc'\"\n ></span>\n <span\n *ngIf=\"sortingConfig?.order_by == 'desc'\"\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/selectedAscIcon.svg'\n \"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center mt-1 cursor-pointer\"\n (click)=\"sortAsc(col)\"\n [class.active]=\"sortingConfig?.order_by === 'desc'\"\n ></span>\n </div> -->\n <div class=\"three-dots p-1 me-0 zaid-test1\" [class.threeDotActive]=\"activeCol === col && clickedOnSortIcon\"\n (click)=\"openThreeDotsMenu($event, col, true);\"\n style=\"cursor: pointer\">\n <div *ngIf=\"sortingConfig?.field === col.field\" \n class=\"d-flex align-items-center\">\n \n <!-- Ascending Sort Icon -->\n <span\n *ngIf=\"sortingConfig?.order_by == 'asc'\"\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/sort-ascending-green.svg'\"\n class=\"data-grid-svg-icon ascendingAppliedIcon flex justify-content-center align-items-center cursor-pointer\"\n (click)=\"openThreeDotsMenu($event, col, true)\"\n [class.active]=\"sortingConfig?.order_by === 'asc'\">\n </span>\n\n <!-- Descending Sort Icon -->\n <span\n *ngIf=\"sortingConfig?.order_by == 'desc'\"\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/sort-ascending-green.svg'\"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center cursor-pointer rotated-180\"\n (click)=\"openThreeDotsMenu($event, col, true)\"\n [class.active]=\"sortingConfig?.order_by === 'desc'\">\n </span>\n </div>\n <span *ngIf=\"sortingConfig?.field !== col.field\"\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/sortIconGray.svg'\"\n class=\"data-grid-svg-icon figmaIconSize d-flex justify-content-center align-items-center\"\n (click)=\"openThreeDotsMenu($event, col, true)\">\n </span>\n </div>\n <div class=\"three-dots p-1 zaid-test1\" [class.threeDotActive]=\"activeCol === col && !clickedOnSortIcon\" *ngIf=\"!col?.pinned\"\n (click)=\"\n openThreeDotsMenu($event, col, false);\n isThreeDotsFilterOpen = false\n \"\n style=\"cursor: pointer\">\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath +\n 'data-grid/icons/three-dots-vertical.svg'\n \"\n class=\"data-grid-svg-icon setting_dropdown dropdown d-flex justify-content-center align-items-center\"\n ></span>\n </div>\n\n <!-- Only show menu if this column is active -->\n <div\n class=\"position-absolute\"\n *ngIf=\"activeCol === col\"\n style=\"z-index: 21\"\n [style.left.px]=\"\n -(!col?.pinned ? centerPinnedHeader.scrollLeft : 0)\n \"\n [style.top.px]=\"\n isThreeDotsFilterOpen\n ? showFilterRow || showColumnsGrouping\n ? headerRowHeight * 2 - 10\n : headerRowHeight - 10\n : 25\n \"\n >\n <ng-container\n *ngTemplateOutlet=\"\n columnMenu;\n context: {\n col: col,\n isNestedTable: false,\n section: sections\n }\n \"\n ></ng-container>\n </div>\n\n <div\n class=\"resize-handle\"\n [class.w-100]=\"col.pinned == 'right'\"\n (dblclick)=\"autosizeColumn(col)\"\n (mousedown)=\"\n $event.stopPropagation(); onResizeColumn($event, col)\n \"\n >\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/resize-handle1.svg'\n \"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n </div>\n </div>\n </div>\n </div>\n </div>\n\n <!-- Filter Cell -->\n <div\n *ngIf=\"showFilterRow\"\n [style.backgroundColor]=\"headerBackgroundColor\"\n class=\"header-cell filter-cell\"\n [class.border-right]=\"showVerticalBorder\"\n [attr.field]=\"col.field\"\n [style.width.px]=\"col.width\"\n [style.min-width.px]=\"col.width\"\n [style.height.px]=\"headerRowHeight\"\n [style.min-height.px]=\"headerRowHeight\"\n [style.max-height.px]=\"headerRowHeight\"\n >\n <input\n type=\"text\"\n class=\"form-control form-control-sm\"\n placeholder=\"Filter\"\n [(ngModel)]=\"col.filterValue\"\n (ngModelChange)=\"onFilterChange(col)\"\n [readonly]=\"col?.type == 'dropdown' || col?.type == 'image'\"\n [class.disabled-search-input]=\"\n col?.type == 'dropdown' || col?.type == 'image'\n \"\n (paste)=\"onPasteInFilterRowSearch($event, col)\"\n (click)=\"\n $event.stopPropagation(); openFilterFromDisabledSearchedInput(col)\n \"\n (keydown.enter)=\"applyDropdownFilter()\"\n (mousedown)=\"$event.stopPropagation()\"\n />\n <span\n class=\"filter-icon-wrapper\"\n (click)=\"$event.stopPropagation(); openFilter(col)\"\n [class.filter-applied]=\"isFilterAppliedOnColumn(col)\"\n [class.pe-none]=\"col?.type == 'image'\"\n ><span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n <span\n *ngIf=\"isFilterAppliedOnColumn(col)\"\n style=\"\n width: 7px;\n height: 7px;\n box-shadow: 0px 0px 3px #7486ff;\n background-color: rgb(0 163 233);\n position: absolute;\n right: 4px;\n top: 12px;\n \"\n class=\"rounded-circle d-block\"\n ></span\n ></span>\n\n <div\n class=\"position-absolute filter-row-filter-wrapper\"\n *ngIf=\"activeFilterCell === col\"\n style=\"top: 100%; right: 0; z-index: 99\"\n [style.left.px]=\"col?.pinned ? 0 : -centerPinnedHeader.scrollLeft\"\n >\n <ng-container\n *ngTemplateOutlet=\"filterMenu; context: { col: col }\"\n ></ng-container>\n </div>\n </div>\n </div>\n </ng-template>\n </div>\n</ng-template>\n\n<!-- -------------------------------------------------------------------------------------------------------------------------------------------------------------------- -->\n<!-- -------------------------------------------------------------------------------------------------------------------------------------------------------------------- -->\n<!-- Body Cell Template -->\n<!-- -------------------------------------------------------------------------------------------------------------------------------------------------------------------- -->\n<!-- -------------------------------------------------------------------------------------------------------------------------------------------------------------------- -->\n\n<ng-template\n #rowCell\n let-row\n let-columns=\"columns\"\n let-isEven=\"isEven\"\n let-isOdd=\"isOdd\"\n let-isLeftSection=\"isLeft\"\n let-section=\"section\"\n let-rowIndex=\"rowIndex\"\n let-isTotalRow=\"isTotalRow\"\n>\n <!-- Check if row is a group -->\n <ng-container\n *ngTemplateOutlet=\"groupRowTemplate; context: { $implicit: row, depth: 0 }\"\n ></ng-container>\n <ng-template #groupRowTemplate let-row let-depth=\"depth\">\n <ng-container *ngIf=\"row.isGroup; else regularRow\">\n <!-- Group Header -->\n <div\n class=\"group-header-row d-flex align-items-center\"\n [style.height.px]=\"rowHeight\"\n [class.border-below]=\"section !== 'center'\"\n [style.width]=\"\n section === 'center'\n ? (centerScrollableBody?.scrollWidth ?? 0) + 'px'\n : '100%'\n \"\n >\n <div\n *ngIf=\"section == 'left'\"\n class=\"h-100 d-flex\"\n [style.width.px]=\"leftPinnedHeader.offsetWidth - 1\"\n [class.row-selected]=\"rowSelectedIndexes.has(row.__virtualIndex)\"\n >\n <div\n *ngIf=\"showSerialNumber\"\n style=\"width: 50px\"\n class=\"d-flex align-items-center h-100 border-right justify-content-end pe-2 s-no\"\n [style.backgroundColor]=\"checkboxesBackgroundColor\"\n [style.width.px]=\"55\"\n [style.cursor]=\"\n 'url(' +\n singleSpaAssetsPath +\n 'data-grid/icons/arrow-right.svg), auto'\n \"\n (mousedown)=\"onRowMouseDown(row.__virtualIndex, $event)\"\n (mouseover)=\"onRowMouseOver(row.__virtualIndex, $event)\"\n [style.color]=\"checkboxesColor\"\n >\n {{ getStartIndex() + (row.__virtualIndex - 1) || \"\" }}\n </div>\n <div\n *ngIf=\"showCheckboxes\"\n style=\"width: 50px\"\n class=\"d-flex align-items-center justify-content-center h-100 border-right\"\n [style.backgroundColor]=\"checkboxesBackgroundColor\"\n [class.row-selected]=\"rowSelectedIndexes.has(row.__virtualIndex)\"\n [class.left-selection-border]=\"\n rowSelectedIndexes.has(row.__virtualIndex)\n \"\n [class.first-row-selected]=\"firstSelectedRow === row.__virtualIndex\"\n [class.last-row-selected]=\"lastSelectedRow === row.__virtualIndex\"\n [style.color]=\"checkboxesColor\"\n >\n <input\n style=\"width: 16px; height: 16px\"\n type=\"checkbox\"\n [checked]=\"getGroupCheckedState(row) === true\"\n [indeterminate]=\"getGroupCheckedState(row) === undefined\"\n (change)=\"selectGroupRow($event, row)\"\n />\n\n </div>\n </div>\n\n <div\n *ngIf=\"section == 'center'\"\n [style.width.px]=\"centerPinnedHeader.scrollWidth\"\n [style.minWidth.px]=\"centerPinnedHeader.scrollWidth\"\n class=\"d-flex align-items-center ps-2 h-100 border-below\"\n [class.row-selected]=\"rowSelectedIndexes.has(row.__virtualIndex)\"\n [class.first-row-selected]=\"firstSelectedRow === row.__virtualIndex\"\n [class.last-row-selected]=\"lastSelectedRow === row.__virtualIndex\"\n >\n <div\n class=\"d-flex align-items-center justify-content-between\"\n [style.paddingLeft.px]=\"depth > 0 ? depth * 30 : 0\"\n >\n <span class=\"me-2 filter-icon-wrapper\" (click)=\"toggleExpand(row)\">\n <span\n class=\"data-grid-svg-icon align-items-center d-flex\"\n [inlineSVG]=\"\n row.isExpand\n ? singleSpaAssetsPath + 'data-grid/icons/chevron-down.svg'\n : singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\n \"\n ></span>\n </span>\n <strong (click)=\"toggleExpand(row)\" class=\"cursor-pointer\">\n {{ row.groupValue }} ({{ countLeafRows(row) }})\n </strong>\n </div>\n </div>\n\n <div\n *ngIf=\"section == 'right'\"\n [style.width.px]=\"rightPinnedHeader.offsetWidth\"\n [class.row-selected]=\"rowSelectedIndexes.has(row.__virtualIndex)\"\n [class.first-row-selected]=\"firstSelectedRow === row.__virtualIndex\"\n [class.last-row-selected]=\"lastSelectedRow === row.__virtualIndex\"\n ></div>\n </div>\n\n <!-- Recursive Children -->\n <div class=\"group-children\" *ngIf=\"row.isExpand\" [@slideToggle]>\n <ng-container\n *ngFor=\"let child of row.children; let i = index; trackBy: trackById\"\n >\n <ng-container *ngIf=\"child.isGroup; else dataRow\">\n <!-- Recursive call for nested group -->\n <ng-container\n *ngTemplateOutlet=\"\n groupRowTemplate;\n context: { $implicit: child, depth: depth + 1 }\n \"\n ></ng-container>\n </ng-container>\n\n <ng-template #dataRow>\n <!-- Regular data row -->\n <ng-container\n *ngTemplateOutlet=\"\n rowCell;\n context: {\n $implicit: child,\n columns: columns,\n isEven: i % 2 === 0,\n isOdd: i % 2 !== 0,\n isLeft: isLeftSection,\n section: section,\n isTotalRow: isTotalRow\n }\n \"\n ></ng-container>\n </ng-template>\n </ng-container>\n </div>\n </ng-container>\n </ng-template>\n\n <!-- Regular row (not a group) -->\n <ng-template #regularRow>\n <div\n class=\"d-flex\"\n [style.height.px]=\"rowHeight\"\n [style.minHeight.px]=\"rowHeight\"\n [style.maxHeight.px]=\"rowHeight\"\n >\n <span\n class=\"d-flex align-items-center justify-content-center cursor-pointer border-below\"\n style=\"min-width: 30px; height: 100%\"\n *ngIf=\"section == 'center' && (gridType === 'Assets' || gridType === 'Tasks')\"\n [ngStyle]=\"{\n 'background-color': rowSelectedIndexes.has(row.__virtualIndex)\n ? null\n : getBackgroundColor(row, isEven, section)\n }\"\n [class.selected-cell]=\"rowSelectedIndexes.has(row.__virtualIndex)\"\n [class.first-row-selected]=\"firstSelectedRow === row.__virtualIndex\"\n [class.last-row-selected]=\"lastSelectedRow === row.__virtualIndex\"\n >\n <span\n (click)=\"toggleDetailRowExpand(row)\"\n *ngIf=\"row?.detail?.result?.length || gridType === 'Tasks'\"\n class=\"data-grid-svg-icon filter-icon-wrapper\"\n [inlineSVG]=\"\n isDetailsExpanded(row)\n ? singleSpaAssetsPath + 'data-grid/icons/chevron-down.svg'\n : singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\n \"\n ></span>\n </span>\n <div\n [style.min-width.px]=\"\n section == 'center' && groupedColumns?.length ? groupBoxPadding : 0\n \"\n [class.row-selected]=\"rowSelectedIndexes.has(row.__virtualIndex)\"\n [class.first-row-selected]=\"firstSelectedRow === row.__virtualIndex\"\n [class.last-row-selected]=\"lastSelectedRow === row.__virtualIndex\"\n (contextmenu)=\"onRightClick($event, row)\"\n [style.height.px]=\"rowHeight\"\n class=\"data-grid-row h-100\"\n [class.even-row]=\"isEven\"\n [class.odd-row]=\"isOdd\"\n [class.hovered-row]=\"hoveredRowId === (row._id || row.id)\"\n (mouseenter)=\"onRowHover(row)\"\n (mouseleave)=\"onRowLeave()\"\n [ngStyle]=\"{\n 'background-color': getBackgroundColor(row, isEven, section)\n }\"\n [style.minHeight.px]=\"rowHeight\"\n [style.maxHeight.px]=\"rowHeight\"\n ></div>\n <div\n (contextmenu)=\"onRightClick($event, row)\"\n [style.height.px]=\"rowHeight\"\n class=\"data-grid-row\"\n [class.even-row]=\"isEven\"\n [class.odd-row]=\"isOdd\"\n [class.hovered-row]=\"hoveredRowId === (row._id || row.id)\"\n (mouseenter)=\"onRowHover(row)\"\n (mouseleave)=\"onRowLeave()\"\n [ngStyle]=\"{\n 'background-color': getBackgroundColor(row, isEven, section)\n }\"\n >\n <div\n [style.backgroundColor]=\"checkboxesBackgroundColor\"\n [ngStyle]=\"{\n 'background-color': rowSelectedIndexes.has(row.__virtualIndex)\n ? null\n : getBackgroundColor(row, isEven, section)\n }\"\n class=\"select-all-checkbox-cell border-below justify-content-end pe-2 s-no\"\n [style.width.px]=\"55\"\n *ngIf=\"isLeftSection && showSerialNumber\"\n [style.cursor]=\"\n 'url(' +\n singleSpaAssetsPath +\n 'data-grid/icons/arrow-right.svg), auto'\n \"\n (mousedown)=\"onRowMouseDown(row.__virtualIndex, $event)\"\n (mouseover)=\"onRowMouseOver(row.__virtualIndex, $event)\"\n [style.color]=\"checkboxesColor\"\n >\n {{ getStartIndex() + (row.__virtualIndex - 1) }}\n </div>\n <div\n [style.backgroundColor]=\"\n rowSelectedIndexes.has(row.__virtualIndex)\n ? selectedRowsBackgroundColor\n : checkboxesBackgroundColor\n \"\n [ngStyle]=\"{\n 'background-color': rowSelectedIndexes.has(row.__virtualIndex)\n ? null\n : getBackgroundColor(row, isEven, section)\n }\"\n class=\"select-all-checkbox-cell border-below left_checkbox_ailgnment\"\n *ngIf=\"isLeftSection && showCheckboxes\"\n [class.left-selection-border]=\"\n rowSelectedIndexes.has(row.__virtualIndex)\n \"\n [class.first-row-selected]=\"firstSelectedRow === row.__virtualIndex\"\n [class.last-row-selected]=\"lastSelectedRow === row.__virtualIndex\"\n [style.minHeight.px]=\"rowHeight\"\n [style.maxHeight.px]=\"rowHeight\"\n >\n <input class=\"serialNoCheckbox\"\n *ngIf=\"hasAnyVisibleColumn\"\n style=\"width: 16px; height: 16px\"\n type=\"checkbox\"\n [checked]=\"isRowSelected(row)\"\n (change)=\"toggleRowSelection(row)\"\n />\n </div>\n\n <!-- Render all columns -->\n <ng-container\n *ngFor=\"\n let col of columns;\n trackBy: trackByField;\n let colIndex = index\n \"\n >\n <ng-container *ngIf=\"col.children?.length > 0; else flatColumn\">\n <ng-container\n *ngFor=\"\n let child of col.children;\n trackBy: trackByField;\n let subColIndex = index\n \"\n >\n <ng-container *ngIf=\"child?.is_visible && !child?.isRowGrouped\">\n <ng-container\n *ngTemplateOutlet=\"\n cellTemplate;\n context: {\n col: child,\n row: row,\n rowIndex: rowIndex,\n colIndex: colIndex,\n subColIndex: subColIndex,\n section: section,\n isTotalRow: isTotalRow\n }\n \"\n ></ng-container>\n </ng-container>\n </ng-container>\n </ng-container>\n\n <ng-template #flatColumn>\n <ng-container *ngIf=\"col?.is_visible && !col?.isRowGrouped\">\n <ng-container\n *ngTemplateOutlet=\"\n cellTemplate;\n context: {\n col: col,\n row: row,\n rowIndex: rowIndex,\n colIndex: colIndex,\n subColIndex: null,\n section: section,\n isTotalRow: isTotalRow\n }\n \"\n ></ng-container>\n </ng-container>\n </ng-template>\n </ng-container>\n </div>\n </div>\n\n <div\n [@slideToggle]\n *ngIf=\"section === 'left' && isDetailsExpanded(row)\"\n class=\"accordion-details\"\n style=\"max-height: 350px; overflow: hidden\"\n [style.maxHeight.px]=\"hasHorizontalScroll ? 339 : 341\"\n >\n <ng-container\n *ngTemplateOutlet=\"\n leftRightNestedPlaceholder;\n context: { $implicit: row }\n \"\n >\n </ng-container>\n </div>\n\n <div\n [@slideToggle]\n *ngIf=\"section === 'center' && isDetailsExpanded(row)\"\n class=\"accordion-details center-section\"\n style=\"\n max-height: 350px;\n overflow-y: hidden;\n overflow-x: auto;\n scrollbar-width: thin;\n \"\n #nestedTable\n [style.width]=\"\n hasRightPinnedColumns\n ? '100%'\n : hasVerticalScroll\n ? 'calc(100% - 12px)'\n : '100%'\n \"\n >\n <ng-container *ngIf=\"gridType == 'Assets'\">\n <ng-container\n *ngTemplateOutlet=\"nestedTableTemplate; context: { $implicit: row }\"\n ></ng-container>\n </ng-container>\n <ng-container *ngIf=\"gridType == 'Tasks'\">\n <ng-container\n *ngTemplateOutlet=\"\n taskManagementTemplate;\n context: { taskDetails: row }\n \"\n ></ng-container>\n </ng-container>\n </div>\n\n <div\n [@slideToggle]\n *ngIf=\"section === 'right' && isDetailsExpanded(row)\"\n class=\"accordion-details\"\n style=\"max-height: 350px; overflow: hidden\"\n [style.maxHeight.px]=\"hasHorizontalScroll ? 339 : 341\"\n >\n <ng-container\n *ngTemplateOutlet=\"\n leftRightNestedPlaceholder;\n context: { $implicit: row }\n \"\n >\n </ng-container>\n </div>\n </ng-template>\n</ng-template>\n\n<!-- Actual Cell is Here -->\n<ng-template\n #cellTemplate\n let-col=\"col\"\n let-row=\"row\"\n let-section=\"section\"\n let-subColIndex=\"subColIndex\"\n let-rowIndex=\"rowIndex\"\n let-colIndex=\"colIndex\"\n let-isTotalRow=\"isTotalRow\"\n>\n <div\n #cellContainer\n (click)=\"\n editingKey = ''; setActiveCell(row, col); collapseAllExpandedCells()\n \"\n [style.fontWeight]=\"bodyFontWeight\"\n [class.border-right]=\"showVerticalBorder\"\n class=\"cell overflow-visible position-relative data-grid-cell\"\n [attr.field]=\"col.field\"\n [style.width.px]=\"col.width\"\n [style.min-width.px]=\"col.width\"\n [style.fontSize.px]=\"bodyTextFontsSize\"\n [style.minHeight.px]=\"rowHeight\"\n [style.maxHeight.px]=\"rowHeight\"\n [class.active-cell]=\"\n isActiveCell(row, col) && !isEditing(row, col) && selectedKeys.size == 1\n \"\n (dblclick)=\"\n $event.stopPropagation();\n $event.preventDefault();\n enableEdit(row, col, false, cellContainer)\n \"\n [class.row-selected]=\"rowSelectedIndexes.has(row.__virtualIndex)\"\n [class.first-row-selected]=\"firstSelectedRow === row?.__virtualIndex\"\n [class.last-row-selected]=\"lastSelectedRow === row?.__virtualIndex\"\n tabindex=\"-1\"\n (keydown.enter)=\"$event.preventDefault(); enableEdit(row, col)\"\n (mousedown)=\"\n startSelection(\n row.__virtualIndex,\n colIndex,\n subColIndex ?? 0,\n col.field,\n $event,\n section\n )\n \"\n (mouseenter)=\"\n extendSelection(\n row.__virtualIndex,\n colIndex,\n subColIndex ?? 0,\n col.field,\n $event,\n section\n )\n \"\n (mouseup)=\"endSelection()\"\n [class.selected-cell]=\"\n isSelected(\n row.__virtualIndex,\n colIndex,\n subColIndex ?? 0,\n col.field,\n section\n )\n \"\n [class.top-border]=\"\n isTopBorder(row.__virtualIndex, colIndex, subColIndex, section)\n \"\n [class.bottom-border]=\"\n isBottomBorder(row.__virtualIndex, colIndex, subColIndex, section)\n \"\n [class.left-border]=\"\n isLeftBorder(row.__virtualIndex, colIndex, subColIndex, section)\n \"\n [class.right-border]=\"\n isRightBorder(row.__virtualIndex, colIndex, subColIndex, section)\n \"\n [class.top-left-corner]=\"\n isTopLeftCorner(row.__virtualIndex, colIndex, subColIndex, section)\n \"\n [class.top-right-corner]=\"\n isTopRightCorner(row.__virtualIndex, colIndex, subColIndex, section)\n \"\n [class.bottom-left-corner]=\"\n isBottomLeftCorner(row.__virtualIndex, colIndex, subColIndex, section)\n \"\n [class.bottom-right-corner]=\"\n isBottomRightCorner(row.__virtualIndex, colIndex, subColIndex, section)\n \"\n >\n <!-- (mousedown)=\"startSelection(row.__virtualIndex, colIndex, subColIndex ?? 0, col.field, $event)\"\n (mouseenter)=\"extendSelection(row.__virtualIndex, colIndex, subColIndex ?? 0, col.field, $event)\"\n (mouseup)=\"endSelection()\"\n [class.selected-cell]=\"isSelected(row.__virtualIndex, colIndex, subColIndex ?? 0, col.field)\" -->\n <div\n class=\"table-cell\"\n [class.active-for-editing]=\"\n isEditing(row, col) &&\n (getNestedValue(row, col.field)?.length === undefined ||\n getNestedValue(row, col.field)?.length <= 50)\n \"\n >\n <div\n (click)=\"$event.stopPropagation()\"\n *ngIf=\"\n isEditing(row, col) &&\n (getNestedValue(row, col.field)?.length === undefined ||\n (getNestedValue(row, col.field)?.length <= 50 &&\n !expandedCells.size));\n else viewMode\n \"\n >\n <ng-container [ngSwitch]=\"col.type\">\n <!-- Text Input -->\n <input\n [style.height.px]=\"rowHeight - 10\"\n *ngSwitchCase=\"'input'\"\n type=\"text\"\n [(ngModel)]=\"row[col.field]\"\n (blur)=\"disableEdit(row, col)\"\n autofocus\n class=\"form-control form-control-sm\"\n (mousedown)=\"$event.stopPropagation()\"\n />\n\n <!-- Number Input -->\n <input\n [style.height.px]=\"rowHeight - 8\"\n *ngSwitchCase=\"'number'\"\n #numberInput=\"ngModel\"\n #numberRef\n (keypress)=\"allowOnlyNumbers($event)\"\n type=\"number\"\n required\n [(ngModel)]=\"row[col.field]\"\n (blur)=\"disableEdit(row, col)\"\n autofocus\n (keydown.enter)=\"numberRef.blur()\"\n class=\"form-control form-control-sm\"\n [ngClass]=\"{\n 'is-invalid': numberInput.invalid\n }\"\n (mousedown)=\"$event.stopPropagation()\"\n />\n\n <!-- Date Input -->\n <input\n [style.height.px]=\"rowHeight - 8\"\n *ngSwitchCase=\"'date'\"\n type=\"date\"\n [(ngModel)]=\"row[col.field]\"\n (blur)=\"disableEdit(row, col)\"\n autofocus\n class=\"form-control form-control-sm\"\n #dateInput=\"ngModel\"\n [ngClass]=\"{\n 'is-invalid': dateInput.invalid\n }\"\n (mousedown)=\"$event.stopPropagation()\"\n />\n\n <!-- Dropdown -->\n <!-- ng-select like dropdown -->\n <div\n *ngSwitchCase=\"'dropdown'\"\n class=\"dropdown w-100\"\n (blur)=\"disableEdit(row, col)\"\n >\n <!-- Trigger -->\n <button\n class=\"form-select form-select-sm text-start w-100 text-ellipsis\"\n type=\"button\"\n data-bs-toggle=\"dropdown\"\n aria-expanded=\"false\"\n [style.minHeight.px]=\"rowHeight - 10\"\n data-bs-display=\"static\"\n (mousedown)=\"$event.stopPropagation()\"\n >\n <ng-container>\n {{\n getNestedValue(row, col.field)?.value ||\n getNestedValue(row, col.field)?.name ||\n getNestedValue(row, col.field)\n }}\n </ng-container>\n <ng-template #placeholder> Select options... </ng-template>\n </button>\n\n <!-- Menu -->\n <div\n class=\"dropdown-menu w-100 p-0 cell-editing-dropdown-menu rounded-3\"\n [class.show]=\"isEditing(row, col)\"\n >\n <!-- Search -->\n <div class=\"px-2 py-1 editing-dropdown-search-input\">\n <input\n type=\"text\"\n class=\"form-control form-control-sm\"\n placeholder=\"Search...\"\n [(ngModel)]=\"editinDropdownSearch\"\n (mousedown)=\"$event.stopPropagation()\"\n />\n </div>\n\n <!-- Options -->\n <!-- <div\n class=\"cell-editin-dropdown\"\n style=\"max-height: 200px; overflow: auto\"\n >\n <div\n (click)=\"\n setNestedValue(row, col, option, true); editingKey = null\n \"\n class=\"px-2 py-1 d-flex align-items-center deopdown-item\"\n *ngFor=\"\n let option of col.column_dropdown_value\n | filter : editinDropdownSearch: 'value'\n \"\n >\n <label\n class=\"form-check-label d-flex align-items-center mb-0 cursor-pointer\"\n [for]=\"col.field + '-' + option.value || option\"\n >\n {{ option.value || option }}\n </label>\n </div>\n </div> -->\n <cdk-virtual-scroll-viewport \n itemSize=\"35\" \n class=\"dropdown-viewport\"\n style=\"height: 120px\"\n >\n <div\n class=\"px-2 py-1 d-flex align-items-center dropdown-item\"\n *cdkVirtualFor=\"\n let option of col.column_dropdown_value \n | filter : editinDropdownSearch : 'value'\n \"\n (click)=\"setNestedValue(row, col, option, true); editingKey = null\"\n >\n <label\n class=\"form-check-label d-flex align-items-center mb-0 cursor-pointer\"\n [for]=\"col.field + '-' + (option.value || option)\"\n >\n {{ option.value || option }}\n </label>\n </div>\n </cdk-virtual-scroll-viewport>\n\n </div>\n </div>\n\n <input\n *ngSwitchCase=\"'email'\"\n [style.height.px]=\"rowHeight - 10\"\n [style.maxHeight.px]=\"rowHeight - 10\"\n #emailModel=\"ngModel\"\n #emailInput\n type=\"email\"\n [(ngModel)]=\"row[col.field]\"\n name=\"{{ col.field }}\"\n required\n pattern=\"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$\"\n (blur)=\"disableEdit(row, col, emailModel)\"\n (keydown.enter)=\"\n emailModel.control.markAsTouched(); emailInput.blur()\n \"\n autofocus\n class=\"form-control form-control-sm\"\n [ngClass]=\"{\n 'is-invalid': emailModel.invalid\n }\"\n (mousedown)=\"$event.stopPropagation()\"\n />\n <!-- Default fallback -->\n <input\n *ngSwitchDefault\n [style.height.px]=\"rowHeight - 10\"\n [style.maxHeight.px]=\"rowHeight - 10\"\n #textModel=\"ngModel\"\n #textInput\n type=\"text\"\n [(ngModel)]=\"row[col.field]\"\n name=\"{{ col.field }}\"\n required\n (blur)=\"disableEdit(row, col, textModel)\"\n (keydown.enter)=\"\n textModel.control.markAsTouched(); textInput.blur()\n \"\n autofocus\n class=\"form-control form-control-sm\"\n [ngClass]=\"{\n 'is-invalid': textModel.invalid\n }\"\n (mousedown)=\"$event.stopPropagation()\"\n />\n </ng-container>\n </div>\n\n <!-- Display mode -->\n <ng-template #viewMode>\n <div\n class=\"d-flex justify-content-between align-items-center overflow-hidden\"\n [ngClass]=\"getCellClasses(col, getNestedValue(row, col.field))\"\n >\n <!-- Field icon (for Tasks grid) -->\n <ng-container\n *ngIf=\"gridType === 'Tasks' && iconMap[col.field] && !isTotalRow\"\n >\n <span\n class=\"cursor-pointer me-2\"\n (click)=\"$event.preventDefault(); $event.stopPropagation()\"\n [inlineSVG]=\"iconMap[col.field](row, col)\"\n ></span>\n </ng-container>\n\n <!-- \u2705 Custom cell renderer support -->\n <ng-container *ngIf=\"col.cellRenderer; else defaultCell\">\n <ng-container\n [cellRenderInit]=\"col.cellRenderer\"\n [rowData]=\"row\"\n [colData]=\"col\"\n [cellValue]=\"getNestedValue(row, col?.field)\"\n (cellEvent)=\"onCellEvent($event)\"\n >\n </ng-container>\n </ng-container>\n\n <!-- \uD83E\uDDFE Default text-based cell rendering -->\n <ng-template #defaultCell>\n <div\n #cellText\n class=\"text-ellipsis flex-grow-1\"\n [title]=\"getCellTitle(row, col)\"\n >\n <!-- Normal cell -->\n <ng-container\n *ngIf=\"\n col.type !== 'image' &&\n col.field != 'image' &&\n col.field != 'invoice.invoice_image' &&\n !isTotalRow\n \"\n >\n <ng-container *ngIf=\"col.is_amount\">{{\n currencySymbol\n }}</ng-container>\n {{getCellTitle(row, col)}}\n </ng-container>\n\n <!-- Total row -->\n <ng-container *ngIf=\"isTotalRow\">\n {{ getTotalAmount(col) }}\n </ng-container>\n\n <!-- Invoice Image -->\n <ng-container *ngIf=\"col.field == 'invoice.invoice_image'\">\n <div style=\"display: flex; align-items: center; zoom: 0.7\">\n <span\n title=\"{{ getNestedValue(row, col.field) || 'Attachment' }}\"\n (click)=\"downloadAttchment(getNestedValue(row, col.field))\"\n [inlineSVG]=\"\n singleSpaAssetsPath +\n 'data-grid/document-icons/' +\n getExtention(getNestedValue(row, col.field)) +\n '.svg'\n \"\n ></span>\n </div>\n </ng-container>\n\n <!-- Image cell -->\n <ng-container *ngIf=\"col.type == 'image' && !isTotalRow\">\n <ng-container\n *ngTemplateOutlet=\"\n defaultImagePlaceholder;\n context: { row: row, col: col }\n \"\n ></ng-container>\n </ng-container>\n </div>\n <span\n *ngIf=\"\n (!col?.cellRenderer && showCellDetailsBox &&\n getNestedValue(row, col.field)?.length > 50 && col.type !== 'image') ||\n (isNestedValueArray(row, col.field) &&\n getNestedValue(row, col.field)?.length > 1)\n \"\n class=\"toggle-icon data-grid-svg-icon ms-2 cursor-pointer\"\n [inlineSVG]=\"\n isExpanded(row, col)\n ? singleSpaAssetsPath + 'data-grid/icons/chevron-down.svg'\n : singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\n \"\n (click)=\"\n $event.stopPropagation();\n toggleExpandOfLongCellText(row, col, columns, true)\n \"\n (dblclick)=\"$event.preventDefault(); $event.stopPropagation()\"\n ></span>\n </ng-template>\n <!-- Expand / Collapse icon -->\n </div>\n\n <!-- Expanded text -->\n <div\n class=\"position-absolute w-100 expanded-box\"\n *ngIf=\"isExpanded(row, col)\"\n [style.zIndex]=\"getZIndex(row, col)\"\n style=\"top: 100%; left: 0\"\n [attr.id]=\"(row.id || row._id) + '-' + (col.id || col._id)\"\n [class.invisible]=\"!showDetailsBox\"\n >\n <ng-container\n *ngTemplateOutlet=\"\n fullTextTemplate;\n context: {\n row: row,\n col: col,\n isArray: isNestedValueArray(row, col.field)\n }\n \"\n ></ng-container>\n </div>\n </ng-template>\n </div>\n </div>\n</ng-template>\n\n<!-- Headers Action List On clicking three dots -->\n\n<ng-template\n #columnMenu\n let-col=\"col\"\n let-isNestedTable=\"isNestedTable\"\n let-columns=\"columns\"\n let-section=\"section\"\n>\n <div\n class=\"column-menu three-dots-col-menu\"\n [class.visually-hidden]=\"isMenueHidden\"\n *ngIf=\"activeCol && !isThreeDotsFilterOpen\"\n [style.backgroundColor]=\"dropdownsBackgroundColor\"\n (click)=\"$event.stopPropagation()\"\n [style.color]=\"headerTextColor\"\n >\n <!-- Sort Ascending -->\n <ng-container *ngIf=\"clickedOnSortIcon\">\n <div class=\"sorting_dropdown\" [class.disable-sorting]=\"!col.is_sortable\">\n <!-- <span class=\"muted-text fs-7\" style=\"margin-left: 12px\">Sort</span> -->\n \n <!-- *ngIf=\"\n columnThreedotsMunuConfig?.showAscending &&\n (sortingConfig?.field != col.field ||\n sortingConfig?.order_by == 'desc')\n \" -->\n <div\n class=\"column-menu-item\" [class.active-sort]=\"sortingConfig?.field === col.field && sortingConfig?.order_by === 'asc'\"\n (click)=\"sortAsc(activeCol);\">\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/headerSortingIcon.svg'\"\n class=\"data-grid-svg-icon me-2 setting_dropdown\"\n ></span>\n Sort Ascending\n <span *ngIf=\"sortingConfig?.field === col.field && sortingConfig?.order_by === 'asc'\" [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/tickBlueIconNew.svg'\"\n class=\"data-grid-svg-icon setting_dropdown no-stroke\" style=\"margin-left: auto;\"\n ></span>\n </div>\n\n <!-- Sort Descending -->\n \n <!-- *ngIf=\"\n columnThreedotsMunuConfig?.showDescending &&\n (sortingConfig?.field != col.field ||\n sortingConfig?.order_by == 'asc')\n \" -->\n <div\n class=\"column-menu-item\" [class.active-sort]=\"sortingConfig?.field === col.field && sortingConfig?.order_by === 'desc'\"\n (click)=\"sortDesc(activeCol);\"\n >\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/headerSortingIcon1.svg'\"\n class=\"data-grid-svg-icon me-2 setting_dropdown\"\n ></span>\n Sort Descending\n <span *ngIf=\"sortingConfig?.field === col.field && sortingConfig?.order_by === 'desc'\" [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/tickBlueIconNew.svg'\"\n class=\"data-grid-svg-icon setting_dropdown no-stroke\" style=\"margin-left: auto;\"\n ></span>\n </div>\n\n <div\n *ngIf=\"\n sortingConfig?.field === col.field &&\n (sortingConfig?.order_by === 'asc' ||\n sortingConfig?.order_by === 'desc')\n \"\n class=\"column-menu-item\"\n (click)=\"resetSort(activeCol)\"\n >\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/resetSortIconNew.svg'\n \"\n class=\"data-grid-svg-icon me-2 setting_dropdown\"\n ></span>\n Reset Sort\n </div>\n </div>\n </ng-container>\n <!-- <div class=\"py-2 border-below three-dots-filter\">\n <div\n *ngIf=\"columnThreedotsMunuConfig?.showFilter\"\n class=\"column-menu-item three-dots-filter\"\n (click)=\"openFilteronThreeDotsClick(col)\"\n >\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\"\n class=\"data-grid-svg-icon me-2\"\n ></span>\n Filter\n </div>\n </div> -->\n\n <ng-container *ngIf=\"!clickedOnSortIcon\">\n <div class=\"sorting_dropdown\">\n <!-- <span class=\"muted-text fs-7\" style=\"margin-left: 12px\">Pin</span> -->\n \n <!-- *ngIf=\"columnThreedotsMunuConfig?.showPinleft && col?.pinned !== 'left'\" -->\n <div\n class=\"column-menu-item\" [class.active-sort]=\"col?.pinned == 'left'\"\n (click)=\"\n $event.stopPropagation();\n updateColumnPinInSourceByField(\n activeCol,\n 'left',\n isNestedTable,\n columns\n )\n \"\n >\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/pinLeftIconNew.svg'\"\n class=\"data-grid-svg-icon me-2 setting_dropdown\"\n ></span\n >Pin Left\n <span *ngIf=\"col?.pinned == 'left'\" [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/tickBlueIconNew.svg'\"\n class=\"data-grid-svg-icon setting_dropdown no-stroke\" style=\"margin-left: auto;\"\n ></span>\n </div>\n <!-- *ngIf=\"\n columnThreedotsMunuConfig?.showPinright && col?.pinned !== 'right'\n \" -->\n <div [class.active-sort]=\"col?.pinned == 'right'\"\n class=\"column-menu-item\"\n (click)=\"\n $event.stopPropagation();\n updateColumnPinInSourceByField(\n activeCol,\n 'right',\n isNestedTable,\n columns\n )\n \"\n >\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/pinRightIconNew.svg'\"\n class=\"data-grid-svg-icon data-grid-svg-icon me-2 setting_dropdown\"\n ></span\n >Pin Right\n <span *ngIf=\"col?.pinned == 'right'\" [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/tickBlueIconNew.svg'\"\n class=\"data-grid-svg-icon setting_dropdown no-stroke\" style=\"margin-left: auto;\"\n ></span>\n </div>\n\n <div\n *ngIf=\"col?.pinned\"\n class=\"column-menu-item\"\n (click)=\"\n $event.stopPropagation();\n updateColumnPinInSourceByField(\n activeCol,\n null,\n isNestedTable,\n columns\n )\n \"\n >\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/layout-three-columns.svg'\"\n class=\"data-grid-svg-icon me-2 setting_dropdown d-flex align-items-center justify-content-center\"\n ></span\n >Unpin\n </div>\n </div>\n </ng-container>\n <!-- <div\n *ngIf=\"columnThreedotsMunuConfig?.showAutosizeThisColumn\"\n class=\"column-menu-item\"\n (click)=\"autosizeColumn(activeCol)\"\n >\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/arrows-expand-vertical.svg'\n \"\n class=\"me-2\"\n ></span>\n Autosize This Column\n </div> -->\n\n <!-- Autosize All Columns -->\n <!-- <div\n *ngIf=\"columnThreedotsMunuConfig?.showAutosizeAllColumns\"\n class=\"column-menu-item\"\n (click)=\"autosizeAllColumns()\"\n >\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/arrows-angle-expand.svg'\n \"\n class=\"data-grid-svg-icon me-2\"\n ></span\n >Autosize All Columns\n </div> -->\n\n <!-- Group By -->\n <div\n *ngIf=\"showRowsGrouping\"\n class=\"column-menu-item\"\n (click)=\"groupBy(activeCol)\"\n [class.disable-sorting]=\"!col.is_groupable\"\n >\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/diagram-3.svg'\"\n class=\"data-grid-svg-icon me-2\"\n ></span>\n Group by {{ col.header }}\n </div>\n\n <!-- Choose Columns -->\n <div\n *ngIf=\"columnThreedotsMunuConfig?.showChoseColumns\"\n class=\"column-menu-item\"\n (click)=\"chooseColumns()\"\n >\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/ui-checks-grid.svg'\"\n class=\"data-grid-svg-icon me-2\"\n ></span>\n Choose Columns\n </div>\n\n <!-- Reset Columns -->\n <div\n *ngIf=\"columnThreedotsMunuConfig?.showResetColumns\"\n class=\"column-menu-item\"\n (click)=\"resetColumns()\"\n >\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/arrow-counterclockwise.svg'\n \"\n class=\"data-grid-svg-icon me-2\"\n ></span\n >Reset Columns\n </div>\n </div>\n <div\n @slideToggle\n *ngIf=\"isThreeDotsFilterOpen\"\n class=\"three-dots-col-menu position-relative\"\n [style.right.px]=\"section == 'right' ? null : col.width - 45\"\n [class.visually-hidden]=\"isMenueHidden\"\n >\n <ng-container\n *ngTemplateOutlet=\"filterMenu; context: { col: col }\"\n ></ng-container>\n </div>\n</ng-template>\n\n<!-- Filter Menue -->\n<ng-template #filterMenu let-col=\"col\">\n <div\n class=\"filter-menu-container filter-menu dropdown_outer\"\n [style.backgroundColor]=\"dropdownsBackgroundColor\"\n >\n <!-- Dropdown Type -->\n <ng-container *ngIf=\"col.type === 'dropdown'; else textFilter\">\n <div class=\"filter-dropdown-section p-1\">\n <input\n class=\"form-control form-control-sm\"\n placeholder=\"Search...\"\n type=\"search\"\n [(ngModel)]=\"addFilterColumnInput\"\n />\n\n <div class=\"form-check mb-1 mt-2 ps-4 ms-1\">\n <input\n class=\"form-check-input\"\n type=\"checkbox\"\n [checked]=\"isAllSideFilterOptionsSelected(col)\"\n (change)=\"toggleSelectAllSideFilters(col, $event)\"\n id=\"selectAll_{{ col.field }}\"\n />\n <label class=\"form-check-label\" for=\"selectAll_{{ col.field }}\">\n Select All\n </label>\n </div>\n\n <!-- <div class=\"dropdown-options ps-1\">\n <div\n class=\"form-check mb-1\"\n *ngFor=\"\n let option of selectedColumnForFilter?.column_dropdown_value\n | filter : addFilterColumnInput : 'value';\n trackBy: trackById;\n let i = index\n \"\n >\n <input\n class=\"form-check-input\"\n type=\"checkbox\"\n [id]=\"i\"\n [checked]=\"\n currentFilterSelectedIds.has(option?.id ?? option?._id ?? option)\n \"\n (change)=\"toggleSelectionInFilter(option)\"\n />\n <label class=\"form-check-label fw-semibold\" [for]=\"i\">\n {{ option?.value ?? option?.name ?? option }}\n </label>\n </div>\n </div> -->\n <cdk-virtual-scroll-viewport\n itemSize=\"32\"\n class=\"filter-viewport\"\n style=\"height: 120px\"\n >\n <div\n class=\"form-check mb-1 ms-1\"\n *cdkVirtualFor=\"\n let option of selectedColumnForFilter?.column_dropdown_value\n | filter : addFilterColumnInput : 'value';\n trackBy: trackById\n \"\n >\n <input\n class=\"form-check-input\"\n type=\"checkbox\"\n [id]=\"option?.id ?? option?._id ?? option\"\n [checked]=\"\n currentFilterSelectedIds.has(option?.id ?? option?._id ?? option)\n \"\n (change)=\"toggleSelectionInFilter(option)\"\n />\n\n <label\n class=\"form-check-label fw-semibold\"\n [for]=\"option?.id ?? option?._id ?? option\"\n >\n {{ option?.value ?? option?.name ?? option }}\n </label>\n </div>\n </cdk-virtual-scroll-viewport>\n </div>\n </ng-container>\n\n <!-- Text Filter Section -->\n <ng-template #textFilter>\n <div class=\"filter-text-section\">\n <div class=\"form-group mb-2\">\n <select\n class=\"form-select form-select-sm custom-select\"\n [(ngModel)]=\"firstCondition\"\n >\n <ng-container *ngIf=\"selectedColumnForFilter.type !== 'date'\">\n <option value=\"contain\">Contains</option>\n <option value=\"does_not_contain\">Does Not Contain</option>\n <option value=\"equal\">Equals</option>\n <option value=\"before\">Starts With</option>\n <option value=\"after\">Ends With</option>\n </ng-container>\n\n <ng-container *ngIf=\"selectedColumnForFilter.type == 'date'\">\n <option value=\"equal\">Equals To</option>\n <option value=\"not_equal\">Not Equal</option>\n <option value=\"after\">After</option>\n <option value=\"before\">Before</option>\n </ng-container>\n </select>\n </div>\n\n <input\n [type]=\"col.type == 'string' ? 'text' : col.type\"\n class=\"form-control form-control-sm mb-3\"\n placeholder=\"Value\"\n [(ngModel)]=\"firstValue\"\n #filterMenueTextchInput\n (keydown.enter)=\"applyDropdownFilter()\"\n />\n\n <div class=\"form-group mb-3 d-flex flex-row\">\n <div\n class=\"form-check form-check-inline m-0 col-4 d-flex align-items-center gap-1\"\n >\n <input\n class=\"form-check-input filter-radio-inputs\"\n type=\"radio\"\n name=\"condition\"\n [(ngModel)]=\"condition\"\n value=\"and\"\n id=\"and_{{ col.field }}\"\n (change)=\"cdr.detectChanges()\"\n />\n <label class=\"form-check-label mb-0 mt-1\" for=\"and_{{ col.field }}\"\n >AND</label\n >\n </div>\n <div\n class=\"form-check form-check-inline m-0 col-4 d-flex align-items-center gap-1 gap-1\"\n >\n <input\n class=\"form-check-input filter-radio-inputs\"\n type=\"radio\"\n name=\"condition\"\n [(ngModel)]=\"condition\"\n value=\"or\"\n id=\"or_{{ col.field }}\"\n (change)=\"cdr.detectChanges()\"\n />\n <label class=\"form-check-label mb-0 mt-1\" for=\"or_{{ col.field }}\"\n >OR</label\n >\n </div>\n <div\n class=\"form-check form-check-inline m-0 col-4 d-flex align-items-center gap-1 gap-1\"\n >\n <input\n class=\"form-check-input filter-radio-inputs\"\n type=\"radio\"\n name=\"condition\"\n [(ngModel)]=\"condition\"\n value=\"none\"\n id=\"none_{{ col.field }}\"\n (change)=\"cdr.detectChanges()\"\n />\n <label class=\"form-check-label mb-0 mt-1\" for=\"none_{{ col.field }}\"\n >None</label\n >\n </div>\n </div>\n <div @slideToggle *ngIf=\"firstValue && condition != 'none'\">\n <div class=\"form-group mb-2\">\n <select\n class=\"form-select form-select-sm custom-select\"\n [(ngModel)]=\"secondCondition\"\n >\n <ng-container *ngIf=\"selectedColumnForFilter.type !== 'date'\">\n <option value=\"contain\">Contains</option>\n <option value=\"does_not_contain\">Does Not Contain</option>\n <option value=\"equal\">Equals</option>\n <option value=\"before\">Starts With</option>\n <option value=\"after\">Ends With</option>\n </ng-container>\n\n <ng-container *ngIf=\"selectedColumnForFilter.type == 'date'\">\n <option value=\"equal\">Equals To</option>\n <option value=\"not_equal\">Not Equal</option>\n <option value=\"after\">After</option>\n <option value=\"before\">Before</option>\n </ng-container>\n </select>\n </div>\n\n <input\n [type]=\"col.type == 'string' ? 'text' : col.type\"\n class=\"form-control form-control-sm mb-3\"\n placeholder=\"Second Value\"\n [(ngModel)]=\"secondValue\"\n />\n </div>\n </div>\n </ng-template>\n\n <!-- Actions -->\n <div class=\"d-flex gap-2 mt-2\">\n <div\n class=\"primary_btn_new common_btn flex justify-content-center align-items-center w-100\"\n style=\"height: 30px\"\n (click)=\"applyDropdownFilter()\"\n >\n Apply\n </div>\n <div\n class=\"cancel_btn_new common_btn d-flex justify-content-center align-items-center w-100\"\n style=\"height: 30px\"\n (click)=\"resetSideFilter(col)\"\n >\n Reset\n </div>\n </div>\n </div>\n</ng-template>\n\n<!-- Side Menue -->\n\n<!-- Column Pannel / Pivot Mode / Searching -->\n\n<ng-template #columnPannel>\n <div class=\"column-panel-header\">\n <!-- Pivot Toggle -->\n <div\n class=\"form-check form-switch d-flex align-items-center mb-2 pivot-mode px-5 ms-2 d-none\"\n >\n <input\n class=\"form-check-input me-2\"\n type=\"checkbox\"\n id=\"pivotToggle\"\n [(ngModel)]=\"pivotMode\"\n />\n <label class=\"form-check-label\" for=\"pivotToggle\">Pivot Mode</label>\n </div>\n\n <!-- Select All & Search -->\n <div class=\"d-flex align-items-center mb-2 px-3 mt-3\">\n <span class=\"filter-icon-wrapper me-2\" *ngIf=\"showColumnsGrouping\">\n <span\n class=\"toggle-icon data-grid-svg-icon\"\n [inlineSVG]=\"\n accordionState === 'all'\n ? singleSpaAssetsPath + 'data-grid/icons/chevron-down.svg'\n : accordionState === 'some'\n ? singleSpaAssetsPath + 'data-grid/icons/dash.svg'\n : singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\n \"\n (click)=\"toggleAllAccordions()\"\n ></span>\n </span>\n <input\n type=\"checkbox\"\n class=\"form-check-input me-2\"\n [checked]=\"allColumnsSelected()\"\n (change)=\"toggleAllColumnsVisibility()\"\n />\n <input\n type=\"text\"\n class=\"form-control form-control-sm\"\n placeholder=\"Search columns...\"\n [(ngModel)]=\"columnSearch\"\n />\n </div>\n\n <!-- Separator -->\n <hr class=\"my-2\" />\n </div>\n</ng-template>\n\n<!-- Right Columns Menue -->\n\n<!-- Column Panel Item Template -->\n<ng-template #columnPanelItem let-col=\"col\">\n <!-- Group Column -->\n <ng-container *ngIf=\"col.children?.length\">\n <div class=\"column-group d-flex align-items-center mb-2\">\n <span class=\"filter-icon-wrapper me-2\">\n <span\n class=\"toggle-icon data-grid-svg-icon\"\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\n \"\n [class.rotate]=\"col.expanded\"\n (click)=\"col.expanded = !col.expanded\"\n ></span>\n </span>\n <input\n type=\"checkbox\"\n class=\"form-check-input me-2\"\n [id]=\"'group_' + col.header\"\n [checked]=\"isColumnVisible(col)\"\n (change)=\"toggleGroupVisibility(col)\"\n />\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/grid-3x2-gap.svg'\"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center me-2\"\n ></span>\n <label\n class=\"d-flex align-items-center mb-0 w-100\"\n [for]=\"'group_' + col.header\"\n style=\"cursor: pointer\"\n >\n <span class=\"text-truncate\">{{ col.header }}</span>\n </label>\n </div>\n <div *ngIf=\"col.expanded\" class=\"ps-4\">\n <ng-container *ngFor=\"let child of col.children; trackBy: trackByField\">\n <ng-container\n *ngTemplateOutlet=\"columnPanelItem; context: { col: child }\"\n ></ng-container>\n </ng-container>\n </div>\n </ng-container>\n\n <!-- Leaf Column -->\n <ng-container *ngIf=\"!col.children?.length\">\n <div class=\"d-flex align-items-center mb-2\">\n <span class=\"me-2\" style=\"width: 1.5rem\"></span>\n <input\n type=\"checkbox\"\n class=\"form-check-input me-2\"\n [(ngModel)]=\"col.is_visible\"\n [id]=\"'col_' + col.field\"\n (change)=\"onSideMenuColumnsVisibilityChange()\"\n />\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/grid-3x2-gap.svg'\"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center me-2\"\n ></span>\n <label\n class=\"d-flex align-items-center mb-0 w-100\"\n [for]=\"'col_' + col.field\"\n style=\"cursor: pointer\"\n >\n <span class=\"text-truncate\">{{ col.header }}</span>\n </label>\n </div>\n </ng-container>\n</ng-template>\n\n<!-- Columns Side Filter -->\n<ng-template #sideFilters>\n <div class=\"py-3 px-2 pe-3 h-100\">\n <div class=\"d-flex align-items-center mb-2\">\n <span class=\"filter-icon-wrapper me-2\" *ngIf=\"showColumnsGrouping\">\n <span\n class=\"toggle-icon data-grid-svg-icon\"\n [inlineSVG]=\"\n filterAccordionState === 'all'\n ? singleSpaAssetsPath + 'data-grid/icons/chevron-down.svg'\n : filterAccordionState === 'some'\n ? singleSpaAssetsPath + 'data-grid/icons/dash.svg'\n : singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\n \"\n (click)=\"toggleAllFilterAccordions()\"\n ></span>\n </span>\n <input\n type=\"text\"\n class=\"form-control form-control-sm\"\n placeholder=\"Search...\"\n [(ngModel)]=\"columnSearch\"\n />\n </div>\n <div\n class=\"overflow-auto side-filter-columns-wrapper\"\n style=\"height: calc(100% - 70px); scrollbar-width: thin\"\n >\n <ng-container\n *ngFor=\"\n let col of columns | filter : columnSearch : 'header';\n trackBy: trackByField\n \"\n >\n <ng-container\n *ngTemplateOutlet=\"filterPannelItem; context: { col: col }\"\n ></ng-container>\n </ng-container>\n </div>\n </div>\n</ng-template>\n\n<ng-template #filterPannelItem let-col=\"col\">\n <!-- Group Column -->\n <ng-container *ngIf=\"col.children?.length\">\n <div\n class=\"column-group d-flex align-items-center mb-2\"\n *ngIf=\"col.type !== 'image'\"\n >\n <!-- Chevron toggle -->\n <span class=\"filter-icon-wrapper me-2\">\n <span\n class=\"toggle-icon data-grid-svg-icon\"\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\n \"\n [class.rotate]=\"col.expandedFilter\"\n (click)=\"col.expandedFilter = !col.expandedFilter\"\n ></span>\n </span>\n\n <!-- Group label toggle -->\n <label\n class=\"d-flex align-items-center mb-0 w-100\"\n style=\"cursor: pointer\"\n (click)=\"col.expandedFilter = !col.expandedFilter\"\n >\n <span class=\"fw-bold text-truncate\"\n >{{ col.header }}\n <span\n class=\"text-primary ms-1\"\n *ngIf=\"col?.query?._ids?.length || col?.query?._first_value\"\n >*</span\n >\n </span>\n </label>\n </div>\n\n <!-- Children columns -->\n <div *ngIf=\"col.expandedFilter\" class=\"ps-4\">\n <ng-container *ngFor=\"let child of col.children; trackBy: trackByField\">\n <ng-container\n *ngTemplateOutlet=\"filterPannelItem; context: { col: child }\"\n ></ng-container>\n </ng-container>\n </div>\n </ng-container>\n\n <!-- Leaf Column -->\n <ng-container *ngIf=\"!col.children?.length\">\n <div class=\"d-flex align-items-center mb-2\" *ngIf=\"col.type !== 'image'\">\n <span\n class=\"me-2 filter-icon-wrapper me-2\"\n (click)=\"col.expandedFilter = !col.expandedFilter\"\n >\n <span\n class=\"toggle-icon data-grid-svg-icon\"\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\n \"\n [class.rotate]=\"col.expandedFilter\"\n ></span>\n </span>\n\n <label\n class=\"d-flex align-items-center mb-0 w-100\"\n style=\"cursor: pointer\"\n (click)=\"col.expandedFilter = !col.expandedFilter\"\n >\n <span class=\"text-truncate fw-bold\">{{ col.header }}</span>\n </label>\n </div>\n\n <!-- Show filter when expanded -->\n <div *ngIf=\"col.expandedFilter\" class=\"ps-4 pe-3\">\n <ng-container\n *ngTemplateOutlet=\"sideNestedFilter; context: { col: col }\"\n ></ng-container>\n </div>\n </ng-container>\n</ng-template>\n\n<!-- Side Nested Filters -->\n<ng-template #sideNestedFilter let-col=\"col\">\n <div class=\"\">\n <!-- Dropdown Type -->\n <ng-container *ngIf=\"col.type === 'dropdown'; else textFilter\">\n <div class=\"p-1\">\n <!-- Search -->\n <input\n type=\"text\"\n class=\"form-control form-control-sm mb-2\"\n placeholder=\"Search...\"\n [(ngModel)]=\"sideNestedFilterSearch\"\n />\n\n <!-- Select All -->\n <div class=\"form-check mb-1 ms-1\">\n <input\n class=\"form-check-input\"\n type=\"checkbox\"\n [checked]=\"\n col.query?._ids?.length == col?.column_dropdown_value?.length\n \"\n (change)=\"toggleSelectAllSideFilters(col, $event)\"\n id=\"selectAll_{{ col.field }}\"\n />\n <label class=\"form-check-label\" for=\"selectAll_{{ col.field }}\">\n Select All\n </label>\n </div>\n\n <!-- Options -->\n <!-- <div class=\"dropdown-options\">\n <div\n class=\"form-check mb-1 ms-1\"\n *ngFor=\"\n let option of col?.column_dropdown_value\n | filter : sideNestedFilterSearch : 'value'\n \"\n >\n <input\n class=\"form-check-input\"\n type=\"checkbox\"\n [value]=\"option\"\n [checked]=\"\n col.query?._ids?.includes(option?._id || option?.id || option)\n \"\n (change)=\"onOptionToggle(col, option)\"\n id=\"option_{{ col.field }}_{{\n option?.id || option?._id || option\n }}\"\n />\n <label\n class=\"form-check-label\"\n [for]=\"\n 'option_' +\n col.field +\n '_' +\n (option?.id || option?._id || option)\n \"\n >\n {{ option.value || option }}\n </label>\n </div>\n </div> -->\n <cdk-virtual-scroll-viewport\n itemSize=\"32\"\n class=\"dropdown-viewport\"\n style=\"height: 120px\"\n >\n <div\n class=\"form-check mb-1 ms-1\"\n *cdkVirtualFor=\"\n let option of col?.column_dropdown_value\n | filter : sideNestedFilterSearch : 'value'\n \"\n >\n <input\n class=\"form-check-input\"\n type=\"checkbox\"\n [value]=\"option\"\n [checked]=\"\n col.query?._ids?.includes(option?._id || option?.id || option)\n \"\n (change)=\"onOptionToggle(col, option)\"\n id=\"option_{{ col.field }}_{{\n option?.id || option?._id || option\n }}\"\n />\n\n <label\n class=\"form-check-label\"\n [for]=\"\n 'option_' +\n col.field +\n '_' +\n (option?.id || option?._id || option)\n \"\n >\n {{ option.value || option }}\n </label>\n </div>\n </cdk-virtual-scroll-viewport>\n\n\n <!-- Actions -->\n <!-- <div class=\"d-flex gap-2 mt-2\">\n <div\n class=\"btn btn-sm btn-primary d-flex justify-content-center align-items-center\"\n style=\"height: 22px;\"\n (click)=\"applySideFilter(col)\"\n >\n Apply\n </div>\n <div\n class=\"btn btn-sm btn-secondary d-flex justify-content-center align-items-center\" \n style=\"height: 22px;\"\n (click)=\"resetSideFilter(col)\"\n >\n Reset\n </div>\n </div> -->\n </div>\n </ng-container>\n\n <!-- Text Filter Section -->\n <ng-template #textFilter>\n <div class=\"filter-text-section\">\n <div class=\"form-group mb-2\">\n <select\n class=\"form-select form-select-sm\"\n [(ngModel)]=\"col.query.first_condition\"\n >\n <ng-container *ngIf=\"col.type !== 'date'\">\n <option value=\"contain\">Contains</option>\n <option value=\"does_not_contain\">Does Not Contain</option>\n <option value=\"equal\">Equals</option>\n <option value=\"before\">Starts With</option>\n <option value=\"after\">Ends With</option>\n </ng-container>\n\n <ng-container *ngIf=\"col.type == 'date'\">\n <option value=\"equal\">Equals To</option>\n <option value=\"not_equal\">Not Equal</option>\n <option value=\"after\">After</option>\n <option value=\"before\">Before</option>\n </ng-container>\n </select>\n </div>\n\n <input\n [type]=\"col.type == 'date' ? 'date' : 'text'\"\n class=\"form-control form-control-sm mb-3\"\n placeholder=\"Value\"\n [(ngModel)]=\"col!.query!.first_value\"\n />\n\n <div\n class=\"form-group mb-3 d-flex flex-row muted\"\n style=\"font-size: 14px\"\n >\n <div\n class=\"form-check form-check-inline m-0 col-4 d-flex align-items-center gap-1\"\n >\n <input\n class=\"form-check-input filter-radio-inputs\"\n type=\"radio\"\n name=\"condition\"\n [(ngModel)]=\"col!.query.condition\"\n value=\"and\"\n id=\"and_{{ col.field }}\"\n />\n <label class=\"form-check-label mb-0 mt-1\" for=\"and_{{ col.field }}\"\n >AND</label\n >\n </div>\n <div\n class=\"form-check form-check-inline m-0 col-4 d-flex align-items-center gap-1\"\n >\n <input\n class=\"form-check-input filter-radio-inputs\"\n type=\"radio\"\n name=\"condition\"\n [(ngModel)]=\"col!.query.condition\"\n value=\"or\"\n id=\"or_{{ col.field }}\"\n />\n <label class=\"form-check-label mb-0 mt-1\" for=\"or_{{ col.field }}\"\n >OR</label\n >\n </div>\n <div\n class=\"form-check form-check-inline m-0 col-4 d-flex align-items-center gap-1\"\n >\n <input\n class=\"form-check-input filter-radio-inputs\"\n type=\"radio\"\n name=\"condition\"\n [(ngModel)]=\"col!.query.condition\"\n value=\"none\"\n id=\"none_{{ col.field }}\"\n />\n <label\n class=\"nnonem-check-label mb-0 mt-1\"\n for=\"none_{{ col.field }}\"\n >None</label\n >\n </div>\n </div>\n <ng-container\n *ngIf=\"col?.query?.first_value && col?.query?.condition !== 'none'\"\n >\n <div class=\"form-group mb-2\">\n <select\n class=\"form-select form-select-sm\"\n [(ngModel)]=\"col!.query.second_condition\"\n >\n <ng-container *ngIf=\"col.type !== 'date'\">\n <option value=\"contain\">Contains</option>\n <option value=\"does_not_contain\">Does Not Contain</option>\n <option value=\"equal\">Equals</option>\n <option value=\"before\">Starts With</option>\n <option value=\"after\">Ends With</option>\n </ng-container>\n\n <ng-container *ngIf=\"col.type == 'date'\">\n <option value=\"equal\">Equals To</option>\n <option value=\"not_equal\">Not Equal</option>\n <option value=\"after\">After</option>\n <option value=\"before\">Before</option>\n </ng-container>\n </select>\n </div>\n\n <input\n [type]=\"col.type == 'date' ? 'date' : 'text'\"\n class=\"form-control form-control-sm mb-3\"\n placeholder=\"Second Value\"\n [(ngModel)]=\"col!.query.second_value\"\n />\n </ng-container>\n <!-- <div class=\"d-flex gap-2\">\n <div class=\"btn btn-sm btn-primary d-flex justify-content-center align-items-center\" style=\"height: 22px;\" (click)=\"applyDropdownFilter()\">apply</div>\n <div class=\"btn btn-sm btn-secondary d-flex justify-content-center align-items-center\" style=\"height: 22px;\" (click)=\"applyDropdownFilter()\">reset</div>\n\n </div> -->\n </div>\n </ng-template>\n <div\n class=\"d-flex justify-content-center gap-2 border-top\"\n style=\"height: 38px\">\n <button\n type=\"button\"\n style=\"max-height: 30px\"\n class=\"btn btn-outline-secondary btn-light border w-100 d-flex align-items-center justify-content-center mt-1\"\n (click)=\"$event.stopPropagation(); removeSideFilter(col)\">\n <span>Clear</span>\n </button>\n <button\n type=\"button\"\n style=\"max-height: 30px\"\n class=\"btn btn-primary w-100 d-flex align-items-center justify-content-center mt-1\"\n (click)=\"applySideFilter(col)\"\n [class.disabled]=\"(col?.query.condition !== 'none' && !col?.query?.second_value)\"\n [class.pe-none]=\"(col!?.query.condition !== 'none' && !col?.query?.second_value)\"\n >\n <span style=\"margin-top: -1px\">Apply</span>\n </button>\n </div>\n </div>\n</ng-template>\n\n<!-- Centr Overlay for showing the chose columns -->\n\n<div *ngIf=\"showColumnPanel\" class=\"custom-modal-overlay\">\n <div\n class=\"custom-modal-content\"\n [style.backgroundColor]=\"dropdownsBackgroundColor\"\n (click)=\"$event.stopPropagation()\"\n >\n <ng-container *ngTemplateOutlet=\"modalColumnPannel\"></ng-container>\n </div>\n</div>\n\n<!-- The existing ng-template you provided -->\n<ng-template #modalColumnPannel>\n <div class=\"column-panel-header\">\n <div\n class=\"d-flex justify-content-between align-items-center px-2 ps-3 rounded-top-2 moda-header\"\n [style.height.px]=\"48\"\n >\n Choose Columns\n <span class=\"filter-icon-wrapper\" (click)=\"closeModalColumnPanel()\"\n ><span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/x.svg'\"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span\n ></span>\n </div>\n <hr class=\"my-0\" />\n <div>\n <div class=\"d-flex align-items-center px-2 pe-3\" [style.height.px]=\"48\">\n <span class=\"filter-icon-wrapper me-2\" *ngIf=\"showColumnsGrouping\">\n <span\n class=\"toggle-icon data-grid-svg-icon\"\n [inlineSVG]=\"\n accordionState === 'all'\n ? singleSpaAssetsPath + 'data-grid/icons/chevron-down.svg'\n : accordionState === 'some'\n ? singleSpaAssetsPath + 'data-grid/icons/dash.svg'\n : singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\n \"\n (click)=\"toggleAllAccordions()\"\n ></span>\n </span>\n <input\n type=\"checkbox\"\n class=\"form-check-input me-2\"\n [checked]=\"allColumnsSelected()\"\n (change)=\"toggleAllColumnsVisibility()\"\n />\n <input\n type=\"text\"\n class=\"form-control form-control-sm\"\n placeholder=\"Search columns...\"\n [(ngModel)]=\"choseColumnsSearch\"\n />\n </div>\n\n <hr class=\"mt-0 mb-1\" />\n <div class=\"px-2 overlay-scrollable\">\n <ng-container\n *ngFor=\"\n let col of columns | filter : choseColumnsSearch : 'header';\n trackBy: trackByField\n \"\n >\n <ng-container\n *ngTemplateOutlet=\"columnPanelItem; context: { col: col }\"\n ></ng-container>\n </ng-container>\n </div>\n </div>\n </div>\n</ng-template>\n\n<ng-template #sideMenuRowGroups>\n <div class=\"d-flex flex-column h-100 d-none\">\n <div class=\"px-3 h-100\">\n <div class=\"d-flex gap-3 mb-4\">\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/justify.svg'\"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n <span>Row Groups</span>\n </div>\n <div class=\"h-50\">\n <div\n class=\"px-3 py-2 border-dashed h-100 d-flex justify-content-center align-items-center\"\n style=\"font-size: 14px\"\n >\n Drag here to set row Groups\n </div>\n </div>\n </div>\n\n <hr class=\"mt-4\" />\n\n <div class=\"px-3 h-100\">\n <div class=\"d-flex gap-3 mb-4\">\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/justify.svg'\"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n <span>Values</span>\n </div>\n <div class=\"h-50 d-flex\">\n <div\n class=\"px-3 py-2 border-dashed h-100 d-flex justify-content-center align-items-center\"\n style=\"font-size: 14px\"\n >\n Drag here aggregate\n </div>\n </div>\n </div>\n </div>\n</ng-template>\n\n<!-- *************************************************** -->\n<!-- *************************************************** -->\n<!-- *************************************************** -->\n<!-- Drag Preview Template -->\n<!-- *************************************************** -->\n<!-- *************************************************** -->\n<ng-template #dragPreview let-col>\n <div class=\"p-2 border d-flex gap-2\">\n <div>\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrows-move.svg'\"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n </div>\n <div>{{ col.header }}</div>\n </div>\n</ng-template>\n\n<!-- Drag Placeholder Template -->\n<ng-template\n #dragPlaceholder\n let-col\n let-i=\"index\"\n let-section=\"section\"\n let-draggingInGroupArea=\"draggingInGroupArea\"\n>\n <div *ngIf=\"!draggingInGroupArea\">\n <div\n *ngTemplateOutlet=\"\n headerCell;\n context: { $implicit: col, index: i, section: section }\n \"\n ></div>\n </div>\n <div *ngIf=\"draggingInGroupArea\">New Placeholder</div>\n</ng-template>\n\n<!-- Top Group Row Placeholder -->\n<ng-template #topGroupingRowPlaceholder let-col let-showChevron=\"showChevron\">\n <div class=\"d-flex gap-2\">\n <div\n class=\"d-flex gap-2 top-row-grouping-placeholder\"\n [style.backgroundColor]=\"topGroupedBadgesBackgroundColor\"\n >\n <span\n cdkDragHandle\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/grid-3x2-gap.svg'\"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n <span>{{ col.header }}</span>\n <span\n (click)=\"ungroupColumn(col)\"\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/x.svg'\"\n class=\"cursor-pointer data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n </div>\n </div>\n <div *ngIf=\"showChevron\" style=\"opacity: 0.6; font-size: 14px\">\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n </div>\n</ng-template>\n\n<ng-template\n #childHeaderPlaceholder\n let-col\n let-pinnedRight=\"pinnedRight\"\n let-i=\"index\"\n let-sections=\"sections\"\n>\n <div\n class=\"header-cell one-row-header-cells\"\n [class.border-right]=\"showVerticalBorder\"\n [style.width.px]=\"col.width\"\n [style.min-width.px]=\"col.width\"\n [style.min-height.px]=\"headerRowHeight\"\n [style.max-height.px]=\"headerRowHeight\"\n [style.fontWeight]=\"headerFontWeight\"\n >\n <div class=\"d-flex justify-content-between h-100 align-items-center w-100\">\n <div\n class=\"d-flex justify-content-between align-items-center w-100\"\n [class.flex-row-reverse]=\"pinnedRight\"\n >\n <div\n class=\"text-ellipsis h-100 d-flex align-items-center\"\n [title]=\"col.header\"\n [class.w-100]=\"pinnedRight\"\n >\n {{ col.header }}\n </div>\n\n <div\n class=\"position-relative d-flex\"\n [class.flex-row-reverse]=\"pinnedRight\"\n >\n <div class=\"three-dots p-1\" style=\"cursor: pointer\">\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/three-dots-vertical.svg'\n \"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n </div>\n\n <div class=\"resize-handle resize-test\">\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/resize-handle1.svg'\n \"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n </div>\n </div>\n </div>\n </div>\n </div>\n <div\n *ngIf=\"showFilterRow\"\n [style.backgroundColor]=\"headerBackgroundColor\"\n class=\"header-cell filter-cell\"\n [class.border-right]=\"showVerticalBorder\"\n [style.width.px]=\"col.width\"\n [style.min-width.px]=\"col.width\"\n [style.height.px]=\"headerRowHeight\"\n [style.min-height.px]=\"headerRowHeight\"\n [style.max-height.px]=\"headerRowHeight\"\n [class.border-right]=\"showVerticalBorder\"\n style=\"grid-row: 3\"\n >\n <div\n class=\"header-cell filter-cell\"\n [style.backgroundColor]=\"headerBackgroundColor\"\n [style.width.px]=\"col.width\"\n [style.min-width.px]=\"col.width\"\n [style.height.px]=\"headerRowHeight\"\n [style.min-height.px]=\"headerRowHeight\"\n [style.max-height.px]=\"headerRowHeight\"\n >\n <input\n type=\"text\"\n class=\"form-control form-control-sm\"\n placeholder=\"Filter\"\n [(ngModel)]=\"col.filterValue\"\n [readonly]=\"col?.type == 'dropdown' || col?.type == 'image'\"\n [class.disabled-search-input]=\"\n col?.type == 'dropdown' || col?.type == 'image'\n \"\n />\n <span\n class=\"filter-icon-wrapper\"\n (click)=\"activeFilterCell = col; activeCol = null\"\n ><span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span\n ></span>\n\n <div\n class=\"position-absolute\"\n *ngIf=\"activeFilterCell === col\"\n style=\"top: 100%; right: 0; z-index: 10; left: 0\"\n ></div>\n </div>\n </div>\n</ng-template>\n\n<ng-template #tableLayout>\n <div\n (click)=\"$event.stopPropagation()\"\n class=\"p-3 action_dropdown_new_design actions-dropdown mt-1 dropdown-menu show shadow custom-menu table-layout\"\n style=\"width: 320px\"\n >\n <div class=\"d-flex align-items-center mb-3\">\n <button\n class=\"btn btn-link p-0\"\n style=\"margin-left: -10px\"\n (click)=\"toggleActions('setting')\"\n >\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrow-left.svg'\"\n class=\"data-grid-svg-icon me-2\"\n ></span>\n </button>\n <h6 class=\"mb-0 ms-2 text_common_14px\">Table Layout</h6>\n </div>\n <hr class=\"my-2\" />\n <div class=\"w-100 mb-3 d-flex\" role=\"group\">\n <input\n type=\"radio\"\n class=\"btn-check layout-button-check\"\n name=\"layoutSize\"\n id=\"small\"\n autocomplete=\"off\"\n (change)=\"changeTableLayout($event, 'small')\"\n [checked]=\"selectedTableLayout == 'small'\"\n />\n <label\n class=\"border d-flex flex-column align-items-center layout-button\"\n for=\"small\"\n [ngStyle]=\"{\n color: selectedTableLayout == 'small' ? '#000' : '#727272'\n }\"\n >\n <div class=\"preview-box border mb-1\" style=\"height: 8px\"></div>\n Small\n </label>\n\n <input\n type=\"radio\"\n class=\"btn-check layout-button-check\"\n name=\"layoutSize\"\n id=\"medium\"\n autocomplete=\"off\"\n [checked]=\"selectedTableLayout == 'medium'\"\n (change)=\"changeTableLayout($event, 'medium')\"\n />\n <label\n class=\"border mx-3 d-flex flex-column align-items-center layout-button\"\n for=\"medium\"\n [ngStyle]=\"{\n color: selectedTableLayout == 'medium' ? '#000' : '#727272'\n }\"\n >\n <div class=\"preview-box border mb-1\" style=\"height: 12px\"></div>\n Medium\n </label>\n\n <input\n type=\"radio\"\n class=\"btn-check layout-button-check\"\n name=\"layoutSize\"\n id=\"large\"\n autocomplete=\"off\"\n (change)=\"changeTableLayout($event, 'large')\"\n [checked]=\"selectedTableLayout == 'large'\"\n />\n <label\n class=\"border d-flex flex-column align-items-center layout-button\"\n for=\"large\"\n [ngStyle]=\"{\n color: selectedTableLayout == 'large' ? '#000' : '#727272'\n }\"\n >\n <div class=\"preview-box border mb-1\" style=\"height: 16px\"></div>\n Large\n </label>\n </div>\n\n <hr class=\"my-2\" />\n <div class=\"d-flex justify-content-between align-items-center mb-2\">\n <span class=\"text_common_14px\">Show separators</span>\n <div class=\"form-check form-switch m-0\">\n <input\n class=\"form-check-input\"\n type=\"checkbox\"\n id=\"separators\"\n [(ngModel)]=\"showVerticalBorder\"\n (change)=\"onFontChange()\"\n />\n </div>\n </div>\n <div class=\"d-flex justify-content-between align-items-center\">\n <span class=\"text_common_14px\">Row shading</span>\n <div class=\"form-check form-switch m-0\">\n <input\n class=\"form-check-input\"\n [(ngModel)]=\"rowShadingEnabled\"\n (change)=\"toggleRowShading()\"\n type=\"checkbox\"\n id=\"rowShading\"\n />\n </div>\n </div>\n <!-- <div class=\"d-flex justify-content-between align-items-center mb-2\">\n <span>Show Side Menu</span>\n <div class=\"form-check form-switch m-0\">\n <input\n class=\"form-check-input\"\n [(ngModel)]=\"showSideMenu\"\n type=\"checkbox\"\n id=\"rowShading\"\n />\n </div>\n </div>\n <div class=\"d-flex justify-content-between align-items-center mb-2\">\n <span>Show Filter Row</span>\n <div class=\"form-check form-switch m-0\">\n <input\n class=\"form-check-input\"\n [(ngModel)]=\"showFilterRow\"\n type=\"checkbox\"\n id=\"rowShading\"\n />\n </div>\n </div> -->\n </div>\n</ng-template>\n\n<ng-template #tablePreset>\n <div\n *ngIf=\"activeSubButton !== 'save-preset'\"\n (click)=\"$event.stopPropagation()\"\n class=\"p-3 action_dropdown_new_design actions-dropdown mt-1 dropdown-menu show shadow custom-menu table-layout\"\n style=\"width: 280px\"\n >\n <!-- Header -->\n <div class=\"d-flex justify-content-between align-items-center mb-3\">\n <div class=\"d-flex align-items-center\">\n <button\n class=\"btn btn-link p-0\"\n style=\"margin-left: -10px\"\n (click)=\"toggleActions('setting')\"\n >\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrow-left.svg'\"\n class=\"data-grid-svg-icon\"\n ></span>\n </button>\n <h6 class=\"mb-0 ms-2 text_common_14px\">Table Presets</h6>\n </div>\n <!-- Save Preset Button with Dropdown -->\n <div>\n <a\n class=\"text-decoration-none text-primary\"\n type=\"button\"\n id=\"savePresetDropdown\"\n (click)=\"$event.stopPropagation(); toggleSubActions('save-preset')\"\n >\n {{ isTablePresetNotChanged ? \"Save preset\" : \"Update Preset\" }}\n </a>\n </div>\n </div>\n\n <!-- Search -->\n <div class=\"mb-3\">\n <div class=\"col-12 global-search position-relative\">\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/search.svg'\"\n class=\"data-grid-svg-icon mx-2 position-absolute icon\"\n ></span>\n <input\n class=\"form-control form-control-sm\"\n placeholder=\"Search...\"\n [(ngModel)]=\"searchTextPresetTable\"\n type=\"search\"/>\n </div>\n </div>\n\n <!-- Preset List -->\n <ng-container\n *ngIf=\"\n tableView | filter : searchTextPresetTable : 'name' as filteredList\n \"\n >\n <!-- If filteredList exists and none is default -> show fallback -->\n <div\n class=\" pb-5 overflow-auto\"\n [style.maxHeight.px]=\"dataGridContainer.offsetHeight - 250\"\n >\n <div\n class=\"cursor-pointer\"\n (click)=\"\n clearAllFilters();\n openIndex = null;\n temp_state.id = '';\n activeTopButton = '';\n curretaTablePresetForUpdate = null\n \"\n >\n <div class=\"fw-semibold\">Default View</div>\n </div>\n <div class=\"d-flex justify-content-between\">\n <small class=\"text-dark\">Created by system</small>\n <span\n *ngIf=\"!tableFilterViewId && !hasAnyDefaultView()\"\n class=\"badge bg-light text-primary ms-2\"\n >Default</span\n >\n <span\n *ngIf=\"!tableFilterViewId && !hasAnyDefaultView()\"\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/check-blue.svg'\"\n class=\"me-2\"\n ></span>\n <div\n class=\"dropdown d-flex justify-content-end\"\n *ngIf=\"tableFilterViewId\"\n ></div>\n </div>\n\n <!-- The list: render each table from filteredList -->\n <div\n class=\"list-group list-group-flush\"\n *ngFor=\"\n let table of filteredList;\n let i = index;\n trackBy: trackByTable\n \"\n >\n <!-- Item -->\n <div\n (click)=\"\n $event.stopPropagation(); openIndex = null; activeTopButton = ''\n \"\n class=\"list-group-item px-0 d-flex justify-content-between align-items-center\"\n >\n <div (click)=\"selectFilter(table); openIndex = null\">\n <div class=\"fw-semibold\" style=\"cursor: pointer\">\n {{ table?.name }}\n <!-- {{table?.is_temp}} -->\n <span\n *ngIf=\"\n (table?.is_temp && !temp_state.id) ||\n temp_state.id == table.id\n \"\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/check-blue.svg'\n \"\n class=\"me-2\"\n ></span>\n <span\n *ngIf=\"table?.is_default\"\n class=\"badge bg-light text-primary ms-2\"\n >Default</span\n >\n </div>\n <small class=\"text-dark\" *ngIf=\"table?.config?.filterNames\" [title]=\"table?.config?.filterNames\">\n {{\n table?.config?.filterNames?.length > 25\n ? (table?.config?.filterNames | slice:0:25) + '...'\n : table?.config?.filterNames\n }}\n ({{ table?.config?.totalCount }})\n </small>\n <small class=\"text-dark\" *ngIf=\"!table?.config?.filterNames\">{{ table?.createdAt | date : \"MMM d, y\" }}</small>\n </div>\n\n <div class=\"d-flex align-items-center\">\n <span\n *ngIf=\"table?.is_default\"\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/check-blue.svg'\n \"\n class=\"me-2\"\n ></span>\n\n <div class=\"dropdown\" *ngIf=\"!table?.is_default\">\n <div\n class=\"dropdown-wrapper\"\n (click)=\"$event.stopPropagation()\"\n >\n <button\n type=\"button\"\n class=\"btn-icon muted-text\"\n (click)=\"toggleMenu(i, $event)\"\n aria-haspopup=\"true\"\n [attr.aria-expanded]=\"openIndex === i\"\n >\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath +\n 'data-grid/icons/horizontal-dots.svg'\n \"\n class=\"me-2\"\n ></span>\n </button>\n\n <!-- menu -->\n <ul\n *ngIf=\"openIndex === i\"\n class=\"custom-dropdown-menu position-fixed top-auto\"\n role=\"menu\"\n [style.right.px]=\"'auto'\"\n [style.left.px]=\"dataGridContainer.offsetWidth - 100\"\n style=\"top: unset; right: unset\"\n >\n <li role=\"none\">\n <button\n role=\"menuitem\"\n class=\"dropdown-item\"\n (click)=\"\n actionPreset(table, 'setPreset'); temp_state.id = ''\n \"\n >\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/star.svg'\n \"\n class=\"me-2\"\n ></span>\n Set as default\n </button>\n </li>\n\n <li role=\"none\" *ngIf=\"!table.confirmDelete\">\n <button\n role=\"menuitem\"\n class=\"dropdown-item text-danger\"\n (click)=\"table.confirmDelete = true\"\n >\n <span\n style=\"margin-top: -4px\"\n [inlineSVG]=\"\n singleSpaAssetsPath +\n 'data-grid/icons/trash-red.svg'\n \"\n class=\"me-2\"\n ></span>\n Delete\n </button>\n </li>\n\n <li\n role=\"none\"\n *ngIf=\"table.confirmDelete\"\n class=\"confirm-block\"\n >\n <div class=\"px-3 py-2 text-center\">\n <div class=\"mb-2 text_common_16px_gray\">\n Are you sure you want to delete this view<b>?</b><br/> This action can\u2019t be undone.\n </div>\n <div class=\"d-flex gap-2\">\n <button\n class=\"cancel_btn_new common_btn\"\n (click)=\"table.confirmDelete = false\">\n Cancel\n </button>\n <button class=\"delete_btn_new common_btn\"\n (click)=\"actionPreset(table, 'deletePreset')\">\n Delete\n </button>\n </div>\n </div>\n </li>\n </ul>\n </div>\n </div>\n </div>\n </div>\n <!-- Item End Here -->\n </div>\n </div>\n </ng-container>\n </div>\n\n <div\n (click)=\"$event.stopPropagation()\"\n *ngIf=\"activeSubButton == 'save-preset'\"\n class=\"dropdown-menu p-3 badge mt-4 save-preset-dropdown mt-1\"\n aria-labelledby=\"savePresetDropdown\"\n style=\"min-width: 250px\"\n >\n <div class=\"text_common_16px mb-2\">\n {{ isTablePresetNotChanged ? \"Create New Preset\" : \"Update Preset\" }}\n </div>\n <!-- <div class=\"fs-14px mb-2\" style=\"line-height: 20px\">\n This will save the current table adjustments as a preset.\n </div> -->\n <!-- Input -->\n <div class=\"my-3\">\n <label for=\"presetName\" class=\"form-label fs-12px fw-bold\">Name</label>\n <div class=\"col-12 global-search position-relative\">\n <input\n #presetNameCtrl=\"ngModel\"\n required\n [(ngModel)]=\"presetName\"\n [ngClass]=\"{\n 'is-invalid':\n presetNameCtrl.invalid &&\n (presetNameCtrl.dirty || presetNameCtrl.touched)\n }\"\n class=\"form-control form-control-sm ps-2\"\n placeholder=\"Enter preset name\"\n type=\"text\"\n />\n </div>\n </div>\n\n <!-- Checkbox -->\n <div class=\"form-check mb-2\">\n <input\n class=\"form-check-input\"\n [(ngModel)]=\"presetFilter\"\n type=\"checkbox\"\n id=\"saveFilters\"\n />\n <label class=\"form-check-label mt-1\" for=\"saveFilters\">\n Save active filters\n </label>\n </div>\n\n <!-- Save Button -->\n <div class=\"d-flex justify-content-end gap-2\" style=\"height: 32px\">\n <button\n type=\"button\"\n style=\"height: 32px\"\n class=\"cancel_btn_new common_btn w-100 d-flex align-items-center justify-content-center\"\n (click)=\"$event.stopPropagation(); toggleActions('table-presets')\"\n style=\"margin-top: -2px\">\n <span>Cancel</span>\n </button>\n <button\n [disabled]=\"closeDropdown.preset.loading\"\n (click)=\"savePreset(presetNameCtrl)\"\n type=\"button\"\n style=\"height: 32px\"\n class=\"primary_btn_new common_btn d-flex align-items-center justify-content-center\"\n >\n <span style=\"margin-top: -2px\" *ngIf=\"isTablePresetNotChanged\">\n <ng-container *ngIf=\"!closeDropdown.preset.loading\"\n >Create</ng-container\n >\n <ng-container *ngIf=\"closeDropdown.preset.loading\"\n ><span class=\"spinner-border spinner-border-sm\"></span\n ></ng-container>\n </span>\n <span style=\"white-space: nowrap\" *ngIf=\"!isTablePresetNotChanged\"\n >Update Preset</span\n >\n </button>\n </div>\n </div>\n</ng-template>\n\n<ng-template #showHideColumns>\n <div\n (click)=\"$event.stopPropagation()\"\n class=\"p-3 action_dropdown_new_design actions-dropdown mt-1 dropdown-menu show shadow custom-menu table-layout\"\n style=\"width: 280px\"\n >\n <!-- Header -->\n <div class=\"d-flex justify-content-between align-items-center mb-2\" style=\"border-bottom: 1px solid #E0E0E0;\">\n <div class=\"d-flex align-items-center\">\n <button\n class=\"btn btn-link p-0\"\n style=\"margin-left: -10px\"\n (click)=\"toggleActions('setting')\"\n >\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrow-left.svg'\"\n class=\"data-grid-svg-icon\"\n ></span>\n </button>\n <h6 class=\"mb-0 ms-2 text_common_14px\">Columns</h6>\n </div>\n <a\n (click)=\"resetColumns()\"\n href=\"javascript:void(0)\"\n class=\"text-primary text-decoration-none\"\n >Reset</a\n >\n </div>\n\n <!-- Search -->\n <div class=\"mb-3\">\n <div class=\"col-12 global-search position-relative\">\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/search.svg'\"\n class=\"mx-2 position-absolute icon data-grid-svg-icon\"\n ></span>\n <input\n class=\"form-control form-control-sm\"\n placeholder=\"Search column\"\n type=\"search\"\n [(ngModel)]=\"topShowHideColumns\"\n />\n </div>\n </div>\n <!-- Preset List -->\n <div\n class=\"list-group list-group-flush\"\n style=\"overflow: auto; scrollbar-width: thin\"\n [style.maxHeight.px]=\"dataGridContainer.offsetHeight - 220\"\n >\n <div class=\"muted-text show-hide-table-label d-flex justify-content-between\" *ngIf=\"hasAnyVisibleColumn\">\n Show in table\n <div class=\"form-check\">\n <input\n class=\"form-check-input\"\n type=\"checkbox\"\n id=\"hide_all\"\n [checked]=\"allColumnsSelected()\"\n (change)=\"toggleAllColumnsVisibility()\"\n />\n <label class=\"form-check-label fw-semibold\" for=\"hide_all\">\n Show/Hide All \n </label>\n </div>\n </div>\n <!-- Item -->\n <ng-container\n *ngFor=\"\n let col of columns | filter : topShowHideColumns : 'header';\n trackBy: trackByField\n \"\n >\n <div\n *ngIf=\"col.is_visible\"\n class=\"list-group-item border-0 px-0 d-flex justify-content-between align-items-center\"\n >\n <div class=\"d-flex gap-1\">\n <div class=\"me-1\">\n <input type=\"checkbox\" [(ngModel)]=\"col.is_visible\" [checked]=\"col.is_visible\">\n <!-- show checkbox instead of icon -->\n <!-- <span\n *ngIf=\"!col?.pinned\"\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/grip-vertical.svg'\n \"\n class=\"cursor-grap data-grid-svg-icon\"\n (mousedown)=\"$event.preventDefault()\"\n ></span> -->\n <span\n *ngIf=\"col?.pinned\"\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/pin.svg'\n \"\n class=\"cursor-grap data-grid-svg-icon\"\n (mousedown)=\"$event.preventDefault()\"\n ></span>\n </div>\n <div class=\"fw-semibold\">\n {{ col.header }}\n </div>\n </div>\n <div\n *ngIf=\"!col?.query?.first_value && !col?.query?._ids?.length\"\n class=\"d-flex align-items-center cursor-pointer\"\n (click)=\"toggleColumnVisibility(col, false)\"\n [class.disabled]=\"visibleColumns().length <= 2 || col?.is_always_visible\"\n [class.pe-none]=\"visibleColumns().length <= 2 || col?.is_always_visible\"\n [class.opacity-50]=\"visibleColumns().length <= 2 || col?.is_always_visible\"\n >\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/columnIconNew(2).svg'\"\n class=\"data-grid-svg-icon me-2 setting_dropdown\"\n ></span>\n </div>\n <div\n *ngIf=\"col?.query?.first_value || col?.query?._ids?.length\"\n class=\"d-flex align-items-center\"\n style=\"opacity: 0.5\"\n >\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/eye.svg'\"\n class=\"data-grid-svg-icon me-2\"\n ></span>\n </div>\n </div>\n </ng-container>\n\n <!-- Item End Here -->\n\n <div\n class=\"dropdown-divider\"\n *ngIf=\"hasAnyVisibleColumn && hasAnyInVisibleColumn\"\n ></div>\n\n <div\n class=\"muted-text show-hide-table-label d-flex justify-content-between\"\n *ngIf=\"hasAnyInVisibleColumn\"\n >\n Hide in table\n <div class=\"form-check\">\n <input\n class=\"form-check-input\"\n type=\"checkbox\"\n id=\"show_all\"\n [checked]=\"allColumnsSelected()\"\n (change)=\"toggleAllColumnsVisibility()\"\n />\n <label class=\"form-check-label fw-semibold\" for=\"show_all\">\n Show/Hide All \n </label>\n </div>\n </div>\n <div class=\"list-group list-group-flush\">\n <ng-container *ngFor=\"let col of columns; trackBy: trackByField\">\n <div\n *ngIf=\"!col.is_visible\"\n class=\"list-group-item border-0 px-0 d-flex justify-content-between align-items-center\"\n >\n <div class=\"d-flex gap-1\">\n <div class=\"me-1\">\n <input type=\"checkbox\" [(ngModel)]=\"col.is_visible\" [checked]=\"col.is_visible\">\n <!-- <span\n *ngIf=\"!col?.pinned\"\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/grip-vertical.svg'\n \"\n class=\"data-grid-svg-icon cursor-grap\"\n (mousedown)=\"$event.preventDefault()\"\n ></span> -->\n <span\n *ngIf=\"col?.pinned\"\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/pin.svg'\n \"\n class=\"data-grid-svg-icon cursor-grap\"\n (mousedown)=\"$event.preventDefault()\"\n ></span>\n </div>\n <div class=\"fw-semibold\">\n {{ col.header }}\n </div>\n </div>\n <div\n class=\"d-flex align-items-center cursor-pointer\"\n (click)=\"toggleColumnVisibility(col, true)\"\n >\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/columnIconNew(2).svg'\n \"\n class=\"data-grid-svg-icon me-2 setting_dropdown\"\n ></span>\n </div>\n </div>\n </ng-container>\n </div>\n\n <!-- Item End Here -->\n </div>\n </div>\n</ng-template>\n\n<ng-template #filterColumns let-col=\"column\">\n <div\n @slideToggle\n *ngIf=\"!isFilterOpen && activeTopButton == 'filter-columns'\"\n (click)=\"$event.stopPropagation()\"\n class=\"action_dropdown_new_design actions-dropdown mt-1 show shadow custom-menu table-layout filter-columns\"\n style=\"width: 280px; right: unset; max-width: 230px\"\n [style.backgroundColor]=\"checkboxesBackgroundColor\"\n >\n <div class=\"py-2 px-3\">\n <div class=\"col-12 global-search position-relative\">\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/search.svg'\"\n class=\"data-grid-svg-icon mx-2 position-absolute icon\"\n ></span>\n <input\n class=\"form-control form-control-sm\"\n placeholder=\"Filter by\"\n type=\"search\"\n [(ngModel)]=\"addFilterColumnInput\"\n />\n </div>\n </div>\n <div\n class=\"list-group list-group-flush\"\n style=\"max-height: calc(100vh - 500px); overflow: auto\"\n >\n <ng-container\n *ngFor=\"\n let col of columns | filter : addFilterColumnInput : 'header';\n trackBy: trackByField\n \"\n >\n <div\n (click)=\"openFilter(col)\"\n *ngIf=\"\n col.is_visible &&\n !col?.query?.first_value &&\n !col?.query?._ids?.length && col.type !== 'image'\n \"\n class=\"list-group-item border-0 px-3 d-flex justify-content-between align-items-center dropdown-item cursor-pointer\"\n >\n <div class=\"d-flex align-items-center justify-content-between gap-1 w-100\">\n <!-- <div style=\"margin-top: -3px\"></div> -->\n <div class=\"fw-semibold\">\n {{ col.header }}\n </div>\n <div class=\"d-flex align-items-center justify-content-between\">\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\"\n class=\"data-grid-svg-icon me-2\"\n ></span>\n </div>\n </div>\n </div>\n </ng-container>\n </div>\n </div>\n\n <!-- Dropdown -->\n <div\n @slideToggle\n *ngIf=\"isFilterOpen && selectedColumnForFilter.type == 'dropdown'\"\n (click)=\"$event.stopPropagation()\"\n class=\"shadow actions-dropdown mt-1 show shadow custom-menu table-layout filter-columns pb-2\"\n style=\"width: 280px; right: unset; max-width: 230px\"\n [style.backgroundColor]=\"checkboxesBackgroundColor\"\n >\n <div class=\"px-3 my-2 border-below py-1 pb-2 mb-3 d-flex ps-1\">\n <span\n (click)=\"toggleActions('filter-columns'); isActiveFilterOpen = false\"\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrow-left.svg'\"\n class=\"data-grid-svg-icon me-2 cursor-pointer\"\n ></span\n ><b>{{ selectedColumnForFilter?.header }}</b>\n </div>\n <div class=\"mb-2 px-3\">\n <div\n class=\"col-12 position-relative border rounded d-flex align-items-center flex-wrap px-2 filter-serach-inpt\"\n >\n <span\n *ngFor=\"let selected of selectedFilterOptions\"\n class=\"badge d-flex align-items-center gap-1 me-1 mb-1 top-row-filter-dropdown\"\n >\n {{ selected?.value ? selected.value : selected }}\n <span\n (click)=\"toggleSelectionInFilter(selected)\"\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/cross-primary.svg'\n \"\n class=\"me-2\"\n ></span>\n </span>\n <input\n class=\"form-control form-control-sm border-0 flex-grow-1\"\n style=\"padding: 0\"\n [placeholder]=\"selectedFilterOptions?.length ? '' : 'Filter by'\"\n type=\"search\"\n [(ngModel)]=\"searchTextForFilterDropDown\"\n (keydown.backspace)=\"handleBackspace($event)\"\n />\n </div>\n </div>\n <div\n class=\"list-group list-group-flush\"\n style=\"max-height: calc(100vh - 600px); overflow: auto\"\n >\n <ng-container\n *ngFor=\"\n let col of selectedColumnForFilter.column_dropdown_value\n | filter : searchTextForFilterDropDown : 'value';\n let i = index\n \"\n >\n <div\n class=\"list-group-item border-0 px-2 d-flex justify-content-between align-items-center dropdown-item cursor-pointer\"\n >\n <div class=\"form-check\">\n <input\n class=\"form-check-input\"\n type=\"checkbox\"\n [id]=\"i\"\n [checked]=\"currentFilterSelectedIds.has(col.id || col._id || col)\"\n (change)=\"toggleSelectionInFilter(col)\"\n />\n <label class=\"form-check-label fw-semibold\" [for]=\"i\">\n {{ col?.value || col?.name || col }}\n </label>\n </div>\n </div>\n </ng-container>\n </div>\n <div\n class=\"d-flex justify-content-center gap-2 px-2 border-top\"\n style=\"height: 38px\"\n >\n <button\n type=\"button\"\n style=\"height: 32px\"\n class=\"cancel_btn_new common_btn w-100 d-flex align-items-center justify-content-center mt-1 btn-light\"\n (click)=\"$event.stopPropagation(); resetFilterChanges()\"\n >\n <span>Cancel</span>\n </button>\n <button\n type=\"button\"\n style=\"height: 32px\"\n class=\"primary_btn_new common_btn d-flex align-items-center justify-content-center mt-1\"\n (click)=\"applyDropdownFilter()\"\n >\n <span style=\"margin-top: -2px\">Save</span>\n </button>\n </div>\n </div>\n\n <!-- For Text fields and number fields-->\n\n <div\n @slideToggle\n *ngIf=\"\n isFilterOpen &&\n (selectedColumnForFilter.type == 'string' ||\n selectedColumnForFilter.type == 'number' ||\n selectedColumnForFilter.type == 'date')\n \"\n (click)=\"$event.stopPropagation()\"\n class=\"shadow actions-dropdown mt-1 show shadow custom-menu table-layout filter-columns pb-2\"\n style=\"width: 210px; right: unset; max-width: 230px\"\n [style.backgroundColor]=\"checkboxesBackgroundColor\"\n >\n <div class=\"px-3 border-below py-1 pb-2 d-flex ps-1\">\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrow-left.svg'\"\n (click)=\"toggleActions('filter-columns'); isActiveFilterOpen = false\"\n class=\"data-grid-svg-icon me-2 cursor-pointer\"\n ></span\n ><b>{{ selectedColumnForFilter?.header }}</b>\n </div>\n <div class=\"col-12 position-relative p-2 text-filter\">\n <div class=\"mb-2\">\n <select\n class=\"form-select form-select-sm custom-select border\"\n [(ngModel)]=\"firstCondition\"\n >\n <ng-container *ngIf=\"selectedColumnForFilter.type !== 'date'\">\n <option value=\"contain\">Contains</option>\n <option value=\"does_not_contain\">Does Not Contain</option>\n <option value=\"equal\">Equals</option>\n <option value=\"before\">Starts With</option>\n <option value=\"after\">Ends With</option>\n </ng-container>\n\n <ng-container *ngIf=\"selectedColumnForFilter.type == 'date'\">\n <option value=\"equal\">Equals To</option>\n <option value=\"not_equal\">Not Equal</option>\n <option value=\"after\">After</option>\n <option value=\"before\">Before</option>\n </ng-container>\n </select>\n </div>\n <div class=\"mb-2\">\n <input\n class=\"form-control form-control-sm\"\n placeholder=\"Enter first value\"\n type=\"search\"\n [type]=\"\n selectedColumnForFilter.type == 'string'\n ? 'text'\n : selectedColumnForFilter.type\n \"\n [(ngModel)]=\"firstValue\"\n (keydown.enter)=\"applyDropdownFilter()\"\n />\n </div>\n <div>\n <div class=\"d-flex my-3 d-flex flex-row\" style=\"font-size: 14px\">\n <div\n class=\"form-check form-check-inline col-4 m-0 d-flex align-items-center gap-1\"\n >\n <input\n class=\"form-check-input\"\n type=\"radio\"\n id=\"logicalAnd\"\n name=\"logicalOperator\"\n value=\"and\"\n [(ngModel)]=\"condition\"\n />\n <label class=\"form-check-label mb-0 mt-1\" for=\"logicalAnd\"\n >AND</label\n >\n </div>\n\n <div\n class=\"form-check form-check-inline col-4 m-0 d-flex align-items-center gap-1\"\n >\n <input\n class=\"form-check-input\"\n type=\"radio\"\n id=\"logicalOr\"\n name=\"logicalOperator\"\n value=\"or\"\n [(ngModel)]=\"condition\"\n />\n <label class=\"form-check-label mb-0 mt-1\" for=\"logicalOr\">OR</label>\n </div>\n\n <div\n class=\"form-check form-check-inline col-4 m-0 d-flex align-items-center gap-1\"\n >\n <input\n class=\"form-check-input\"\n type=\"radio\"\n id=\"logicalNone\"\n name=\"logicalOperator\"\n value=\"none\"\n [(ngModel)]=\"condition\"\n />\n <label class=\"form-check-label mb-0 mt-1\" for=\"logicalNone\"\n >None</label\n >\n </div>\n </div>\n\n <ng-container *ngIf=\"condition !== 'none' && firstValue\">\n <div class=\"mb-2 mt-3\">\n <!-- Second condition select -->\n <select\n class=\"form-select form-select-sm border\"\n [(ngModel)]=\"secondCondition\"\n >\n <ng-container *ngIf=\"selectedColumnForFilter.type !== 'date'\">\n <option value=\"contain\">Contains</option>\n <option value=\"does_not_contain\">Does Not Contain</option>\n <option value=\"equal\">Equals</option>\n <option value=\"before\">Starts With</option>\n <option value=\"after\">Ends With</option>\n </ng-container>\n\n <ng-container *ngIf=\"selectedColumnForFilter.type == 'date'\">\n <option value=\"equal\">Equals To</option>\n <option value=\"not_equal\">Not Equal</option>\n <option value=\"after\">After</option>\n <option value=\"before\">Before</option>\n </ng-container>\n </select>\n </div>\n\n <div class=\"mb-2\">\n <!-- Second value input -->\n <input\n [type]=\"\n selectedColumnForFilter.type == 'string'\n ? 'text'\n : selectedColumnForFilter.type\n \"\n class=\"form-control form-control-sm\"\n placeholder=\"Enter second value\"\n type=\"search\"\n [(ngModel)]=\"secondValue\"\n (keydown.enter)=\"applyDropdownFilter()\"\n />\n </div>\n </ng-container>\n </div>\n </div>\n\n <div\n class=\"d-flex justify-content-center gap-2 px-2 border-top\"\n style=\"height: 38px\">\n <button\n [disabled]=\"!currentFilterSelectedIds?.size && !firstValue\"\n type=\"button\"\n style=\"height: 32px\"\n class=\"cancel_btn_new common_btn w-100 d-flex align-items-center justify-content-center mt-1\"\n (click)=\"$event.stopPropagation(); resetTextFilterChanges()\">\n <span>Cancel</span>\n </button>\n <button\n [disabled]=\"(currentFilterSelectedIds?.size === 0 && !firstValue) || (condition !== 'none' && !secondValue)\"\n type=\"button\"\n style=\"height: 32px\"\n class=\"primary_btn_new common_btn d-flex align-items-center justify-content-center mt-1\"\n (click)=\"applyDropdownFilter()\">\n <span style=\"margin-top: -2px\">Apply</span>\n </button>\n </div>\n </div>\n</ng-template>\n\n<!-- Edit dropdown here -->\n<ng-template let-col>\n <div class=\"drop-down-edit\"></div>\n</ng-template>\n\n<ng-template\n #fullTextTemplate\n let-row=\"row\"\n let-col=\"col\"\n let-isArray=\"isArray\"\n>\n <div\n class=\"full-text-box\"\n (dblclick)=\"$event.stopPropagation(); $event.preventDefault()\"\n (click)=\"$event.stopPropagation(); $event.preventDefault()\"\n [style.maxHeight.px]=\"dataGridContainer.offsetHeight / 2\"\n >\n <ng-container *ngIf=\"!isEditing(row, col)\">\n <div\n *ngIf=\"!isArray\"\n class=\"full-text-content\"\n [style.maxHeight.px]=\"dataGridContainer.offsetHeight / 2\"\n (dblclick)=\"\n $event.stopPropagation();\n $event.preventDefault();\n enableEdit(row, col, true)\n \"\n (click)=\"$event.stopPropagation(); $event.preventDefault()\"\n >\n {{\n getNestedValue(row, col.field)?.value ||\n getNestedValue(row, col.field)?.name ||\n getNestedValue(row, col.field)\n }}\n </div>\n <div *ngIf=\"isArray\">\n <ul>\n <ng-container\n *ngFor=\"let item of getNestedValue(row, col.field); let i = index\"\n >\n <li *ngIf=\"i !== 0\">\n <ng-container>\n {{\n item?.department_name ||\n item?.roleName ||\n item?.full_name ||\n \"-\"\n }}\n </ng-container>\n </li>\n </ng-container>\n </ul>\n </div>\n </ng-container>\n <ng-container *ngIf=\"isEditing(row, col)\">\n <textarea\n (dblclick)=\"\n $event.stopPropagation();\n $event.preventDefault();\n enableEdit(row, col, true)\n \"\n #textModel=\"ngModel\"\n rows=\"4\"\n #textAreadInput\n [(ngModel)]=\"row[col.field]\"\n name=\"{{ col.field }}\"\n required\n (blur)=\"disableEdit(row, col, textModel)\"\n (keydown.enter)=\"textAreadInput.blur()\"\n autofocus\n class=\"form-control\"\n [ngClass]=\"{\n 'is-invalid': textModel.invalid\n }\"\n (mousedown)=\"$event.stopPropagation()\"\n ></textarea>\n </ng-container>\n </div>\n</ng-template>\n\n<ng-template #defaultImagePlaceholder let-row=\"row\" let-col=\"col\">\n <span\n class=\"px-2 d-flex w-100 cell-content image-placeholder\"\n [title]=\"row?.full_name || row?.name || 'N/A'\"\n >\n <ng-container\n *ngIf=\"\n row?.logo ||\n row?.assetImage ||\n row?.invoice?.invoice_image ||\n row?.invoice_image;\n else placeholder\n \"\n >\n <span\n (click)=\"fullscreenImage = row?.profile_pictures?.[4]?.path ||\n row?.logo ||\n row?.assetImage ||\n row?.invoice_image\"\n class=\"pic\"\n [style.width.px]=\"rowHeight - 10\"\n [style.height.px]=\"rowHeight - 10\"\n [class.assets-pic]=\"gridType == 'Assets'\"\n >\n <img\n [width]=\"rowHeight - 12\"\n [height]=\"rowHeight - 12\"\n [style.width.px]=\"rowHeight - 10\"\n [style.height.px]=\"rowHeight - 10\"\n [src]=\"\n row?.profile_pictures?.[4]?.path ||\n row?.logo ||\n row?.assetImage ||\n row?.invoice_image\n \"\n alt=\"icon\"\n class=\"option-icon\"\n loading=\"lazy\"\n />\n </span>\n </ng-container>\n <!-- <div\n class=\"fullscreen-overlay\"\n *ngIf=\"fullscreenImage\"\n (click)=\"fullscreenImage = null\"\n >\n <img [src]=\"fullscreenImage\" class=\"fullscreen-img\" />\n </div> -->\n\n <ng-template #placeholder>\n <span\n [ngClass]=\"getDynamicClass(row?.full_name || row?.name)\"\n class=\"pic d-flex align-items-center rounded-circle\"\n [style.width.px]=\"rowHeight - 12\"\n [style.height.px]=\"rowHeight - 12\"\n [style.fontSize.px]=\"rowHeight / 3\"\n [class.assets-pic]=\"gridType == 'Assets'\"\n >\n {{ getInitials(row?.full_name) }}\n </span>\n </ng-template>\n </span>\n</ng-template>\n\n<!-- Right Click Menue -->\n<div\n [class.invisible]=\"!positionedYet\"\n class=\"context-menu p-2\"\n *ngIf=\"actionHide && actions?.length\"\n [ngStyle]=\"{ 'top.px': yPos, 'left.px': xPos }\"\n [class.show]=\"isVisible\"\n appendTo=\"body\"\n>\n <ul>\n <li\n *ngFor=\"let action of actions\"\n class=\"rounded d-flex align-items-center\"\n (click)=\"onActionClick(action)\"\n >\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/' + action + '.svg'\"\n class=\"data-grid-svg-icon right-click-menu-icons me-2\"\n ></span>\n <span class=\"text-capitalize fw-500\">{{ action }}</span>\n </li>\n </ul>\n</div>\n\n<!-- Details Toggle from bottom -->\n\n<ng-template #nestedTableTemplate let-row>\n <div\n class=\"nested-table table table-sm w-100 mb-0 center-nested-table w-100\"\n style=\"table-layout: fixed !important\"\n #nestedTableContainer\n >\n <thead\n #nestedHeader\n [style.backgroundColor]=\"nestedTableHeaderBackgroundColor\"\n >\n <div\n cdkDropList\n [cdkDropListData]=\"row?.detail.columns\"\n cdkDropListOrientation=\"horizontal\"\n (cdkDropListDropped)=\"dropColumn($event, row)\"\n (cdkDropListSorted)=\"onNestedColSort($event, previewNestedCols)\"\n [style.height.px]=\"nestedTableHeaderRowHeight\"\n class=\"d-flex tr border-below\"\n >\n <div\n *ngFor=\"let col of row.detail.columns; let i = index\"\n [style.width.px]=\"col?.width || 250\"\n [style.minWidth.px]=\"col?.width || 250\"\n [style.maxWidth.px]=\"col?.width || 250\"\n class=\"px-4 th\"\n [attr.field]=\"col.field\"\n [style.backgroundColor]=\"nestedTableHeaderBackgroundColor\"\n cdkDrag\n >\n <div\n class=\"d-flex h-100 justify-content-between position-relative align-items-center\"\n >\n <div class=\"text-ellipsis\" (click)=\"sortNestedCol(col, row)\">\n {{ col.header }}\n </div>\n <div class=\"d-flex gap-2\">\n <span\n *ngIf=\"currentSubSortColumn == col.field\"\n [inlineSVG]=\"\n singleSpaAssetsPath +\n (col?.order_by == 'desc'\n ? 'data-grid/icons/sort-desc.svg'\n : 'data-grid/icons/sort-asc.svg')\n \"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center ms-2 start-50\"\n >\n </span>\n <!-- <div\n class=\"three-dots p-1\"\n (click)=\"openThreeDotsMenu($event, col)\"\n style=\"cursor: pointer\"\n >\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath +\n 'data-grid/icons/three-dots-vertical.svg'\n \"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n </div> -->\n\n <!-- Only show menu if this column is active -->\n <div\n class=\"position-absolute\"\n *ngIf=\"activeCol === col\"\n style=\"top: -50%; z-index: 21; left: 0\"\n >\n <ng-container\n *ngTemplateOutlet=\"\n columnMenu;\n context: {\n col: col,\n isNestedTable: true,\n columns: row?.detail.columns\n }\n \"\n ></ng-container>\n </div>\n <div\n class=\"resize-handle\"\n (click)=\"$event.stopPropagation()\"\n (mousedown)=\"\n $event.preventDefault();\n onResizeColumn($event, col);\n $event.stopPropagation()\n \"\n >\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/resize-handle1.svg'\n \"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n </div>\n </div>\n </div>\n <ng-template cdkDragPreview>\n <div class=\"p-2 border d-flex gap-2\">\n <div>\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/arrows-move.svg'\n \"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n </div>\n <div>{{ col.header }}</div>\n </div>\n </ng-template>\n </div>\n </div>\n </thead>\n <div\n [style.width.px]=\"nestedHeader.offsetWidth - 10\"\n [style.minWidth.px]=\"nestedHeader.offsetWidth - 10\"\n >\n <cdk-virtual-scroll-viewport\n [itemSize]=\"nestedTablerowHeight\"\n class=\"viewport\"\n [style.height.px]=\"\n (row?.detail?.result?.length < 5\n ? nestedTablerowHeight * row?.detail?.result?.length + 40\n : 300) + (hasHorizontalScroll ? -12 : 1)\n \"\n [style.width.px]=\"nestedHeader.offsetWidth - 10\"\n [style.minWidth.px]=\"nestedHeader.offsetWidth - 10\"\n >\n <div\n class=\"cursor-pointer border-below d-flex tr\"\n *cdkVirtualFor=\"let d of row?.detail?.result; trackBy: trackById\"\n [style.height.px]=\"nestedTablerowHeight\"\n [style.width.px]=\"nestedHeader?.offsetWidth\"\n [style.minWidth.px]=\"nestedHeader?.offsetWidth\"\n [style.backgroundColor]=\"bodyBackgroundColor\"\n (contextmenu)=\"onRightClick($event, d)\"\n >\n <div\n class=\"px-4 py-0 td\"\n *ngFor=\"let col of previewNestedCols; let j = index\"\n [style.fontSize.px]=\"nestedTablerowFontsize\"\n [attr.field]=\"col.field\"\n [style.width.px]=\"col?.width || 250\"\n [style.minWidth.px]=\"col?.width || 250\"\n [style.maxWidth.px]=\"col?.width || 250\"\n >\n <div\n [style.height.px]=\"nestedTablerowHeight - 1\"\n [style.max-width.px]=\"col?.width\"\n class=\"d-flex align-items-center\"\n >\n <!-- {{ d[col.field] || (col.is_amount ? 0 : \"-\") }} -->\n <div\n #cellText\n class=\"text-ellipsis flex-grow-1\"\n [title]=\"\n col.type === 'date'\n ? (getNestedValue(d, col.field) | date : dateFormat)\n : getNestedValue(d, col.field) || '-'\n \"\n >\n <ng-container *ngIf=\"col.type !== 'image'\">\n <ng-container *ngIf=\"col.is_amount\">{{\n currencySymbol\n }}</ng-container>\n {{\n !isNestedValueArray(d, col.field)\n ? col.type === 'date'\n ? (isDate(getNestedValue(d, col.field))\n ? (getNestedValue(d, col.field) | date: dateFormat)\n : (getNestedValue(d, col.field)?.value ||\n getNestedValue(d, col.field)?.name ||\n getNestedValue(d, col.field) ||\n '-'))\n : (getNestedValue(d, col.field)?.value ||\n getNestedValue(d, col.field)?.name ||\n getNestedValue(d, col.field) ||\n (col.is_amount ? 0: '-'))\n : (getNestedValue(d, col.field)?.[0]?.department_name ||\n getNestedValue(d, col.field)?.[0]?.roleName || getNestedValue(d, col.field)?.[0]?.full_name ||\n '-')\n }}\n </ng-container>\n <ng-container *ngIf=\"false\">\n {{ getTotalAmount(col) }}\n </ng-container>\n <ng-container *ngIf=\"col.type == 'image'\">\n <ng-container\n *ngTemplateOutlet=\"\n defaultImagePlaceholder;\n context: {\n row: d,\n col: col,\n }\n \"\n ></ng-container>\n </ng-container>\n </div>\n </div>\n </div>\n </div>\n </cdk-virtual-scroll-viewport>\n </div>\n </div>\n</ng-template>\n\n<ng-template #leftRightNestedPlaceholder let-row>\n <table\n class=\"nested-table table table-sm w-100 mb-0\"\n [style.backgroundColor]=\"bodyBackgroundColor\"\n [style.height.px]=\"\n gridType == 'Assets'\n ? (nestedTableContainer?.nativeElement?.offsetHeight ?? 0) + 12\n : (taskManagementContainer?.nativeElement?.offsetHeight ?? 0)\n \"\n >\n <!-- <div class=\"thead\">\n <div\n class=\"tr d-flex border-below\"\n [style.height.px]=\"nestedTableHeaderRowHeight\"\n [style.backgroundColor]=\"headerBackgroundColor\"\n >\n <div class=\"th\" *ngFor=\"let _ of [1, 2, 3, 4, 5]\"></div>\n </div>\n </div> -->\n <!-- <div class=\"tbody\">\n <div\n class=\"tr border-below\"\n [style.height.px]=\"nestedTablerowHeight\"\n *ngFor=\"let _ of row?.detail?.result\"\n [style.backgroundColor]=\"headerBackgroundColor\"\n >\n <div class=\"td\" *ngFor=\"let __ of [1, 2, 3, 4, 5]\" class=\"py-0\">\n <span\n [style.height.px]=\"nestedTablerowHeight\"\n [style.max-width.px]=\"nestedTablerowHeight\"\n ></span>\n </div>\n </div>\n </div> -->\n </table>\n</ng-template>\n\n<ng-template #taskManagementTemplate let-taskDetails=\"taskDetails\">\n <div\n class=\"p-4\"\n #taskManagementContainer\n [style.backgroundColor]=\"nestedTableHeaderBackgroundColor\"\n [style.fontFaimly]=\"fontFaimly\"\n >\n <div class=\"d-flex justify-content-between\">\n <div class=\"col-4\">\n <div class=\"item-title\">Description</div>\n <!-- <div class=\"item-content firstDiv\">\n {{ taskDetails.description }}\n </div> -->\n <p\n [style.fontSize]=\"bodyTextFontsSize\"\n class=\"item-content firstDiv taskDescription pe-4\"\n [innerHTML]=\"getSafeComment(taskDetails?.editor_description)\"\n (click)=\"openFullImage($event)\"\n ></p>\n </div>\n <div class=\"col-4\">\n <div class=\"item-title\">Attachments</div>\n <h5 *ngIf=\"taskDetails?.attachments?.length == 0\">\n No Attachments found\n </h5>\n <div\n *ngIf=\"taskDetails?.attachments?.length\"\n class=\"item-content d-flex flex-wrap\"\n style=\"gap: 10px\"\n >\n <a\n *ngFor=\"let attachement of taskDetails?.attachments; let i = index\"\n class=\"symbol-label fs-2 fw-semibold text-success cursor-pointer\"\n >\n <span\n title=\"{{ taskDetails?.attachments_name[i] || 'Attachment' }}\"\n (click)=\"downloadAttchment(attachement)\"\n [inlineSVG]=\"\n singleSpaAssetsPath +\n 'data-grid/document-icons/' +\n getExtention(attachement) +\n '.svg'\n \"\n >\n </span>\n </a>\n </div>\n </div>\n <div class=\"col-4\">\n <div class=\"item-title\">\n Comments ({{ taskDetails?.comments?.length }})\n </div>\n <h5 *ngIf=\"taskDetails?.comments?.length == 0\">No Comments found</h5>\n <div *ngIf=\"taskDetails?.comments?.length\" class=\"item-content\">\n <div class=\"comment\" *ngFor=\"let comment of taskDetails.comments\">\n <div class=\"d-flex align-items-center pe-3\">\n <img\n class=\"pic image-input-wrapper\"\n [style.width.px]=\"rowHeight - 12\"\n [style.height.px]=\"rowHeight - 12\"\n *ngIf=\"comment?.comment_by.logo\"\n src=\"{{ comment?.comment_by.logo }}\"\n alt=\"{{ comment.comment_by.full_name }}\"\n />\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> -->\n <span\n *ngIf=\"!comment?.comment_by.logo\"\n [ngClass]=\"getDynamicClass(comment.comment_by.full_name)\"\n class=\"pic d-flex align-items-center rounded-circle\"\n [style.width.px]=\"rowHeight - 12\"\n [style.height.px]=\"rowHeight - 12\"\n [style.fontSize.px]=\"rowHeight / 3\"\n title=\"{{ comment.comment_by.full_name }}\"\n >\n {{ getInitials(comment.comment_by.full_name) }}\n </span>\n </div>\n <div>\n <div class=\"comment-author fs-14px\">\n {{ comment?.comment_by.full_name }}\n </div>\n <div\n class=\"comment-content forCommentImg\"\n [innerHTML]=\"getSafeComment(comment.comment)\"\n ></div>\n <div class=\"comment-timestamp\">\n {{ comment.comment_date | date }}\n </div>\n <div class=\"comment-timestamp\">\n Replies: ({{ comment.replies.length }})\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n</ng-template>", styles: ["@charset \"UTF-8\";@import\"bootstrap/dist/css/bootstrap.min.css\";:host,:host *{font-family:Inter,sans-serif!important}.data-grid-table-wrapper{height:100%;width:100%;border:1px solid #E0E0E0;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:0 0 0 8px;font-weight:700;border-bottom:1px solid #E0E0E0;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 #E0E0E0}.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}:host ::ng-deep .resize-handle svg{stroke-width:2px}.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 #E0E0E0}.hovered-row{background-color:#ccc}.checkbox-row{border-bottom:#E0E0E0}.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 #E0E0E0;z-index:unset}.left-pinned{left:0}.right-pinned{right:0;border-left:1px solid #E0E0E0}.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 #E0E0E0!important}.right-pinned-body{right:0;border-left:1px solid #E0E0E0}.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%}.select-all-checkbox-cell input{width:16px;height:14px}.border-below{border-bottom:1px solid #E0E0E0!important}.figmaIconSize.data-grid-svg-icon{width:24px!important;height:24px!important}.actions-dropdown .list-group .list-group-item{color:#1b1f22!important}.productSortingDropdownMenu{width:220px!important}.three-dots{width:24px;height:24px;display:flex;justify-content:center;align-items:center;border-radius:6px;margin-right:4px;margin-left:2px;cursor:pointer}.three-dots:hover,.three-dots.threeDotActive{background-color:#0084ff1a;padding:5px}.rotated-180{transform:scaleY(-1)}.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:200px;border:1px solid #ddd;box-shadow:0 0 12px #00000014;border:1px solid #E0E0E0;padding:4px 0;font-size:14px;position:fixed;border-radius:8px}.column-menu-item{padding:8px 12px;cursor:pointer;display:flex;align-items:center;transition:background-color .2s ease}.column-menu-item.active-sort,.column-menu-item:hover{background-color:#0084ff1a}.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 #E0E0E0;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 #E0E0E0;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 #E0E0E0;font-size:14px}.border-start{border-left:1px solid #E0E0E0!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 #E0E0E0;padding-left:32px}.fake-horizintal-scrollbar{position:relative;bottom:17px;overflow-x:auto;overflow-y:hidden;height:17px}.border-dashed{border:1px dashed #E0E0E0}.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 #E0E0E0!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 #E0E0E0}.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{width:100%;display:flex!important;align-items:center!important;height:32px;max-width:335px}.global-search span{margin-top:0!important;top:8px}.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 #E0E0E0!important;border-radius:8px!important}.custom-menu{width:250px;border-radius:8px;padding:4px 0;background-color:#fff}.custom-menu.setting_dropdown_menu{width:270px}.custom-menu .dropdown-item{font-size:14px;padding:8px 14px;color:#1b1f22!important;font-weight:400}.custom-menu .dropdown-item:hover{background-color:#0084ff1a;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 #E0E0E0!important;background-color:#fff}.action_dropdown_new_design{background:#fff;border-radius:8px!important;border:1px solid #E0E0E0!important;box-shadow:0 2px 12px #00000014}.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{border-color:#0084ff!important;background-color:#f5f5f5!important;color:#1b1f22!important}#small:checked+label .preview-box{background-color:#fff!important}#medium:checked+label{border-color:#0084ff!important;background-color:#f5f5f5!important;color:#1b1f22!important}#medium:checked+label .preview-box{background-color:#fff!important}#large:checked+label{border-color:#0084ff!important;background-color:#f5f5f5!important;color:#1b1f22!important}#large:checked+label .preview-box{background-color:#fff!important}.btn-check:checked+.btn{background-color:transparent!important;border-color:#007cf5!important}.layout-button{padding:8px 6px!important;width:82px;border-radius:8px!important;color:#1b1f22!important;height:60px;margin-bottom:0!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:14px;color:#1b1f22}.page-size select{padding:3px 6px;border:1px solid #E0E0E0;border-radius:6px;background:#fff;font-size:13px}.page-buttons{display:flex;gap:4px;margin-left:auto;align-items:center}.page-buttons button{padding:7px 11px;background:#fff;border-radius:4px;cursor:pointer;font-size:13px;line-height:1.2;border:0;color:#6a6b6d}.page-buttons button.active{font-weight:400;border:1px solid #E0E0E0;border-radius:8px;font-size:14px;color:#1b1f22}.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 #E0E0E0}.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}.table-layout .dropdown-item{border-radius:0!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;font-size:14px;font-weight:400;color:#1b1f22;background:#ebebeb}.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 span:not(.no-stroke) svg,:host ::ng-deep .three-dots-col-menu span:not(.no-stroke) svg path{stroke:#000!important}:host ::ng-deep .ascendingAppliedIcon svg{stroke:#006fd6}.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;justify-content:center;z-index:1050;border:1px solid #dedede;border-radius:8px;padding:12px 14px;box-shadow:0 2px 8px #00000026}.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:4px!important;height:24px;align-items:center;width:-moz-fit-content;width:fit-content}.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 #E0E0E0}.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}.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}.card-outer{border:1px solid var(--semantics-border-subtle-secondary, #E0E0E0);border-radius:16px;padding:16px;background-color:#fff}.consumerDropdownButton{height:32px;display:flex;align-items:center}a.grid-header-icon:hover{background:#e0e0e0;width:32px;height:32px;border-radius:8px;transition:none}a.grid-header-icon{width:32px;height:32px}.action-buttons-row.active a.grid-header-icon,a.grid-header-icon.show{background-color:#e0e0e0;border-radius:8px}.data-grid-svg-icon.setting_dropdown{width:32px!important;height:32px!important}.new_design_dropdown .dropdown_main_button{color:#6a6b6d;text-decoration:none}.new_design_dropdown ul{border-radius:8px!important;border:1px solid #E0E0E0!important;box-shadow:0 0 12px #00000014!important}.new_design_dropdown ul li{color:#1b1f22!important;height:32px}.new_design_dropdown ul li:hover{background:#0084ff1a!important}.new_design_dropdown ul li a.dropdown-item.hover_dropdown_bg{height:inherit;border-radius:6px;padding:6px 10px;color:#1b1f22!important;font-size:14px;font-weight:400}.new_design_dropdown ul li a.dropdown-item.hover_dropdown_bg .new_old_filter{display:inline-block;width:24px;height:24px}.new_design_dropdown ul li a.dropdown-item.hover_dropdown_bg label,.new_design_dropdown ul li a.dropdown-item.hover_dropdown_bg span.newest,.new_design_dropdown ul li a.dropdown-item.hover_dropdown_bg span.oldest{padding-left:5px}.new_design_dropdown ul li a.dropdown-item.hover_dropdown_bg:hover{background-color:transparent!important}.new_design_dropdown ul li .action_dropdown{padding:6px 16px}.new_design_dropdown ul li.active-filter{background-color:#0084ff1a}.new_design_dropdown.hide_arrow .dropdown-toggle:after{display:none}.new_design_dropdown.hide_arrow ul li a label{line-height:1}.dropdown_main_button{border-radius:8px;transition:none;padding:5px 10px}.dropdown_main_button:hover,.dropdown_main_button.show{background:#e0e0e0}.sorting_icon_input{width:24px;height:24px;display:flex;align-items:center;justify-content:center}.sorting_dropdown .column-menu-item{padding:0 6px!important;color:#1b1f22!important;font-size:14px!important;font-weight:400!important}.greenBgHover{background:#0084ff1a!important;border-radius:6px!important}.cancel_btn_new{font-weight:400!important;font-size:14px!important;color:#1b1f22!important;border:none;box-shadow:none;background:transparent;height:32px;padding:3px 14px;display:flex;align-items:center;justify-content:center}.primary_btn_new{font-weight:500!important;font-size:14px!important;color:#fff!important;background:#0084ff;border:none;box-shadow:none;height:32px;padding:3px 14px;display:flex;align-items:center;justify-content:center;border-radius:6px}.dropdown_outer{border:1px solid #E0E0E0;box-shadow:0 2px 12px #00000014;border-radius:8px;font-size:14px}.text_common_14px{font-size:14px;font-weight:400;color:#1b1f22}.text_common_16px{font-size:16px;font-weight:500;color:#1b1f22}.page_refresh{font-size:13px;font-weight:400;color:#6a6b6d}\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: "pipe", type: i6.SlicePipe, name: "slice" }, { kind: "pipe", type: i6.DatePipe, name: "date" }, { kind: "pipe", type: FilterPipe, name: "filter" }], animations: [
|
|
6494
6103
|
trigger('accordionToggle', [
|
|
6495
6104
|
state('collapsed', style({ height: '0px', overflow: 'unset' })),
|
|
6496
6105
|
state('expanded', style({ height: '*', overflow: 'unset' })),
|
|
@@ -6706,8 +6315,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
|
|
|
6706
6315
|
], { optional: true })
|
|
6707
6316
|
]),
|
|
6708
6317
|
])
|
|
6709
|
-
], 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 *ngIf=\"paginationConfig\"\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"] }]
|
|
6710
|
-
}], 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 }
|
|
6318
|
+
], template: "<div class=\"position-relative h-100 card-outer\">\n <div class=\"d-flex justify-content-between mb-3 align-items-center position-relative\">\n <div class=\"d-flex gap-2\">\n <div class=\"nav nav-tabs\" *ngIf=\"true\">\n <div class=\"nav nav-tabs\" id=\"nav-tab\" role=\"tablist\">\n <span\n *ngFor=\"let tab of tabs; let i = index\"\n (click)=\"setActiveTab(tab)\"\n class=\"nav-link cursor-pointer\"\n [class.active]=\"activeTab == tab\"\n >\n {{ tab }}\n </span>\n </div>\n </div>\n <div class=\"new_design_dropdown hide_arrow\">\n <a href=\"JavaScript:void(0)\" (click)=\"activeFilter('all')\" [class.active-filter]=\"activeFilterType === 'all'\"\n class=\"d-flex align-items-center justify-content-center dropdown_main_button\">\n All\n </a>\n </div>\n <div>\n <div class=\"btn-group new_design_dropdown hide_arrow\">\n <a href=\"JavaScript:void(0)\" data-bs-toggle=\"dropdown\" aria-expanded=\"false\" data-bs-auto-close=\"outside\"\n class=\"d-flex align-items-center dropdown-toggle justify-content-center dropdown_main_button\">\n Unfulfilled\n </a>\n <ul class=\"dropdown-menu\">\n <li>\n <a class=\"dropdown-item hover_dropdown_bg d-flex align-items-center\" href=\"javascript:void(0)\">\n <div>\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/resetIconNew.svg'\"\n class=\"svg-icon svg-icon-2\"\n ></span>\n </div>\n <span> Reset</span>\n </a>\n </li>\n <li>\n <a class=\"dropdown-item hover_dropdown_bg d-flex align-items-center\" href=\"javascript:void(0)\">\n <div>\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/updatePresetIconNew.svg'\"\n class=\"svg-icon svg-icon-2\"\n ></span>\n </div>\n <span> Update and Re-save</span>\n </a>\n </li>\n <hr class=\"mt-1\">\n <li>\n <a class=\"dropdown-item hover_dropdown_bg d-flex align-items-center\" href=\"javascript:void(0)\">\n <div>\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/infoIconNew.svg'\"\n class=\"svg-icon svg-icon-2\"\n ></span>\n </div>\n <span> Rename</span>\n </a>\n </li>\n <li>\n <a class=\"dropdown-item hover_dropdown_bg d-flex align-items-center\" href=\"javascript:void(0)\">\n <div>\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/duplicateIconNew.svg'\"\n class=\"svg-icon svg-icon-2\"\n ></span>\n </div>\n <span>Duplicate</span>\n </a>\n </li>\n <li>\n <a class=\"dropdown-item hover_dropdown_bg d-flex align-items-center\" href=\"javascript:void(0)\">\n <div>\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/trashIconNew.svg'\"\n class=\"svg-icon svg-icon-2\"\n ></span>\n </div>\n <span class=\"text-danger\">Delete</span>\n </a>\n </li>\n </ul>\n </div>\n </div>\n <div>\n <div class=\"btn-group new_design_dropdown hide_arrow\">\n <a href=\"JavaScript:void(0)\" data-bs-toggle=\"dropdown\" aria-expanded=\"false\" data-bs-auto-close=\"outside\"\n class=\"d-flex align-items-center dropdown-toggle justify-content-center dropdown_main_button\">\n Unpaid\n </a>\n <ul class=\"dropdown-menu\">\n <li>\n <a class=\"dropdown-item hover_dropdown_bg d-flex align-items-center\" href=\"javascript:void(0)\">\n <div>\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/infoIconNew.svg'\"\n class=\"svg-icon svg-icon-2\"\n ></span>\n </div>\n <span> Test Type</span>\n </a>\n </li>\n </ul>\n </div>\n </div>\n </div>\n <div class=\"d-flex gap-1 align-items-center table-right-top-actions\">\n <div class=\"global-search position-relative\" [style.width.px]=\"350\">\n <span *ngIf=\"enableGlobalSearch\"\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/search.svg'\"\n class=\"data-grid-svg-icon ms-2 mt-0 position-absolute icon\" style=\"top: 8px;\"\n ></span>\n <input #globalSearchInput\n *ngIf=\"enableGlobalSearch\"\n class=\"form-control\"\n placeholder=\"Search\"\n [(ngModel)]=\"tableSearch\"\n (keydown.enter)=\"onGlobalSearch()\"\n (input)=\"onSearchInput($event)\"\n type=\"search\"\n />\n </div>\n <!-- <ng-container *ngFor=\"let button of buttons\">\n <div\n class=\"d-flex align-items-center gap-2 action-buttons-row\"\n *ngIf=\"button?.has_permission\"\n >\n <a\n href=\"JavaScript:void(0)\"\n (click)=\"onActionButtonClick(button.name)\"\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\"\n >\n <span\n *ngIf=\"button.is_showIcon\"\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/' + button.icon + '.svg'\n \"\n class=\"svg-icon svg-icon-2\"\n ></span>\n <span\n class=\"label-hidden text-white\"\n [class.ms-0]=\"button.is_showIcon\"\n >{{ button?.name }}</span\n >\n </a>\n </div>\n </ng-container> -->\n <div *ngIf=\"!showFilterRow\"\n class=\"cursor-pointer position-relative action-buttons-row\"\n (click)=\"toggleOpenFilter()\"\n [class.active]=\"showFilters\">\n <a href=\"JavaScript:void(0)\"\n class=\"p-0 d-flex align-items-center justify-content-center grid-header-icon\">\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/filterIconNew.svg'\" class=\"svg-icon svg-icon-2\"></span>\n </a>\n <span *ngIf=\"activeFilteredColumns?.length\"\n style=\"\n width: 7px;\n height: 7px;\n box-shadow: 0px 0px 3px #0022ff;\n background-color: rgb(0, 60, 255);\n position: absolute;\n right: 8px;\n top: 6px;\n \"\n class=\"rounded-circle d-block\"\n ></span>\n </div>\n <div class=\"cursor-pointer d-none\"\n (click)=\"toggleActions('advance-filter')\"\n [class.active]=\"activeTopButton === 'advance-filter'\">\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/zoom-charge.svg'\"\n class=\"data-grid-svg-icon top-icon me-2\"\n ></span>\n </div>\n <div class=\"cursor-pointer actions-buttons-row\">\n <div class=\"btn-group new_design_dropdown hide_arrow\">\n <a href=\"JavaScript:void(0)\" data-bs-toggle=\"dropdown\" aria-expanded=\"false\" data-bs-auto-close=\"outside\"\n class=\"p-0 d-flex align-items-center dropdown-toggle justify-content-center grid-header-icon\">\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/sortingIconNew.svg'\"\n class=\"svg-icon svg-icon-2\"\n ></span>\n </a>\n <ul class=\"dropdown-menu dropdown-menu-left productSortingDropdownMenu\">\n <li>\n <a class=\"dropdown-item hover_dropdown_bg d-flex align-items-center\" href=\"javascript:void(0)\">\n <div class=\"sorting_icon_input\">\n <input class=\"form-check-input\" type=\"radio\" name=\"exampleRadios\" id=\"productName\" value=\"option1\" checked>\n </div>\n <label class=\"form-check-label mb-0 mt-1\" for=\"productName\">\n Product Name\n </label>\n </a>\n </li>\n <li>\n <a class=\"dropdown-item hover_dropdown_bg d-flex align-items-center\" href=\"javascript:void(0)\">\n <div class=\"sorting_icon_input\">\n <input class=\"form-check-input\" type=\"radio\" name=\"exampleRadios\" id=\"createdDate\" value=\"option1\" checked>\n </div>\n <label class=\"form-check-label mb-0 mt-1\" for=\"createdDate\">\n Created Date\n </label>\n </a>\n </li>\n <li>\n <a class=\"dropdown-item hover_dropdown_bg d-flex align-items-center\" href=\"javascript:void(0)\">\n <div class=\"sorting_icon_input\">\n <input class=\"form-check-input\" type=\"radio\" name=\"exampleRadios\" id=\"updatedDate\" value=\"option1\" checked>\n </div>\n <label class=\"form-check-label mb-0 mt-1\" for=\"updatedDate\">\n Updated Date\n </label>\n </a>\n </li>\n <li>\n <a class=\"dropdown-item hover_dropdown_bg d-flex align-items-center\" href=\"javascript:void(0)\">\n <div class=\"sorting_icon_input\">\n <input class=\"form-check-input\" type=\"radio\" name=\"exampleRadios\" id=\"productType\" value=\"option1\" checked>\n </div>\n <label class=\"form-check-label mb-0 mt-1\" for=\"productType\">\n Product Type\n </label>\n </a>\n </li>\n <hr class=\"my-2\" style=\"border: 1px solid #E0E0E0;\">\n <li class=\"d-flex\" (click)=\"activeFilter('newest')\" [class.active-filter]=\"activeFilterType === 'newest'\">\n <a class=\"dropdown-item hover_dropdown_bg d-flex align-items-center\" href=\"javascript:void(0)\">\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrowupIconNew.svg'\"\n class=\"svg-icon svg-icon-2 mb-1 new_old_filter\"\n ></span>\n <span class=\"mt-1 newest\">Oldest First</span>\n </a>\n <div *ngIf=\"activeFilterType === 'newest'\">\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/tickIconNew.svg'\"\n class=\"svg-icon svg-icon-2 mb-1\"\n ></span>\n </div>\n </li>\n <li class=\"d-flex\" (click)=\"activeFilter('oldest')\" [class.active-filter]=\"activeFilterType === 'oldest'\">\n <a class=\"dropdown-item hover_dropdown_bg d-flex align-items-center\" href=\"javascript:void(0)\">\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrowdownIconNew.svg'\"\n class=\"svg-icon svg-icon-2 mb-1 new_old_filter\"\n ></span>\n <span class=\"mt-1 oldest\">Newest First</span>\n </a>\n <div *ngIf=\"activeFilterType === 'oldest'\">\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/tickIconNew.svg'\"\n class=\"svg-icon svg-icon-2 mb-1\"\n ></span>\n </div>\n </li>\n </ul>\n </div>\n </div>\n <div class=\"cursor-pointer action-buttons-row\"\n (click)=\"toggleActions('setting')\"\n [class.active]=\"\n activeTopButton === 'setting' ||\n activeTopButton === 'table-layout' ||\n activeTopButton === 'table-presets' ||\n activeTopButton === 'show-hide-columns'\">\n <!-- <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/settings-2.svg'\"\n class=\"data-grid-svg-icon top-icon me-2\"\n ></span> -->\n\n <a href=\"JavaScript:void(0)\"\n class=\"p-0 d-flex align-items-center justify-content-center grid-header-icon\">\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/settingIconNew.svg'\"\n class=\"svg-icon svg-icon-2\"\n ></span>\n </a>\n\n <div *ngIf=\"activeTopButton === 'setting'\"\n class=\"actions-dropdown mt-1 actions-dropdown-setting\"\n style=\"position: absolute\">\n <div class=\"dropdown-menu show shadow custom-menu setting_dropdown_menu\">\n <!-- Table Layout -->\n <a class=\"dropdown-item py-0 px-2 d-flex justify-content-between align-items-center cursor-pointer\"\n (click)=\"$event.stopPropagation(); toggleActions('table-layout')\">\n <span class=\"d-flex justify-content-between align-items-center\">\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/layoutIconNew.svg'\n \"\n class=\"data-grid-svg-icon setting_dropdown\"\n ></span>\n Table Layout</span\n >\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\n \"\n class=\"data-grid-svg-icon d-flex align-items-center justify-content-center\"\n ></span>\n </a>\n <!-- Table Presets -->\n <a (click)=\"$event.stopPropagation(); toggleActions('table-presets')\"\n class=\"dropdown-item py-0 px-2 d-flex justify-content-between align-items-center cursor-pointer\">\n <span class=\"d-flex align-items-center justify-content-center\">\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/list-details.svg'\n \"\n class=\"data-grid-svg-icon setting_dropdown d-flex align-items-center justify-content-center\"\n ></span>\n Table Presets</span\n >\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\n \"\n class=\"data-grid-svg-icon d-flex align-items-center justify-content-center\"\n ></span>\n </a>\n\n <!-- Columns -->\n <a *ngIf=\"!showSideMenu\" (click)=\"$event.stopPropagation(); toggleActions('show-hide-columns')\"\n class=\"dropdown-item py-0 px-2 d-flex justify-content-between align-items-center cursor-pointer\">\n <span class=\"d-flex align-items-center justify-content-center\"><span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/eyeIconNew.svg'\"\n class=\"data-grid-svg-icon setting_dropdown me-2\"\n ></span>\n Columns</span>\n <div class=\"d-flex align-items-center gap-2\">\n <span class=\"muted-text\">{{ columnsCount }}</span>\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\n \"\n class=\"data-grid-svg-icon d-flex align-items-center justify-content-center\"\n ></span>\n </div>\n </a>\n\n <a (click)=\"autosizeAllColumns()\" class=\"dropdown-item py-0 px-2 d-flex justify-content-between align-items-center cursor-pointer\">\n <span class=\"d-flex align-items-center justify-content-center\"><span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/resizeIconNew.svg'\"\n class=\"data-grid-svg-icon setting_dropdown me-2\"></span>\n <span>Autosize all columns</span>\n </span>\n <!-- <div class=\"d-flex align-items-center gap-2\">\n <div class=\"form-check form-switch\">\n <input class=\"form-check-input\" type=\"checkbox\" id=\"flexSwitchCheckChecked\">\n <label class=\"form-check-label\" for=\"flexSwitchCheckChecked\"></label>\n </div>\n </div> -->\n </a>\n\n <a class=\"dropdown-item py-0 px-2 d-flex justify-content-between align-items-center cursor-pointer\">\n <span class=\"d-flex align-items-center justify-content-center\"><span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/multicellNew.svg'\"\n class=\"data-grid-svg-icon setting_dropdown me-2\"></span>\n <span>Multi-cell tooltip mode</span>\n </span>\n <!-- <div class=\"d-flex align-items-center gap-2\">\n <div class=\"form-check form-switch\">\n <input class=\"form-check-input\" type=\"checkbox\" id=\"flexSwitchCheckChecked\">\n <label class=\"form-check-label\" for=\"flexSwitchCheckChecked\"></label>\n </div>\n </div> -->\n </a>\n\n <div class=\"dropdown-divider\"></div>\n\n <!-- Filter -->\n <!-- <a class=\"dropdown-item py-0 px-2 d-flex align-items-center cursor-pointer\"\n (click)=\"toggleOpenFilter(); activeTopButton = '';\"\n *ngIf=\"!showFilterRow\">\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/filterIconNew.svg'\n \"\n class=\"data-grid-svg-icon setting_dropdown d-flex align-items-center justify-content-center cursor-pointer\"\n ></span>\n Filter\n </a> -->\n\n <!-- Download -->\n <a class=\"dropdown-item py-0 px-2 d-flex align-items-center cursor-pointer\"\n (click)=\"downloadCsv('csv')\">\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/exportIconNew.svg'\"\n class=\"data-grid-svg-icon setting_dropdown d-flex align-items-center justify-content-center cursor-pointer\"\n ></span>\n CSV Export\n </a>\n <a *ngIf=\"enableExport\"\n class=\"dropdown-item py-0 px-2 d-flex align-items-center cursor-pointer\"\n (click)=\"downloadCsv('xlsx')\">\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/exportIconNew.svg'\n \"\n class=\"data-grid-svg-icon setting_dropdown d-flex align-items-center justify-content-center cursor-pointer\"\n ></span>\n Excel Export\n </a>\n <!-- Font Family & Font Size -->\n <div class=\"px-2 pb-2 pt-2\">\n <div class=\"d-flex gap-2\">\n <!-- <select\n class=\"form-select form-select-sm\"\n [(ngModel)]=\"fontFaimly\"\n (change)=\"onFontChange()\"\n >\n <option *ngFor=\"let font of fontFamilies\" [value]=\"font\">\n {{ font }}\n </option>\n </select> -->\n\n <!-- Font Size -->\n <!-- <select\n class=\"form-select form-select-sm\"\n (change)=\"onFontChange()\"\n [(ngModel)]=\"bodyTextFontsSize\"\n >\n <option *ngFor=\"let size of fontSizes\" [value]=\"size\">\n {{ size }}\n </option>\n </select> -->\n </div>\n </div>\n </div>\n </div>\n\n <!-- Table Layout -->\n\n <ng-container *ngIf=\"activeTopButton === 'table-layout'\">\n <div\n *ngTemplateOutlet=\"tableLayout\"\n class=\"actions-dropdown mt-1\"\n style=\"position: absolute\"\n ></div>\n </ng-container>\n\n <!-- Table Presets -->\n <ng-container *ngIf=\"activeTopButton === 'table-presets'\">\n <div\n *ngTemplateOutlet=\"tablePreset\"\n class=\"actions-dropdown mt-1\"\n style=\"position: absolute\"\n ></div>\n </ng-container>\n\n <!-- Table Presets -->\n <ng-container *ngIf=\"activeTopButton === 'show-hide-columns'\">\n <div\n *ngTemplateOutlet=\"showHideColumns\"\n class=\"actions-dropdown mt-1\"\n style=\"position: absolute\"\n ></div>\n </ng-container>\n </div>\n <div class=\"cursor-pointer actions-buttons-row\">\n <div class=\"btn-group new_design_dropdown\">\n <button type=\"button\" class=\"primary_btn_new common_btn dropdown-toggle consumerDropdownButton px-2\" data-bs-toggle=\"dropdown\" aria-expanded=\"false\">\n Actions\n </button>\n <ul class=\"dropdown-menu\">\n <li>\n <a class=\"dropdown-item hover_dropdown_bg action_dropdown\" (click)=\"createCustomColumn()\">Create custom column</a>\n </li>\n <ng-container *ngFor=\"let button of buttons\">\n <li *ngIf=\"button?.has_permission\">\n <a class=\"dropdown-item hover_dropdown_bg action_dropdown\" \n href=\"javascript:void(0)\" \n (click)=\"onActionButtonClick(button.name)\">\n <!-- <span *ngIf=\"button.is_showIcon\" \n class=\"me-2\">\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/' + button.icon + '.svg'\"\n class=\"svg-icon svg-icon-2\"></span>\n </span> -->\n <span>{{ button?.name }}</span>\n </a>\n </li>\n </ng-container>\n </ul>\n </div>\n </div>\n <!-- <div class=\"cursor-pointer actions-buttons-row\" *ngIf=\"buttons.length == 1\">\n <a href=\"JavaScript:void(0)\"\n (click)=\"onActionButtonClick(buttons[0].name)\"\n class=\"btn btn-primary border border-primary py-1 d-flex align-items-center justify-content-center px-3\">\n <span class=\"text-white\"\n [class.ms-0]=\"buttons[0].is_showIcon\"\n >{{ buttons[0].name }}</span>\n </a>\n </div> -->\n <div class=\"action-buttons-row\" *ngIf=\"showFullScreenButton\">\n <a\n *ngIf=\"!isFullScreen\"\n class=\"button button-small btn btn-active-primary border border-primary expend d-flex justify-content-center align-items-center\"\n (click)=\"toggleFullscreen()\"\n data-bs-toggle=\"tooltip\"\n data-bs-placement=\"top\"\n title=\"Minimise\"\n [ngClass]=\"{ minArrow: !isFullScreen, maxArrow: isFullScreen }\"\n style=\"transition: color 0.2s\"\n >\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/expend.svg'\"\n class=\"svg-icon svg-icon-2 mb-1\"\n ></span>\n </a>\n <a\n *ngIf=\"isFullScreen\"\n class=\"button button-small btn btn-active-primary border border-primary expend d-flex justify-content-center align-items-center\"\n (click)=\"toggleFullscreen()\"\n data-bs-toggle=\"tooltip\"\n data-bs-placement=\"top\"\n title=\"Maximise\"\n [ngClass]=\"{ minArrow: !isFullScreen, maxArrow: isFullScreen }\"\n style=\"transition: color 0.2s\"\n >\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/minimize.svg'\"\n class=\"svg-icon svg-icon-2 mb-1\"\n ></span>\n </a>\n </div>\n <div>\n <!-- Example single danger button -->\n\n <!-- <button\n type=\"button\"\n class=\"btn btn-primary btn-sm d-flex gap-2 action-button\"\n (click)=\"toggleActions('actions')\"\n >\n Action\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/Vector.svg'\"\n class=\"data-grid-svg-icon\"\n ></span>\n </button>\n <div\n *ngIf=\"activeTopButton === 'actions'\"\n class=\"actions-dropdown mt-1\"\n >\n <div class=\"dropdown-menu show\">\n <a class=\"dropdown-item\" href=\"#\">Action</a>\n <a class=\"dropdown-item\" href=\"#\">Another action</a>\n <a class=\"dropdown-item\" href=\"#\">Something else here</a>\n <div class=\"dropdown-divider\"></div>\n <a class=\"dropdown-item\" href=\"#\">Separated link</a>\n </div>\n </div> -->\n </div>\n </div>\n </div>\n\n <div\n *ngIf=\"showFilters && !showFilterRow\"\n class=\"top-filter-row border-top py-2 d-flex justify-content-between align-items-center\"\n [style.height.px]=\"topFilterRowHeight\"\n >\n <!-- LEFT SIDE (Filter tags + Filter button) -->\n <div class=\"d-flex gap-2 align-items-center\">\n <ng-container>\n <div\n *ngFor=\"let col of activeFilteredColumns; trackBy: trackByField\"\n class=\"filter-tags\"\n >\n <div\n (click)=\"\n isActiveFilterOpen = true;\n activeTopButton = 'filter-columns';\n openFilter(col)\n \"\n class=\"d-flex justify-content-center align-items-center muted-text add-filter-button active-filters\"\n style=\"white-space: nowrap\"\n [class.active]=\"\n col?.field == selectedColumnForFilter?.field &&\n isActiveFilterOpen &&\n activeTopButton == 'filter-columns'\n \"\n >\n <span class=\"header-tag mt-0 d-flex align-items-center left-side-pinned\">\n <span\n *ngIf=\"col?.pinned\"\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/pin.svg'\"\n class=\"data-grid-svg-icon me-2\"\n ></span>\n {{ col.header }}: {{col.query.first_value || col.query?._ids[0]}}\n <span\n (click)=\"\n $event.stopPropagation(); removeColumnFilterFromColumn(col)\n \"\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/filterCrossNew.svg'\n \"\n class=\"data-grid-svg-icon cross-secondary ms-2\"\n ></span>\n </span>\n </div>\n\n <ng-container\n *ngIf=\"\n activeTopButton === 'filter-columns' &&\n col?.field == selectedColumnForFilter?.field &&\n isActiveFilterOpen\n \"\n >\n <div\n *ngTemplateOutlet=\"filterColumns; context: { column: col }\"\n class=\"actions-dropdown mt-1\"\n ></div>\n </ng-container>\n </div>\n </ng-container>\n\n <!-- Filter Button -->\n <div class=\"add-filter-button-menu\">\n <div\n (click)=\"toggleActions('filter-columns'); isActiveFilterOpen = false\"\n class=\"d-flex justify-content-center align-items-center muted-text add-filter-button button-filter\"\n style=\"width: 70px\">\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/plus.svg'\"\n class=\"me-2 data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n Filter\n </div>\n\n <ng-container\n *ngIf=\"activeTopButton === 'filter-columns' && !isActiveFilterOpen\"\n >\n <div\n *ngTemplateOutlet=\"filterColumns\"\n class=\"actions-dropdown mt-1\"\n ></div>\n </ng-container>\n </div>\n </div>\n\n <!-- RIGHT SIDE (Update + Reset) -->\n <div class=\"d-flex gap-3 align-items-center\">\n <div\n (click)=\"savePreset()\"\n class=\"text-primary cursor-pointer all-filters-reset-button\"\n *ngIf=\"!checkFilterChangesEffect()\"\n >\n Update View\n </div>\n\n <div\n class=\"text-primary cursor-pointer all-filters-reset-button\"\n *ngIf=\"!tableFilterViewId && activeFilteredColumns?.length\"\n (click)=\"clearAllFilters()\">\n Clear filters\n </div>\n </div>\n </div>\n\n <div\n [style.height]=\"\n showFilters ? 'calc(100% - ' + (topFilterRowHeight + footerRowHeight) + 'px)' : 'calc(100% - ' + footerRowHeight + 'px)'\n \"\n cdkDropListGroup\n class=\"data-grid-table-wrapper overflow-hidden\"\n #dataGridContainer\n [style.fontFamily]=\"fontFaimly\"\n [style.backgroundColor]=\"bodyBackgroundColor\"\n id=\"data-grid-main-container\"\n >\n <div\n *ngIf=\"showRowsGrouping\"\n [style.height.px]=\"headerRowHeight\"\n [cdkDropListData]=\"columns\"\n [style.backgroundColor]=\"\n topGroupedBadgesBackgroundColor || headerBackgroundColor\n \"\n cdkDropList\n (cdkDropListEntered)=\"enterToTopRowGrouping($event)\"\n (cdkDropListExited)=\"exitedFromTheTopRow($event)\"\n (cdkDropListDropped)=\"onDropTopGroup($event)\"\n [cdkDropListEnterPredicate]=\"canEnterToRowsGrouping\"\n id=\"rows-grouping-top-container\"\n class=\"border-below d-flex px-4 align-items-center\"\n >\n <div\n class=\"d-flex gap-2 align-items-center\"\n [style.color]=\"headerTextColor\"\n >\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/justify.svg'\"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n <div *ngIf=\"!draggingInGroupArea && !groupedColumns?.length\">\n Drag here to set row groups\n </div>\n <div\n cdkDropListOrientation=\"horizontal\"\n cdkDropList\n (cdkDropListDropped)=\"onGroupReorder($event)\"\n class=\"d-flex\"\n >\n <div\n cdkDrag\n [cdkDragLockAxis]=\"'x'\"\n *ngFor=\"\n let child of groupedColumns;\n let i = index;\n trackBy: trackByField\n \"\n class=\"d-flex align-items-center\"\n >\n <ng-container\n *ngTemplateOutlet=\"\n topGroupingRowPlaceholder;\n context: {\n $implicit: child,\n showChevron:\n groupedColumns.length > 1 && i != groupedColumns.length - 1\n }\n \"\n ></ng-container>\n <ng-template cdkDragPreview\n ><div class=\"p-2 border d-flex gap-2\">\n <div>\n <span\n *ngIf=\"!draggingInGroupArea\"\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/arrows-move.svg'\n \"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n </div>\n <div>{{ child.header }}</div>\n </div>\n </ng-template>\n </div>\n </div>\n </div>\n </div>\n <div\n class=\"d-flex overflow-hidden\"\n [style.height]=\"\n 'calc(100% - ' +\n (showRowsGrouping\n ? headerRowHeight + footerRowHeight\n : footerRowHeight) +\n 'px)'\n \"\n >\n <div\n class=\"h-100\"\n [style.width]=\"\n !showSideMenu\n ? '100%'\n : sideMenuVisible\n ? 'calc(100% - 280px)'\n : 'calc(100% - 30px)'\n \"\n >\n <div class=\"h-100 transition position-relative w-100\">\n <!-- ##################################################################################################################################################################################### -->\n <!-- ##################################################################################################################################################################################### -->\n <!-- Data Grid Header starts here -->\n <!-- ##################################################################################################################################################################################### -->\n <!-- ##################################################################################################################################################################################### -->\n <!-- [style.backgroundColor]=\"headerBackgroundColor\" -->\n <div\n class=\"data-grid-header-wrapper w-100\"\n [style.color]=\"headerTextColor\"\n [style.backgroundColor]=\"headerBackgroundColor\"\n [style.fontSize.px]=\"headerTextFontsSize\"\n [class.border-below]=\"!hasAnyVisibleColumn\"\n [style.height.px]=\"\n showColumnsGrouping && showFilterRow\n ? headerRowHeight * 3\n : showColumnsGrouping || showFilterRow\n ? headerRowHeight * 2\n : headerRowHeight\n \"\n >\n <!-- ********************************************************************************* -->\n <!-- ********************************************************************************* -->\n <!-- Data Grid Left Pinned Header starts here -->\n <!-- ********************************************************************************* -->\n <!-- ********************************************************************************* -->\n <div\n class=\"data-grid-header left-pinned\"\n #leftPinnedHeader\n [class.border-right]=\"hasLeftPinnedColumns\">\n <div *ngIf=\"showSerialNumber\"\n [style.backgroundColor]=\"checkboxesBackgroundColor\"\n class=\"select-all-checkbox-cell border-below\"\n [style.width.px]=\"55\"\n [style.height.px]=\"\n showColumnsGrouping && showFilterRow\n ? headerRowHeight * 3\n : showColumnsGrouping || showFilterRow\n ? headerRowHeight * 2\n : headerRowHeight\n \"\n >\n S.No\n </div>\n <div *ngIf=\"showCheckboxes\"\n class=\"select-all-checkbox-cell border-below\"\n [style.height.px]=\"\n showColumnsGrouping && showFilterRow\n ? headerRowHeight * 3\n : showColumnsGrouping || showFilterRow\n ? headerRowHeight * 2\n : headerRowHeight\n \"\n >\n <input class=\"serialNoCheckbox\"\n *ngIf=\"hasAnyVisibleColumn\"\n style=\"width: 16px; height: 16px\"\n type=\"checkbox\"\n [indeterminate]=\"isIndeterminateState(dataSet)\"\n [checked]=\"isAllSelected(dataSet)\"\n (change)=\"toggleSelectAll(dataSet)\"\n />\n </div>\n <div\n [style.backgroundColor]=\"headerBackgroundColor\"\n class=\"d-flex\"\n cdkDropList\n id=\"left-pinned-header\"\n cdkDropListOrientation=\"horizontal\"\n [cdkDropListData]=\"leftPinnedColumns\"\n (cdkDropListEntered)=\"onDropListEnter($event, 'left')\"\n (cdkDropListSorted)=\"\n onSortGroup($event, 'previewLeftPinnedColumns')\n \"\n (cdkDropListDropped)=\"onDropGroup()\"\n style=\"min-width: 1px\"\n >\n <div\n class=\"dragable-header\"\n cdkDrag\n [cdkDragData]=\"col\"\n *ngFor=\"\n let col of leftPinnedColumns;\n let i = index;\n trackBy: trackByField\n \"\n >\n <ng-container\n *ngTemplateOutlet=\"\n headerCell;\n context: {\n $implicit: col,\n index: i,\n section: 'previewLeftPinnedColumns'\n }\n \"\n ></ng-container>\n <ng-template cdkDragPreview\n ><div class=\"p-2 border d-flex gap-2\">\n <div>\n <span\n *ngIf=\"!draggingInGroupArea\"\n [inlineSVG]=\"\n singleSpaAssetsPath +\n 'data-grid/icons/arrows-move.svg'\n \"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n </div>\n <div>{{ col.header }}</div>\n </div>\n </ng-template>\n <ng-template cdkDragPlaceholder>\n <div *ngIf=\"!draggingInGroupArea\">\n <div\n *ngTemplateOutlet=\"\n headerCell;\n context: {\n $implicit: col,\n index: i,\n section: ''\n }\n \"\n ></div>\n </div>\n <div\n *ngIf=\"draggingInGroupArea\"\n class=\"d-flex gap-2 ms-2\"\n style=\"opacity: 0.6\"\n >\n <ng-container\n *ngIf=\"col?.children?.length; else singleCol\"\n >\n <ng-container\n *ngFor=\"\n let child of col.children;\n let i = index;\n trackBy: trackByField\n \"\n >\n <ng-container\n *ngTemplateOutlet=\"\n topGroupingRowPlaceholder;\n context: {\n $implicit: child,\n showChevron:\n col.children.length > 1 &&\n i != col.children.length - 1\n }\n \"\n ></ng-container>\n </ng-container>\n </ng-container>\n\n <ng-template #singleCol>\n <ng-container\n *ngTemplateOutlet=\"\n topGroupingRowPlaceholder;\n context: {\n $implicit: col,\n showChevron: col?.children?.length > 1\n }\n \"\n ></ng-container>\n </ng-template>\n </div>\n </ng-template>\n </div>\n </div>\n </div>\n\n <!-- ********************************************************************************* -->\n <!-- ********************************************************************************* -->\n <!-- Data Grid Center Pinned Header starts here -->\n <!-- ********************************************************************************* -->\n <!-- ********************************************************************************* -->\n <div\n class=\"data-grid-header center-scrollable\"\n #centerPinnedHeader\n (scroll)=\"onCenterBodyScroll($event)\"\n id=\"center-pinned-header\"\n cdkDropList\n [cdkDropListConnectedTo]=\"\n showRowsGrouping ? ['rows-grouping-top-container'] : []\n \"\n [cdkDropListData]=\"centerColumns\"\n cdkDropListOrientation=\"horizontal\"\n [cdkDropListSortingDisabled]=\"\n isDisableColumnGrouping && draggingInGroupArea\n \"\n (cdkDropListEntered)=\"onDropListEnter($event, 'center')\"\n (cdkDropListSorted)=\"onSortGroup($event, 'previewCenterColumns')\"\n (cdkDropListDropped)=\"onDropGroup()\"\n [style.maxWidth]=\"\n 'calc(100% - ' +\n (rightPinnedHeader.offsetWidth + leftPinnedHeader.offsetWidth) +\n 'px)'\n \"\n >\n <div\n *ngIf=\"groupedColumns?.length\"\n style=\"min-width: 200px\"\n class=\"h-100 align-items-center\"\n #columnsGroupedBox\n id=\"groupBoxHeaderDiv\"\n >\n <div\n class=\"d-flex w-100 justify-content-between align-items-center border-below\"\n [style.height.px]=\"\n showFilterRow ? headerRowHeight * 2 : headerRowHeight\n \"\n >\n <div class=\"ps-3\">Group</div>\n <div class=\"d-flex\">\n <div\n class=\"three-dots cursor-pointer\"\n (click)=\"\n openThreeDotsMenu($event, 'group');\n isThreeDotsFilterOpen = false\n \"\n >\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath +\n 'data-grid/icons/three-dots-vertical.svg'\n \"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n </div>\n <div\n (mousedown)=\"\n $event.stopPropagation(); onResizeGroupBox($event)\n \"\n class=\"resize-handle\"\n style=\"margin-right: -2px\"\n >\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath +\n 'data-grid/icons/resize-handle1.svg'\n \"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n </div>\n </div>\n </div>\n\n <div\n [style.height.px]=\"headerRowHeight\"\n class=\"border-below\"\n ></div>\n </div>\n <span\n class=\"d-flex align-items-center justify-content-center cursor-pointer border-below\"\n style=\"min-width: 30px; height: 100%\"\n *ngIf=\"gridType === 'Assets' || gridType === 'Tasks'\"\n >\n </span>\n <div\n class=\"dragable-header\"\n (cdkDragStarted)=\"\n checkColumnGroupingStatus(col);\n dragStartOnGroup(col);\n onDragStarted(col)\n \"\n (cdkDragMoved)=\"onDragMoved($event)\"\n (cdkDragEnded)=\"onDragEnded()\"\n cdkDrag\n [cdkDragData]=\"col\"\n *ngFor=\"\n let col of centerColumns;\n let i = index;\n trackBy: trackById\n \"\n >\n <ng-container\n *ngTemplateOutlet=\"\n headerCell;\n context: {\n $implicit: col,\n index: i,\n section: 'previewCenterColumns'\n }\n \"\n >\n </ng-container>\n <ng-template cdkDragPreview\n ><div class=\"p-2 border d-flex gap-2\">\n <div>\n <span\n *ngIf=\"!isOutsideContainer\"\n [inlineSVG]=\"\n singleSpaAssetsPath +\n (draggingInGroupArea\n ? 'data-grid/icons/justify.svg'\n : 'data-grid/icons/arrows-move.svg')\n \"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n >\n </span>\n <span\n *ngIf=\"isOutsideContainer\"\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/eye-cross.svg'\n \"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n >\n </span>\n </div>\n <div>{{ col.header }}</div>\n </div>\n </ng-template>\n <ng-template cdkDragPlaceholder>\n <div *ngIf=\"!draggingInGroupArea\">\n <div\n *ngTemplateOutlet=\"\n headerCell;\n context: {\n $implicit: col,\n index: i,\n section: 'centerColumns'\n }\n \"\n ></div>\n </div>\n <div\n *ngIf=\"draggingInGroupArea && !isOutsideContainer\"\n class=\"d-flex gap-2 ms-2\"\n style=\"opacity: 0.6\"\n >\n <ng-container *ngIf=\"col?.children?.length; else singleCol\">\n <ng-container\n *ngFor=\"\n let child of col.children;\n let i = index;\n trackBy: trackById\n \"\n >\n <ng-container *ngIf=\"child?.is_groupable\">\n <ng-container\n *ngTemplateOutlet=\"\n topGroupingRowPlaceholder;\n context: {\n $implicit: child,\n showChevron:\n col.children.length > 1 &&\n i != col.children.length - 1\n }\n \"\n ></ng-container>\n </ng-container>\n </ng-container>\n </ng-container>\n\n <ng-template #singleCol>\n <ng-container *ngIf=\"col?.is_groupable\">\n <ng-container\n *ngTemplateOutlet=\"\n topGroupingRowPlaceholder;\n context: {\n $implicit: col,\n showChevron: col?.children?.length > 1\n }\n \"\n ></ng-container>\n </ng-container>\n </ng-template>\n </div>\n </ng-template>\n </div>\n </div>\n\n <!-- ********************************************************************************* -->\n <!-- ********************************************************************************* -->\n <!-- Data Grid Right Pinned Header starts here -->\n <!-- ********************************************************************************* -->\n <!-- ********************************************************************************* -->\n <div\n [style.backgroundColor]=\"headerBackgroundColor\"\n cdkDropList\n id=\"right-pinned-header\"\n [cdkDropListConnectedTo]=\"\n showRowsGrouping ? ['rows-grouping-top-container'] : []\n \"\n cdkDropListOrientation=\"horizontal\"\n class=\"data-grid-header right-pinned\"\n (cdkDropListSorted)=\"\n onSortGroup($event, 'previewRightPinnedColumns')\n \"\n (cdkDropListEntered)=\"onDropListEnter($event, 'right')\"\n (cdkDropListDropped)=\"onDropGroup()\"\n #rightPinnedHeader\n class=\"right-pinned-header d-flex\"\n style=\"min-width: 0.2px\"\n >\n <div\n class=\"dragable-header\"\n cdkDrag\n [cdkDragData]=\"col\"\n *ngFor=\"\n let col of rightPinnedColumns;\n let i = index;\n trackBy: trackById\n \"\n >\n <ng-container\n *ngTemplateOutlet=\"\n headerCell;\n context: {\n $implicit: col,\n pinnedRight: true,\n index: i,\n section: 'right'\n }\n \"\n ></ng-container>\n <ng-template cdkDragPreview\n ><div class=\"p-2 border d-flex gap-2\">\n <div>\n <span\n *ngIf=\"!draggingInGroupArea\"\n [inlineSVG]=\"\n singleSpaAssetsPath +\n 'data-grid/icons/arrows-move.svg'\n \"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n </div>\n <div>{{ col.header }}</div>\n </div>\n </ng-template>\n <ng-template cdkDragPlaceholder>\n <div *ngIf=\"!draggingInGroupArea\">\n <div\n *ngTemplateOutlet=\"\n headerCell;\n context: {\n $implicit: col,\n index: i,\n section: 'right'\n }\n \"\n ></div>\n </div>\n <div\n *ngIf=\"draggingInGroupArea\"\n class=\"d-flex gap-2 ms-2\"\n style=\"opacity: 0.6\"\n >\n <ng-container *ngIf=\"col?.children?.length; else singleCol\">\n <ng-container\n *ngFor=\"\n let child of col.children;\n let i = index;\n trackBy: trackById\n \"\n >\n <ng-container\n *ngTemplateOutlet=\"\n topGroupingRowPlaceholder;\n context: {\n $implicit: child,\n showChevron:\n col.children.length > 1 &&\n i != col.children.length - 1\n }\n \"\n ></ng-container>\n </ng-container>\n </ng-container>\n\n <ng-template #singleCol>\n <ng-container\n *ngTemplateOutlet=\"\n topGroupingRowPlaceholder;\n context: {\n $implicit: col,\n showChevron: col?.children?.length > 1\n }\n \"\n ></ng-container>\n </ng-template>\n </div>\n </ng-template>\n </div>\n </div>\n </div>\n\n <!--########################################################################################################################################################################################################################### -->\n <!--########################################################################################################################################################################################################################### -->\n <!-- Data Grid Body starts here -->\n <!--########################################################################################################################################################################################################################### -->\n <!--########################################################################################################################################################################################################################### -->\n <div\n class=\"h-100 d-flex justify-content-center align-items-center\"\n *ngIf=\"!dataSet?.length && !loading && !dataSetLoading\">\n <!-- <div\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/record-not-found.svg'\n \"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></div> -->\n <div class=\"d-flex flex-column justify-content-center align-items-center\">\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/no-data-image.svg'\"\n class=\"data-grid-svg-icon mb-3 d-flex justify-content-center align-items-center\">\n </span>\n <p class=\"text_common_16px mb-0\">No data available</p>\n <p class=\"page_refresh mb-0\">Try adjusting filters or refresh the page</p>\n </div>\n </div>\n\n <div\n class=\"position-absolute w-100 h-100 d-flex justify-content-center align-items-center loading-overlay\"\n *ngIf=\"loading || dataSetLoading\"\n style=\"\n z-index: 999;\n backdrop-filter: blur(1px);\n \"\n [style.backgroundColor]=\"bodyBackgroundColor\"\n >\n <div class=\"spinner-border text-primary\" role=\"status\">\n <!-- <span class=\"loader\"></span> -->\n <!-- <span class=\"visually-hidden\">Loading...</span> -->\n <!-- </div> -->\n </div>\n </div>\n\n <div\n class=\"data-grid-body-wrapper position-relative d-flex\"\n [style.height]=\"bodyWrapperHeight\"\n style=\"overflow-y: auto; overflow-x: hidden\"\n #mainScroll\n (scroll)=\"onMainScroll($event)\"\n [style.scrollbarWidth]=\"verticalScrollbarWidth\"\n >\n <!-- LEFT PINNED -->\n <div\n [style.height.px]=\"\n !groupedColumns.length ? originalDataSet.length * rowHeight : 0\n \"\n ></div>\n <!-- [class.transparent-border-right]=\"!hasLeftPinnedColumns\" -->\n <div [class.h-100]=\"originalDataSet.length < 8\">\n <div\n class=\"data-grid-body left-pinned-body w-100\"\n style=\"overflow-y: hidden\"\n [class.border-right]=\"hasLeftPinnedColumns\"\n [class.transparent-border-right]=\"!hasLeftPinnedColumns\"\n [style.boxShadow]=\"leftPinnedBoxshadow\"\n [style.transform]=\"'translateY(' + translateY + 'px)'\"\n [style.backgroundColor]=\"leftPinnedBackgroundColor\"\n [class.h-100]=\"originalDataSet.length < 8\"\n *ngIf=\"!loading && !dataSetLoading\"\n [@rowDynamic]=\"rowAnimation\"\n\n \n >\n <ng-container\n *ngFor=\"\n let row of visibleRows;\n let i = index;\n trackBy: trackById\n \"\n >\n <ng-container\n *ngTemplateOutlet=\"\n rowCell;\n context: {\n $implicit: row,\n columns: previewLeftPinnedColumns,\n isEven: (startIndex + i) % 2 === 0,\n isOdd: (startIndex + i) % 2 !== 0,\n isLeft: true,\n section: 'left',\n isTotalRow: false\n }\n \"\n ></ng-container>\n </ng-container>\n <ng-container *ngIf=\"showTotalAmountRow && originalDataSet?.length\">\n <ng-container\n *ngTemplateOutlet=\"\n rowCell;\n context: {\n $implicit: { __virtualIndex: 0 },\n columns: previewLeftPinnedColumns,\n isEven: false,\n isOdd: false,\n section: 'left',\n isTotalRow: true\n }\n \"\n ></ng-container>\n </ng-container>\n </div>\n </div>\n\n <!-- CENTER -->\n <div\n class=\"h-100\"\n [style.width.px]=\"centerPinnedHeader.clientWidth\"\n [style.backgroundColor]=\"bodyBackgroundColor\"\n >\n <div\n class=\"data-grid-body center-scrollable\"\n [class.h-100]=\"originalDataSet.length < 8\"\n style=\"overflow-y: hidden; overflow-x: auto\"\n [style.transform]=\"'translateY(' + translateY + 'px)'\"\n [style.backgroundColor]=\"bodyBackgroundColor\"\n #centerScrollableBody\n (scroll)=\"onCenterBodyScroll($event)\"\n [style.boxShadow]=\"leftPinnedBoxshadow\"\n \n >\n <div [@rowDynamic]=\"rowAnimation\" *ngIf=\"!loading && !dataSetLoading\">\n <ng-container\n *ngFor=\"\n let row of visibleRows;\n let i = index;\n trackBy: trackById\n \"\n >\n <ng-container\n *ngTemplateOutlet=\"\n rowCell;\n context: {\n $implicit: row,\n columns: previewCenterColumns,\n isEven: (startIndex + i) % 2 === 0,\n isOdd: (startIndex + i) % 2 !== 0,\n section: 'center',\n isTotalRow: false\n }\n \"\n ></ng-container>\n </ng-container>\n </div>\n <ng-container *ngIf=\"showTotalAmountRow && originalDataSet?.length\">\n <ng-container\n *ngTemplateOutlet=\"\n rowCell;\n context: {\n $implicit: { __virtualIndex: 0 },\n columns: previewCenterColumns,\n isEven: false,\n isOdd: false,\n section: 'center',\n isTotalRow: true\n }\n \"\n ></ng-container>\n </ng-container>\n </div>\n </div>\n\n <!-- RIGHT PINNED -->\n <div\n class=\"right-pinned-body-wrapper\"\n *ngIf=\"true\"\n [class.h-100]=\"originalDataSet.length < 8\"\n [style.maxWidth.px]=\"\n isScrollbarVisible\n ? rightPinnedHeader.offsetWidth - 15\n : rightPinnedHeader.offsetWidth\n \"\n [style.backgroundColor]=\"rightPinnedBackgroundColor\"\n [@rowDynamic]=\"rowAnimation\"\n >\n <div\n class=\"data-grid-body right-pinned-body w-100 h-100\"\n style=\"overflow-y: hidden\"\n [style.transform]=\"'translateY(' + translateY + 'px)'\"\n [style.boxShadow]=\"rightPinnedBoxshadow\"\n [style.backgroundColor]=\"rightPinnedBackgroundColor\"\n *ngIf=\"!loading && !dataSetLoading && hasRightPinnedColumns\"\n >\n <ng-container\n *ngFor=\"\n let row of visibleRows;\n let i = index;\n trackBy: trackById\n \"\n >\n <ng-container\n *ngTemplateOutlet=\"\n rowCell;\n context: {\n $implicit: row,\n columns: previewRightPinnedColumns,\n isEven: (startIndex + i) % 2 === 0,\n isOdd: (startIndex + i) % 2 !== 0,\n section: 'right',\n isTotalRow: false\n }\n \"\n ></ng-container>\n </ng-container>\n <ng-container *ngIf=\"showTotalAmountRow && originalDataSet?.length\">\n <ng-container\n *ngTemplateOutlet=\"\n rowCell;\n context: {\n $implicit: { __virtualIndex: 0 },\n columns: previewRightPinnedColumns,\n isEven: false,\n isOdd: false,\n section: 'right',\n isTotalRow: true\n }\n \"\n ></ng-container>\n </ng-container>\n </div>\n </div>\n\n <div\n style=\"top: auto; left: auto\"\n (click)=\"\n $event.stopPropagation();\n fullscreenImage = null;\n cdr.detectChanges()\n \"\n [style.width.px]=\"dataGridContainer.offsetWidth\"\n [style.height.px]=\"\n dataGridContainer.offsetHeight - (footerRowHeight + 100)\n \"\n class=\"image-modal full-image-modal\"\n *ngIf=\"fullscreenImage\"\n >\n <img\n (click)=\"$event.stopPropagation()\"\n [src]=\"fullscreenImage\"\n alt=\"Fullscreen Image\"\n />\n </div>\n <div\n *ngIf=\"selectedRows.size > 0 && showTaskbar\"\n class=\"taskbar w-100\"\n [style.bottom.px]=\"85\"\n >\n <div class=\"selected-rows-action-bar\" [@slideUp]>\n <span class=\"selected-count\">\n {{ selectedRows.size }} selected of\n {{\n paginationConfig.totalResults ||\n config?.paginationParams?.totalItems\n }}\n Total\n </span>\n <div class=\"action-buttons d-flex align-items-center\">\n <ng-container\n *ngFor=\"let action of taskbarActions; let i = index\"\n >\n <ng-container *ngIf=\"action?.has_permission\">\n <span\n class=\"action-btn verified btn {{ action }}\"\n (click)=\"onVerifyClick(action?.actionName)\"\n >{{ action?.actionName }}</span\n >\n <span\n *ngIf=\"\n taskbarActions.length > 1 &&\n i !== taskbarActions.length - 1 &&\n taskbarActions[i + 1]?.has_permission\n \"\n class=\"\"\n >|</span\n >\n </ng-container>\n </ng-container>\n <button (click)=\"clearSelectionState(tableType);selectedRows.clear();\" class=\"clear-btn ms-2 mt-2\">\n <i class=\"bi bi-x-circle\"></i> Clear Selection\n </button>\n </div>\n </div>\n </div>\n </div>\n <!-- Vertical Fake scroll Bar -->\n <!-- <div\n (scroll)=\"onMainFakeScroll($event)\"\n class=\"fake-scrollbar fake-scrollbar-vertical d-none\"\n [style.scrollbarWidth]=\"verticalScrollbarWidth\"\n [style.top.px]=\"\n showColumnsGrouping && showFilterRow\n ? headerRowHeight * 3\n : showColumnsGrouping || showFilterRow\n ? headerRowHeight * 2\n : headerRowHeight\n \"\n #fakeScroll\n [style.height]=\"bodyWrapperHeight\"\n style=\"\n overflow-y: auto;\n overflow-x: hidden;\n width: 17px;\n position: absolute;\n right: 0;\n background-color: f1f2f3;\n z-index: 10;\n \"\n >\n <div [style.height.px]=\"rowHeight * dataSetLength\"></div>\n </div> -->\n </div>\n\n <!-- Horizintal Fake Scrollbars -->\n <div\n class=\"d-flex justify-content-between\"\n *ngIf=\"hasScroll\"\n >\n <div\n [style.scrollbarWidth]=\"horizintalScrollbarWidth\"\n class=\"fake-horizintal-scrollbar\"\n #fakeScroll\n [style.width.px]=\"leftPinnedHeader.offsetWidth\"\n style=\"overflow-x: scroll\"\n ></div>\n <div\n [style.scrollbarWidth]=\"horizintalScrollbarWidth\"\n (scroll)=\"onCenterBodyScroll($event)\"\n class=\"fake-horizintal-scrollbar\"\n #horizintalFakeScroll\n [style.width.px]=\"centerPinnedHeader.offsetWidth\"\n >\n <div [style.width.px]=\"centerPinnedHeader.scrollWidth - 10\"></div>\n </div>\n <div\n [style.scrollbarWidth]=\"horizintalScrollbarWidth\"\n class=\"fake-horizintal-scrollbar\"\n #fakeScroll\n [style.width.px]=\"rightPinnedHeader.offsetWidth\"\n style=\"overflow-x: scroll\"\n ></div>\n </div>\n </div>\n\n <!-- Side Menu Implemented Here -->\n <div\n *ngIf=\"showSideMenu\"\n [style.width.px]=\"sideMenuVisible ? 280 : 30\"\n class=\"right-menu h-100\"\n [style.backgroundColor]=\"sidemenuBackgroundColor\"\n >\n <div class=\"h-100 d-flex flex-row-reverse\">\n <div\n style=\"width: 30px\"\n class=\"d-flex flex-column align-items-center cursor-pointer\"\n [class.border-start]=\"sideMenuVisible\"\n >\n <div\n (click)=\"toggleSideMenu('cols')\"\n [class.bg-fff]=\"\n currentOpenedSideMenue == 'cols' && sideMenuVisible\n \"\n [class.border-below]=\"sideMenuVisible\"\n class=\"columns-button d-flex flex-column align-items-center\"\n >\n <div>\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/ui-checks-grid.svg'\n \"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n </div>\n <div class=\"side-menue-text\">Columns</div>\n </div>\n\n <div\n (click)=\"toggleSideMenu('filtrs')\"\n [class.bg-fff]=\"\n currentOpenedSideMenue == 'filtrs' && sideMenuVisible\n \"\n [class.border-below]=\"\n sideMenuVisible && currentOpenedSideMenue == 'filtrs'\n \"\n class=\"columns-button d-flex flex-column align-items-center\"\n >\n <div>\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\n \"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n </div>\n <div class=\"side-menue-text\">Filter</div>\n </div>\n </div>\n <div\n class=\"h-100\"\n *ngIf=\"sideMenuVisible\"\n [ngStyle]=\"{ width: sideMenuVisible ? '250px' : '' }\"\n >\n <div class=\"h-100\">\n <ng-container\n *ngIf=\"currentOpenedSideMenue == 'cols' && sideMenuVisible\"\n >\n <ng-container *ngTemplateOutlet=\"columnPannel\"></ng-container>\n <!-- Column Items -->\n <div class=\"column-panel-body px-3\">\n <ng-container\n *ngFor=\"let col of columns; trackBy: trackByField\"\n >\n <ng-container\n *ngTemplateOutlet=\"columnPanelItem; context: { col: col }\"\n ></ng-container>\n </ng-container>\n </div>\n <hr />\n\n <div class=\"side-menu-row-groups\" style=\"height: 30%\">\n <ng-container\n *ngTemplateOutlet=\"sideMenuRowGroups\"\n ></ng-container>\n </div>\n </ng-container>\n <ng-container\n *ngIf=\"currentOpenedSideMenue == 'filtrs' && sideMenuVisible\"\n >\n <ng-container *ngTemplateOutlet=\"sideFilters\"></ng-container>\n </ng-container>\n </div>\n </div>\n </div>\n </div>\n </div>\n <div\n [style.height.px]=\"footerRowHeight\"\n class=\"border-top\"\n [style.backgroundColor]=\"footerRowBackgroundColor\"\n >\n <!-- Rows: <span class=\"fw-500 ms-1\">{{ dataSet.length }}</span> -->\n\n <div class=\"pagination-container\"\n [style.height.px]=\"footerRowHeight\"\n [style.padding.px]=\"footerPadding\">\n <div class=\"page-size\">\n <select\n [(ngModel)]=\"paginationConfig.limit\"\n (change)=\"onPageSizeChange()\"\n >\n <option *ngFor=\"let size of pageSizeOptions\" [value]=\"size\">\n {{ size }}\n </option>\n </select>\n <span class=\"separator\"> per page </span>\n </div>\n\n <div class=\"page-info\">\n \n {{ (paginationConfig.page - 1) * paginationConfig.limit + 1 }}-{{\n paginationConfig.page * paginationConfig.limit <\n paginationConfig.totalResults\n ? paginationConfig.page * paginationConfig.limit\n : paginationConfig.totalResults\n }}\n of\n {{ paginationConfig.totalResults }}\n results\n </div>\n\n <div class=\"page-buttons\">\n <button\n (click)=\"goToPage(paginationConfig.page - 1)\"\n [disabled]=\"paginationConfig.page === 1\">\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/chevron-left.svg'\"\n class=\"d-flex justify-content-center align-items-center\"\n ></span>\n </button>\n\n <ng-container *ngFor=\"let page of visiblePages\">\n <button\n *ngIf=\"page !== '...'\"\n (click)=\"goToPage(page)\"\n [class.active]=\"page === paginationConfig.page\"\n >\n {{ page }}\n </button>\n <span *ngIf=\"page === '...'\">...</span>\n </ng-container>\n\n <button\n (click)=\"goToPage(paginationConfig.page + 1)\"\n [disabled]=\"paginationConfig.page === paginationConfig.totalResults\">\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\"\n class=\"d-flex justify-content-center align-items-center\"\n ></span>\n </button>\n </div>\n </div>\n </div>\n </div>\n</div>\n\n<!-- ------------------------------------------------------------------------------------------------------------------------ -->\n<!-- ------------------------------------------------------------------------------------------------------------------------ -->\n<!-- Header Cell Template -->\n<!-- ------------------------------------------------------------------------------------------------------------------------ -->\n<!-- ------------------------------------------------------------------------------------------------------------------------ -->\n\n<ng-template\n #headerCell\n let-col\n let-pinnedRight=\"pinnedRight\"\n let-i=\"index\"\n let-sections=\"section\"\n let-calledFromNestedPlaceholder=\"calledFromNestedPlaceholder\"\n>\n <div>\n <!-- Group Header -->\n <ng-container *ngIf=\"col.children?.length > 0; else flatHeader\">\n <div cdkDroplistGroup class=\"group-column-wrapper\">\n <!-- Parent Header -->\n <div\n *ngIf=\"shouldTheGroupHeaderShow(col)\"\n class=\"header-cell group-header\"\n [style.height.px]=\"headerRowHeight\"\n [style.min-height.px]=\"headerRowHeight\"\n [style.max-height.px]=\"headerRowHeight\"\n [class.border-right]=\"showVerticalBorder\"\n [style.gridColumn]=\"'span ' + col.children.length\"\n [style.fontWeight]=\"headerFontWeight\"\n [class.flex-row-reverse]=\"pinnedRight\"\n [class.justify-content-end]=\"pinnedRight\"\n style=\"grid-row: 1\"\n >\n <div\n class=\"group-header-content\"\n [title]=\"col.header\"\n [class.ms-2]=\"pinnedRight\"\n >\n {{ col.header }}\n </div>\n <div\n class=\"resize-handle\"\n (dblclick)=\"autosizeColumn(col.children)\"\n (mousedown)=\"\n $event.stopPropagation(); onResizeGroup($event, col, pinnedRight)\n \"\n >\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/resize-handle1.svg'\n \"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n </div>\n </div>\n\n <!-- Child Headers and Filters -->\n\n <div\n class=\"d-flex\"\n cdkDropList\n cdkDropListOrientation=\"horizontal\"\n [cdkDropListData]=\"col.children\"\n (cdkDropListSorted)=\"onChildDroplistSorted($event, sections)\"\n (cdkDropListDropped)=\"onChildDroplistDroped($event)\"\n [cdkDropListSortingDisabled]=\"false\"\n [cdkDropListConnectedTo]=\"\n showRowsGrouping ? ['rows-grouping-top-container'] : []\n \"\n >\n <div\n cdkDrag\n [cdkDragData]=\"child\"\n *ngFor=\"let child of col.children; let i = index\"\n >\n <!-- Child Header -->\n <ng-container *ngIf=\"child.is_visible && !child['isRowGrouped']\">\n <div\n cdkDragHandle\n class=\"header-cell one-row-header-cells cursor-pointer\"\n [class.border-right]=\"showVerticalBorder\"\n [attr.field]=\"child.field\"\n [style.width.px]=\"child.width\"\n [style.min-width.px]=\"child.width\"\n [style.min-height.px]=\"headerRowHeight\"\n [style.max-height.px]=\"headerRowHeight\"\n [style.fontWeight]=\"headerFontWeight\"\n style=\"grid-row: 2\"\n [class.filter-applied-on-text]=\"isFilterAppliedOnColumn(child)\"\n >\n <div\n class=\"d-flex justify-content-between h-100 align-items-center w-100\"\n >\n <div\n class=\"d-flex justify-content-between align-items-center w-100\"\n [class.flex-row-reverse]=\"pinnedRight\"\n >\n <div\n class=\"text-ellipsis h-100 d-flex align-items-center w-100\"\n [title]=\"col.header\"\n [class.w-100]=\"pinnedRight\"\n >\n <div\n class=\"text-ellipsis h-100\"\n [class.editable-header]=\"child?.is_editable\"\n (click)=\"\n openThreeDotsMenu($event, child);\n openFilteronThreeDotsClick(child)\n \"\n >\n {{ child.header }}\n </div>\n </div>\n\n <div\n class=\"position-relative d-flex\"\n [class.flex-row-reverse]=\"pinnedRight\"\n >\n <div\n [class.me-2]=\"pinnedRight\"\n class=\"d-flex align-items-center\"\n *ngIf=\"child.pinned\"\n >\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/pin.svg'\n \"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n </div>\n <div\n class=\"three-dots p-1 zaid-test\"\n (click)=\"\n openThreeDotsMenu($event, child);\n isThreeDotsFilterOpen = false\n \"\n style=\"cursor: pointer\"\n >\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath +\n 'data-grid/icons/three-dots-vertical.svg'\n \"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n </div>\n\n <!-- Only show menu if this column is active -->\n <div\n class=\"position-absolute\"\n *ngIf=\"activeCol === child\"\n style=\"top: -50%; z-index: 21\"\n [style.left.px]=\"\n -(!child?.pinned ? centerPinnedHeader.scrollLeft : 0)\n \"\n [style.top.px]=\"\n isThreeDotsFilterOpen\n ? showFilterRow || showColumnsGrouping\n ? headerRowHeight * 2 - 10\n : headerRowHeight - 10\n : 0\n \"\n >\n <ng-container\n *ngTemplateOutlet=\"\n columnMenu;\n context: {\n col: child,\n isNestedTable: false,\n section: sections\n }\n \"\n ></ng-container>\n </div>\n\n <div\n class=\"resize-handle\"\n (dblclick)=\"autosizeColumn(child)\"\n (mousedown)=\"\n $event.stopPropagation();\n onResizeColumn($event, child)\n \"\n >\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath +\n 'data-grid/icons/resize-handle1.svg'\n \"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n </div>\n </div>\n </div>\n </div>\n </div>\n\n <!-- Filter Cell -->\n <div\n *ngIf=\"showFilterRow\"\n [style.backgroundColor]=\"headerBackgroundColor\"\n class=\"header-cell filter-cell\"\n [class.border-right]=\"showVerticalBorder\"\n [attr.field]=\"child.field\"\n [style.width.px]=\"child.width\"\n [style.min-width.px]=\"child.width\"\n [style.height.px]=\"headerRowHeight\"\n [style.min-height.px]=\"headerRowHeight\"\n [style.max-height.px]=\"headerRowHeight\"\n [class.border-right]=\"showVerticalBorder\"\n style=\"grid-row: 3\"\n >\n <div\n class=\"header-cell filter-cell\"\n [attr.field]=\"col.field\"\n [style.width.px]=\"col.width\"\n [style.min-width.px]=\"col.width\"\n [style.height.px]=\"headerRowHeight\"\n [style.min-height.px]=\"headerRowHeight\"\n [style.max-height.px]=\"headerRowHeight\"\n >\n <input\n type=\"text\"\n class=\"form-control form-control-sm\"\n placeholder=\"Filter\"\n [(ngModel)]=\"child.filterValue\"\n (ngModelChange)=\"onFilterChange(child)\"\n (paste)=\"onFilterChange(child); applyDropdownFilter()\"\n [readonly]=\"\n child?.type == 'dropdown' || child?.type == 'image'\n \"\n [class.disabled-search-input]=\"\n child?.type == 'dropdown' || child?.type == 'image'\n \"\n (click)=\"\n $event.stopPropagation();\n openFilterFromDisabledSearchedInput(child)\n \"\n (keydown.enter)=\"applyDropdownFilter()\"\n (mousedown)=\"$event.stopPropagation()\"\n />\n <span\n class=\"filter-icon-wrapper\"\n (click)=\"$event.stopPropagation(); openFilter(child)\"\n [class.filter-applied]=\"isFilterAppliedOnColumn(child)\"\n [class.pe-none]=\"child?.type == 'image'\"\n ><span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\n \"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n <span\n *ngIf=\"isFilterAppliedOnColumn(child)\"\n style=\"\n width: 7px;\n height: 7px;\n box-shadow: 0px 0px 3px #7486ff;\n background-color: rgb(0 163 233);\n position: absolute;\n right: 4px;\n top: 12px;\n \"\n class=\"rounded-circle d-block\"\n ></span\n ></span>\n\n <div\n class=\"position-absolute filter-row-filter-wrapper\"\n *ngIf=\"activeFilterCell?.field == child?.field\"\n style=\"top: 100%; right: 0; z-index: 99\"\n [style.left.px]=\"\n child?.pinned ? 0 : -centerPinnedHeader.scrollLeft\n \"\n >\n <ng-container\n *ngTemplateOutlet=\"filterMenu; context: { col: child }\"\n ></ng-container>\n </div>\n </div>\n </div>\n </ng-container>\n <ng-template cdkDragPreview\n ><div class=\"p-2 border d-flex gap-2\">\n <div\n *ngIf=\"\n !draggingInGroupArea ||\n (child.is_groupable && draggingInGroupArea)\n \"\n >\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/arrows-move.svg'\n \"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n </div>\n <div *ngIf=\"draggingInGroupArea && !child.is_groupable\">\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/ban.svg'\n \"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n </div>\n <div>{{ child.header }}</div>\n </div>\n </ng-template>\n <ng-template cdkDragPlaceholder>\n <div *ngIf=\"!draggingInGroupArea\" class=\"position-relative\">\n <div\n *ngTemplateOutlet=\"\n childHeaderPlaceholder;\n context: {\n $implicit: child,\n index: i,\n sections: sections,\n calledFromNestedPlaceholder: true,\n }\n \"\n ></div>\n </div>\n <div\n *ngIf=\"draggingInGroupArea && child?.is_groupable\"\n class=\"d-flex gap-2 ms-2\"\n style=\"opacity: 0.6\"\n >\n <ng-container\n *ngTemplateOutlet=\"\n topGroupingRowPlaceholder;\n context: {\n $implicit: child,\n showChevron: false,\n pinnedRight: pinnedRight,\n sections: sections,\n index: i\n }\n \"\n ></ng-container>\n </div>\n </ng-template>\n </div>\n </div>\n </div>\n </ng-container>\n\n <!-- Flat Header || Single Header Cell-->\n <ng-template #flatHeader>\n <div\n class=\"group-column-wrapper\"\n *ngIf=\"col.is_visible && !col['isRowGrouped']\"\n >\n <!-- Full-height Header Cell (spans 2 rows visually) -->\n <div\n class=\"header-cell one-row-header-cells\"\n [attr.field]=\"col.field\"\n [style.width.px]=\"col.width\"\n [style.min-width.px]=\"col.width\"\n [class.border-right]=\"showVerticalBorder\"\n [style.min-height.px]=\"\n showColumnsGrouping ? headerRowHeight * 2 : headerRowHeight\n \"\n [style.height.px]=\"\n showColumnsGrouping ? headerRowHeight * 2 : headerRowHeight\n \"\n [style.fontWeight]=\"headerFontWeight\"\n style=\"grid-row: 1 / span 2\"\n >\n <div\n class=\"d-flex justify-content-between h-100 align-items-center w-100\"\n >\n <div\n class=\"d-flex justify-content-between w-100 align-items-center\"\n [class.flex-row-reverse]=\"pinnedRight\"\n >\n <div\n class=\"text-ellipsis h-100 d-flex align-items-center w-100\"\n [title]=\"col.header\"\n >\n <div\n class=\"text-ellipsis h-100 cursor-pointer\"\n [class.editable-header]=\"col?.is_editable\"\n [class.filter-applied-on-text]=\"isFilterAppliedOnColumn(col)\"\n (click)=\"\n openThreeDotsMenu($event, col);\n openFilteronThreeDotsClick(col)\n \"\n >\n {{ col.header }}\n </div>\n </div>\n\n <div\n class=\"position-relative d-flex align-items-center\"\n [class.flex-row-reverse]=\"pinnedRight\"\n >\n <div\n [class.me-2]=\"pinnedRight\" [class.threeDotActive]=\"activeCol === col && !clickedOnSortIcon\"\n class=\"d-flex align-items-center three-dots\"\n *ngIf=\"col?.pinned\">\n <span (click)=\"\n openThreeDotsMenu($event, col, false);\n isThreeDotsFilterOpen = false\n \"\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/pin.svg'\n \"\n class=\"data-grid-svg-icon setting_dropdown d-flex justify-content-center align-items-center pin_blue_icon\"\n ></span>\n </div>\n <!-- <div\n [class.me-2]=\"col.order_by\"\n class=\"d-flex align-items-center\"\n *ngIf=\"sortingConfig?.field == col.field\">\n <span\n *ngIf=\"sortingConfig?.order_by == 'asc'\"\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/selectedAscIcon.svg'\n \"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center mt-1 cursor-pointer\"\n (click)=\"sortDesc(col)\"\n [class.active]=\"sortingConfig?.order_by === 'asc'\"\n ></span>\n <span\n *ngIf=\"sortingConfig?.order_by == 'desc'\"\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/selectedAscIcon.svg'\n \"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center mt-1 cursor-pointer\"\n (click)=\"sortAsc(col)\"\n [class.active]=\"sortingConfig?.order_by === 'desc'\"\n ></span>\n </div> -->\n <div class=\"three-dots p-1 me-0 zaid-test1\" [class.threeDotActive]=\"activeCol === col && clickedOnSortIcon\"\n (click)=\"openThreeDotsMenu($event, col, true);\"\n style=\"cursor: pointer\">\n <div *ngIf=\"sortingConfig?.field === col.field\" \n class=\"d-flex align-items-center\">\n \n <!-- Ascending Sort Icon -->\n <span\n *ngIf=\"sortingConfig?.order_by == 'asc'\"\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/sort-ascending-green.svg'\"\n class=\"data-grid-svg-icon ascendingAppliedIcon flex justify-content-center align-items-center cursor-pointer\"\n (click)=\"openThreeDotsMenu($event, col, true)\"\n [class.active]=\"sortingConfig?.order_by === 'asc'\">\n </span>\n\n <!-- Descending Sort Icon -->\n <span\n *ngIf=\"sortingConfig?.order_by == 'desc'\"\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/sort-ascending-green.svg'\"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center cursor-pointer rotated-180\"\n (click)=\"openThreeDotsMenu($event, col, true)\"\n [class.active]=\"sortingConfig?.order_by === 'desc'\">\n </span>\n </div>\n <span *ngIf=\"sortingConfig?.field !== col.field\"\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/sortIconGray.svg'\"\n class=\"data-grid-svg-icon figmaIconSize d-flex justify-content-center align-items-center\"\n (click)=\"openThreeDotsMenu($event, col, true)\">\n </span>\n </div>\n <div class=\"three-dots p-1 zaid-test1\" [class.threeDotActive]=\"activeCol === col && !clickedOnSortIcon\" *ngIf=\"!col?.pinned\"\n (click)=\"\n openThreeDotsMenu($event, col, false);\n isThreeDotsFilterOpen = false\n \"\n style=\"cursor: pointer\">\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath +\n 'data-grid/icons/three-dots-vertical.svg'\n \"\n class=\"data-grid-svg-icon setting_dropdown dropdown d-flex justify-content-center align-items-center\"\n ></span>\n </div>\n\n <!-- Only show menu if this column is active -->\n <div\n class=\"position-absolute\"\n *ngIf=\"activeCol === col\"\n style=\"z-index: 21\"\n [style.left.px]=\"\n -(!col?.pinned ? centerPinnedHeader.scrollLeft : 0)\n \"\n [style.top.px]=\"\n isThreeDotsFilterOpen\n ? showFilterRow || showColumnsGrouping\n ? headerRowHeight * 2 - 10\n : headerRowHeight - 10\n : 25\n \"\n >\n <ng-container\n *ngTemplateOutlet=\"\n columnMenu;\n context: {\n col: col,\n isNestedTable: false,\n section: sections\n }\n \"\n ></ng-container>\n </div>\n\n <div\n class=\"resize-handle\"\n [class.w-100]=\"col.pinned == 'right'\"\n (dblclick)=\"autosizeColumn(col)\"\n (mousedown)=\"\n $event.stopPropagation(); onResizeColumn($event, col)\n \"\n >\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/resize-handle1.svg'\n \"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n </div>\n </div>\n </div>\n </div>\n </div>\n\n <!-- Filter Cell -->\n <div\n *ngIf=\"showFilterRow\"\n [style.backgroundColor]=\"headerBackgroundColor\"\n class=\"header-cell filter-cell\"\n [class.border-right]=\"showVerticalBorder\"\n [attr.field]=\"col.field\"\n [style.width.px]=\"col.width\"\n [style.min-width.px]=\"col.width\"\n [style.height.px]=\"headerRowHeight\"\n [style.min-height.px]=\"headerRowHeight\"\n [style.max-height.px]=\"headerRowHeight\"\n >\n <input\n type=\"text\"\n class=\"form-control form-control-sm\"\n placeholder=\"Filter\"\n [(ngModel)]=\"col.filterValue\"\n (ngModelChange)=\"onFilterChange(col)\"\n [readonly]=\"col?.type == 'dropdown' || col?.type == 'image'\"\n [class.disabled-search-input]=\"\n col?.type == 'dropdown' || col?.type == 'image'\n \"\n (paste)=\"onPasteInFilterRowSearch($event, col)\"\n (click)=\"\n $event.stopPropagation(); openFilterFromDisabledSearchedInput(col)\n \"\n (keydown.enter)=\"applyDropdownFilter()\"\n (mousedown)=\"$event.stopPropagation()\"\n />\n <span\n class=\"filter-icon-wrapper\"\n (click)=\"$event.stopPropagation(); openFilter(col)\"\n [class.filter-applied]=\"isFilterAppliedOnColumn(col)\"\n [class.pe-none]=\"col?.type == 'image'\"\n ><span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n <span\n *ngIf=\"isFilterAppliedOnColumn(col)\"\n style=\"\n width: 7px;\n height: 7px;\n box-shadow: 0px 0px 3px #7486ff;\n background-color: rgb(0 163 233);\n position: absolute;\n right: 4px;\n top: 12px;\n \"\n class=\"rounded-circle d-block\"\n ></span\n ></span>\n\n <div\n class=\"position-absolute filter-row-filter-wrapper\"\n *ngIf=\"activeFilterCell === col\"\n style=\"top: 100%; right: 0; z-index: 99\"\n [style.left.px]=\"col?.pinned ? 0 : -centerPinnedHeader.scrollLeft\"\n >\n <ng-container\n *ngTemplateOutlet=\"filterMenu; context: { col: col }\"\n ></ng-container>\n </div>\n </div>\n </div>\n </ng-template>\n </div>\n</ng-template>\n\n<!-- -------------------------------------------------------------------------------------------------------------------------------------------------------------------- -->\n<!-- -------------------------------------------------------------------------------------------------------------------------------------------------------------------- -->\n<!-- Body Cell Template -->\n<!-- -------------------------------------------------------------------------------------------------------------------------------------------------------------------- -->\n<!-- -------------------------------------------------------------------------------------------------------------------------------------------------------------------- -->\n\n<ng-template\n #rowCell\n let-row\n let-columns=\"columns\"\n let-isEven=\"isEven\"\n let-isOdd=\"isOdd\"\n let-isLeftSection=\"isLeft\"\n let-section=\"section\"\n let-rowIndex=\"rowIndex\"\n let-isTotalRow=\"isTotalRow\"\n>\n <!-- Check if row is a group -->\n <ng-container\n *ngTemplateOutlet=\"groupRowTemplate; context: { $implicit: row, depth: 0 }\"\n ></ng-container>\n <ng-template #groupRowTemplate let-row let-depth=\"depth\">\n <ng-container *ngIf=\"row.isGroup; else regularRow\">\n <!-- Group Header -->\n <div\n class=\"group-header-row d-flex align-items-center\"\n [style.height.px]=\"rowHeight\"\n [class.border-below]=\"section !== 'center'\"\n [style.width]=\"\n section === 'center'\n ? (centerScrollableBody?.scrollWidth ?? 0) + 'px'\n : '100%'\n \"\n >\n <div\n *ngIf=\"section == 'left'\"\n class=\"h-100 d-flex\"\n [style.width.px]=\"leftPinnedHeader.offsetWidth - 1\"\n [class.row-selected]=\"rowSelectedIndexes.has(row.__virtualIndex)\"\n >\n <div\n *ngIf=\"showSerialNumber\"\n style=\"width: 50px\"\n class=\"d-flex align-items-center h-100 border-right justify-content-end pe-2 s-no\"\n [style.backgroundColor]=\"checkboxesBackgroundColor\"\n [style.width.px]=\"55\"\n [style.cursor]=\"\n 'url(' +\n singleSpaAssetsPath +\n 'data-grid/icons/arrow-right.svg), auto'\n \"\n (mousedown)=\"onRowMouseDown(row.__virtualIndex, $event)\"\n (mouseover)=\"onRowMouseOver(row.__virtualIndex, $event)\"\n [style.color]=\"checkboxesColor\"\n >\n {{ getStartIndex() + (row.__virtualIndex - 1) || \"\" }}\n </div>\n <div\n *ngIf=\"showCheckboxes\"\n style=\"width: 50px\"\n class=\"d-flex align-items-center justify-content-center h-100 border-right\"\n [style.backgroundColor]=\"checkboxesBackgroundColor\"\n [class.row-selected]=\"rowSelectedIndexes.has(row.__virtualIndex)\"\n [class.left-selection-border]=\"\n rowSelectedIndexes.has(row.__virtualIndex)\n \"\n [class.first-row-selected]=\"firstSelectedRow === row.__virtualIndex\"\n [class.last-row-selected]=\"lastSelectedRow === row.__virtualIndex\"\n [style.color]=\"checkboxesColor\"\n >\n <input\n style=\"width: 16px; height: 16px\"\n type=\"checkbox\"\n [checked]=\"getGroupCheckedState(row) === true\"\n [indeterminate]=\"getGroupCheckedState(row) === undefined\"\n (change)=\"selectGroupRow($event, row)\"\n />\n\n </div>\n </div>\n\n <div\n *ngIf=\"section == 'center'\"\n [style.width.px]=\"centerPinnedHeader.scrollWidth\"\n [style.minWidth.px]=\"centerPinnedHeader.scrollWidth\"\n class=\"d-flex align-items-center ps-2 h-100 border-below\"\n [class.row-selected]=\"rowSelectedIndexes.has(row.__virtualIndex)\"\n [class.first-row-selected]=\"firstSelectedRow === row.__virtualIndex\"\n [class.last-row-selected]=\"lastSelectedRow === row.__virtualIndex\"\n >\n <div\n class=\"d-flex align-items-center justify-content-between\"\n [style.paddingLeft.px]=\"depth > 0 ? depth * 30 : 0\"\n >\n <span class=\"me-2 filter-icon-wrapper\" (click)=\"toggleExpand(row)\">\n <span\n class=\"data-grid-svg-icon align-items-center d-flex\"\n [inlineSVG]=\"\n row.isExpand\n ? singleSpaAssetsPath + 'data-grid/icons/chevron-down.svg'\n : singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\n \"\n ></span>\n </span>\n <strong (click)=\"toggleExpand(row)\" class=\"cursor-pointer\">\n {{ row.groupValue }} ({{ countLeafRows(row) }})\n </strong>\n </div>\n </div>\n\n <div\n *ngIf=\"section == 'right'\"\n [style.width.px]=\"rightPinnedHeader.offsetWidth\"\n [class.row-selected]=\"rowSelectedIndexes.has(row.__virtualIndex)\"\n [class.first-row-selected]=\"firstSelectedRow === row.__virtualIndex\"\n [class.last-row-selected]=\"lastSelectedRow === row.__virtualIndex\"\n ></div>\n </div>\n\n <!-- Recursive Children -->\n <div class=\"group-children\" *ngIf=\"row.isExpand\" [@slideToggle]>\n <ng-container\n *ngFor=\"let child of row.children; let i = index; trackBy: trackById\"\n >\n <ng-container *ngIf=\"child.isGroup; else dataRow\">\n <!-- Recursive call for nested group -->\n <ng-container\n *ngTemplateOutlet=\"\n groupRowTemplate;\n context: { $implicit: child, depth: depth + 1 }\n \"\n ></ng-container>\n </ng-container>\n\n <ng-template #dataRow>\n <!-- Regular data row -->\n <ng-container\n *ngTemplateOutlet=\"\n rowCell;\n context: {\n $implicit: child,\n columns: columns,\n isEven: i % 2 === 0,\n isOdd: i % 2 !== 0,\n isLeft: isLeftSection,\n section: section,\n isTotalRow: isTotalRow\n }\n \"\n ></ng-container>\n </ng-template>\n </ng-container>\n </div>\n </ng-container>\n </ng-template>\n\n <!-- Regular row (not a group) -->\n <ng-template #regularRow>\n <div\n class=\"d-flex\"\n [style.height.px]=\"rowHeight\"\n [style.minHeight.px]=\"rowHeight\"\n [style.maxHeight.px]=\"rowHeight\"\n >\n <span\n class=\"d-flex align-items-center justify-content-center cursor-pointer border-below\"\n style=\"min-width: 30px; height: 100%\"\n *ngIf=\"section == 'center' && (gridType === 'Assets' || gridType === 'Tasks')\"\n [ngStyle]=\"{\n 'background-color': rowSelectedIndexes.has(row.__virtualIndex)\n ? null\n : getBackgroundColor(row, isEven, section)\n }\"\n [class.selected-cell]=\"rowSelectedIndexes.has(row.__virtualIndex)\"\n [class.first-row-selected]=\"firstSelectedRow === row.__virtualIndex\"\n [class.last-row-selected]=\"lastSelectedRow === row.__virtualIndex\"\n >\n <span\n (click)=\"toggleDetailRowExpand(row)\"\n *ngIf=\"row?.detail?.result?.length || gridType === 'Tasks'\"\n class=\"data-grid-svg-icon filter-icon-wrapper\"\n [inlineSVG]=\"\n isDetailsExpanded(row)\n ? singleSpaAssetsPath + 'data-grid/icons/chevron-down.svg'\n : singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\n \"\n ></span>\n </span>\n <div\n [style.min-width.px]=\"\n section == 'center' && groupedColumns?.length ? groupBoxPadding : 0\n \"\n [class.row-selected]=\"rowSelectedIndexes.has(row.__virtualIndex)\"\n [class.first-row-selected]=\"firstSelectedRow === row.__virtualIndex\"\n [class.last-row-selected]=\"lastSelectedRow === row.__virtualIndex\"\n (contextmenu)=\"onRightClick($event, row)\"\n [style.height.px]=\"rowHeight\"\n class=\"data-grid-row h-100\"\n [class.even-row]=\"isEven\"\n [class.odd-row]=\"isOdd\"\n [class.hovered-row]=\"hoveredRowId === (row._id || row.id)\"\n (mouseenter)=\"onRowHover(row)\"\n (mouseleave)=\"onRowLeave()\"\n [ngStyle]=\"{\n 'background-color': getBackgroundColor(row, isEven, section)\n }\"\n [style.minHeight.px]=\"rowHeight\"\n [style.maxHeight.px]=\"rowHeight\"\n ></div>\n <div\n (contextmenu)=\"onRightClick($event, row)\"\n [style.height.px]=\"rowHeight\"\n class=\"data-grid-row\"\n [class.even-row]=\"isEven\"\n [class.odd-row]=\"isOdd\"\n [class.hovered-row]=\"hoveredRowId === (row._id || row.id)\"\n (mouseenter)=\"onRowHover(row)\"\n (mouseleave)=\"onRowLeave()\"\n [ngStyle]=\"{\n 'background-color': getBackgroundColor(row, isEven, section)\n }\"\n >\n <div\n [style.backgroundColor]=\"checkboxesBackgroundColor\"\n [ngStyle]=\"{\n 'background-color': rowSelectedIndexes.has(row.__virtualIndex)\n ? null\n : getBackgroundColor(row, isEven, section)\n }\"\n class=\"select-all-checkbox-cell border-below justify-content-end pe-2 s-no\"\n [style.width.px]=\"55\"\n *ngIf=\"isLeftSection && showSerialNumber\"\n [style.cursor]=\"\n 'url(' +\n singleSpaAssetsPath +\n 'data-grid/icons/arrow-right.svg), auto'\n \"\n (mousedown)=\"onRowMouseDown(row.__virtualIndex, $event)\"\n (mouseover)=\"onRowMouseOver(row.__virtualIndex, $event)\"\n [style.color]=\"checkboxesColor\"\n >\n {{ getStartIndex() + (row.__virtualIndex - 1) }}\n </div>\n <div\n [style.backgroundColor]=\"\n rowSelectedIndexes.has(row.__virtualIndex)\n ? selectedRowsBackgroundColor\n : checkboxesBackgroundColor\n \"\n [ngStyle]=\"{\n 'background-color': rowSelectedIndexes.has(row.__virtualIndex)\n ? null\n : getBackgroundColor(row, isEven, section)\n }\"\n class=\"select-all-checkbox-cell border-below left_checkbox_ailgnment\"\n *ngIf=\"isLeftSection && showCheckboxes\"\n [class.left-selection-border]=\"\n rowSelectedIndexes.has(row.__virtualIndex)\n \"\n [class.first-row-selected]=\"firstSelectedRow === row.__virtualIndex\"\n [class.last-row-selected]=\"lastSelectedRow === row.__virtualIndex\"\n [style.minHeight.px]=\"rowHeight\"\n [style.maxHeight.px]=\"rowHeight\"\n >\n <input class=\"serialNoCheckbox\"\n *ngIf=\"hasAnyVisibleColumn\"\n style=\"width: 16px; height: 16px\"\n type=\"checkbox\"\n [checked]=\"isRowSelected(row)\"\n (change)=\"toggleRowSelection(row)\"\n />\n </div>\n\n <!-- Render all columns -->\n <ng-container\n *ngFor=\"\n let col of columns;\n trackBy: trackByField;\n let colIndex = index\n \"\n >\n <ng-container *ngIf=\"col.children?.length > 0; else flatColumn\">\n <ng-container\n *ngFor=\"\n let child of col.children;\n trackBy: trackByField;\n let subColIndex = index\n \"\n >\n <ng-container *ngIf=\"child?.is_visible && !child?.isRowGrouped\">\n <ng-container\n *ngTemplateOutlet=\"\n cellTemplate;\n context: {\n col: child,\n row: row,\n rowIndex: rowIndex,\n colIndex: colIndex,\n subColIndex: subColIndex,\n section: section,\n isTotalRow: isTotalRow\n }\n \"\n ></ng-container>\n </ng-container>\n </ng-container>\n </ng-container>\n\n <ng-template #flatColumn>\n <ng-container *ngIf=\"col?.is_visible && !col?.isRowGrouped\">\n <ng-container\n *ngTemplateOutlet=\"\n cellTemplate;\n context: {\n col: col,\n row: row,\n rowIndex: rowIndex,\n colIndex: colIndex,\n subColIndex: null,\n section: section,\n isTotalRow: isTotalRow\n }\n \"\n ></ng-container>\n </ng-container>\n </ng-template>\n </ng-container>\n </div>\n </div>\n\n <div\n [@slideToggle]\n *ngIf=\"section === 'left' && isDetailsExpanded(row)\"\n class=\"accordion-details\"\n style=\"max-height: 350px; overflow: hidden\"\n [style.maxHeight.px]=\"hasHorizontalScroll ? 339 : 341\"\n >\n <ng-container\n *ngTemplateOutlet=\"\n leftRightNestedPlaceholder;\n context: { $implicit: row }\n \"\n >\n </ng-container>\n </div>\n\n <div\n [@slideToggle]\n *ngIf=\"section === 'center' && isDetailsExpanded(row)\"\n class=\"accordion-details center-section\"\n style=\"\n max-height: 350px;\n overflow-y: hidden;\n overflow-x: auto;\n scrollbar-width: thin;\n \"\n #nestedTable\n [style.width]=\"\n hasRightPinnedColumns\n ? '100%'\n : hasVerticalScroll\n ? 'calc(100% - 12px)'\n : '100%'\n \"\n >\n <ng-container *ngIf=\"gridType == 'Assets'\">\n <ng-container\n *ngTemplateOutlet=\"nestedTableTemplate; context: { $implicit: row }\"\n ></ng-container>\n </ng-container>\n <ng-container *ngIf=\"gridType == 'Tasks'\">\n <ng-container\n *ngTemplateOutlet=\"\n taskManagementTemplate;\n context: { taskDetails: row }\n \"\n ></ng-container>\n </ng-container>\n </div>\n\n <div\n [@slideToggle]\n *ngIf=\"section === 'right' && isDetailsExpanded(row)\"\n class=\"accordion-details\"\n style=\"max-height: 350px; overflow: hidden\"\n [style.maxHeight.px]=\"hasHorizontalScroll ? 339 : 341\"\n >\n <ng-container\n *ngTemplateOutlet=\"\n leftRightNestedPlaceholder;\n context: { $implicit: row }\n \"\n >\n </ng-container>\n </div>\n </ng-template>\n</ng-template>\n\n<!-- Actual Cell is Here -->\n<ng-template\n #cellTemplate\n let-col=\"col\"\n let-row=\"row\"\n let-section=\"section\"\n let-subColIndex=\"subColIndex\"\n let-rowIndex=\"rowIndex\"\n let-colIndex=\"colIndex\"\n let-isTotalRow=\"isTotalRow\"\n>\n <div\n #cellContainer\n (click)=\"\n editingKey = ''; setActiveCell(row, col); collapseAllExpandedCells()\n \"\n [style.fontWeight]=\"bodyFontWeight\"\n [class.border-right]=\"showVerticalBorder\"\n class=\"cell overflow-visible position-relative data-grid-cell\"\n [attr.field]=\"col.field\"\n [style.width.px]=\"col.width\"\n [style.min-width.px]=\"col.width\"\n [style.fontSize.px]=\"bodyTextFontsSize\"\n [style.minHeight.px]=\"rowHeight\"\n [style.maxHeight.px]=\"rowHeight\"\n [class.active-cell]=\"\n isActiveCell(row, col) && !isEditing(row, col) && selectedKeys.size == 1\n \"\n (dblclick)=\"\n $event.stopPropagation();\n $event.preventDefault();\n enableEdit(row, col, false, cellContainer)\n \"\n [class.row-selected]=\"rowSelectedIndexes.has(row.__virtualIndex)\"\n [class.first-row-selected]=\"firstSelectedRow === row?.__virtualIndex\"\n [class.last-row-selected]=\"lastSelectedRow === row?.__virtualIndex\"\n tabindex=\"-1\"\n (keydown.enter)=\"$event.preventDefault(); enableEdit(row, col)\"\n (mousedown)=\"\n startSelection(\n row.__virtualIndex,\n colIndex,\n subColIndex ?? 0,\n col.field,\n $event,\n section\n )\n \"\n (mouseenter)=\"\n extendSelection(\n row.__virtualIndex,\n colIndex,\n subColIndex ?? 0,\n col.field,\n $event,\n section\n )\n \"\n (mouseup)=\"endSelection()\"\n [class.selected-cell]=\"\n isSelected(\n row.__virtualIndex,\n colIndex,\n subColIndex ?? 0,\n col.field,\n section\n )\n \"\n [class.top-border]=\"\n isTopBorder(row.__virtualIndex, colIndex, subColIndex, section)\n \"\n [class.bottom-border]=\"\n isBottomBorder(row.__virtualIndex, colIndex, subColIndex, section)\n \"\n [class.left-border]=\"\n isLeftBorder(row.__virtualIndex, colIndex, subColIndex, section)\n \"\n [class.right-border]=\"\n isRightBorder(row.__virtualIndex, colIndex, subColIndex, section)\n \"\n [class.top-left-corner]=\"\n isTopLeftCorner(row.__virtualIndex, colIndex, subColIndex, section)\n \"\n [class.top-right-corner]=\"\n isTopRightCorner(row.__virtualIndex, colIndex, subColIndex, section)\n \"\n [class.bottom-left-corner]=\"\n isBottomLeftCorner(row.__virtualIndex, colIndex, subColIndex, section)\n \"\n [class.bottom-right-corner]=\"\n isBottomRightCorner(row.__virtualIndex, colIndex, subColIndex, section)\n \"\n >\n <!-- (mousedown)=\"startSelection(row.__virtualIndex, colIndex, subColIndex ?? 0, col.field, $event)\"\n (mouseenter)=\"extendSelection(row.__virtualIndex, colIndex, subColIndex ?? 0, col.field, $event)\"\n (mouseup)=\"endSelection()\"\n [class.selected-cell]=\"isSelected(row.__virtualIndex, colIndex, subColIndex ?? 0, col.field)\" -->\n <div\n class=\"table-cell\"\n [class.active-for-editing]=\"\n isEditing(row, col) &&\n (getNestedValue(row, col.field)?.length === undefined ||\n getNestedValue(row, col.field)?.length <= 50)\n \"\n >\n <div\n (click)=\"$event.stopPropagation()\"\n *ngIf=\"\n isEditing(row, col) &&\n (getNestedValue(row, col.field)?.length === undefined ||\n (getNestedValue(row, col.field)?.length <= 50 &&\n !expandedCells.size));\n else viewMode\n \"\n >\n <ng-container [ngSwitch]=\"col.type\">\n <!-- Text Input -->\n <input\n [style.height.px]=\"rowHeight - 10\"\n *ngSwitchCase=\"'input'\"\n type=\"text\"\n [(ngModel)]=\"row[col.field]\"\n (blur)=\"disableEdit(row, col)\"\n autofocus\n class=\"form-control form-control-sm\"\n (mousedown)=\"$event.stopPropagation()\"\n />\n\n <!-- Number Input -->\n <input\n [style.height.px]=\"rowHeight - 8\"\n *ngSwitchCase=\"'number'\"\n #numberInput=\"ngModel\"\n #numberRef\n (keypress)=\"allowOnlyNumbers($event)\"\n type=\"number\"\n required\n [(ngModel)]=\"row[col.field]\"\n (blur)=\"disableEdit(row, col)\"\n autofocus\n (keydown.enter)=\"numberRef.blur()\"\n class=\"form-control form-control-sm\"\n [ngClass]=\"{\n 'is-invalid': numberInput.invalid\n }\"\n (mousedown)=\"$event.stopPropagation()\"\n />\n\n <!-- Date Input -->\n <input\n [style.height.px]=\"rowHeight - 8\"\n *ngSwitchCase=\"'date'\"\n type=\"date\"\n [(ngModel)]=\"row[col.field]\"\n (blur)=\"disableEdit(row, col)\"\n autofocus\n class=\"form-control form-control-sm\"\n #dateInput=\"ngModel\"\n [ngClass]=\"{\n 'is-invalid': dateInput.invalid\n }\"\n (mousedown)=\"$event.stopPropagation()\"\n />\n\n <!-- Dropdown -->\n <!-- ng-select like dropdown -->\n <div\n *ngSwitchCase=\"'dropdown'\"\n class=\"dropdown w-100\"\n (blur)=\"disableEdit(row, col)\"\n >\n <!-- Trigger -->\n <button\n class=\"form-select form-select-sm text-start w-100 text-ellipsis\"\n type=\"button\"\n data-bs-toggle=\"dropdown\"\n aria-expanded=\"false\"\n [style.minHeight.px]=\"rowHeight - 10\"\n data-bs-display=\"static\"\n (mousedown)=\"$event.stopPropagation()\"\n >\n <ng-container>\n {{\n getNestedValue(row, col.field)?.value ||\n getNestedValue(row, col.field)?.name ||\n getNestedValue(row, col.field)\n }}\n </ng-container>\n <ng-template #placeholder> Select options... </ng-template>\n </button>\n\n <!-- Menu -->\n <div\n class=\"dropdown-menu w-100 p-0 cell-editing-dropdown-menu rounded-3\"\n [class.show]=\"isEditing(row, col)\"\n >\n <!-- Search -->\n <div class=\"px-2 py-1 editing-dropdown-search-input\">\n <input\n type=\"text\"\n class=\"form-control form-control-sm\"\n placeholder=\"Search...\"\n [(ngModel)]=\"editinDropdownSearch\"\n (mousedown)=\"$event.stopPropagation()\"\n />\n </div>\n\n <!-- Options -->\n <!-- <div\n class=\"cell-editin-dropdown\"\n style=\"max-height: 200px; overflow: auto\"\n >\n <div\n (click)=\"\n setNestedValue(row, col, option, true); editingKey = null\n \"\n class=\"px-2 py-1 d-flex align-items-center deopdown-item\"\n *ngFor=\"\n let option of col.column_dropdown_value\n | filter : editinDropdownSearch: 'value'\n \"\n >\n <label\n class=\"form-check-label d-flex align-items-center mb-0 cursor-pointer\"\n [for]=\"col.field + '-' + option.value || option\"\n >\n {{ option.value || option }}\n </label>\n </div>\n </div> -->\n <cdk-virtual-scroll-viewport \n itemSize=\"35\" \n class=\"dropdown-viewport\"\n style=\"height: 120px\"\n >\n <div\n class=\"px-2 py-1 d-flex align-items-center dropdown-item\"\n *cdkVirtualFor=\"\n let option of col.column_dropdown_value \n | filter : editinDropdownSearch : 'value'\n \"\n (click)=\"setNestedValue(row, col, option, true); editingKey = null\"\n >\n <label\n class=\"form-check-label d-flex align-items-center mb-0 cursor-pointer\"\n [for]=\"col.field + '-' + (option.value || option)\"\n >\n {{ option.value || option }}\n </label>\n </div>\n </cdk-virtual-scroll-viewport>\n\n </div>\n </div>\n\n <input\n *ngSwitchCase=\"'email'\"\n [style.height.px]=\"rowHeight - 10\"\n [style.maxHeight.px]=\"rowHeight - 10\"\n #emailModel=\"ngModel\"\n #emailInput\n type=\"email\"\n [(ngModel)]=\"row[col.field]\"\n name=\"{{ col.field }}\"\n required\n pattern=\"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$\"\n (blur)=\"disableEdit(row, col, emailModel)\"\n (keydown.enter)=\"\n emailModel.control.markAsTouched(); emailInput.blur()\n \"\n autofocus\n class=\"form-control form-control-sm\"\n [ngClass]=\"{\n 'is-invalid': emailModel.invalid\n }\"\n (mousedown)=\"$event.stopPropagation()\"\n />\n <!-- Default fallback -->\n <input\n *ngSwitchDefault\n [style.height.px]=\"rowHeight - 10\"\n [style.maxHeight.px]=\"rowHeight - 10\"\n #textModel=\"ngModel\"\n #textInput\n type=\"text\"\n [(ngModel)]=\"row[col.field]\"\n name=\"{{ col.field }}\"\n required\n (blur)=\"disableEdit(row, col, textModel)\"\n (keydown.enter)=\"\n textModel.control.markAsTouched(); textInput.blur()\n \"\n autofocus\n class=\"form-control form-control-sm\"\n [ngClass]=\"{\n 'is-invalid': textModel.invalid\n }\"\n (mousedown)=\"$event.stopPropagation()\"\n />\n </ng-container>\n </div>\n\n <!-- Display mode -->\n <ng-template #viewMode>\n <div\n class=\"d-flex justify-content-between align-items-center overflow-hidden\"\n [ngClass]=\"getCellClasses(col, getNestedValue(row, col.field))\"\n >\n <!-- Field icon (for Tasks grid) -->\n <ng-container\n *ngIf=\"gridType === 'Tasks' && iconMap[col.field] && !isTotalRow\"\n >\n <span\n class=\"cursor-pointer me-2\"\n (click)=\"$event.preventDefault(); $event.stopPropagation()\"\n [inlineSVG]=\"iconMap[col.field](row, col)\"\n ></span>\n </ng-container>\n\n <!-- \u2705 Custom cell renderer support -->\n <ng-container *ngIf=\"col.cellRenderer; else defaultCell\">\n <ng-container\n [cellRenderInit]=\"col.cellRenderer\"\n [rowData]=\"row\"\n [colData]=\"col\"\n [cellValue]=\"getNestedValue(row, col?.field)\"\n (cellEvent)=\"onCellEvent($event)\"\n >\n </ng-container>\n </ng-container>\n\n <!-- \uD83E\uDDFE Default text-based cell rendering -->\n <ng-template #defaultCell>\n <div\n #cellText\n class=\"text-ellipsis flex-grow-1\"\n [title]=\"getCellTitle(row, col)\"\n >\n <!-- Normal cell -->\n <ng-container\n *ngIf=\"\n col.type !== 'image' &&\n col.field != 'image' &&\n col.field != 'invoice.invoice_image' &&\n !isTotalRow\n \"\n >\n <ng-container *ngIf=\"col.is_amount\">{{\n currencySymbol\n }}</ng-container>\n {{getCellTitle(row, col)}}\n </ng-container>\n\n <!-- Total row -->\n <ng-container *ngIf=\"isTotalRow\">\n {{ getTotalAmount(col) }}\n </ng-container>\n\n <!-- Invoice Image -->\n <ng-container *ngIf=\"col.field == 'invoice.invoice_image'\">\n <div style=\"display: flex; align-items: center; zoom: 0.7\">\n <span\n title=\"{{ getNestedValue(row, col.field) || 'Attachment' }}\"\n (click)=\"downloadAttchment(getNestedValue(row, col.field))\"\n [inlineSVG]=\"\n singleSpaAssetsPath +\n 'data-grid/document-icons/' +\n getExtention(getNestedValue(row, col.field)) +\n '.svg'\n \"\n ></span>\n </div>\n </ng-container>\n\n <!-- Image cell -->\n <ng-container *ngIf=\"col.type == 'image' && !isTotalRow\">\n <ng-container\n *ngTemplateOutlet=\"\n defaultImagePlaceholder;\n context: { row: row, col: col }\n \"\n ></ng-container>\n </ng-container>\n </div>\n <span\n *ngIf=\"\n (!col?.cellRenderer && showCellDetailsBox &&\n getNestedValue(row, col.field)?.length > 50 && col.type !== 'image') ||\n (isNestedValueArray(row, col.field) &&\n getNestedValue(row, col.field)?.length > 1)\n \"\n class=\"toggle-icon data-grid-svg-icon ms-2 cursor-pointer\"\n [inlineSVG]=\"\n isExpanded(row, col)\n ? singleSpaAssetsPath + 'data-grid/icons/chevron-down.svg'\n : singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\n \"\n (click)=\"\n $event.stopPropagation();\n toggleExpandOfLongCellText(row, col, columns, true)\n \"\n (dblclick)=\"$event.preventDefault(); $event.stopPropagation()\"\n ></span>\n </ng-template>\n <!-- Expand / Collapse icon -->\n </div>\n\n <!-- Expanded text -->\n <div\n class=\"position-absolute w-100 expanded-box\"\n *ngIf=\"isExpanded(row, col)\"\n [style.zIndex]=\"getZIndex(row, col)\"\n style=\"top: 100%; left: 0\"\n [attr.id]=\"(row.id || row._id) + '-' + (col.id || col._id)\"\n [class.invisible]=\"!showDetailsBox\"\n >\n <ng-container\n *ngTemplateOutlet=\"\n fullTextTemplate;\n context: {\n row: row,\n col: col,\n isArray: isNestedValueArray(row, col.field)\n }\n \"\n ></ng-container>\n </div>\n </ng-template>\n </div>\n </div>\n</ng-template>\n\n<!-- Headers Action List On clicking three dots -->\n\n<ng-template\n #columnMenu\n let-col=\"col\"\n let-isNestedTable=\"isNestedTable\"\n let-columns=\"columns\"\n let-section=\"section\"\n>\n <div\n class=\"column-menu three-dots-col-menu\"\n [class.visually-hidden]=\"isMenueHidden\"\n *ngIf=\"activeCol && !isThreeDotsFilterOpen\"\n [style.backgroundColor]=\"dropdownsBackgroundColor\"\n (click)=\"$event.stopPropagation()\"\n [style.color]=\"headerTextColor\"\n >\n <!-- Sort Ascending -->\n <ng-container *ngIf=\"clickedOnSortIcon\">\n <div class=\"sorting_dropdown\" [class.disable-sorting]=\"!col.is_sortable\">\n <!-- <span class=\"muted-text fs-7\" style=\"margin-left: 12px\">Sort</span> -->\n \n <!-- *ngIf=\"\n columnThreedotsMunuConfig?.showAscending &&\n (sortingConfig?.field != col.field ||\n sortingConfig?.order_by == 'desc')\n \" -->\n <div\n class=\"column-menu-item\" [class.active-sort]=\"sortingConfig?.field === col.field && sortingConfig?.order_by === 'asc'\"\n (click)=\"sortAsc(activeCol);\">\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/headerSortingIcon.svg'\"\n class=\"data-grid-svg-icon me-2 setting_dropdown\"\n ></span>\n Sort Ascending\n <span *ngIf=\"sortingConfig?.field === col.field && sortingConfig?.order_by === 'asc'\" [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/tickBlueIconNew.svg'\"\n class=\"data-grid-svg-icon setting_dropdown no-stroke\" style=\"margin-left: auto;\"\n ></span>\n </div>\n\n <!-- Sort Descending -->\n \n <!-- *ngIf=\"\n columnThreedotsMunuConfig?.showDescending &&\n (sortingConfig?.field != col.field ||\n sortingConfig?.order_by == 'asc')\n \" -->\n <div\n class=\"column-menu-item\" [class.active-sort]=\"sortingConfig?.field === col.field && sortingConfig?.order_by === 'desc'\"\n (click)=\"sortDesc(activeCol);\"\n >\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/headerSortingIcon1.svg'\"\n class=\"data-grid-svg-icon me-2 setting_dropdown\"\n ></span>\n Sort Descending\n <span *ngIf=\"sortingConfig?.field === col.field && sortingConfig?.order_by === 'desc'\" [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/tickBlueIconNew.svg'\"\n class=\"data-grid-svg-icon setting_dropdown no-stroke\" style=\"margin-left: auto;\"\n ></span>\n </div>\n\n <div\n *ngIf=\"\n sortingConfig?.field === col.field &&\n (sortingConfig?.order_by === 'asc' ||\n sortingConfig?.order_by === 'desc')\n \"\n class=\"column-menu-item\"\n (click)=\"resetSort(activeCol)\"\n >\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/resetSortIconNew.svg'\n \"\n class=\"data-grid-svg-icon me-2 setting_dropdown\"\n ></span>\n Reset Sort\n </div>\n </div>\n </ng-container>\n <!-- <div class=\"py-2 border-below three-dots-filter\">\n <div\n *ngIf=\"columnThreedotsMunuConfig?.showFilter\"\n class=\"column-menu-item three-dots-filter\"\n (click)=\"openFilteronThreeDotsClick(col)\"\n >\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\"\n class=\"data-grid-svg-icon me-2\"\n ></span>\n Filter\n </div>\n </div> -->\n\n <ng-container *ngIf=\"!clickedOnSortIcon\">\n <div class=\"sorting_dropdown\">\n <!-- <span class=\"muted-text fs-7\" style=\"margin-left: 12px\">Pin</span> -->\n \n <!-- *ngIf=\"columnThreedotsMunuConfig?.showPinleft && col?.pinned !== 'left'\" -->\n <div\n class=\"column-menu-item\" [class.active-sort]=\"col?.pinned == 'left'\"\n (click)=\"\n $event.stopPropagation();\n updateColumnPinInSourceByField(\n activeCol,\n 'left',\n isNestedTable,\n columns\n )\n \"\n >\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/pinLeftIconNew.svg'\"\n class=\"data-grid-svg-icon me-2 setting_dropdown\"\n ></span\n >Pin Left\n <span *ngIf=\"col?.pinned == 'left'\" [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/tickBlueIconNew.svg'\"\n class=\"data-grid-svg-icon setting_dropdown no-stroke\" style=\"margin-left: auto;\"\n ></span>\n </div>\n <!-- *ngIf=\"\n columnThreedotsMunuConfig?.showPinright && col?.pinned !== 'right'\n \" -->\n <div [class.active-sort]=\"col?.pinned == 'right'\"\n class=\"column-menu-item\"\n (click)=\"\n $event.stopPropagation();\n updateColumnPinInSourceByField(\n activeCol,\n 'right',\n isNestedTable,\n columns\n )\n \"\n >\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/pinRightIconNew.svg'\"\n class=\"data-grid-svg-icon data-grid-svg-icon me-2 setting_dropdown\"\n ></span\n >Pin Right\n <span *ngIf=\"col?.pinned == 'right'\" [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/tickBlueIconNew.svg'\"\n class=\"data-grid-svg-icon setting_dropdown no-stroke\" style=\"margin-left: auto;\"\n ></span>\n </div>\n\n <div\n *ngIf=\"col?.pinned\"\n class=\"column-menu-item\"\n (click)=\"\n $event.stopPropagation();\n updateColumnPinInSourceByField(\n activeCol,\n null,\n isNestedTable,\n columns\n )\n \"\n >\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/layout-three-columns.svg'\"\n class=\"data-grid-svg-icon me-2 setting_dropdown d-flex align-items-center justify-content-center\"\n ></span\n >Unpin\n </div>\n </div>\n </ng-container>\n <!-- <div\n *ngIf=\"columnThreedotsMunuConfig?.showAutosizeThisColumn\"\n class=\"column-menu-item\"\n (click)=\"autosizeColumn(activeCol)\"\n >\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/arrows-expand-vertical.svg'\n \"\n class=\"me-2\"\n ></span>\n Autosize This Column\n </div> -->\n\n <!-- Autosize All Columns -->\n <!-- <div\n *ngIf=\"columnThreedotsMunuConfig?.showAutosizeAllColumns\"\n class=\"column-menu-item\"\n (click)=\"autosizeAllColumns()\"\n >\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/arrows-angle-expand.svg'\n \"\n class=\"data-grid-svg-icon me-2\"\n ></span\n >Autosize All Columns\n </div> -->\n\n <!-- Group By -->\n <div\n *ngIf=\"showRowsGrouping\"\n class=\"column-menu-item\"\n (click)=\"groupBy(activeCol)\"\n [class.disable-sorting]=\"!col.is_groupable\"\n >\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/diagram-3.svg'\"\n class=\"data-grid-svg-icon me-2\"\n ></span>\n Group by {{ col.header }}\n </div>\n\n <!-- Choose Columns -->\n <div\n *ngIf=\"columnThreedotsMunuConfig?.showChoseColumns\"\n class=\"column-menu-item\"\n (click)=\"chooseColumns()\"\n >\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/ui-checks-grid.svg'\"\n class=\"data-grid-svg-icon me-2\"\n ></span>\n Choose Columns\n </div>\n\n <!-- Reset Columns -->\n <div\n *ngIf=\"columnThreedotsMunuConfig?.showResetColumns\"\n class=\"column-menu-item\"\n (click)=\"resetColumns()\"\n >\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/arrow-counterclockwise.svg'\n \"\n class=\"data-grid-svg-icon me-2\"\n ></span\n >Reset Columns\n </div>\n </div>\n <div\n @slideToggle\n *ngIf=\"isThreeDotsFilterOpen\"\n class=\"three-dots-col-menu position-relative\"\n [style.right.px]=\"section == 'right' ? null : col.width - 45\"\n [class.visually-hidden]=\"isMenueHidden\"\n >\n <ng-container\n *ngTemplateOutlet=\"filterMenu; context: { col: col }\"\n ></ng-container>\n </div>\n</ng-template>\n\n<!-- Filter Menue -->\n<ng-template #filterMenu let-col=\"col\">\n <div\n class=\"filter-menu-container filter-menu dropdown_outer\"\n [style.backgroundColor]=\"dropdownsBackgroundColor\"\n >\n <!-- Dropdown Type -->\n <ng-container *ngIf=\"col.type === 'dropdown'; else textFilter\">\n <div class=\"filter-dropdown-section p-1\">\n <input\n class=\"form-control form-control-sm\"\n placeholder=\"Search...\"\n type=\"search\"\n [(ngModel)]=\"addFilterColumnInput\"\n />\n\n <div class=\"form-check mb-1 mt-2 ps-4 ms-1\">\n <input\n class=\"form-check-input\"\n type=\"checkbox\"\n [checked]=\"isAllSideFilterOptionsSelected(col)\"\n (change)=\"toggleSelectAllSideFilters(col, $event)\"\n id=\"selectAll_{{ col.field }}\"\n />\n <label class=\"form-check-label\" for=\"selectAll_{{ col.field }}\">\n Select All\n </label>\n </div>\n\n <!-- <div class=\"dropdown-options ps-1\">\n <div\n class=\"form-check mb-1\"\n *ngFor=\"\n let option of selectedColumnForFilter?.column_dropdown_value\n | filter : addFilterColumnInput : 'value';\n trackBy: trackById;\n let i = index\n \"\n >\n <input\n class=\"form-check-input\"\n type=\"checkbox\"\n [id]=\"i\"\n [checked]=\"\n currentFilterSelectedIds.has(option?.id ?? option?._id ?? option)\n \"\n (change)=\"toggleSelectionInFilter(option)\"\n />\n <label class=\"form-check-label fw-semibold\" [for]=\"i\">\n {{ option?.value ?? option?.name ?? option }}\n </label>\n </div>\n </div> -->\n <cdk-virtual-scroll-viewport\n itemSize=\"32\"\n class=\"filter-viewport\"\n style=\"height: 120px\"\n >\n <div\n class=\"form-check mb-1 ms-1\"\n *cdkVirtualFor=\"\n let option of selectedColumnForFilter?.column_dropdown_value\n | filter : addFilterColumnInput : 'value';\n trackBy: trackById\n \"\n >\n <input\n class=\"form-check-input\"\n type=\"checkbox\"\n [id]=\"option?.id ?? option?._id ?? option\"\n [checked]=\"\n currentFilterSelectedIds.has(option?.id ?? option?._id ?? option)\n \"\n (change)=\"toggleSelectionInFilter(option)\"\n />\n\n <label\n class=\"form-check-label fw-semibold\"\n [for]=\"option?.id ?? option?._id ?? option\"\n >\n {{ option?.value ?? option?.name ?? option }}\n </label>\n </div>\n </cdk-virtual-scroll-viewport>\n </div>\n </ng-container>\n\n <!-- Text Filter Section -->\n <ng-template #textFilter>\n <div class=\"filter-text-section\">\n <div class=\"form-group mb-2\">\n <select\n class=\"form-select form-select-sm custom-select\"\n [(ngModel)]=\"firstCondition\"\n >\n <ng-container *ngIf=\"selectedColumnForFilter.type !== 'date'\">\n <option value=\"contain\">Contains</option>\n <option value=\"does_not_contain\">Does Not Contain</option>\n <option value=\"equal\">Equals</option>\n <option value=\"before\">Starts With</option>\n <option value=\"after\">Ends With</option>\n </ng-container>\n\n <ng-container *ngIf=\"selectedColumnForFilter.type == 'date'\">\n <option value=\"equal\">Equals To</option>\n <option value=\"not_equal\">Not Equal</option>\n <option value=\"after\">After</option>\n <option value=\"before\">Before</option>\n </ng-container>\n </select>\n </div>\n\n <input\n [type]=\"col.type == 'string' ? 'text' : col.type\"\n class=\"form-control form-control-sm mb-3\"\n placeholder=\"Value\"\n [(ngModel)]=\"firstValue\"\n #filterMenueTextchInput\n (keydown.enter)=\"applyDropdownFilter()\"\n />\n\n <div class=\"form-group mb-3 d-flex flex-row\">\n <div\n class=\"form-check form-check-inline m-0 col-4 d-flex align-items-center gap-1\"\n >\n <input\n class=\"form-check-input filter-radio-inputs\"\n type=\"radio\"\n name=\"condition\"\n [(ngModel)]=\"condition\"\n value=\"and\"\n id=\"and_{{ col.field }}\"\n (change)=\"cdr.detectChanges()\"\n />\n <label class=\"form-check-label mb-0 mt-1\" for=\"and_{{ col.field }}\"\n >AND</label\n >\n </div>\n <div\n class=\"form-check form-check-inline m-0 col-4 d-flex align-items-center gap-1 gap-1\"\n >\n <input\n class=\"form-check-input filter-radio-inputs\"\n type=\"radio\"\n name=\"condition\"\n [(ngModel)]=\"condition\"\n value=\"or\"\n id=\"or_{{ col.field }}\"\n (change)=\"cdr.detectChanges()\"\n />\n <label class=\"form-check-label mb-0 mt-1\" for=\"or_{{ col.field }}\"\n >OR</label\n >\n </div>\n <div\n class=\"form-check form-check-inline m-0 col-4 d-flex align-items-center gap-1 gap-1\"\n >\n <input\n class=\"form-check-input filter-radio-inputs\"\n type=\"radio\"\n name=\"condition\"\n [(ngModel)]=\"condition\"\n value=\"none\"\n id=\"none_{{ col.field }}\"\n (change)=\"cdr.detectChanges()\"\n />\n <label class=\"form-check-label mb-0 mt-1\" for=\"none_{{ col.field }}\"\n >None</label\n >\n </div>\n </div>\n <div @slideToggle *ngIf=\"firstValue && condition != 'none'\">\n <div class=\"form-group mb-2\">\n <select\n class=\"form-select form-select-sm custom-select\"\n [(ngModel)]=\"secondCondition\"\n >\n <ng-container *ngIf=\"selectedColumnForFilter.type !== 'date'\">\n <option value=\"contain\">Contains</option>\n <option value=\"does_not_contain\">Does Not Contain</option>\n <option value=\"equal\">Equals</option>\n <option value=\"before\">Starts With</option>\n <option value=\"after\">Ends With</option>\n </ng-container>\n\n <ng-container *ngIf=\"selectedColumnForFilter.type == 'date'\">\n <option value=\"equal\">Equals To</option>\n <option value=\"not_equal\">Not Equal</option>\n <option value=\"after\">After</option>\n <option value=\"before\">Before</option>\n </ng-container>\n </select>\n </div>\n\n <input\n [type]=\"col.type == 'string' ? 'text' : col.type\"\n class=\"form-control form-control-sm mb-3\"\n placeholder=\"Second Value\"\n [(ngModel)]=\"secondValue\"\n />\n </div>\n </div>\n </ng-template>\n\n <!-- Actions -->\n <div class=\"d-flex gap-2 mt-2\">\n <div\n class=\"primary_btn_new common_btn flex justify-content-center align-items-center w-100\"\n style=\"height: 30px\"\n (click)=\"applyDropdownFilter()\"\n >\n Apply\n </div>\n <div\n class=\"cancel_btn_new common_btn d-flex justify-content-center align-items-center w-100\"\n style=\"height: 30px\"\n (click)=\"resetSideFilter(col)\"\n >\n Reset\n </div>\n </div>\n </div>\n</ng-template>\n\n<!-- Side Menue -->\n\n<!-- Column Pannel / Pivot Mode / Searching -->\n\n<ng-template #columnPannel>\n <div class=\"column-panel-header\">\n <!-- Pivot Toggle -->\n <div\n class=\"form-check form-switch d-flex align-items-center mb-2 pivot-mode px-5 ms-2 d-none\"\n >\n <input\n class=\"form-check-input me-2\"\n type=\"checkbox\"\n id=\"pivotToggle\"\n [(ngModel)]=\"pivotMode\"\n />\n <label class=\"form-check-label\" for=\"pivotToggle\">Pivot Mode</label>\n </div>\n\n <!-- Select All & Search -->\n <div class=\"d-flex align-items-center mb-2 px-3 mt-3\">\n <span class=\"filter-icon-wrapper me-2\" *ngIf=\"showColumnsGrouping\">\n <span\n class=\"toggle-icon data-grid-svg-icon\"\n [inlineSVG]=\"\n accordionState === 'all'\n ? singleSpaAssetsPath + 'data-grid/icons/chevron-down.svg'\n : accordionState === 'some'\n ? singleSpaAssetsPath + 'data-grid/icons/dash.svg'\n : singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\n \"\n (click)=\"toggleAllAccordions()\"\n ></span>\n </span>\n <input\n type=\"checkbox\"\n class=\"form-check-input me-2\"\n [checked]=\"allColumnsSelected()\"\n (change)=\"toggleAllColumnsVisibility()\"\n />\n <input\n type=\"text\"\n class=\"form-control form-control-sm\"\n placeholder=\"Search columns...\"\n [(ngModel)]=\"columnSearch\"\n />\n </div>\n\n <!-- Separator -->\n <hr class=\"my-2\" />\n </div>\n</ng-template>\n\n<!-- Right Columns Menue -->\n\n<!-- Column Panel Item Template -->\n<ng-template #columnPanelItem let-col=\"col\">\n <!-- Group Column -->\n <ng-container *ngIf=\"col.children?.length\">\n <div class=\"column-group d-flex align-items-center mb-2\">\n <span class=\"filter-icon-wrapper me-2\">\n <span\n class=\"toggle-icon data-grid-svg-icon\"\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\n \"\n [class.rotate]=\"col.expanded\"\n (click)=\"col.expanded = !col.expanded\"\n ></span>\n </span>\n <input\n type=\"checkbox\"\n class=\"form-check-input me-2\"\n [id]=\"'group_' + col.header\"\n [checked]=\"isColumnVisible(col)\"\n (change)=\"toggleGroupVisibility(col)\"\n />\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/grid-3x2-gap.svg'\"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center me-2\"\n ></span>\n <label\n class=\"d-flex align-items-center mb-0 w-100\"\n [for]=\"'group_' + col.header\"\n style=\"cursor: pointer\"\n >\n <span class=\"text-truncate\">{{ col.header }}</span>\n </label>\n </div>\n <div *ngIf=\"col.expanded\" class=\"ps-4\">\n <ng-container *ngFor=\"let child of col.children; trackBy: trackByField\">\n <ng-container\n *ngTemplateOutlet=\"columnPanelItem; context: { col: child }\"\n ></ng-container>\n </ng-container>\n </div>\n </ng-container>\n\n <!-- Leaf Column -->\n <ng-container *ngIf=\"!col.children?.length\">\n <div class=\"d-flex align-items-center mb-2\">\n <span class=\"me-2\" style=\"width: 1.5rem\"></span>\n <input\n type=\"checkbox\"\n class=\"form-check-input me-2\"\n [(ngModel)]=\"col.is_visible\"\n [id]=\"'col_' + col.field\"\n (change)=\"onSideMenuColumnsVisibilityChange()\"\n />\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/grid-3x2-gap.svg'\"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center me-2\"\n ></span>\n <label\n class=\"d-flex align-items-center mb-0 w-100\"\n [for]=\"'col_' + col.field\"\n style=\"cursor: pointer\"\n >\n <span class=\"text-truncate\">{{ col.header }}</span>\n </label>\n </div>\n </ng-container>\n</ng-template>\n\n<!-- Columns Side Filter -->\n<ng-template #sideFilters>\n <div class=\"py-3 px-2 pe-3 h-100\">\n <div class=\"d-flex align-items-center mb-2\">\n <span class=\"filter-icon-wrapper me-2\" *ngIf=\"showColumnsGrouping\">\n <span\n class=\"toggle-icon data-grid-svg-icon\"\n [inlineSVG]=\"\n filterAccordionState === 'all'\n ? singleSpaAssetsPath + 'data-grid/icons/chevron-down.svg'\n : filterAccordionState === 'some'\n ? singleSpaAssetsPath + 'data-grid/icons/dash.svg'\n : singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\n \"\n (click)=\"toggleAllFilterAccordions()\"\n ></span>\n </span>\n <input\n type=\"text\"\n class=\"form-control form-control-sm\"\n placeholder=\"Search...\"\n [(ngModel)]=\"columnSearch\"\n />\n </div>\n <div\n class=\"overflow-auto side-filter-columns-wrapper\"\n style=\"height: calc(100% - 70px); scrollbar-width: thin\"\n >\n <ng-container\n *ngFor=\"\n let col of columns | filter : columnSearch : 'header';\n trackBy: trackByField\n \"\n >\n <ng-container\n *ngTemplateOutlet=\"filterPannelItem; context: { col: col }\"\n ></ng-container>\n </ng-container>\n </div>\n </div>\n</ng-template>\n\n<ng-template #filterPannelItem let-col=\"col\">\n <!-- Group Column -->\n <ng-container *ngIf=\"col.children?.length\">\n <div\n class=\"column-group d-flex align-items-center mb-2\"\n *ngIf=\"col.type !== 'image'\"\n >\n <!-- Chevron toggle -->\n <span class=\"filter-icon-wrapper me-2\">\n <span\n class=\"toggle-icon data-grid-svg-icon\"\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\n \"\n [class.rotate]=\"col.expandedFilter\"\n (click)=\"col.expandedFilter = !col.expandedFilter\"\n ></span>\n </span>\n\n <!-- Group label toggle -->\n <label\n class=\"d-flex align-items-center mb-0 w-100\"\n style=\"cursor: pointer\"\n (click)=\"col.expandedFilter = !col.expandedFilter\"\n >\n <span class=\"fw-bold text-truncate\"\n >{{ col.header }}\n <span\n class=\"text-primary ms-1\"\n *ngIf=\"col?.query?._ids?.length || col?.query?._first_value\"\n >*</span\n >\n </span>\n </label>\n </div>\n\n <!-- Children columns -->\n <div *ngIf=\"col.expandedFilter\" class=\"ps-4\">\n <ng-container *ngFor=\"let child of col.children; trackBy: trackByField\">\n <ng-container\n *ngTemplateOutlet=\"filterPannelItem; context: { col: child }\"\n ></ng-container>\n </ng-container>\n </div>\n </ng-container>\n\n <!-- Leaf Column -->\n <ng-container *ngIf=\"!col.children?.length\">\n <div class=\"d-flex align-items-center mb-2\" *ngIf=\"col.type !== 'image'\">\n <span\n class=\"me-2 filter-icon-wrapper me-2\"\n (click)=\"col.expandedFilter = !col.expandedFilter\"\n >\n <span\n class=\"toggle-icon data-grid-svg-icon\"\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\n \"\n [class.rotate]=\"col.expandedFilter\"\n ></span>\n </span>\n\n <label\n class=\"d-flex align-items-center mb-0 w-100\"\n style=\"cursor: pointer\"\n (click)=\"col.expandedFilter = !col.expandedFilter\"\n >\n <span class=\"text-truncate fw-bold\">{{ col.header }}</span>\n </label>\n </div>\n\n <!-- Show filter when expanded -->\n <div *ngIf=\"col.expandedFilter\" class=\"ps-4 pe-3\">\n <ng-container\n *ngTemplateOutlet=\"sideNestedFilter; context: { col: col }\"\n ></ng-container>\n </div>\n </ng-container>\n</ng-template>\n\n<!-- Side Nested Filters -->\n<ng-template #sideNestedFilter let-col=\"col\">\n <div class=\"\">\n <!-- Dropdown Type -->\n <ng-container *ngIf=\"col.type === 'dropdown'; else textFilter\">\n <div class=\"p-1\">\n <!-- Search -->\n <input\n type=\"text\"\n class=\"form-control form-control-sm mb-2\"\n placeholder=\"Search...\"\n [(ngModel)]=\"sideNestedFilterSearch\"\n />\n\n <!-- Select All -->\n <div class=\"form-check mb-1 ms-1\">\n <input\n class=\"form-check-input\"\n type=\"checkbox\"\n [checked]=\"\n col.query?._ids?.length == col?.column_dropdown_value?.length\n \"\n (change)=\"toggleSelectAllSideFilters(col, $event)\"\n id=\"selectAll_{{ col.field }}\"\n />\n <label class=\"form-check-label\" for=\"selectAll_{{ col.field }}\">\n Select All\n </label>\n </div>\n\n <!-- Options -->\n <!-- <div class=\"dropdown-options\">\n <div\n class=\"form-check mb-1 ms-1\"\n *ngFor=\"\n let option of col?.column_dropdown_value\n | filter : sideNestedFilterSearch : 'value'\n \"\n >\n <input\n class=\"form-check-input\"\n type=\"checkbox\"\n [value]=\"option\"\n [checked]=\"\n col.query?._ids?.includes(option?._id || option?.id || option)\n \"\n (change)=\"onOptionToggle(col, option)\"\n id=\"option_{{ col.field }}_{{\n option?.id || option?._id || option\n }}\"\n />\n <label\n class=\"form-check-label\"\n [for]=\"\n 'option_' +\n col.field +\n '_' +\n (option?.id || option?._id || option)\n \"\n >\n {{ option.value || option }}\n </label>\n </div>\n </div> -->\n <cdk-virtual-scroll-viewport\n itemSize=\"32\"\n class=\"dropdown-viewport\"\n style=\"height: 120px\"\n >\n <div\n class=\"form-check mb-1 ms-1\"\n *cdkVirtualFor=\"\n let option of col?.column_dropdown_value\n | filter : sideNestedFilterSearch : 'value'\n \"\n >\n <input\n class=\"form-check-input\"\n type=\"checkbox\"\n [value]=\"option\"\n [checked]=\"\n col.query?._ids?.includes(option?._id || option?.id || option)\n \"\n (change)=\"onOptionToggle(col, option)\"\n id=\"option_{{ col.field }}_{{\n option?.id || option?._id || option\n }}\"\n />\n\n <label\n class=\"form-check-label\"\n [for]=\"\n 'option_' +\n col.field +\n '_' +\n (option?.id || option?._id || option)\n \"\n >\n {{ option.value || option }}\n </label>\n </div>\n </cdk-virtual-scroll-viewport>\n\n\n <!-- Actions -->\n <!-- <div class=\"d-flex gap-2 mt-2\">\n <div\n class=\"btn btn-sm btn-primary d-flex justify-content-center align-items-center\"\n style=\"height: 22px;\"\n (click)=\"applySideFilter(col)\"\n >\n Apply\n </div>\n <div\n class=\"btn btn-sm btn-secondary d-flex justify-content-center align-items-center\" \n style=\"height: 22px;\"\n (click)=\"resetSideFilter(col)\"\n >\n Reset\n </div>\n </div> -->\n </div>\n </ng-container>\n\n <!-- Text Filter Section -->\n <ng-template #textFilter>\n <div class=\"filter-text-section\">\n <div class=\"form-group mb-2\">\n <select\n class=\"form-select form-select-sm\"\n [(ngModel)]=\"col.query.first_condition\"\n >\n <ng-container *ngIf=\"col.type !== 'date'\">\n <option value=\"contain\">Contains</option>\n <option value=\"does_not_contain\">Does Not Contain</option>\n <option value=\"equal\">Equals</option>\n <option value=\"before\">Starts With</option>\n <option value=\"after\">Ends With</option>\n </ng-container>\n\n <ng-container *ngIf=\"col.type == 'date'\">\n <option value=\"equal\">Equals To</option>\n <option value=\"not_equal\">Not Equal</option>\n <option value=\"after\">After</option>\n <option value=\"before\">Before</option>\n </ng-container>\n </select>\n </div>\n\n <input\n [type]=\"col.type == 'date' ? 'date' : 'text'\"\n class=\"form-control form-control-sm mb-3\"\n placeholder=\"Value\"\n [(ngModel)]=\"col!.query!.first_value\"\n />\n\n <div\n class=\"form-group mb-3 d-flex flex-row muted\"\n style=\"font-size: 14px\"\n >\n <div\n class=\"form-check form-check-inline m-0 col-4 d-flex align-items-center gap-1\"\n >\n <input\n class=\"form-check-input filter-radio-inputs\"\n type=\"radio\"\n name=\"condition\"\n [(ngModel)]=\"col!.query.condition\"\n value=\"and\"\n id=\"and_{{ col.field }}\"\n />\n <label class=\"form-check-label mb-0 mt-1\" for=\"and_{{ col.field }}\"\n >AND</label\n >\n </div>\n <div\n class=\"form-check form-check-inline m-0 col-4 d-flex align-items-center gap-1\"\n >\n <input\n class=\"form-check-input filter-radio-inputs\"\n type=\"radio\"\n name=\"condition\"\n [(ngModel)]=\"col!.query.condition\"\n value=\"or\"\n id=\"or_{{ col.field }}\"\n />\n <label class=\"form-check-label mb-0 mt-1\" for=\"or_{{ col.field }}\"\n >OR</label\n >\n </div>\n <div\n class=\"form-check form-check-inline m-0 col-4 d-flex align-items-center gap-1\"\n >\n <input\n class=\"form-check-input filter-radio-inputs\"\n type=\"radio\"\n name=\"condition\"\n [(ngModel)]=\"col!.query.condition\"\n value=\"none\"\n id=\"none_{{ col.field }}\"\n />\n <label\n class=\"nnonem-check-label mb-0 mt-1\"\n for=\"none_{{ col.field }}\"\n >None</label\n >\n </div>\n </div>\n <ng-container\n *ngIf=\"col?.query?.first_value && col?.query?.condition !== 'none'\"\n >\n <div class=\"form-group mb-2\">\n <select\n class=\"form-select form-select-sm\"\n [(ngModel)]=\"col!.query.second_condition\"\n >\n <ng-container *ngIf=\"col.type !== 'date'\">\n <option value=\"contain\">Contains</option>\n <option value=\"does_not_contain\">Does Not Contain</option>\n <option value=\"equal\">Equals</option>\n <option value=\"before\">Starts With</option>\n <option value=\"after\">Ends With</option>\n </ng-container>\n\n <ng-container *ngIf=\"col.type == 'date'\">\n <option value=\"equal\">Equals To</option>\n <option value=\"not_equal\">Not Equal</option>\n <option value=\"after\">After</option>\n <option value=\"before\">Before</option>\n </ng-container>\n </select>\n </div>\n\n <input\n [type]=\"col.type == 'date' ? 'date' : 'text'\"\n class=\"form-control form-control-sm mb-3\"\n placeholder=\"Second Value\"\n [(ngModel)]=\"col!.query.second_value\"\n />\n </ng-container>\n <!-- <div class=\"d-flex gap-2\">\n <div class=\"btn btn-sm btn-primary d-flex justify-content-center align-items-center\" style=\"height: 22px;\" (click)=\"applyDropdownFilter()\">apply</div>\n <div class=\"btn btn-sm btn-secondary d-flex justify-content-center align-items-center\" style=\"height: 22px;\" (click)=\"applyDropdownFilter()\">reset</div>\n\n </div> -->\n </div>\n </ng-template>\n <div\n class=\"d-flex justify-content-center gap-2 border-top\"\n style=\"height: 38px\">\n <button\n type=\"button\"\n style=\"max-height: 30px\"\n class=\"btn btn-outline-secondary btn-light border w-100 d-flex align-items-center justify-content-center mt-1\"\n (click)=\"$event.stopPropagation(); removeSideFilter(col)\">\n <span>Clear</span>\n </button>\n <button\n type=\"button\"\n style=\"max-height: 30px\"\n class=\"btn btn-primary w-100 d-flex align-items-center justify-content-center mt-1\"\n (click)=\"applySideFilter(col)\"\n [class.disabled]=\"(col?.query.condition !== 'none' && !col?.query?.second_value)\"\n [class.pe-none]=\"(col!?.query.condition !== 'none' && !col?.query?.second_value)\"\n >\n <span style=\"margin-top: -1px\">Apply</span>\n </button>\n </div>\n </div>\n</ng-template>\n\n<!-- Centr Overlay for showing the chose columns -->\n\n<div *ngIf=\"showColumnPanel\" class=\"custom-modal-overlay\">\n <div\n class=\"custom-modal-content\"\n [style.backgroundColor]=\"dropdownsBackgroundColor\"\n (click)=\"$event.stopPropagation()\"\n >\n <ng-container *ngTemplateOutlet=\"modalColumnPannel\"></ng-container>\n </div>\n</div>\n\n<!-- The existing ng-template you provided -->\n<ng-template #modalColumnPannel>\n <div class=\"column-panel-header\">\n <div\n class=\"d-flex justify-content-between align-items-center px-2 ps-3 rounded-top-2 moda-header\"\n [style.height.px]=\"48\"\n >\n Choose Columns\n <span class=\"filter-icon-wrapper\" (click)=\"closeModalColumnPanel()\"\n ><span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/x.svg'\"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span\n ></span>\n </div>\n <hr class=\"my-0\" />\n <div>\n <div class=\"d-flex align-items-center px-2 pe-3\" [style.height.px]=\"48\">\n <span class=\"filter-icon-wrapper me-2\" *ngIf=\"showColumnsGrouping\">\n <span\n class=\"toggle-icon data-grid-svg-icon\"\n [inlineSVG]=\"\n accordionState === 'all'\n ? singleSpaAssetsPath + 'data-grid/icons/chevron-down.svg'\n : accordionState === 'some'\n ? singleSpaAssetsPath + 'data-grid/icons/dash.svg'\n : singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\n \"\n (click)=\"toggleAllAccordions()\"\n ></span>\n </span>\n <input\n type=\"checkbox\"\n class=\"form-check-input me-2\"\n [checked]=\"allColumnsSelected()\"\n (change)=\"toggleAllColumnsVisibility()\"\n />\n <input\n type=\"text\"\n class=\"form-control form-control-sm\"\n placeholder=\"Search columns...\"\n [(ngModel)]=\"choseColumnsSearch\"\n />\n </div>\n\n <hr class=\"mt-0 mb-1\" />\n <div class=\"px-2 overlay-scrollable\">\n <ng-container\n *ngFor=\"\n let col of columns | filter : choseColumnsSearch : 'header';\n trackBy: trackByField\n \"\n >\n <ng-container\n *ngTemplateOutlet=\"columnPanelItem; context: { col: col }\"\n ></ng-container>\n </ng-container>\n </div>\n </div>\n </div>\n</ng-template>\n\n<ng-template #sideMenuRowGroups>\n <div class=\"d-flex flex-column h-100 d-none\">\n <div class=\"px-3 h-100\">\n <div class=\"d-flex gap-3 mb-4\">\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/justify.svg'\"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n <span>Row Groups</span>\n </div>\n <div class=\"h-50\">\n <div\n class=\"px-3 py-2 border-dashed h-100 d-flex justify-content-center align-items-center\"\n style=\"font-size: 14px\"\n >\n Drag here to set row Groups\n </div>\n </div>\n </div>\n\n <hr class=\"mt-4\" />\n\n <div class=\"px-3 h-100\">\n <div class=\"d-flex gap-3 mb-4\">\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/justify.svg'\"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n <span>Values</span>\n </div>\n <div class=\"h-50 d-flex\">\n <div\n class=\"px-3 py-2 border-dashed h-100 d-flex justify-content-center align-items-center\"\n style=\"font-size: 14px\"\n >\n Drag here aggregate\n </div>\n </div>\n </div>\n </div>\n</ng-template>\n\n<!-- *************************************************** -->\n<!-- *************************************************** -->\n<!-- *************************************************** -->\n<!-- Drag Preview Template -->\n<!-- *************************************************** -->\n<!-- *************************************************** -->\n<ng-template #dragPreview let-col>\n <div class=\"p-2 border d-flex gap-2\">\n <div>\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrows-move.svg'\"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n </div>\n <div>{{ col.header }}</div>\n </div>\n</ng-template>\n\n<!-- Drag Placeholder Template -->\n<ng-template\n #dragPlaceholder\n let-col\n let-i=\"index\"\n let-section=\"section\"\n let-draggingInGroupArea=\"draggingInGroupArea\"\n>\n <div *ngIf=\"!draggingInGroupArea\">\n <div\n *ngTemplateOutlet=\"\n headerCell;\n context: { $implicit: col, index: i, section: section }\n \"\n ></div>\n </div>\n <div *ngIf=\"draggingInGroupArea\">New Placeholder</div>\n</ng-template>\n\n<!-- Top Group Row Placeholder -->\n<ng-template #topGroupingRowPlaceholder let-col let-showChevron=\"showChevron\">\n <div class=\"d-flex gap-2\">\n <div\n class=\"d-flex gap-2 top-row-grouping-placeholder\"\n [style.backgroundColor]=\"topGroupedBadgesBackgroundColor\"\n >\n <span\n cdkDragHandle\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/grid-3x2-gap.svg'\"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n <span>{{ col.header }}</span>\n <span\n (click)=\"ungroupColumn(col)\"\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/x.svg'\"\n class=\"cursor-pointer data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n </div>\n </div>\n <div *ngIf=\"showChevron\" style=\"opacity: 0.6; font-size: 14px\">\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n </div>\n</ng-template>\n\n<ng-template\n #childHeaderPlaceholder\n let-col\n let-pinnedRight=\"pinnedRight\"\n let-i=\"index\"\n let-sections=\"sections\"\n>\n <div\n class=\"header-cell one-row-header-cells\"\n [class.border-right]=\"showVerticalBorder\"\n [style.width.px]=\"col.width\"\n [style.min-width.px]=\"col.width\"\n [style.min-height.px]=\"headerRowHeight\"\n [style.max-height.px]=\"headerRowHeight\"\n [style.fontWeight]=\"headerFontWeight\"\n >\n <div class=\"d-flex justify-content-between h-100 align-items-center w-100\">\n <div\n class=\"d-flex justify-content-between align-items-center w-100\"\n [class.flex-row-reverse]=\"pinnedRight\"\n >\n <div\n class=\"text-ellipsis h-100 d-flex align-items-center\"\n [title]=\"col.header\"\n [class.w-100]=\"pinnedRight\"\n >\n {{ col.header }}\n </div>\n\n <div\n class=\"position-relative d-flex\"\n [class.flex-row-reverse]=\"pinnedRight\"\n >\n <div class=\"three-dots p-1\" style=\"cursor: pointer\">\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/three-dots-vertical.svg'\n \"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n </div>\n\n <div class=\"resize-handle resize-test\">\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/resize-handle1.svg'\n \"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n </div>\n </div>\n </div>\n </div>\n </div>\n <div\n *ngIf=\"showFilterRow\"\n [style.backgroundColor]=\"headerBackgroundColor\"\n class=\"header-cell filter-cell\"\n [class.border-right]=\"showVerticalBorder\"\n [style.width.px]=\"col.width\"\n [style.min-width.px]=\"col.width\"\n [style.height.px]=\"headerRowHeight\"\n [style.min-height.px]=\"headerRowHeight\"\n [style.max-height.px]=\"headerRowHeight\"\n [class.border-right]=\"showVerticalBorder\"\n style=\"grid-row: 3\"\n >\n <div\n class=\"header-cell filter-cell\"\n [style.backgroundColor]=\"headerBackgroundColor\"\n [style.width.px]=\"col.width\"\n [style.min-width.px]=\"col.width\"\n [style.height.px]=\"headerRowHeight\"\n [style.min-height.px]=\"headerRowHeight\"\n [style.max-height.px]=\"headerRowHeight\"\n >\n <input\n type=\"text\"\n class=\"form-control form-control-sm\"\n placeholder=\"Filter\"\n [(ngModel)]=\"col.filterValue\"\n [readonly]=\"col?.type == 'dropdown' || col?.type == 'image'\"\n [class.disabled-search-input]=\"\n col?.type == 'dropdown' || col?.type == 'image'\n \"\n />\n <span\n class=\"filter-icon-wrapper\"\n (click)=\"activeFilterCell = col; activeCol = null\"\n ><span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span\n ></span>\n\n <div\n class=\"position-absolute\"\n *ngIf=\"activeFilterCell === col\"\n style=\"top: 100%; right: 0; z-index: 10; left: 0\"\n ></div>\n </div>\n </div>\n</ng-template>\n\n<ng-template #tableLayout>\n <div\n (click)=\"$event.stopPropagation()\"\n class=\"p-3 action_dropdown_new_design actions-dropdown mt-1 dropdown-menu show shadow custom-menu table-layout\"\n style=\"width: 320px\"\n >\n <div class=\"d-flex align-items-center mb-3\">\n <button\n class=\"btn btn-link p-0\"\n style=\"margin-left: -10px\"\n (click)=\"toggleActions('setting')\"\n >\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrow-left.svg'\"\n class=\"data-grid-svg-icon me-2\"\n ></span>\n </button>\n <h6 class=\"mb-0 ms-2 text_common_14px\">Table Layout</h6>\n </div>\n <hr class=\"my-2\" />\n <div class=\"w-100 mb-3 d-flex\" role=\"group\">\n <input\n type=\"radio\"\n class=\"btn-check layout-button-check\"\n name=\"layoutSize\"\n id=\"small\"\n autocomplete=\"off\"\n (change)=\"changeTableLayout($event, 'small')\"\n [checked]=\"selectedTableLayout == 'small'\"\n />\n <label\n class=\"border d-flex flex-column align-items-center layout-button\"\n for=\"small\"\n [ngStyle]=\"{\n color: selectedTableLayout == 'small' ? '#000' : '#727272'\n }\"\n >\n <div class=\"preview-box border mb-1\" style=\"height: 8px\"></div>\n Small\n </label>\n\n <input\n type=\"radio\"\n class=\"btn-check layout-button-check\"\n name=\"layoutSize\"\n id=\"medium\"\n autocomplete=\"off\"\n [checked]=\"selectedTableLayout == 'medium'\"\n (change)=\"changeTableLayout($event, 'medium')\"\n />\n <label\n class=\"border mx-3 d-flex flex-column align-items-center layout-button\"\n for=\"medium\"\n [ngStyle]=\"{\n color: selectedTableLayout == 'medium' ? '#000' : '#727272'\n }\"\n >\n <div class=\"preview-box border mb-1\" style=\"height: 12px\"></div>\n Medium\n </label>\n\n <input\n type=\"radio\"\n class=\"btn-check layout-button-check\"\n name=\"layoutSize\"\n id=\"large\"\n autocomplete=\"off\"\n (change)=\"changeTableLayout($event, 'large')\"\n [checked]=\"selectedTableLayout == 'large'\"\n />\n <label\n class=\"border d-flex flex-column align-items-center layout-button\"\n for=\"large\"\n [ngStyle]=\"{\n color: selectedTableLayout == 'large' ? '#000' : '#727272'\n }\"\n >\n <div class=\"preview-box border mb-1\" style=\"height: 16px\"></div>\n Large\n </label>\n </div>\n\n <hr class=\"my-2\" />\n <div class=\"d-flex justify-content-between align-items-center mb-2\">\n <span class=\"text_common_14px\">Show separators</span>\n <div class=\"form-check form-switch m-0\">\n <input\n class=\"form-check-input\"\n type=\"checkbox\"\n id=\"separators\"\n [(ngModel)]=\"showVerticalBorder\"\n (change)=\"onFontChange()\"\n />\n </div>\n </div>\n <div class=\"d-flex justify-content-between align-items-center\">\n <span class=\"text_common_14px\">Row shading</span>\n <div class=\"form-check form-switch m-0\">\n <input\n class=\"form-check-input\"\n [(ngModel)]=\"rowShadingEnabled\"\n (change)=\"toggleRowShading()\"\n type=\"checkbox\"\n id=\"rowShading\"\n />\n </div>\n </div>\n <!-- <div class=\"d-flex justify-content-between align-items-center mb-2\">\n <span>Show Side Menu</span>\n <div class=\"form-check form-switch m-0\">\n <input\n class=\"form-check-input\"\n [(ngModel)]=\"showSideMenu\"\n type=\"checkbox\"\n id=\"rowShading\"\n />\n </div>\n </div>\n <div class=\"d-flex justify-content-between align-items-center mb-2\">\n <span>Show Filter Row</span>\n <div class=\"form-check form-switch m-0\">\n <input\n class=\"form-check-input\"\n [(ngModel)]=\"showFilterRow\"\n type=\"checkbox\"\n id=\"rowShading\"\n />\n </div>\n </div> -->\n </div>\n</ng-template>\n\n<ng-template #tablePreset>\n <div\n *ngIf=\"activeSubButton !== 'save-preset'\"\n (click)=\"$event.stopPropagation()\"\n class=\"p-3 action_dropdown_new_design actions-dropdown mt-1 dropdown-menu show shadow custom-menu table-layout\"\n style=\"width: 280px\"\n >\n <!-- Header -->\n <div class=\"d-flex justify-content-between align-items-center mb-3\">\n <div class=\"d-flex align-items-center\">\n <button\n class=\"btn btn-link p-0\"\n style=\"margin-left: -10px\"\n (click)=\"toggleActions('setting')\"\n >\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrow-left.svg'\"\n class=\"data-grid-svg-icon\"\n ></span>\n </button>\n <h6 class=\"mb-0 ms-2 text_common_14px\">Table Presets</h6>\n </div>\n <!-- Save Preset Button with Dropdown -->\n <div>\n <a\n class=\"text-decoration-none text-primary\"\n type=\"button\"\n id=\"savePresetDropdown\"\n (click)=\"$event.stopPropagation(); toggleSubActions('save-preset')\"\n >\n {{ isTablePresetNotChanged ? \"Save preset\" : \"Update Preset\" }}\n </a>\n </div>\n </div>\n\n <!-- Search -->\n <div class=\"mb-3\">\n <div class=\"col-12 global-search position-relative\">\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/search.svg'\"\n class=\"data-grid-svg-icon mx-2 position-absolute icon\"\n ></span>\n <input\n class=\"form-control form-control-sm\"\n placeholder=\"Search...\"\n [(ngModel)]=\"searchTextPresetTable\"\n type=\"search\"/>\n </div>\n </div>\n\n <!-- Preset List -->\n <ng-container\n *ngIf=\"\n tableView | filter : searchTextPresetTable : 'name' as filteredList\n \"\n >\n <!-- If filteredList exists and none is default -> show fallback -->\n <div\n class=\" pb-5 overflow-auto\"\n [style.maxHeight.px]=\"dataGridContainer.offsetHeight - 250\"\n >\n <div\n class=\"cursor-pointer\"\n (click)=\"\n clearAllFilters();\n openIndex = null;\n temp_state.id = '';\n activeTopButton = '';\n curretaTablePresetForUpdate = null\n \"\n >\n <div class=\"fw-semibold\">Default View</div>\n </div>\n <div class=\"d-flex justify-content-between\">\n <small class=\"text-dark\">Created by system</small>\n <span\n *ngIf=\"!tableFilterViewId && !hasAnyDefaultView()\"\n class=\"badge bg-light text-primary ms-2\"\n >Default</span\n >\n <span\n *ngIf=\"!tableFilterViewId && !hasAnyDefaultView()\"\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/check-blue.svg'\"\n class=\"me-2\"\n ></span>\n <div\n class=\"dropdown d-flex justify-content-end\"\n *ngIf=\"tableFilterViewId\"\n ></div>\n </div>\n\n <!-- The list: render each table from filteredList -->\n <div\n class=\"list-group list-group-flush\"\n *ngFor=\"\n let table of filteredList;\n let i = index;\n trackBy: trackByTable\n \"\n >\n <!-- Item -->\n <div\n (click)=\"\n $event.stopPropagation(); openIndex = null; activeTopButton = ''\n \"\n class=\"list-group-item px-0 d-flex justify-content-between align-items-center\"\n >\n <div (click)=\"selectFilter(table); openIndex = null\">\n <div class=\"fw-semibold\" style=\"cursor: pointer\">\n {{ table?.name }}\n <!-- {{table?.is_temp}} -->\n <span\n *ngIf=\"\n (table?.is_temp && !temp_state.id) ||\n temp_state.id == table.id\n \"\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/check-blue.svg'\n \"\n class=\"me-2\"\n ></span>\n <span\n *ngIf=\"table?.is_default\"\n class=\"badge bg-light text-primary ms-2\"\n >Default</span\n >\n </div>\n <small class=\"text-dark\" *ngIf=\"table?.config?.filterNames\" [title]=\"table?.config?.filterNames\">\n {{\n table?.config?.filterNames?.length > 25\n ? (table?.config?.filterNames | slice:0:25) + '...'\n : table?.config?.filterNames\n }}\n ({{ table?.config?.totalCount }})\n </small>\n <small class=\"text-dark\" *ngIf=\"!table?.config?.filterNames\">{{ table?.createdAt | date : \"MMM d, y\" }}</small>\n </div>\n\n <div class=\"d-flex align-items-center\">\n <span\n *ngIf=\"table?.is_default\"\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/check-blue.svg'\n \"\n class=\"me-2\"\n ></span>\n\n <div class=\"dropdown\" *ngIf=\"!table?.is_default\">\n <div\n class=\"dropdown-wrapper\"\n (click)=\"$event.stopPropagation()\"\n >\n <button\n type=\"button\"\n class=\"btn-icon muted-text\"\n (click)=\"toggleMenu(i, $event)\"\n aria-haspopup=\"true\"\n [attr.aria-expanded]=\"openIndex === i\"\n >\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath +\n 'data-grid/icons/horizontal-dots.svg'\n \"\n class=\"me-2\"\n ></span>\n </button>\n\n <!-- menu -->\n <ul\n *ngIf=\"openIndex === i\"\n class=\"custom-dropdown-menu position-fixed top-auto\"\n role=\"menu\"\n [style.right.px]=\"'auto'\"\n [style.left.px]=\"dataGridContainer.offsetWidth - 100\"\n style=\"top: unset; right: unset\"\n >\n <li role=\"none\">\n <button\n role=\"menuitem\"\n class=\"dropdown-item\"\n (click)=\"\n actionPreset(table, 'setPreset'); temp_state.id = ''\n \"\n >\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/star.svg'\n \"\n class=\"me-2\"\n ></span>\n Set as default\n </button>\n </li>\n\n <li role=\"none\" *ngIf=\"!table.confirmDelete\">\n <button\n role=\"menuitem\"\n class=\"dropdown-item text-danger\"\n (click)=\"table.confirmDelete = true\"\n >\n <span\n style=\"margin-top: -4px\"\n [inlineSVG]=\"\n singleSpaAssetsPath +\n 'data-grid/icons/trash-red.svg'\n \"\n class=\"me-2\"\n ></span>\n Delete\n </button>\n </li>\n\n <li\n role=\"none\"\n *ngIf=\"table.confirmDelete\"\n class=\"confirm-block\"\n >\n <div class=\"px-3 py-2 text-center\">\n <div class=\"mb-2 text_common_16px_gray\">\n Are you sure you want to delete this view<b>?</b><br/> This action can\u2019t be undone.\n </div>\n <div class=\"d-flex gap-2\">\n <button\n class=\"cancel_btn_new common_btn\"\n (click)=\"table.confirmDelete = false\">\n Cancel\n </button>\n <button class=\"delete_btn_new common_btn\"\n (click)=\"actionPreset(table, 'deletePreset')\">\n Delete\n </button>\n </div>\n </div>\n </li>\n </ul>\n </div>\n </div>\n </div>\n </div>\n <!-- Item End Here -->\n </div>\n </div>\n </ng-container>\n </div>\n\n <div\n (click)=\"$event.stopPropagation()\"\n *ngIf=\"activeSubButton == 'save-preset'\"\n class=\"dropdown-menu p-3 badge mt-4 save-preset-dropdown mt-1\"\n aria-labelledby=\"savePresetDropdown\"\n style=\"min-width: 250px\"\n >\n <div class=\"text_common_16px mb-2\">\n {{ isTablePresetNotChanged ? \"Create New Preset\" : \"Update Preset\" }}\n </div>\n <!-- <div class=\"fs-14px mb-2\" style=\"line-height: 20px\">\n This will save the current table adjustments as a preset.\n </div> -->\n <!-- Input -->\n <div class=\"my-3\">\n <label for=\"presetName\" class=\"form-label fs-12px fw-bold\">Name</label>\n <div class=\"col-12 global-search position-relative\">\n <input\n #presetNameCtrl=\"ngModel\"\n required\n [(ngModel)]=\"presetName\"\n [ngClass]=\"{\n 'is-invalid':\n presetNameCtrl.invalid &&\n (presetNameCtrl.dirty || presetNameCtrl.touched)\n }\"\n class=\"form-control form-control-sm ps-2\"\n placeholder=\"Enter preset name\"\n type=\"text\"\n />\n </div>\n </div>\n\n <!-- Checkbox -->\n <div class=\"form-check mb-2\">\n <input\n class=\"form-check-input\"\n [(ngModel)]=\"presetFilter\"\n type=\"checkbox\"\n id=\"saveFilters\"\n />\n <label class=\"form-check-label mt-1\" for=\"saveFilters\">\n Save active filters\n </label>\n </div>\n\n <!-- Save Button -->\n <div class=\"d-flex justify-content-end gap-2\" style=\"height: 32px\">\n <button\n type=\"button\"\n style=\"height: 32px\"\n class=\"cancel_btn_new common_btn w-100 d-flex align-items-center justify-content-center\"\n (click)=\"$event.stopPropagation(); toggleActions('table-presets')\"\n style=\"margin-top: -2px\">\n <span>Cancel</span>\n </button>\n <button\n [disabled]=\"closeDropdown.preset.loading\"\n (click)=\"savePreset(presetNameCtrl)\"\n type=\"button\"\n style=\"height: 32px\"\n class=\"primary_btn_new common_btn d-flex align-items-center justify-content-center\"\n >\n <span style=\"margin-top: -2px\" *ngIf=\"isTablePresetNotChanged\">\n <ng-container *ngIf=\"!closeDropdown.preset.loading\"\n >Create</ng-container\n >\n <ng-container *ngIf=\"closeDropdown.preset.loading\"\n ><span class=\"spinner-border spinner-border-sm\"></span\n ></ng-container>\n </span>\n <span style=\"white-space: nowrap\" *ngIf=\"!isTablePresetNotChanged\"\n >Update Preset</span\n >\n </button>\n </div>\n </div>\n</ng-template>\n\n<ng-template #showHideColumns>\n <div\n (click)=\"$event.stopPropagation()\"\n class=\"p-3 action_dropdown_new_design actions-dropdown mt-1 dropdown-menu show shadow custom-menu table-layout\"\n style=\"width: 280px\"\n >\n <!-- Header -->\n <div class=\"d-flex justify-content-between align-items-center mb-2\" style=\"border-bottom: 1px solid #E0E0E0;\">\n <div class=\"d-flex align-items-center\">\n <button\n class=\"btn btn-link p-0\"\n style=\"margin-left: -10px\"\n (click)=\"toggleActions('setting')\"\n >\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrow-left.svg'\"\n class=\"data-grid-svg-icon\"\n ></span>\n </button>\n <h6 class=\"mb-0 ms-2 text_common_14px\">Columns</h6>\n </div>\n <a\n (click)=\"resetColumns()\"\n href=\"javascript:void(0)\"\n class=\"text-primary text-decoration-none\"\n >Reset</a\n >\n </div>\n\n <!-- Search -->\n <div class=\"mb-3\">\n <div class=\"col-12 global-search position-relative\">\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/search.svg'\"\n class=\"mx-2 position-absolute icon data-grid-svg-icon\"\n ></span>\n <input\n class=\"form-control form-control-sm\"\n placeholder=\"Search column\"\n type=\"search\"\n [(ngModel)]=\"topShowHideColumns\"\n />\n </div>\n </div>\n <!-- Preset List -->\n <div\n class=\"list-group list-group-flush\"\n style=\"overflow: auto; scrollbar-width: thin\"\n [style.maxHeight.px]=\"dataGridContainer.offsetHeight - 220\"\n >\n <div class=\"muted-text show-hide-table-label d-flex justify-content-between\" *ngIf=\"hasAnyVisibleColumn\">\n Show in table\n <div class=\"form-check\">\n <input\n class=\"form-check-input\"\n type=\"checkbox\"\n id=\"hide_all\"\n [checked]=\"allColumnsSelected()\"\n (change)=\"toggleAllColumnsVisibility()\"\n />\n <label class=\"form-check-label fw-semibold\" for=\"hide_all\">\n Show/Hide All \n </label>\n </div>\n </div>\n <!-- Item -->\n <ng-container\n *ngFor=\"\n let col of columns | filter : topShowHideColumns : 'header';\n trackBy: trackByField\n \"\n >\n <div\n *ngIf=\"col.is_visible\"\n class=\"list-group-item border-0 px-0 d-flex justify-content-between align-items-center\"\n >\n <div class=\"d-flex gap-1\">\n <div class=\"me-1\">\n <input type=\"checkbox\" [(ngModel)]=\"col.is_visible\" [checked]=\"col.is_visible\">\n <!-- show checkbox instead of icon -->\n <!-- <span\n *ngIf=\"!col?.pinned\"\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/grip-vertical.svg'\n \"\n class=\"cursor-grap data-grid-svg-icon\"\n (mousedown)=\"$event.preventDefault()\"\n ></span> -->\n <span\n *ngIf=\"col?.pinned\"\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/pin.svg'\n \"\n class=\"cursor-grap data-grid-svg-icon\"\n (mousedown)=\"$event.preventDefault()\"\n ></span>\n </div>\n <div class=\"fw-semibold\">\n {{ col.header }}\n </div>\n </div>\n <div\n *ngIf=\"!col?.query?.first_value && !col?.query?._ids?.length\"\n class=\"d-flex align-items-center cursor-pointer\"\n (click)=\"toggleColumnVisibility(col, false)\"\n [class.disabled]=\"visibleColumns().length <= 2 || col?.is_always_visible\"\n [class.pe-none]=\"visibleColumns().length <= 2 || col?.is_always_visible\"\n [class.opacity-50]=\"visibleColumns().length <= 2 || col?.is_always_visible\"\n >\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/columnIconNew(2).svg'\"\n class=\"data-grid-svg-icon me-2 setting_dropdown\"\n ></span>\n </div>\n <div\n *ngIf=\"col?.query?.first_value || col?.query?._ids?.length\"\n class=\"d-flex align-items-center\"\n style=\"opacity: 0.5\"\n >\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/eye.svg'\"\n class=\"data-grid-svg-icon me-2\"\n ></span>\n </div>\n </div>\n </ng-container>\n\n <!-- Item End Here -->\n\n <div\n class=\"dropdown-divider\"\n *ngIf=\"hasAnyVisibleColumn && hasAnyInVisibleColumn\"\n ></div>\n\n <div\n class=\"muted-text show-hide-table-label d-flex justify-content-between\"\n *ngIf=\"hasAnyInVisibleColumn\"\n >\n Hide in table\n <div class=\"form-check\">\n <input\n class=\"form-check-input\"\n type=\"checkbox\"\n id=\"show_all\"\n [checked]=\"allColumnsSelected()\"\n (change)=\"toggleAllColumnsVisibility()\"\n />\n <label class=\"form-check-label fw-semibold\" for=\"show_all\">\n Show/Hide All \n </label>\n </div>\n </div>\n <div class=\"list-group list-group-flush\">\n <ng-container *ngFor=\"let col of columns; trackBy: trackByField\">\n <div\n *ngIf=\"!col.is_visible\"\n class=\"list-group-item border-0 px-0 d-flex justify-content-between align-items-center\"\n >\n <div class=\"d-flex gap-1\">\n <div class=\"me-1\">\n <input type=\"checkbox\" [(ngModel)]=\"col.is_visible\" [checked]=\"col.is_visible\">\n <!-- <span\n *ngIf=\"!col?.pinned\"\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/grip-vertical.svg'\n \"\n class=\"data-grid-svg-icon cursor-grap\"\n (mousedown)=\"$event.preventDefault()\"\n ></span> -->\n <span\n *ngIf=\"col?.pinned\"\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/pin.svg'\n \"\n class=\"data-grid-svg-icon cursor-grap\"\n (mousedown)=\"$event.preventDefault()\"\n ></span>\n </div>\n <div class=\"fw-semibold\">\n {{ col.header }}\n </div>\n </div>\n <div\n class=\"d-flex align-items-center cursor-pointer\"\n (click)=\"toggleColumnVisibility(col, true)\"\n >\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/columnIconNew(2).svg'\n \"\n class=\"data-grid-svg-icon me-2 setting_dropdown\"\n ></span>\n </div>\n </div>\n </ng-container>\n </div>\n\n <!-- Item End Here -->\n </div>\n </div>\n</ng-template>\n\n<ng-template #filterColumns let-col=\"column\">\n <div\n @slideToggle\n *ngIf=\"!isFilterOpen && activeTopButton == 'filter-columns'\"\n (click)=\"$event.stopPropagation()\"\n class=\"action_dropdown_new_design actions-dropdown mt-1 show shadow custom-menu table-layout filter-columns\"\n style=\"width: 280px; right: unset; max-width: 230px\"\n [style.backgroundColor]=\"checkboxesBackgroundColor\"\n >\n <div class=\"py-2 px-3\">\n <div class=\"col-12 global-search position-relative\">\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/search.svg'\"\n class=\"data-grid-svg-icon mx-2 position-absolute icon\"\n ></span>\n <input\n class=\"form-control form-control-sm\"\n placeholder=\"Filter by\"\n type=\"search\"\n [(ngModel)]=\"addFilterColumnInput\"\n />\n </div>\n </div>\n <div\n class=\"list-group list-group-flush\"\n style=\"max-height: calc(100vh - 500px); overflow: auto\"\n >\n <ng-container\n *ngFor=\"\n let col of columns | filter : addFilterColumnInput : 'header';\n trackBy: trackByField\n \"\n >\n <div\n (click)=\"openFilter(col)\"\n *ngIf=\"\n col.is_visible &&\n !col?.query?.first_value &&\n !col?.query?._ids?.length && col.type !== 'image'\n \"\n class=\"list-group-item border-0 px-3 d-flex justify-content-between align-items-center dropdown-item cursor-pointer\"\n >\n <div class=\"d-flex align-items-center justify-content-between gap-1 w-100\">\n <!-- <div style=\"margin-top: -3px\"></div> -->\n <div class=\"fw-semibold\">\n {{ col.header }}\n </div>\n <div class=\"d-flex align-items-center justify-content-between\">\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\"\n class=\"data-grid-svg-icon me-2\"\n ></span>\n </div>\n </div>\n </div>\n </ng-container>\n </div>\n </div>\n\n <!-- Dropdown -->\n <div\n @slideToggle\n *ngIf=\"isFilterOpen && selectedColumnForFilter.type == 'dropdown'\"\n (click)=\"$event.stopPropagation()\"\n class=\"shadow actions-dropdown mt-1 show shadow custom-menu table-layout filter-columns pb-2\"\n style=\"width: 280px; right: unset; max-width: 230px\"\n [style.backgroundColor]=\"checkboxesBackgroundColor\"\n >\n <div class=\"px-3 my-2 border-below py-1 pb-2 mb-3 d-flex ps-1\">\n <span\n (click)=\"toggleActions('filter-columns'); isActiveFilterOpen = false\"\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrow-left.svg'\"\n class=\"data-grid-svg-icon me-2 cursor-pointer\"\n ></span\n ><b>{{ selectedColumnForFilter?.header }}</b>\n </div>\n <div class=\"mb-2 px-3\">\n <div\n class=\"col-12 position-relative border rounded d-flex align-items-center flex-wrap px-2 filter-serach-inpt\"\n >\n <span\n *ngFor=\"let selected of selectedFilterOptions\"\n class=\"badge d-flex align-items-center gap-1 me-1 mb-1 top-row-filter-dropdown\"\n >\n {{ selected?.value ? selected.value : selected }}\n <span\n (click)=\"toggleSelectionInFilter(selected)\"\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/cross-primary.svg'\n \"\n class=\"me-2\"\n ></span>\n </span>\n <input\n class=\"form-control form-control-sm border-0 flex-grow-1\"\n style=\"padding: 0\"\n [placeholder]=\"selectedFilterOptions?.length ? '' : 'Filter by'\"\n type=\"search\"\n [(ngModel)]=\"searchTextForFilterDropDown\"\n (keydown.backspace)=\"handleBackspace($event)\"\n />\n </div>\n </div>\n <div\n class=\"list-group list-group-flush\"\n style=\"max-height: calc(100vh - 600px); overflow: auto\"\n >\n <ng-container\n *ngFor=\"\n let col of selectedColumnForFilter.column_dropdown_value\n | filter : searchTextForFilterDropDown : 'value';\n let i = index\n \"\n >\n <div\n class=\"list-group-item border-0 px-2 d-flex justify-content-between align-items-center dropdown-item cursor-pointer\"\n >\n <div class=\"form-check\">\n <input\n class=\"form-check-input\"\n type=\"checkbox\"\n [id]=\"i\"\n [checked]=\"currentFilterSelectedIds.has(col.id || col._id || col)\"\n (change)=\"toggleSelectionInFilter(col)\"\n />\n <label class=\"form-check-label fw-semibold\" [for]=\"i\">\n {{ col?.value || col?.name || col }}\n </label>\n </div>\n </div>\n </ng-container>\n </div>\n <div\n class=\"d-flex justify-content-center gap-2 px-2 border-top\"\n style=\"height: 38px\"\n >\n <button\n type=\"button\"\n style=\"height: 32px\"\n class=\"cancel_btn_new common_btn w-100 d-flex align-items-center justify-content-center mt-1 btn-light\"\n (click)=\"$event.stopPropagation(); resetFilterChanges()\"\n >\n <span>Cancel</span>\n </button>\n <button\n type=\"button\"\n style=\"height: 32px\"\n class=\"primary_btn_new common_btn d-flex align-items-center justify-content-center mt-1\"\n (click)=\"applyDropdownFilter()\"\n >\n <span style=\"margin-top: -2px\">Save</span>\n </button>\n </div>\n </div>\n\n <!-- For Text fields and number fields-->\n\n <div\n @slideToggle\n *ngIf=\"\n isFilterOpen &&\n (selectedColumnForFilter.type == 'string' ||\n selectedColumnForFilter.type == 'number' ||\n selectedColumnForFilter.type == 'date')\n \"\n (click)=\"$event.stopPropagation()\"\n class=\"shadow actions-dropdown mt-1 show shadow custom-menu table-layout filter-columns pb-2\"\n style=\"width: 210px; right: unset; max-width: 230px\"\n [style.backgroundColor]=\"checkboxesBackgroundColor\"\n >\n <div class=\"px-3 border-below py-1 pb-2 d-flex ps-1\">\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrow-left.svg'\"\n (click)=\"toggleActions('filter-columns'); isActiveFilterOpen = false\"\n class=\"data-grid-svg-icon me-2 cursor-pointer\"\n ></span\n ><b>{{ selectedColumnForFilter?.header }}</b>\n </div>\n <div class=\"col-12 position-relative p-2 text-filter\">\n <div class=\"mb-2\">\n <select\n class=\"form-select form-select-sm custom-select border\"\n [(ngModel)]=\"firstCondition\"\n >\n <ng-container *ngIf=\"selectedColumnForFilter.type !== 'date'\">\n <option value=\"contain\">Contains</option>\n <option value=\"does_not_contain\">Does Not Contain</option>\n <option value=\"equal\">Equals</option>\n <option value=\"before\">Starts With</option>\n <option value=\"after\">Ends With</option>\n </ng-container>\n\n <ng-container *ngIf=\"selectedColumnForFilter.type == 'date'\">\n <option value=\"equal\">Equals To</option>\n <option value=\"not_equal\">Not Equal</option>\n <option value=\"after\">After</option>\n <option value=\"before\">Before</option>\n </ng-container>\n </select>\n </div>\n <div class=\"mb-2\">\n <input\n class=\"form-control form-control-sm\"\n placeholder=\"Enter first value\"\n type=\"search\"\n [type]=\"\n selectedColumnForFilter.type == 'string'\n ? 'text'\n : selectedColumnForFilter.type\n \"\n [(ngModel)]=\"firstValue\"\n (keydown.enter)=\"applyDropdownFilter()\"\n />\n </div>\n <div>\n <div class=\"d-flex my-3 d-flex flex-row\" style=\"font-size: 14px\">\n <div\n class=\"form-check form-check-inline col-4 m-0 d-flex align-items-center gap-1\"\n >\n <input\n class=\"form-check-input\"\n type=\"radio\"\n id=\"logicalAnd\"\n name=\"logicalOperator\"\n value=\"and\"\n [(ngModel)]=\"condition\"\n />\n <label class=\"form-check-label mb-0 mt-1\" for=\"logicalAnd\"\n >AND</label\n >\n </div>\n\n <div\n class=\"form-check form-check-inline col-4 m-0 d-flex align-items-center gap-1\"\n >\n <input\n class=\"form-check-input\"\n type=\"radio\"\n id=\"logicalOr\"\n name=\"logicalOperator\"\n value=\"or\"\n [(ngModel)]=\"condition\"\n />\n <label class=\"form-check-label mb-0 mt-1\" for=\"logicalOr\">OR</label>\n </div>\n\n <div\n class=\"form-check form-check-inline col-4 m-0 d-flex align-items-center gap-1\"\n >\n <input\n class=\"form-check-input\"\n type=\"radio\"\n id=\"logicalNone\"\n name=\"logicalOperator\"\n value=\"none\"\n [(ngModel)]=\"condition\"\n />\n <label class=\"form-check-label mb-0 mt-1\" for=\"logicalNone\"\n >None</label\n >\n </div>\n </div>\n\n <ng-container *ngIf=\"condition !== 'none' && firstValue\">\n <div class=\"mb-2 mt-3\">\n <!-- Second condition select -->\n <select\n class=\"form-select form-select-sm border\"\n [(ngModel)]=\"secondCondition\"\n >\n <ng-container *ngIf=\"selectedColumnForFilter.type !== 'date'\">\n <option value=\"contain\">Contains</option>\n <option value=\"does_not_contain\">Does Not Contain</option>\n <option value=\"equal\">Equals</option>\n <option value=\"before\">Starts With</option>\n <option value=\"after\">Ends With</option>\n </ng-container>\n\n <ng-container *ngIf=\"selectedColumnForFilter.type == 'date'\">\n <option value=\"equal\">Equals To</option>\n <option value=\"not_equal\">Not Equal</option>\n <option value=\"after\">After</option>\n <option value=\"before\">Before</option>\n </ng-container>\n </select>\n </div>\n\n <div class=\"mb-2\">\n <!-- Second value input -->\n <input\n [type]=\"\n selectedColumnForFilter.type == 'string'\n ? 'text'\n : selectedColumnForFilter.type\n \"\n class=\"form-control form-control-sm\"\n placeholder=\"Enter second value\"\n type=\"search\"\n [(ngModel)]=\"secondValue\"\n (keydown.enter)=\"applyDropdownFilter()\"\n />\n </div>\n </ng-container>\n </div>\n </div>\n\n <div\n class=\"d-flex justify-content-center gap-2 px-2 border-top\"\n style=\"height: 38px\">\n <button\n [disabled]=\"!currentFilterSelectedIds?.size && !firstValue\"\n type=\"button\"\n style=\"height: 32px\"\n class=\"cancel_btn_new common_btn w-100 d-flex align-items-center justify-content-center mt-1\"\n (click)=\"$event.stopPropagation(); resetTextFilterChanges()\">\n <span>Cancel</span>\n </button>\n <button\n [disabled]=\"(currentFilterSelectedIds?.size === 0 && !firstValue) || (condition !== 'none' && !secondValue)\"\n type=\"button\"\n style=\"height: 32px\"\n class=\"primary_btn_new common_btn d-flex align-items-center justify-content-center mt-1\"\n (click)=\"applyDropdownFilter()\">\n <span style=\"margin-top: -2px\">Apply</span>\n </button>\n </div>\n </div>\n</ng-template>\n\n<!-- Edit dropdown here -->\n<ng-template let-col>\n <div class=\"drop-down-edit\"></div>\n</ng-template>\n\n<ng-template\n #fullTextTemplate\n let-row=\"row\"\n let-col=\"col\"\n let-isArray=\"isArray\"\n>\n <div\n class=\"full-text-box\"\n (dblclick)=\"$event.stopPropagation(); $event.preventDefault()\"\n (click)=\"$event.stopPropagation(); $event.preventDefault()\"\n [style.maxHeight.px]=\"dataGridContainer.offsetHeight / 2\"\n >\n <ng-container *ngIf=\"!isEditing(row, col)\">\n <div\n *ngIf=\"!isArray\"\n class=\"full-text-content\"\n [style.maxHeight.px]=\"dataGridContainer.offsetHeight / 2\"\n (dblclick)=\"\n $event.stopPropagation();\n $event.preventDefault();\n enableEdit(row, col, true)\n \"\n (click)=\"$event.stopPropagation(); $event.preventDefault()\"\n >\n {{\n getNestedValue(row, col.field)?.value ||\n getNestedValue(row, col.field)?.name ||\n getNestedValue(row, col.field)\n }}\n </div>\n <div *ngIf=\"isArray\">\n <ul>\n <ng-container\n *ngFor=\"let item of getNestedValue(row, col.field); let i = index\"\n >\n <li *ngIf=\"i !== 0\">\n <ng-container>\n {{\n item?.department_name ||\n item?.roleName ||\n item?.full_name ||\n \"-\"\n }}\n </ng-container>\n </li>\n </ng-container>\n </ul>\n </div>\n </ng-container>\n <ng-container *ngIf=\"isEditing(row, col)\">\n <textarea\n (dblclick)=\"\n $event.stopPropagation();\n $event.preventDefault();\n enableEdit(row, col, true)\n \"\n #textModel=\"ngModel\"\n rows=\"4\"\n #textAreadInput\n [(ngModel)]=\"row[col.field]\"\n name=\"{{ col.field }}\"\n required\n (blur)=\"disableEdit(row, col, textModel)\"\n (keydown.enter)=\"textAreadInput.blur()\"\n autofocus\n class=\"form-control\"\n [ngClass]=\"{\n 'is-invalid': textModel.invalid\n }\"\n (mousedown)=\"$event.stopPropagation()\"\n ></textarea>\n </ng-container>\n </div>\n</ng-template>\n\n<ng-template #defaultImagePlaceholder let-row=\"row\" let-col=\"col\">\n <span\n class=\"px-2 d-flex w-100 cell-content image-placeholder\"\n [title]=\"row?.full_name || row?.name || 'N/A'\"\n >\n <ng-container\n *ngIf=\"\n row?.logo ||\n row?.assetImage ||\n row?.invoice?.invoice_image ||\n row?.invoice_image;\n else placeholder\n \"\n >\n <span\n (click)=\"fullscreenImage = row?.profile_pictures?.[4]?.path ||\n row?.logo ||\n row?.assetImage ||\n row?.invoice_image\"\n class=\"pic\"\n [style.width.px]=\"rowHeight - 10\"\n [style.height.px]=\"rowHeight - 10\"\n [class.assets-pic]=\"gridType == 'Assets'\"\n >\n <img\n [width]=\"rowHeight - 12\"\n [height]=\"rowHeight - 12\"\n [style.width.px]=\"rowHeight - 10\"\n [style.height.px]=\"rowHeight - 10\"\n [src]=\"\n row?.profile_pictures?.[4]?.path ||\n row?.logo ||\n row?.assetImage ||\n row?.invoice_image\n \"\n alt=\"icon\"\n class=\"option-icon\"\n loading=\"lazy\"\n />\n </span>\n </ng-container>\n <!-- <div\n class=\"fullscreen-overlay\"\n *ngIf=\"fullscreenImage\"\n (click)=\"fullscreenImage = null\"\n >\n <img [src]=\"fullscreenImage\" class=\"fullscreen-img\" />\n </div> -->\n\n <ng-template #placeholder>\n <span\n [ngClass]=\"getDynamicClass(row?.full_name || row?.name)\"\n class=\"pic d-flex align-items-center rounded-circle\"\n [style.width.px]=\"rowHeight - 12\"\n [style.height.px]=\"rowHeight - 12\"\n [style.fontSize.px]=\"rowHeight / 3\"\n [class.assets-pic]=\"gridType == 'Assets'\"\n >\n {{ getInitials(row?.full_name) }}\n </span>\n </ng-template>\n </span>\n</ng-template>\n\n<!-- Right Click Menue -->\n<div\n [class.invisible]=\"!positionedYet\"\n class=\"context-menu p-2\"\n *ngIf=\"actionHide && actions?.length\"\n [ngStyle]=\"{ 'top.px': yPos, 'left.px': xPos }\"\n [class.show]=\"isVisible\"\n appendTo=\"body\"\n>\n <ul>\n <li\n *ngFor=\"let action of actions\"\n class=\"rounded d-flex align-items-center\"\n (click)=\"onActionClick(action)\"\n >\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/' + action + '.svg'\"\n class=\"data-grid-svg-icon right-click-menu-icons me-2\"\n ></span>\n <span class=\"text-capitalize fw-500\">{{ action }}</span>\n </li>\n </ul>\n</div>\n\n<!-- Details Toggle from bottom -->\n\n<ng-template #nestedTableTemplate let-row>\n <div\n class=\"nested-table table table-sm w-100 mb-0 center-nested-table w-100\"\n style=\"table-layout: fixed !important\"\n #nestedTableContainer\n >\n <thead\n #nestedHeader\n [style.backgroundColor]=\"nestedTableHeaderBackgroundColor\"\n >\n <div\n cdkDropList\n [cdkDropListData]=\"row?.detail.columns\"\n cdkDropListOrientation=\"horizontal\"\n (cdkDropListDropped)=\"dropColumn($event, row)\"\n (cdkDropListSorted)=\"onNestedColSort($event, previewNestedCols)\"\n [style.height.px]=\"nestedTableHeaderRowHeight\"\n class=\"d-flex tr border-below\"\n >\n <div\n *ngFor=\"let col of row.detail.columns; let i = index\"\n [style.width.px]=\"col?.width || 250\"\n [style.minWidth.px]=\"col?.width || 250\"\n [style.maxWidth.px]=\"col?.width || 250\"\n class=\"px-4 th\"\n [attr.field]=\"col.field\"\n [style.backgroundColor]=\"nestedTableHeaderBackgroundColor\"\n cdkDrag\n >\n <div\n class=\"d-flex h-100 justify-content-between position-relative align-items-center\"\n >\n <div class=\"text-ellipsis\" (click)=\"sortNestedCol(col, row)\">\n {{ col.header }}\n </div>\n <div class=\"d-flex gap-2\">\n <span\n *ngIf=\"currentSubSortColumn == col.field\"\n [inlineSVG]=\"\n singleSpaAssetsPath +\n (col?.order_by == 'desc'\n ? 'data-grid/icons/sort-desc.svg'\n : 'data-grid/icons/sort-asc.svg')\n \"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center ms-2 start-50\"\n >\n </span>\n <!-- <div\n class=\"three-dots p-1\"\n (click)=\"openThreeDotsMenu($event, col)\"\n style=\"cursor: pointer\"\n >\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath +\n 'data-grid/icons/three-dots-vertical.svg'\n \"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n </div> -->\n\n <!-- Only show menu if this column is active -->\n <div\n class=\"position-absolute\"\n *ngIf=\"activeCol === col\"\n style=\"top: -50%; z-index: 21; left: 0\"\n >\n <ng-container\n *ngTemplateOutlet=\"\n columnMenu;\n context: {\n col: col,\n isNestedTable: true,\n columns: row?.detail.columns\n }\n \"\n ></ng-container>\n </div>\n <div\n class=\"resize-handle\"\n (click)=\"$event.stopPropagation()\"\n (mousedown)=\"\n $event.preventDefault();\n onResizeColumn($event, col);\n $event.stopPropagation()\n \"\n >\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/resize-handle1.svg'\n \"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n </div>\n </div>\n </div>\n <ng-template cdkDragPreview>\n <div class=\"p-2 border d-flex gap-2\">\n <div>\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/arrows-move.svg'\n \"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n </div>\n <div>{{ col.header }}</div>\n </div>\n </ng-template>\n </div>\n </div>\n </thead>\n <div\n [style.width.px]=\"nestedHeader.offsetWidth - 10\"\n [style.minWidth.px]=\"nestedHeader.offsetWidth - 10\"\n >\n <cdk-virtual-scroll-viewport\n [itemSize]=\"nestedTablerowHeight\"\n class=\"viewport\"\n [style.height.px]=\"\n (row?.detail?.result?.length < 5\n ? nestedTablerowHeight * row?.detail?.result?.length + 40\n : 300) + (hasHorizontalScroll ? -12 : 1)\n \"\n [style.width.px]=\"nestedHeader.offsetWidth - 10\"\n [style.minWidth.px]=\"nestedHeader.offsetWidth - 10\"\n >\n <div\n class=\"cursor-pointer border-below d-flex tr\"\n *cdkVirtualFor=\"let d of row?.detail?.result; trackBy: trackById\"\n [style.height.px]=\"nestedTablerowHeight\"\n [style.width.px]=\"nestedHeader?.offsetWidth\"\n [style.minWidth.px]=\"nestedHeader?.offsetWidth\"\n [style.backgroundColor]=\"bodyBackgroundColor\"\n (contextmenu)=\"onRightClick($event, d)\"\n >\n <div\n class=\"px-4 py-0 td\"\n *ngFor=\"let col of previewNestedCols; let j = index\"\n [style.fontSize.px]=\"nestedTablerowFontsize\"\n [attr.field]=\"col.field\"\n [style.width.px]=\"col?.width || 250\"\n [style.minWidth.px]=\"col?.width || 250\"\n [style.maxWidth.px]=\"col?.width || 250\"\n >\n <div\n [style.height.px]=\"nestedTablerowHeight - 1\"\n [style.max-width.px]=\"col?.width\"\n class=\"d-flex align-items-center\"\n >\n <!-- {{ d[col.field] || (col.is_amount ? 0 : \"-\") }} -->\n <div\n #cellText\n class=\"text-ellipsis flex-grow-1\"\n [title]=\"\n col.type === 'date'\n ? (getNestedValue(d, col.field) | date : dateFormat)\n : getNestedValue(d, col.field) || '-'\n \"\n >\n <ng-container *ngIf=\"col.type !== 'image'\">\n <ng-container *ngIf=\"col.is_amount\">{{\n currencySymbol\n }}</ng-container>\n {{\n !isNestedValueArray(d, col.field)\n ? col.type === 'date'\n ? (isDate(getNestedValue(d, col.field))\n ? (getNestedValue(d, col.field) | date: dateFormat)\n : (getNestedValue(d, col.field)?.value ||\n getNestedValue(d, col.field)?.name ||\n getNestedValue(d, col.field) ||\n '-'))\n : (getNestedValue(d, col.field)?.value ||\n getNestedValue(d, col.field)?.name ||\n getNestedValue(d, col.field) ||\n (col.is_amount ? 0: '-'))\n : (getNestedValue(d, col.field)?.[0]?.department_name ||\n getNestedValue(d, col.field)?.[0]?.roleName || getNestedValue(d, col.field)?.[0]?.full_name ||\n '-')\n }}\n </ng-container>\n <ng-container *ngIf=\"false\">\n {{ getTotalAmount(col) }}\n </ng-container>\n <ng-container *ngIf=\"col.type == 'image'\">\n <ng-container\n *ngTemplateOutlet=\"\n defaultImagePlaceholder;\n context: {\n row: d,\n col: col,\n }\n \"\n ></ng-container>\n </ng-container>\n </div>\n </div>\n </div>\n </div>\n </cdk-virtual-scroll-viewport>\n </div>\n </div>\n</ng-template>\n\n<ng-template #leftRightNestedPlaceholder let-row>\n <table\n class=\"nested-table table table-sm w-100 mb-0\"\n [style.backgroundColor]=\"bodyBackgroundColor\"\n [style.height.px]=\"\n gridType == 'Assets'\n ? (nestedTableContainer?.nativeElement?.offsetHeight ?? 0) + 12\n : (taskManagementContainer?.nativeElement?.offsetHeight ?? 0)\n \"\n >\n <!-- <div class=\"thead\">\n <div\n class=\"tr d-flex border-below\"\n [style.height.px]=\"nestedTableHeaderRowHeight\"\n [style.backgroundColor]=\"headerBackgroundColor\"\n >\n <div class=\"th\" *ngFor=\"let _ of [1, 2, 3, 4, 5]\"></div>\n </div>\n </div> -->\n <!-- <div class=\"tbody\">\n <div\n class=\"tr border-below\"\n [style.height.px]=\"nestedTablerowHeight\"\n *ngFor=\"let _ of row?.detail?.result\"\n [style.backgroundColor]=\"headerBackgroundColor\"\n >\n <div class=\"td\" *ngFor=\"let __ of [1, 2, 3, 4, 5]\" class=\"py-0\">\n <span\n [style.height.px]=\"nestedTablerowHeight\"\n [style.max-width.px]=\"nestedTablerowHeight\"\n ></span>\n </div>\n </div>\n </div> -->\n </table>\n</ng-template>\n\n<ng-template #taskManagementTemplate let-taskDetails=\"taskDetails\">\n <div\n class=\"p-4\"\n #taskManagementContainer\n [style.backgroundColor]=\"nestedTableHeaderBackgroundColor\"\n [style.fontFaimly]=\"fontFaimly\"\n >\n <div class=\"d-flex justify-content-between\">\n <div class=\"col-4\">\n <div class=\"item-title\">Description</div>\n <!-- <div class=\"item-content firstDiv\">\n {{ taskDetails.description }}\n </div> -->\n <p\n [style.fontSize]=\"bodyTextFontsSize\"\n class=\"item-content firstDiv taskDescription pe-4\"\n [innerHTML]=\"getSafeComment(taskDetails?.editor_description)\"\n (click)=\"openFullImage($event)\"\n ></p>\n </div>\n <div class=\"col-4\">\n <div class=\"item-title\">Attachments</div>\n <h5 *ngIf=\"taskDetails?.attachments?.length == 0\">\n No Attachments found\n </h5>\n <div\n *ngIf=\"taskDetails?.attachments?.length\"\n class=\"item-content d-flex flex-wrap\"\n style=\"gap: 10px\"\n >\n <a\n *ngFor=\"let attachement of taskDetails?.attachments; let i = index\"\n class=\"symbol-label fs-2 fw-semibold text-success cursor-pointer\"\n >\n <span\n title=\"{{ taskDetails?.attachments_name[i] || 'Attachment' }}\"\n (click)=\"downloadAttchment(attachement)\"\n [inlineSVG]=\"\n singleSpaAssetsPath +\n 'data-grid/document-icons/' +\n getExtention(attachement) +\n '.svg'\n \"\n >\n </span>\n </a>\n </div>\n </div>\n <div class=\"col-4\">\n <div class=\"item-title\">\n Comments ({{ taskDetails?.comments?.length }})\n </div>\n <h5 *ngIf=\"taskDetails?.comments?.length == 0\">No Comments found</h5>\n <div *ngIf=\"taskDetails?.comments?.length\" class=\"item-content\">\n <div class=\"comment\" *ngFor=\"let comment of taskDetails.comments\">\n <div class=\"d-flex align-items-center pe-3\">\n <img\n class=\"pic image-input-wrapper\"\n [style.width.px]=\"rowHeight - 12\"\n [style.height.px]=\"rowHeight - 12\"\n *ngIf=\"comment?.comment_by.logo\"\n src=\"{{ comment?.comment_by.logo }}\"\n alt=\"{{ comment.comment_by.full_name }}\"\n />\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> -->\n <span\n *ngIf=\"!comment?.comment_by.logo\"\n [ngClass]=\"getDynamicClass(comment.comment_by.full_name)\"\n class=\"pic d-flex align-items-center rounded-circle\"\n [style.width.px]=\"rowHeight - 12\"\n [style.height.px]=\"rowHeight - 12\"\n [style.fontSize.px]=\"rowHeight / 3\"\n title=\"{{ comment.comment_by.full_name }}\"\n >\n {{ getInitials(comment.comment_by.full_name) }}\n </span>\n </div>\n <div>\n <div class=\"comment-author fs-14px\">\n {{ comment?.comment_by.full_name }}\n </div>\n <div\n class=\"comment-content forCommentImg\"\n [innerHTML]=\"getSafeComment(comment.comment)\"\n ></div>\n <div class=\"comment-timestamp\">\n {{ comment.comment_date | date }}\n </div>\n <div class=\"comment-timestamp\">\n Replies: ({{ comment.replies.length }})\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n</ng-template>", styles: ["@charset \"UTF-8\";@import\"bootstrap/dist/css/bootstrap.min.css\";:host,:host *{font-family:Inter,sans-serif!important}.data-grid-table-wrapper{height:100%;width:100%;border:1px solid #E0E0E0;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:0 0 0 8px;font-weight:700;border-bottom:1px solid #E0E0E0;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 #E0E0E0}.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}:host ::ng-deep .resize-handle svg{stroke-width:2px}.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 #E0E0E0}.hovered-row{background-color:#ccc}.checkbox-row{border-bottom:#E0E0E0}.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 #E0E0E0;z-index:unset}.left-pinned{left:0}.right-pinned{right:0;border-left:1px solid #E0E0E0}.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 #E0E0E0!important}.right-pinned-body{right:0;border-left:1px solid #E0E0E0}.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%}.select-all-checkbox-cell input{width:16px;height:14px}.border-below{border-bottom:1px solid #E0E0E0!important}.figmaIconSize.data-grid-svg-icon{width:24px!important;height:24px!important}.actions-dropdown .list-group .list-group-item{color:#1b1f22!important}.productSortingDropdownMenu{width:220px!important}.three-dots{width:24px;height:24px;display:flex;justify-content:center;align-items:center;border-radius:6px;margin-right:4px;margin-left:2px;cursor:pointer}.three-dots:hover,.three-dots.threeDotActive{background-color:#0084ff1a;padding:5px}.rotated-180{transform:scaleY(-1)}.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:200px;border:1px solid #ddd;box-shadow:0 0 12px #00000014;border:1px solid #E0E0E0;padding:4px 0;font-size:14px;position:fixed;border-radius:8px}.column-menu-item{padding:8px 12px;cursor:pointer;display:flex;align-items:center;transition:background-color .2s ease}.column-menu-item.active-sort,.column-menu-item:hover{background-color:#0084ff1a}.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 #E0E0E0;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 #E0E0E0;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 #E0E0E0;font-size:14px}.border-start{border-left:1px solid #E0E0E0!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 #E0E0E0;padding-left:32px}.fake-horizintal-scrollbar{position:relative;bottom:17px;overflow-x:auto;overflow-y:hidden;height:17px}.border-dashed{border:1px dashed #E0E0E0}.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 #E0E0E0!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 #E0E0E0}.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{width:100%;display:flex!important;align-items:center!important;height:32px;max-width:335px}.global-search span{margin-top:0!important;top:8px}.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 #E0E0E0!important;border-radius:8px!important}.custom-menu{width:250px;border-radius:8px;padding:4px 0;background-color:#fff}.custom-menu.setting_dropdown_menu{width:270px}.custom-menu .dropdown-item{font-size:14px;padding:8px 14px;color:#1b1f22!important;font-weight:400}.custom-menu .dropdown-item:hover{background-color:#0084ff1a;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 #E0E0E0!important;background-color:#fff}.action_dropdown_new_design{background:#fff;border-radius:8px!important;border:1px solid #E0E0E0!important;box-shadow:0 2px 12px #00000014}.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{border-color:#0084ff!important;background-color:#f5f5f5!important;color:#1b1f22!important}#small:checked+label .preview-box{background-color:#fff!important}#medium:checked+label{border-color:#0084ff!important;background-color:#f5f5f5!important;color:#1b1f22!important}#medium:checked+label .preview-box{background-color:#fff!important}#large:checked+label{border-color:#0084ff!important;background-color:#f5f5f5!important;color:#1b1f22!important}#large:checked+label .preview-box{background-color:#fff!important}.btn-check:checked+.btn{background-color:transparent!important;border-color:#007cf5!important}.layout-button{padding:8px 6px!important;width:82px;border-radius:8px!important;color:#1b1f22!important;height:60px;margin-bottom:0!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:14px;color:#1b1f22}.page-size select{padding:3px 6px;border:1px solid #E0E0E0;border-radius:6px;background:#fff;font-size:13px}.page-buttons{display:flex;gap:4px;margin-left:auto;align-items:center}.page-buttons button{padding:7px 11px;background:#fff;border-radius:4px;cursor:pointer;font-size:13px;line-height:1.2;border:0;color:#6a6b6d}.page-buttons button.active{font-weight:400;border:1px solid #E0E0E0;border-radius:8px;font-size:14px;color:#1b1f22}.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 #E0E0E0}.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}.table-layout .dropdown-item{border-radius:0!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;font-size:14px;font-weight:400;color:#1b1f22;background:#ebebeb}.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 span:not(.no-stroke) svg,:host ::ng-deep .three-dots-col-menu span:not(.no-stroke) svg path{stroke:#000!important}:host ::ng-deep .ascendingAppliedIcon svg{stroke:#006fd6}.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;justify-content:center;z-index:1050;border:1px solid #dedede;border-radius:8px;padding:12px 14px;box-shadow:0 2px 8px #00000026}.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:4px!important;height:24px;align-items:center;width:-moz-fit-content;width:fit-content}.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 #E0E0E0}.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}.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}.card-outer{border:1px solid var(--semantics-border-subtle-secondary, #E0E0E0);border-radius:16px;padding:16px;background-color:#fff}.consumerDropdownButton{height:32px;display:flex;align-items:center}a.grid-header-icon:hover{background:#e0e0e0;width:32px;height:32px;border-radius:8px;transition:none}a.grid-header-icon{width:32px;height:32px}.action-buttons-row.active a.grid-header-icon,a.grid-header-icon.show{background-color:#e0e0e0;border-radius:8px}.data-grid-svg-icon.setting_dropdown{width:32px!important;height:32px!important}.new_design_dropdown .dropdown_main_button{color:#6a6b6d;text-decoration:none}.new_design_dropdown ul{border-radius:8px!important;border:1px solid #E0E0E0!important;box-shadow:0 0 12px #00000014!important}.new_design_dropdown ul li{color:#1b1f22!important;height:32px}.new_design_dropdown ul li:hover{background:#0084ff1a!important}.new_design_dropdown ul li a.dropdown-item.hover_dropdown_bg{height:inherit;border-radius:6px;padding:6px 10px;color:#1b1f22!important;font-size:14px;font-weight:400}.new_design_dropdown ul li a.dropdown-item.hover_dropdown_bg .new_old_filter{display:inline-block;width:24px;height:24px}.new_design_dropdown ul li a.dropdown-item.hover_dropdown_bg label,.new_design_dropdown ul li a.dropdown-item.hover_dropdown_bg span.newest,.new_design_dropdown ul li a.dropdown-item.hover_dropdown_bg span.oldest{padding-left:5px}.new_design_dropdown ul li a.dropdown-item.hover_dropdown_bg:hover{background-color:transparent!important}.new_design_dropdown ul li .action_dropdown{padding:6px 16px}.new_design_dropdown ul li.active-filter{background-color:#0084ff1a}.new_design_dropdown.hide_arrow .dropdown-toggle:after{display:none}.new_design_dropdown.hide_arrow ul li a label{line-height:1}.dropdown_main_button{border-radius:8px;transition:none;padding:5px 10px}.dropdown_main_button:hover,.dropdown_main_button.show{background:#e0e0e0}.sorting_icon_input{width:24px;height:24px;display:flex;align-items:center;justify-content:center}.sorting_dropdown .column-menu-item{padding:0 6px!important;color:#1b1f22!important;font-size:14px!important;font-weight:400!important}.greenBgHover{background:#0084ff1a!important;border-radius:6px!important}.cancel_btn_new{font-weight:400!important;font-size:14px!important;color:#1b1f22!important;border:none;box-shadow:none;background:transparent;height:32px;padding:3px 14px;display:flex;align-items:center;justify-content:center}.primary_btn_new{font-weight:500!important;font-size:14px!important;color:#fff!important;background:#0084ff;border:none;box-shadow:none;height:32px;padding:3px 14px;display:flex;align-items:center;justify-content:center;border-radius:6px}.dropdown_outer{border:1px solid #E0E0E0;box-shadow:0 2px 12px #00000014;border-radius:8px;font-size:14px}.text_common_14px{font-size:14px;font-weight:400;color:#1b1f22}.text_common_16px{font-size:16px;font-weight:500;color:#1b1f22}.page_refresh{font-size:13px;font-weight:400;color:#6a6b6d}\n"] }]
|
|
6319
|
+
}], 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: [{
|
|
6711
6320
|
type: Input
|
|
6712
6321
|
}], paginationConfig: [{
|
|
6713
6322
|
type: Input
|
|
@@ -6827,10 +6436,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
|
|
|
6827
6436
|
type: Input
|
|
6828
6437
|
}], nestedTablerowHeight: [{
|
|
6829
6438
|
type: Input
|
|
6830
|
-
}], packageData: [{
|
|
6831
|
-
type: Input
|
|
6832
|
-
}], showUnLink: [{
|
|
6833
|
-
type: Input
|
|
6834
6439
|
}], gridType: [{
|
|
6835
6440
|
type: Input
|
|
6836
6441
|
}], currencySymbol: [{
|
|
@@ -6869,19 +6474,20 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
|
|
|
6869
6474
|
type: Input
|
|
6870
6475
|
}], showCheckboxes: [{
|
|
6871
6476
|
type: Input
|
|
6872
|
-
}],
|
|
6873
|
-
type: Input
|
|
6874
|
-
}], resetAllFilters: [{
|
|
6477
|
+
}], consumerFont: [{
|
|
6875
6478
|
type: Input
|
|
6876
6479
|
}], defaultConfig: [{
|
|
6877
6480
|
type: Input
|
|
6878
|
-
}],
|
|
6481
|
+
}], resetAllFilters: [{
|
|
6879
6482
|
type: Input
|
|
6880
|
-
}],
|
|
6483
|
+
}], columnThreedotsMunuConfig: [{
|
|
6881
6484
|
type: Input
|
|
6882
6485
|
}], cellHosts: [{
|
|
6883
6486
|
type: ViewChildren,
|
|
6884
6487
|
args: [CellHostDirective]
|
|
6488
|
+
}], globalSearchInput: [{
|
|
6489
|
+
type: ViewChild,
|
|
6490
|
+
args: ['globalSearchInput']
|
|
6885
6491
|
}], changeLayout: [{
|
|
6886
6492
|
type: Output
|
|
6887
6493
|
}], customCellEvent: [{
|
|
@@ -6929,9 +6535,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
|
|
|
6929
6535
|
}], rightPinnedHeader: [{
|
|
6930
6536
|
type: ViewChild,
|
|
6931
6537
|
args: ['rightPinnedHeader']
|
|
6932
|
-
}], globalSearchInput: [{
|
|
6933
|
-
type: ViewChild,
|
|
6934
|
-
args: ['globalSearchInput']
|
|
6935
6538
|
}], columnsGroupedBox: [{
|
|
6936
6539
|
type: ViewChild,
|
|
6937
6540
|
args: ['columnsGroupedBox']
|
|
@@ -6985,6 +6588,79 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
|
|
|
6985
6588
|
args: ['fullscreenImageTemplate']
|
|
6986
6589
|
}] } });
|
|
6987
6590
|
|
|
6591
|
+
class CellEditorDirective {
|
|
6592
|
+
constructor(vcr, injector) {
|
|
6593
|
+
this.vcr = vcr;
|
|
6594
|
+
this.injector = injector;
|
|
6595
|
+
// Parent component listens using:
|
|
6596
|
+
// (editorEvent)="finishEdit($event)"
|
|
6597
|
+
this.editorEvent = new EventEmitter();
|
|
6598
|
+
}
|
|
6599
|
+
ngOnInit() {
|
|
6600
|
+
if (!this.componentType)
|
|
6601
|
+
return;
|
|
6602
|
+
// ✅ Dynamically create the editor component
|
|
6603
|
+
const componentRef = this.vcr.createComponent(this.componentType, {
|
|
6604
|
+
injector: Injector.create({
|
|
6605
|
+
providers: [
|
|
6606
|
+
{ provide: 'rowData', useValue: this.rowData },
|
|
6607
|
+
{ provide: 'colData', useValue: this.colData },
|
|
6608
|
+
{ provide: 'cellValue', useValue: this.cellValue }
|
|
6609
|
+
],
|
|
6610
|
+
parent: this.injector
|
|
6611
|
+
})
|
|
6612
|
+
});
|
|
6613
|
+
// -----------------------------------------------
|
|
6614
|
+
// 1️⃣ Call custom lifecycle hook if it exists
|
|
6615
|
+
// -----------------------------------------------
|
|
6616
|
+
if (typeof componentRef.instance.editorInit === 'function') {
|
|
6617
|
+
componentRef.instance.editorInit({
|
|
6618
|
+
row: this.rowData,
|
|
6619
|
+
col: this.colData,
|
|
6620
|
+
value: this.cellValue
|
|
6621
|
+
});
|
|
6622
|
+
}
|
|
6623
|
+
// -----------------------------------------------
|
|
6624
|
+
// 2️⃣ Auto-detect all @Output() EventEmitters
|
|
6625
|
+
// -----------------------------------------------
|
|
6626
|
+
for (const key of Object.keys(componentRef.instance)) {
|
|
6627
|
+
const property = componentRef.instance[key];
|
|
6628
|
+
// Check if any property is an EventEmitter
|
|
6629
|
+
if (property instanceof EventEmitter) {
|
|
6630
|
+
property.subscribe((value) => {
|
|
6631
|
+
this.editorEvent.emit({
|
|
6632
|
+
eventName: key,
|
|
6633
|
+
data: {
|
|
6634
|
+
row: this.rowData,
|
|
6635
|
+
col: this.colData,
|
|
6636
|
+
value
|
|
6637
|
+
}
|
|
6638
|
+
});
|
|
6639
|
+
});
|
|
6640
|
+
}
|
|
6641
|
+
}
|
|
6642
|
+
}
|
|
6643
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: CellEditorDirective, deps: [{ token: i0.ViewContainerRef }, { token: i0.Injector }], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
6644
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: CellEditorDirective, selector: "[cellEditor]", inputs: { componentType: ["cellEditor", "componentType"], rowData: "rowData", colData: "colData", cellValue: "cellValue" }, outputs: { editorEvent: "editorEvent" }, ngImport: i0 }); }
|
|
6645
|
+
}
|
|
6646
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: CellEditorDirective, decorators: [{
|
|
6647
|
+
type: Directive,
|
|
6648
|
+
args: [{
|
|
6649
|
+
selector: '[cellEditor]'
|
|
6650
|
+
}]
|
|
6651
|
+
}], ctorParameters: function () { return [{ type: i0.ViewContainerRef }, { type: i0.Injector }]; }, propDecorators: { componentType: [{
|
|
6652
|
+
type: Input,
|
|
6653
|
+
args: ['cellEditor']
|
|
6654
|
+
}], rowData: [{
|
|
6655
|
+
type: Input
|
|
6656
|
+
}], colData: [{
|
|
6657
|
+
type: Input
|
|
6658
|
+
}], cellValue: [{
|
|
6659
|
+
type: Input
|
|
6660
|
+
}], editorEvent: [{
|
|
6661
|
+
type: Output
|
|
6662
|
+
}] } });
|
|
6663
|
+
|
|
6988
6664
|
// format-index.pipe.ts
|
|
6989
6665
|
class FormatIndexPipe {
|
|
6990
6666
|
transform(value) {
|
|
@@ -7008,7 +6684,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
|
|
|
7008
6684
|
|
|
7009
6685
|
class DataGridModule {
|
|
7010
6686
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DataGridModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
|
|
7011
|
-
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "16.2.12", ngImport: i0, type: DataGridModule, declarations: [DataGridComponent, FilterPipe, FormatIndexPipe, CellHostDirective, CellRenderInitDirective, CellEditorDirective, FormatCurrencyPipe], imports: [CommonModule, FormsModule, DragDropModule,
|
|
6687
|
+
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "16.2.12", ngImport: i0, type: DataGridModule, declarations: [DataGridComponent, FilterPipe, FormatIndexPipe, CellHostDirective, CellRenderInitDirective, CellEditorDirective, FormatCurrencyPipe], imports: [CommonModule, FormsModule, DragDropModule, i10.InlineSVGModule, ScrollingModule, TitleCasePipe], exports: [DataGridComponent] }); }
|
|
7012
6688
|
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DataGridModule, providers: [FormatCurrencyPipe, DatePipe], imports: [CommonModule, FormsModule, DragDropModule, InlineSVGModule.forRoot(), ScrollingModule] }); }
|
|
7013
6689
|
}
|
|
7014
6690
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DataGridModule, decorators: [{
|
|
@@ -7024,6 +6700,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
|
|
|
7024
6700
|
/*
|
|
7025
6701
|
* Public API Surface of data-grid
|
|
7026
6702
|
*/
|
|
6703
|
+
// import './lib/styles/styles.css';
|
|
7027
6704
|
|
|
7028
6705
|
/**
|
|
7029
6706
|
* Generated bundle index. Do not edit.
|