ms-data-grid 0.0.90 → 0.0.93

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.
@@ -1,19 +1,20 @@
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 i9 from '@angular/cdk/drag-drop';
3
+ import * as i10 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 { take } from 'rxjs';
6
+ import { firstValueFrom, take } from 'rxjs';
7
+ import 'bootstrap/dist/js/bootstrap.bundle.min.js';
7
8
  import * as i6 from '@angular/common';
8
9
  import { DatePipe, CommonModule, TitleCasePipe } from '@angular/common';
9
10
  import * as i4 from '@angular/platform-browser';
10
11
  import * as XLSX from 'xlsx-js-style';
11
12
  import { saveAs } from 'file-saver';
12
- import * as i8 from '@angular/forms';
13
+ import * as i9 from '@angular/forms';
13
14
  import { FormsModule } from '@angular/forms';
14
- import * as i10 from 'ng-inline-svg';
15
+ import * as i11 from 'ng-inline-svg';
15
16
  import { InlineSVGModule } from 'ng-inline-svg';
16
- import * as i11 from '@angular/cdk/scrolling';
17
+ import * as i12 from '@angular/cdk/scrolling';
17
18
  import { ScrollingModule } from '@angular/cdk/scrolling';
18
19
 
19
20
  const STATUSES_BADGE_MAP = {
@@ -168,7 +169,7 @@ class SplitColumnsService {
168
169
  // ✅ Total width already consumed
169
170
  const usedWidth = fixedCols.reduce((sum, col) => sum + col.width, 0);
170
171
  // ✅ Remaining width after fixed columns
171
- let remainingWidth = containerWidth - usedWidth;
172
+ let remainingWidth = containerWidth - (usedWidth + 50);
172
173
  if (remainingWidth < 0)
173
174
  remainingWidth = 0;
174
175
  // ✅ Average width for columns without width
@@ -229,7 +230,7 @@ class CommonService {
229
230
  }
230
231
  gethasVisibleColumns(columns) {
231
232
  const checkVisible = (columns) => {
232
- return columns?.some((col) => {
233
+ return columns.some((col) => {
233
234
  if (col?.is_visible)
234
235
  return true;
235
236
  if (col?.children?.length) {
@@ -242,7 +243,7 @@ class CommonService {
242
243
  }
243
244
  gethasInVisibleColumns(columns) {
244
245
  const checkVisible = (columns) => {
245
- return columns?.some((col) => {
246
+ return columns.some((col) => {
246
247
  if (!col?.is_visible)
247
248
  return true;
248
249
  if (col?.children?.length) {
@@ -255,7 +256,7 @@ class CommonService {
255
256
  }
256
257
  getTotalColumnsLength(columns) {
257
258
  let count = 0;
258
- columns?.forEach(col => {
259
+ columns.forEach(col => {
259
260
  if (col.children && Array.isArray(col.children) && col.children.length) {
260
261
  count += col.children.length; // count children instead of parent
261
262
  }
@@ -267,7 +268,7 @@ class CommonService {
267
268
  }
268
269
  gethasRightPinnedColumns(columns) {
269
270
  const checkPinnedRight = (columns) => {
270
- return columns?.some((col) => {
271
+ return columns.some((col) => {
271
272
  if (col?.pinned === 'right' && col?.is_visible)
272
273
  return true;
273
274
  if (col?.children?.length) {
@@ -280,7 +281,7 @@ class CommonService {
280
281
  }
281
282
  gethasLeftPinnedColumns(columns) {
282
283
  const checkPinnedRight = (columns) => {
283
- return columns?.some((col) => {
284
+ return columns.some((col) => {
284
285
  if (col?.pinned === 'left' && col?.is_visible)
285
286
  return true;
286
287
  if (col?.children?.length) {
@@ -294,7 +295,7 @@ class CommonService {
294
295
  getExpandedRowCount(data) {
295
296
  let groupCount = 0;
296
297
  let rowCount = 0;
297
- data?.forEach(group => {
298
+ data.forEach(group => {
298
299
  if (group?.isGroup) {
299
300
  groupCount++;
300
301
  if (group?.isExpand && Array.isArray(group?.children)) {
@@ -347,7 +348,7 @@ class CommonService {
347
348
  col.query = {
348
349
  first_value: null,
349
350
  second_value: null,
350
- first_condition: col.type !== 'date' && col.type !== 'number' ? 'contain' : 'equal',
351
+ first_condition: col.type !== 'date' && col.type !== 'number' && col.type !== 'time' ? 'contain' : 'equal',
351
352
  second_condition: null,
352
353
  condition: 'none',
353
354
  _ids: []
@@ -966,6 +967,149 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
966
967
  }]
967
968
  }] });
968
969
 
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
+
969
1113
  class CellRenderInitDirective {
970
1114
  constructor(vcr, injector) {
971
1115
  this.vcr = vcr;
@@ -1031,6 +1175,79 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
1031
1175
  type: Output
1032
1176
  }] } });
1033
1177
 
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
+
1034
1251
  class FilterPipe {
1035
1252
  transform(items, searchText, key) {
1036
1253
  if (!items || !searchText)
@@ -1085,7 +1302,7 @@ const sortingAnimation = trigger('listSort', [
1085
1302
  ])
1086
1303
  ]);
1087
1304
  class DataGridComponent {
1088
- constructor(columnService, cdr, commonSevice, elementRef, ngZone, copyService, renderer, sanitizer, exportService, datePipe, formatCurrency) {
1305
+ constructor(columnService, cdr, commonSevice, elementRef, ngZone, copyService, renderer, sanitizer, exportService, datePipe, formatCurrency, actionValidator) {
1089
1306
  this.columnService = columnService;
1090
1307
  this.cdr = cdr;
1091
1308
  this.commonSevice = commonSevice;
@@ -1097,6 +1314,7 @@ class DataGridComponent {
1097
1314
  this.exportService = exportService;
1098
1315
  this.datePipe = datePipe;
1099
1316
  this.formatCurrency = formatCurrency;
1317
+ this.actionValidator = actionValidator;
1100
1318
  // **************************************//
1101
1319
  // **************************************//
1102
1320
  // ********** Input Goes Here *********** //
@@ -1104,56 +1322,56 @@ class DataGridComponent {
1104
1322
  // **************************************//
1105
1323
  this.rowAnimation = RowAnimationType.None;
1106
1324
  // Pagination Config Store Here
1107
- this.paginationConfig = {};
1325
+ this.paginationConfig = null;
1108
1326
  // The dataset store here;
1109
1327
  this.dataSet = [];
1110
1328
  // The columns Store Here
1111
1329
  this.columns = [];
1112
1330
  // Row Height;
1113
- this.rowHeight = 50;
1331
+ this.rowHeight = 44;
1114
1332
  // Header Row Height;
1115
- this.headerRowHeight = 40;
1333
+ this.headerRowHeight = 50;
1116
1334
  // Show Vertical Borders;
1117
1335
  this.showVerticalBorder = false;
1118
1336
  // Even Rows Background Color;
1119
1337
  this.evenRowsBackgroundColor = '';
1120
1338
  // Even Rows Background Color;
1121
- this.oddRowsBackgroundColor = '#F5F5F5';
1339
+ this.oddRowsBackgroundColor = '#f2f2f2';
1122
1340
  // Header Rows Background Color;
1123
- this.headerBackgroundColor = '#F5F5F5';
1341
+ this.headerBackgroundColor = '#f6f8ff';
1124
1342
  // Header Rows Background Color;
1125
- this.checkboxesBackgroundColor = '#FFFFFF';
1343
+ this.checkboxesBackgroundColor = '#f6f8ff';
1126
1344
  // Show Columns Grouping;
1127
1345
  this.showColumnsGrouping = false;
1128
1346
  // Row Hovered Background color;
1129
- this.rowHoverColor = '#F5F5F5';
1347
+ this.rowHoverColor = 'rgba(0, 123, 255, 0.1)';
1130
1348
  // Left PinnedBackground color;
1131
- this.leftPinnedBackgroundColor = '#FFFFFF';
1349
+ this.leftPinnedBackgroundColor = '#f6f8ff';
1132
1350
  // Body Background color;
1133
- this.bodyBackgroundColor = '#FFFFFF';
1351
+ this.bodyBackgroundColor = '#f6f8ff';
1134
1352
  // Right Pinned Background color;
1135
- this.rightPinnedBackgroundColor = '#FFFFFF';
1353
+ this.rightPinnedBackgroundColor = '#f6f8ff';
1136
1354
  // Side Menu Background color;
1137
- this.sidemenuBackgroundColor = '#FFFFFF';
1355
+ this.sidemenuBackgroundColor = '#f6f8ff';
1138
1356
  // Body text color;
1139
- this.bodyTextColor = '#1B1F22';
1357
+ this.bodyTextColor = '#0c112b';
1140
1358
  // Header text color;
1141
- this.headerTextColor = '#6A6B6D';
1359
+ this.headerTextColor = '#2a1f73';
1142
1360
  // Header text color;
1143
- this.checkboxesColor = '#FFFFFF';
1361
+ this.checkboxesColor = '#2a1f73';
1144
1362
  // Header text size;
1145
- this.headerTextFontsSize = 13;
1363
+ this.headerTextFontsSize = 14;
1146
1364
  // Body text color;
1147
1365
  this.bodyTextFontsSize = 14;
1148
1366
  // Header font weight;
1149
- this.headerFontWeight = 600; // basit said
1367
+ this.headerFontWeight = 500;
1150
1368
  // Body Font Weight;
1151
1369
  this.bodyFontWeight = 400;
1152
1370
  // Checked Row Background Color;
1153
- this.checkedRowBackgroundColor = '#0084FF1A';
1371
+ this.checkedRowBackgroundColor = 'aliceblue';
1154
1372
  // dropdowns Background Color;
1155
- this.dropdownsBackgroundColor = '#FFFFFF';
1156
- this.footerRowBackgroundColor = '#FFFFFF';
1373
+ this.dropdownsBackgroundColor = '#f6f8f8';
1374
+ this.footerRowBackgroundColor = '';
1157
1375
  // Footer row Height;
1158
1376
  this.footerRowHeight = 46;
1159
1377
  // Footer row Height;
@@ -1205,7 +1423,7 @@ class DataGridComponent {
1205
1423
  // Taskbar actions
1206
1424
  this.taskbarActions = [];
1207
1425
  // Sorting Config to show sort icons
1208
- this.sortingConfig = { field: '', order_by: '' };
1426
+ this.sortingConfig = null;
1209
1427
  this.tableFilterViewId = '';
1210
1428
  this.selectedTableLayout = 'medium';
1211
1429
  this.closeDropdown = { preset: { closed: false, loading: false } };
@@ -1218,10 +1436,11 @@ class DataGridComponent {
1218
1436
  this.nestedTableHeaderRowHeight = 40;
1219
1437
  // Nested Table row height
1220
1438
  this.nestedTablerowHeight = 45;
1439
+ this.packageData = false;
1221
1440
  this.gridType = '';
1222
1441
  this.currencySymbol = '';
1223
1442
  this.currencyFormat = '';
1224
- this.leftPinnedBoxshadow = '1px 0 4px 0 rgba(18, 19, 20, 0.1';
1443
+ this.leftPinnedBoxshadow = '';
1225
1444
  this.rightPinnedBoxshadow = '';
1226
1445
  // GlobalSearch
1227
1446
  this.selectedRowsBackgroundColor = '#8ac5ff';
@@ -1239,9 +1458,9 @@ class DataGridComponent {
1239
1458
  this.enableCut = false;
1240
1459
  this.tabs = [];
1241
1460
  this.showCheckboxes = true;
1242
- this.consumerFont = null;
1243
- this.defaultConfig = null;
1461
+ this.pageSizeOptions = [10, 25, 50, 75, 100, 150, 200, 250, 300, 500];
1244
1462
  this.resetAllFilters = { resetAll: false };
1463
+ this.defaultConfig = null;
1245
1464
  this.columnThreedotsMunuConfig = {
1246
1465
  showPinleft: true,
1247
1466
  showPinright: true,
@@ -1254,6 +1473,8 @@ class DataGridComponent {
1254
1473
  showChoseColumns: false,
1255
1474
  showResetColumns: false,
1256
1475
  };
1476
+ // for action validation;
1477
+ this.validateIcon = false;
1257
1478
  this.changeLayout = new EventEmitter();
1258
1479
  this.customCellEvent = new EventEmitter();
1259
1480
  // Filter Apply event;
@@ -1262,6 +1483,7 @@ class DataGridComponent {
1262
1483
  this.tablePresetConfig = new EventEmitter();
1263
1484
  this.sortingOrderOptions = new EventEmitter();
1264
1485
  this.createUpdateConfigListing = new EventEmitter();
1486
+ this.storePresetName = '';
1265
1487
  this.isFullScreen = false;
1266
1488
  this.activeTab = null;
1267
1489
  this.groupedColumns = [];
@@ -1279,7 +1501,6 @@ class DataGridComponent {
1279
1501
  this.filterColumnsList = [];
1280
1502
  this.groupBoxPadding = 200;
1281
1503
  this.presetName = '';
1282
- this.storePresetName = '';
1283
1504
  this.presetFilter = false;
1284
1505
  this.searchTextPresetTable = '';
1285
1506
  this.addFilterColumnInput = '';
@@ -1361,6 +1582,7 @@ class DataGridComponent {
1361
1582
  ];
1362
1583
  this.hasScroll = false;
1363
1584
  this.injector = inject(Injector);
1585
+ this.shouldRestoreScroll = false;
1364
1586
  // private getDecrypt(key:string){
1365
1587
  // const value = localStorage.getItem(key)
1366
1588
  // try {
@@ -1400,7 +1622,6 @@ class DataGridComponent {
1400
1622
  // Row Hover Logic Here
1401
1623
  this.hoveredRowId = null;
1402
1624
  this.isMenueHidden = false;
1403
- this.clickedOnSortIcon = false;
1404
1625
  this.getVisibleLeafColumns = (columns) => {
1405
1626
  const result = [];
1406
1627
  for (const column of columns) {
@@ -1566,37 +1787,38 @@ class DataGridComponent {
1566
1787
  moveItemInArray(this.columns, prevColIndexInColumns, currColIndexInColumns);
1567
1788
  // await this.refreshPreviewColumns();
1568
1789
  this.cdr.detectChanges();
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
- });
1790
+ await firstValueFrom(this.ngZone.onStable);
1791
+ // this.ngZone.runOutsideAngular(() => {
1792
+ // Wait a tick to make sure elements are rendered
1793
+ requestAnimationFrame(() => {
1794
+ allFields.forEach((field) => {
1795
+ const updatedCells = Array.from(document.querySelectorAll(`[field="${field}"]`));
1796
+ updatedCells.forEach((el) => {
1797
+ const oldLeft = firstPositions.get(el);
1798
+ if (oldLeft == null)
1799
+ return; // skip if old position not available
1800
+ const newLeft = el.getBoundingClientRect().left;
1801
+ const deltaX = oldLeft - newLeft;
1802
+ if (deltaX !== 0) {
1803
+ el.style.willChange = 'transform';
1804
+ el.style.transition = 'none';
1805
+ el.style.transform = `translateX(${deltaX}px)`;
1806
+ // Force reflow
1807
+ void el.offsetWidth;
1808
+ el.style.transition = 'transform 250ms cubic-bezier(0.4, 0, 0.2, 1)';
1809
+ el.style.transform = 'translateX(0)';
1810
+ const handle = () => {
1811
+ el.style.transition = '';
1812
+ el.style.transform = '';
1813
+ el.style.willChange = '';
1814
+ el.removeEventListener('transitionend', handle);
1815
+ };
1816
+ el.addEventListener('transitionend', handle);
1817
+ }
1597
1818
  });
1598
1819
  });
1599
1820
  });
1821
+ // });
1600
1822
  };
1601
1823
  // onChildDragStart() {
1602
1824
  // debugger;
@@ -1661,6 +1883,7 @@ class DataGridComponent {
1661
1883
  moveItemInArray(this[section]?.[groupInSectionIndex].children, event.previousIndex, event.currentIndex);
1662
1884
  // await this.refreshPreviewColumns();
1663
1885
  this.cdr.detectChanges();
1886
+ await firstValueFrom(this.ngZone.onStable);
1664
1887
  // allFields.forEach((field) => {
1665
1888
  // const updatedCells = Array.from(
1666
1889
  // document.querySelectorAll(`[field="${field}"]`)
@@ -1701,7 +1924,7 @@ class DataGridComponent {
1701
1924
  el.style.transform = `translateX(${deltaX}px)`;
1702
1925
  // Force reflow
1703
1926
  void el.offsetWidth;
1704
- el.style.transition = 'transform 400ms cubic-bezier(0.4, 0, 0.2, 1)';
1927
+ el.style.transition = 'transform 250ms cubic-bezier(0.4, 0, 0.2, 1)';
1705
1928
  el.style.transform = 'translateX(0)';
1706
1929
  const handle = () => {
1707
1930
  el.style.transition = '';
@@ -1718,7 +1941,6 @@ class DataGridComponent {
1718
1941
  };
1719
1942
  this.isActiveFilterOpen = false;
1720
1943
  this.activeSubButton = '';
1721
- this.pageSizeOptions = [10, 25, 50, 75, 100, 150, 200, 250, 300, 500];
1722
1944
  this.searchTextForFilterDropDown = '';
1723
1945
  this.isFilterOpen = false;
1724
1946
  this.showFilters = this.showSideMenu ? false : false;
@@ -1855,7 +2077,6 @@ class DataGridComponent {
1855
2077
  '.svg');
1856
2078
  },
1857
2079
  };
1858
- this.activeFilterType = '';
1859
2080
  }
1860
2081
  ngAfterViewInit() {
1861
2082
  this.ngZone.onStable.pipe(take(1)).subscribe(async () => {
@@ -1912,20 +2133,23 @@ class DataGridComponent {
1912
2133
  this.addStylesToImages();
1913
2134
  this.hasScroll = this.hasHorizontalScrollbar();
1914
2135
  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
+ }
1915
2145
  }
1916
2146
  ngOnInit() {
1917
2147
  // if (this.tabs?.length) {
1918
2148
  // this.activeTab = this.tabs[0];
1919
2149
  // }
1920
2150
  // 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
- }
1927
2151
  if (!this.curretaTablePresetForUpdate) {
1928
- this.autosizeAllColumns();
2152
+ // this.autoSizeColumnsByRatio();
1929
2153
  }
1930
2154
  // const user = this.getDecrypt('user');
1931
2155
  // this.currencyFormat = user?.currency_format;
@@ -1933,15 +2157,21 @@ class DataGridComponent {
1933
2157
  // this.dateFormat = user?.date_format;
1934
2158
  if (!this.dateFormat) {
1935
2159
  const storedDateFormat = localStorage.getItem('dateformat');
1936
- this.dateFormat = storedDateFormat ? JSON.parse(storedDateFormat) : 'dd/MM/yyyy';
2160
+ if (storedDateFormat) {
2161
+ this.dateFormat = storedDateFormat ? JSON.parse(storedDateFormat) : 'dd/MM/yyyy';
2162
+ }
1937
2163
  }
1938
2164
  if (!this.currencyFormat) {
1939
2165
  const storedCurrencyFormat = localStorage.getItem('currencyFormat');
1940
- this.currencyFormat = storedCurrencyFormat ? JSON.parse(storedCurrencyFormat) : '1,234,567.89';
2166
+ if (storedCurrencyFormat) {
2167
+ this.currencyFormat = storedCurrencyFormat ? JSON.parse(storedCurrencyFormat) : '1,234,567.89';
2168
+ }
1941
2169
  }
1942
2170
  if (!this.currencySymbol) {
1943
2171
  const storedCurrencySymbol = localStorage.getItem('currencySymbol');
1944
- this.currencySymbol = storedCurrencySymbol ? JSON.parse(storedCurrencySymbol) : '$';
2172
+ if (storedCurrencySymbol) {
2173
+ this.currencySymbol = storedCurrencySymbol ? JSON.parse(storedCurrencySymbol) : '$';
2174
+ }
1945
2175
  }
1946
2176
  }
1947
2177
  async ngOnChanges(changes) {
@@ -1952,10 +2182,15 @@ class DataGridComponent {
1952
2182
  if (changes['tabs']) {
1953
2183
  const allTabs = JSON.parse(localStorage.getItem('activeTabs') || '{}');
1954
2184
  const savedTab = allTabs[this.tableType];
1955
- this.activeTab = savedTab || this.tabs?.[0];
1956
- if (this.tableType) {
1957
- this.setActiveTab(this.activeTab);
2185
+ if (this.tabs.includes('Current Policy')) {
2186
+ this.activeTab = this.tabs?.[1] || 'Current Policy';
2187
+ }
2188
+ else {
2189
+ this.activeTab = savedTab || this.tabs?.[0];
1958
2190
  }
2191
+ // if (this.tableType) {
2192
+ // this.setActiveTab(this.activeTab);
2193
+ // }
1959
2194
  }
1960
2195
  }
1961
2196
  if (changes['filtersConfig']) {
@@ -1992,11 +2227,13 @@ class DataGridComponent {
1992
2227
  this.ngZone.onStable.pipe(take(1)).subscribe(() => {
1993
2228
  this.computeViewportRows();
1994
2229
  this.updateVisibleRows(0);
2230
+ if (this.commonSevice?.mainContainerLeft > 200)
2231
+ this.shouldRestoreScroll = true;
1995
2232
  this.cdr.detectChanges();
1996
2233
  });
1997
2234
  if (this.centerPinnedHeader?.nativeElement) {
1998
2235
  void this.centerPinnedHeader.nativeElement.offsetWidth;
1999
- // this.dataSetLoading = true;
2236
+ this.dataSetLoading = true;
2000
2237
  setTimeout(() => {
2001
2238
  if (this.centerScrollableBody?.nativeElement) {
2002
2239
  this.centerScrollableBody.nativeElement.scrollLeft =
@@ -2073,6 +2310,11 @@ class DataGridComponent {
2073
2310
  this.globalSearchText = temprorySelected.config.globalSearch;
2074
2311
  this.setTableLayout(this.selectedTableLayout);
2075
2312
  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
+ }
2076
2318
  this.cdr.detectChanges();
2077
2319
  }
2078
2320
  else if (this.defaultConfig) {
@@ -2083,12 +2325,13 @@ class DataGridComponent {
2083
2325
  this.selectedTableLayout = this.defaultConfig.selectedTableLayout;
2084
2326
  this.bodyTextFontsSize = this.defaultConfig.bodyTextFontsSize;
2085
2327
  this.globalSearchText = this.defaultConfig.globalSearch;
2328
+ this.setTableLayout(this.selectedTableLayout);
2086
2329
  }
2087
2330
  else {
2088
2331
  this.rowShadingEnabled = false;
2089
2332
  this.showVerticalBorder = false;
2090
2333
  this.fontFaimly = 'Inter';
2091
- this.headerTextFontsSize = 13;
2334
+ this.headerTextFontsSize = 14;
2092
2335
  this.selectedTableLayout = 'medium';
2093
2336
  this.bodyTextFontsSize = 14;
2094
2337
  this.globalSearchText = '';
@@ -2096,7 +2339,7 @@ class DataGridComponent {
2096
2339
  this.presetName = '';
2097
2340
  }
2098
2341
  this.cdr.detectChanges();
2099
- }, 500);
2342
+ }, 0);
2100
2343
  }
2101
2344
  if (changes['pageSizeOptions'] && changes['pageSizeOptions']?.currentValue) {
2102
2345
  this.buildPageSizeKeyMap();
@@ -2105,6 +2348,7 @@ class DataGridComponent {
2105
2348
  async setColumnsColumnDropdownValus() {
2106
2349
  if (!this.columns)
2107
2350
  return;
2351
+ // Just removed temporary for super admin will set it again
2108
2352
  if (this.columns?.length) {
2109
2353
  this.columns = this.columns?.filter(c => c?.field?.trim() !== 'is_deleted');
2110
2354
  }
@@ -2270,9 +2514,22 @@ class DataGridComponent {
2270
2514
  columns: this.cleanColumns(this.columns),
2271
2515
  filters: this.cleanFilterdColumns(),
2272
2516
  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
+ },
2273
2530
  type: this.tableType,
2274
2531
  };
2275
- this.createUpdateConfigListing.emit(sendData);
2532
+ this.createUpdateConfigListing.emit(this.createUpdateColumnConfig);
2276
2533
  };
2277
2534
  window.addEventListener('mousemove', onMouseMove);
2278
2535
  window.addEventListener('mouseup', onMouseUp);
@@ -2291,6 +2548,27 @@ class DataGridComponent {
2291
2548
  update(this.columns);
2292
2549
  this.cdr.detectChanges();
2293
2550
  }
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
+ }
2294
2572
  cleanColumns(columns) {
2295
2573
  return columns.map((col) => {
2296
2574
  const { __typename, _id, column_dropdown_value, filterValue, expandedFilter, query, isRowGrouped, ...rest } = col;
@@ -2310,7 +2588,6 @@ class DataGridComponent {
2310
2588
  ...rest,
2311
2589
  column_dropdown_value: cleanedDropdown,
2312
2590
  query: cleanedQuery,
2313
- is_groupable: rest.type !== 'image',
2314
2591
  };
2315
2592
  });
2316
2593
  }
@@ -2361,7 +2638,7 @@ class DataGridComponent {
2361
2638
  no_of_records: this.paginationConfig.pageSize,
2362
2639
  type: this.tableType,
2363
2640
  };
2364
- this.createUpdateConfigListing.emit(sendData);
2641
+ this.createUpdateConfigListing.emit(this.createUpdateColumnConfig);
2365
2642
  matchingEls.forEach((el) => {
2366
2643
  el.classList.remove('resizing-highlight');
2367
2644
  el.classList.remove('resizing-highlight-right');
@@ -2485,8 +2762,7 @@ class DataGridComponent {
2485
2762
  }
2486
2763
  return false;
2487
2764
  }
2488
- openThreeDotsMenu(event, child, clickedOnSortIcon) {
2489
- this.clickedOnSortIcon = clickedOnSortIcon || false;
2765
+ openThreeDotsMenu(event, child, keepOriginalPosition = false) {
2490
2766
  event.preventDefault();
2491
2767
  event.stopPropagation();
2492
2768
  this.isMenueHidden = true;
@@ -2516,8 +2792,6 @@ class DataGridComponent {
2516
2792
  sortAsc(col) {
2517
2793
  if (!col.is_sortable)
2518
2794
  return;
2519
- this.sortingConfig['order_by'] = 'asc';
2520
- this.sortingConfig['field'] = col.field;
2521
2795
  col.order_by = 'asc';
2522
2796
  const event = {
2523
2797
  order: 'asc',
@@ -2529,8 +2803,6 @@ class DataGridComponent {
2529
2803
  sortDesc(col) {
2530
2804
  if (!col.is_sortable)
2531
2805
  return;
2532
- this.sortingConfig['order_by'] = 'desc';
2533
- this.sortingConfig['field'] = col.field;
2534
2806
  col.order_by = 'desc';
2535
2807
  const event = {
2536
2808
  order: 'desc',
@@ -2546,6 +2818,7 @@ class DataGridComponent {
2546
2818
  this.sortingOrderOptions.emit(event);
2547
2819
  }
2548
2820
  async updateColumnPinInSourceByField(column, pinned, isNestedTable = false, columns) {
2821
+ debugger;
2549
2822
  if (isNestedTable) {
2550
2823
  this.pinUnpinColum(column, pinned, columns);
2551
2824
  return;
@@ -2571,7 +2844,7 @@ class DataGridComponent {
2571
2844
  no_of_records: this.paginationConfig.pageSize,
2572
2845
  type: this.tableType,
2573
2846
  };
2574
- this.createUpdateConfigListing.emit(sendData);
2847
+ this.createUpdateConfigListing.emit(this.createUpdateColumnConfig);
2575
2848
  }
2576
2849
  autosizeColumn(cols) {
2577
2850
  this.activeCol = null;
@@ -2606,7 +2879,7 @@ class DataGridComponent {
2606
2879
  no_of_records: this.paginationConfig.pageSize,
2607
2880
  type: this.tableType,
2608
2881
  };
2609
- this.createUpdateConfigListing.emit(sendData);
2882
+ this.createUpdateConfigListing.emit(this.createUpdateColumnConfig);
2610
2883
  }, 1000);
2611
2884
  this.refreshPreviewColumns();
2612
2885
  }
@@ -2657,7 +2930,7 @@ class DataGridComponent {
2657
2930
  no_of_records: this.paginationConfig.pageSize,
2658
2931
  type: this.tableType,
2659
2932
  };
2660
- this.createUpdateConfigListing.emit(sendData);
2933
+ this.createUpdateConfigListing.emit(this.createUpdateColumnConfig);
2661
2934
  }, 1000);
2662
2935
  }
2663
2936
  markColumnAsGrouped(columns, field) {
@@ -2849,7 +3122,7 @@ class DataGridComponent {
2849
3122
  no_of_records: this.paginationConfig.pageSize,
2850
3123
  type: this.tableType,
2851
3124
  };
2852
- this.createUpdateConfigListing.emit(sendData);
3125
+ this.createUpdateConfigListing.emit(this.createUpdateColumnConfig);
2853
3126
  setTimeout(() => {
2854
3127
  this.updateColumnWidthsAndGroups();
2855
3128
  this.refreshPreviewColumns();
@@ -2888,7 +3161,7 @@ class DataGridComponent {
2888
3161
  }
2889
3162
  async toggleColumnVisibility(column, isVisible) {
2890
3163
  if (isVisible) {
2891
- if (this.visibleColumns()?.length <= 2 && column.is_visible) {
3164
+ if (this.visibleColumns()?.length <= 2 && column.is_visible || (column?.is_always_visible)) {
2892
3165
  return;
2893
3166
  }
2894
3167
  }
@@ -2904,7 +3177,7 @@ class DataGridComponent {
2904
3177
  no_of_records: this.paginationConfig.pageSize,
2905
3178
  type: this.tableType,
2906
3179
  };
2907
- this.createUpdateConfigListing.emit(sendData);
3180
+ this.createUpdateConfigListing.emit(this.createUpdateColumnConfig);
2908
3181
  if (this.tableFilterViewId) {
2909
3182
  this.savePreset('mouseUp');
2910
3183
  }
@@ -2948,7 +3221,7 @@ class DataGridComponent {
2948
3221
  no_of_records: this.paginationConfig.pageSize,
2949
3222
  type: this.tableType,
2950
3223
  };
2951
- this.createUpdateConfigListing.emit(sendData);
3224
+ this.createUpdateConfigListing.emit(this.createUpdateColumnConfig);
2952
3225
  }
2953
3226
  finally {
2954
3227
  this.loading = false;
@@ -3119,7 +3392,7 @@ class DataGridComponent {
3119
3392
  no_of_records: this.paginationConfig.pageSize,
3120
3393
  type: this.tableType,
3121
3394
  };
3122
- this.createUpdateConfigListing.emit(sendData);
3395
+ this.createUpdateConfigListing.emit(this.createUpdateColumnConfig);
3123
3396
  }, 400);
3124
3397
  }
3125
3398
  async refreshHeaders() {
@@ -3486,7 +3759,7 @@ class DataGridComponent {
3486
3759
  no_of_records: this.paginationConfig.pageSize,
3487
3760
  type: this.tableType,
3488
3761
  };
3489
- this.createUpdateConfigListing.emit(sendData);
3762
+ this.createUpdateConfigListing.emit(this.createUpdateColumnConfig);
3490
3763
  this.cdr.detectChanges();
3491
3764
  }
3492
3765
  deepCloneColumns(columns) {
@@ -3608,7 +3881,7 @@ class DataGridComponent {
3608
3881
  no_of_records: this.paginationConfig.pageSize,
3609
3882
  type: this.tableType,
3610
3883
  };
3611
- this.createUpdateConfigListing.emit(sendData);
3884
+ this.createUpdateConfigListing.emit(this.createUpdateColumnConfig);
3612
3885
  setTimeout(() => {
3613
3886
  this.cdr.detectChanges();
3614
3887
  }, 2);
@@ -3650,10 +3923,6 @@ class DataGridComponent {
3650
3923
  // const dateObj = new Date(keyValue);
3651
3924
  // groupKey = this.commonSevice.formatDateValue(dateObj, this.dateFormat || 'dd/MM/yyyy');
3652
3925
  // }
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
- }
3657
3926
  if (!groupedMap.has(groupKey))
3658
3927
  groupedMap.set(groupKey, []);
3659
3928
  groupedMap.get(groupKey).push(item);
@@ -3718,24 +3987,27 @@ class DataGridComponent {
3718
3987
  this.onFontChange();
3719
3988
  }
3720
3989
  setTableLayout(layoutType) {
3990
+ if (!layoutType)
3991
+ return;
3721
3992
  if (layoutType === 'small') {
3722
- this.rowHeight = 50;
3993
+ this.rowHeight = 36;
3723
3994
  this.headerRowHeight = 40;
3724
- this.bodyTextFontsSize = 10;
3725
- this.headerTextFontsSize = 10;
3995
+ this.bodyTextFontsSize = this.bodyTextFontsSize || 10;
3996
+ this.headerTextFontsSize = this.headerTextFontsSize || 10;
3726
3997
  }
3727
3998
  else if (layoutType === 'medium') {
3728
- this.rowHeight = 60;
3729
- this.headerRowHeight = 40;
3730
- this.bodyTextFontsSize = 14;
3731
- this.headerTextFontsSize = 13;
3999
+ this.rowHeight = 44;
4000
+ this.headerRowHeight = 44;
4001
+ this.bodyTextFontsSize = this.bodyTextFontsSize || 14;
4002
+ this.headerTextFontsSize = this.headerTextFontsSize || 14;
3732
4003
  }
3733
4004
  else {
3734
- this.rowHeight = 72;
3735
- this.headerRowHeight = 40;
3736
- this.bodyTextFontsSize = 16;
3737
- this.headerTextFontsSize = 16;
4005
+ this.rowHeight = 60;
4006
+ this.headerRowHeight = 52;
4007
+ this.bodyTextFontsSize = this.bodyTextFontsSize || 16;
4008
+ this.headerTextFontsSize = this.headerTextFontsSize || 16;
3738
4009
  }
4010
+ // this.createUpdateConfigListing.emit(this.createUpdateColumnConfig);
3739
4011
  }
3740
4012
  get startIndexData() {
3741
4013
  return (this.paginationConfig.page - 1) * this.paginationConfig.limit;
@@ -3779,27 +4051,27 @@ class DataGridComponent {
3779
4051
  }
3780
4052
  }
3781
4053
  openFilteronThreeDotsClick(col) {
3782
- if (col.type == 'image' || !col?.type)
4054
+ if (col.type == 'image' || !col?.type || !col.is_search_able)
3783
4055
  return;
3784
4056
  this.selectedColumnForFilter = col;
3785
4057
  this.isThreeDotsFilterOpen = true;
3786
4058
  this.addFilterColumnInput = '';
3787
- if (col.type === 'dropdown') {
4059
+ if (col.type === 'dropdown' || col.type === 'array') {
3788
4060
  this.currentFilterSelectedIds.clear();
3789
4061
  const savedIds = col?.query?._ids || [];
3790
4062
  savedIds.forEach((id) => this.currentFilterSelectedIds.add(id));
3791
- this.selectedFilterOptions = this.selectedColumnForFilter?.column_dropdown_value.filter((option) => this.currentFilterSelectedIds.has(option?.id || option?._id || option));
4063
+ this.selectedFilterOptions = this.selectedColumnForFilter?.column_dropdown_value?.filter((option) => this.currentFilterSelectedIds.has(option?.id || option?._id || option));
3792
4064
  setTimeout(() => {
3793
4065
  if (this.filterMenueSearchInput) {
3794
4066
  this.filterMenueSearchInput.nativeElement.focus();
3795
4067
  }
3796
4068
  }, 100);
3797
4069
  }
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');
4070
+ else if (['string', 'number', 'date', 'time'].includes(col.type)) {
4071
+ this.firstCondition = col.query.first_condition ? col.query.first_condition : ((col.type == 'date' || col.type == 'time' || col.type == 'number') ? 'equal' : 'contain');
3800
4072
  this.firstValue = col?.query?.first_value || '';
3801
4073
  this.condition = col?.query?.condition || 'none';
3802
- this.secondCondition = col.query.first_condition ? col.query.first_condition : (col.type == 'date' ? 'equal' : 'contain');
4074
+ this.secondCondition = col.query.first_condition ? col.query.first_condition : ((col.type == 'date' || col.type == 'time' || col.type == 'number') ? 'equal' : 'contain');
3803
4075
  this.secondValue = col?.query?.second_value || '';
3804
4076
  setTimeout(() => {
3805
4077
  this.filterMenueTextchInput.nativeElement.focus();
@@ -3808,28 +4080,30 @@ class DataGridComponent {
3808
4080
  this.cdr.detectChanges();
3809
4081
  }
3810
4082
  openFilterFromDisabledSearchedInput(col) {
3811
- if (col.type !== 'dropdown')
4083
+ if (col.type !== 'dropdown' && col.type !== 'array' || !col.is_search_able)
3812
4084
  return;
3813
4085
  this.openFilter(col);
3814
4086
  }
3815
4087
  openFilter(col) {
4088
+ if (!col.is_search_able)
4089
+ return;
3816
4090
  this.activeFilterCell = col;
3817
4091
  this.activeCol = null;
3818
4092
  this.isFilterOpen = true;
3819
4093
  this.searchTextForFilterDropDown = '';
3820
4094
  this.addFilterColumnInput = '';
3821
4095
  this.selectedColumnForFilter = col;
3822
- if (col.type === 'dropdown') {
4096
+ if (col.type === 'dropdown' || col.type == 'array') {
3823
4097
  this.currentFilterSelectedIds.clear();
3824
4098
  const savedIds = col?.query?._ids || [];
3825
4099
  savedIds.forEach((id) => this.currentFilterSelectedIds.add(id));
3826
4100
  this.selectedFilterOptions = this.selectedColumnForFilter?.column_dropdown_value?.filter((option) => this.currentFilterSelectedIds.has(option?.id || option?._id || option));
3827
4101
  }
3828
- else if (['string', 'number', 'date'].includes(col.type)) {
3829
- this.firstCondition = col?.query?.first_condition || 'contain';
4102
+ else if (['string', 'number', 'date', 'time'].includes(col.type)) {
4103
+ this.firstCondition = col?.query?.first_condition || (col.type == 'number' || col.type == 'time' || col.type == 'date') ? 'equal' : 'contain';
3830
4104
  this.firstValue = col?.query?.first_value || '';
3831
4105
  this.condition = col?.query?.condition || 'none';
3832
- this.secondCondition = col?.query?.second_condition || 'contain';
4106
+ this.secondCondition = col?.query?.second_condition || (col.type == 'number' || col.type == 'time' || col.type == 'date') ? 'equal' : 'contain';
3833
4107
  this.secondValue = col?.query?.second_value || '';
3834
4108
  }
3835
4109
  this.cdr.detectChanges();
@@ -3887,7 +4161,7 @@ class DataGridComponent {
3887
4161
  };
3888
4162
  const column = findColumn(this.columns, this.selectedColumnForFilter.field);
3889
4163
  if (column) {
3890
- if (column.type === 'dropdown') {
4164
+ if (column.type === 'dropdown' || column.type == 'array') {
3891
4165
  column.query = column.query || {};
3892
4166
  column.query._ids = column.query._ids || [];
3893
4167
  // Remove stale IDs (not present in Set)
@@ -3900,7 +4174,7 @@ class DataGridComponent {
3900
4174
  }
3901
4175
  });
3902
4176
  }
3903
- else if (['string', 'number', 'date'].includes(column.type)) {
4177
+ else if (['string', 'number', 'date', 'time'].includes(column.type)) {
3904
4178
  column.query = {
3905
4179
  first_condition: this.firstCondition || 'contain',
3906
4180
  first_value: this.firstValue || null,
@@ -3936,9 +4210,10 @@ class DataGridComponent {
3936
4210
  no_of_records: Number(this.paginationConfig.limit),
3937
4211
  type: this.tableType,
3938
4212
  };
3939
- this.createUpdateConfigListing.emit(sendData);
4213
+ this.createUpdateConfigListing.emit(this.createUpdateColumnConfig);
3940
4214
  const filters = this.cleanFilterdColumns();
3941
4215
  setTimeout(() => {
4216
+ this.commonSevice.mainContainerLeft = this.centerScrollableBody.nativeElement.scrollLeft;
3942
4217
  this.filterOptions.emit(filters);
3943
4218
  }, 200);
3944
4219
  }
@@ -4028,13 +4303,15 @@ class DataGridComponent {
4028
4303
  no_of_records: Number(this.paginationConfig.limit),
4029
4304
  type: this.tableType,
4030
4305
  };
4031
- this.createUpdateConfigListing.emit(sendData);
4306
+ this.createUpdateConfigListing.emit(this.createUpdateColumnConfig);
4032
4307
  const filters = this.cleanFilterdColumns();
4033
4308
  setTimeout(() => {
4309
+ this.commonSevice.mainContainerLeft = this.centerScrollableBody.nativeElement.scrollLeft;
4034
4310
  this.filterOptions.emit(filters);
4035
4311
  }, 200);
4036
4312
  }
4037
- clearAllFilters() {
4313
+ clearAllFilters(shouldUpdateConfigListing = false) {
4314
+ this.groupedColumns = [];
4038
4315
  this.tableView?.forEach((ele) => { ele.is_temp = false; });
4039
4316
  const resetAllRecursively = (columns) => {
4040
4317
  for (const column of columns) {
@@ -4058,13 +4335,13 @@ class DataGridComponent {
4058
4335
  this.filtersConfig = [];
4059
4336
  this.refreshPreviewColumns();
4060
4337
  this.cdr.detectChanges();
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 = '';
4338
+ // this.rowShadingEnabled = false;
4339
+ // this.showVerticalBorder = false;
4340
+ // this.fontFaimly = 'Inter';
4341
+ // this.headerTextFontsSize = 14;
4342
+ // this.selectedTableLayout = 'mediumd';
4343
+ // this.bodyTextFontsSize = 14;
4344
+ // this.globalSearchText = '';
4068
4345
  const event = { eventType: 'reset', data: { tableType: this.tableType } };
4069
4346
  const sendData = {
4070
4347
  columns: this.cleanColumns(this.columns),
@@ -4072,11 +4349,17 @@ class DataGridComponent {
4072
4349
  no_of_records: Number(this.paginationConfig.limit),
4073
4350
  type: this.tableType,
4074
4351
  };
4075
- this.createUpdateConfigListing.emit(sendData);
4352
+ if (!shouldUpdateConfigListing) {
4353
+ this.createUpdateConfigListing.emit(this.createUpdateColumnConfig);
4354
+ }
4355
+ this.commonSevice.mainContainerLeft = this.centerScrollableBody.nativeElement.scrollLeft;
4356
+ this.commonSevice.mainContainerLeft = this.centerScrollableBody.nativeElement.scrollLeft;
4076
4357
  setTimeout(() => {
4077
4358
  const filteredColumns = this.cleanFilterdColumns();
4078
4359
  this.genericEvent.emit(event);
4079
- this.filterOptions.emit(filteredColumns);
4360
+ if (!shouldUpdateConfigListing) {
4361
+ this.filterOptions.emit(filteredColumns);
4362
+ }
4080
4363
  }, 300);
4081
4364
  this.cdr.detectChanges();
4082
4365
  }
@@ -4113,7 +4396,8 @@ class DataGridComponent {
4113
4396
  no_of_records: Number(this.paginationConfig.limit),
4114
4397
  type: this.tableType,
4115
4398
  };
4116
- this.createUpdateConfigListing.emit(sendData);
4399
+ this.createUpdateConfigListing.emit(this.createUpdateColumnConfig);
4400
+ this.commonSevice.mainContainerLeft = this.centerScrollableBody.nativeElement.scrollLeft;
4117
4401
  setTimeout(() => {
4118
4402
  const filteredColumns = this.cleanFilterdColumns();
4119
4403
  this.filterOptions.emit(filteredColumns);
@@ -4140,7 +4424,8 @@ class DataGridComponent {
4140
4424
  no_of_records: Number(this.paginationConfig.limit),
4141
4425
  type: this.tableType,
4142
4426
  };
4143
- this.createUpdateConfigListing.emit(sendData);
4427
+ this.createUpdateConfigListing.emit(this.createUpdateColumnConfig);
4428
+ this.commonSevice.mainContainerLeft = this.centerScrollableBody.nativeElement.scrollLeft;
4144
4429
  setTimeout(() => {
4145
4430
  const filteredColumns = this.cleanFilterdColumns();
4146
4431
  this.filterOptions.emit(filteredColumns);
@@ -4189,7 +4474,7 @@ class DataGridComponent {
4189
4474
  if (column.type == 'image' || !column?.is_editable)
4190
4475
  return;
4191
4476
  this.editingKey = ((row.id || row._id) + '-' + column.field);
4192
- if (column.type === 'dropdown') {
4477
+ if (column.type === 'dropdown' || column.type == 'array') {
4193
4478
  setTimeout(() => {
4194
4479
  const dropdownMenu = document.querySelector('.cell-editing-dropdown-menu');
4195
4480
  if (dropdownMenu) {
@@ -4225,6 +4510,10 @@ class DataGridComponent {
4225
4510
  this.rowSelectedIndexes.clear();
4226
4511
  if (!this.editingKey)
4227
4512
  return;
4513
+ if (control && control.pristine) {
4514
+ this.editingKey = null;
4515
+ return;
4516
+ }
4228
4517
  this.checkRowEditAndEmitValue(row, column, row[column.field]);
4229
4518
  this.editingKey = null;
4230
4519
  this.cdr.detectChanges();
@@ -4309,6 +4598,7 @@ class DataGridComponent {
4309
4598
  },
4310
4599
  eventType: 'pageChange',
4311
4600
  };
4601
+ this.commonSevice.mainContainerLeft = this.centerScrollableBody.nativeElement.scrollLeft;
4312
4602
  this.genericEvent.emit(event);
4313
4603
  }
4314
4604
  onPageSizeChange() {
@@ -4327,7 +4617,7 @@ class DataGridComponent {
4327
4617
  no_of_records: Number(this.paginationConfig.limit),
4328
4618
  type: this.tableType,
4329
4619
  };
4330
- this.createUpdateConfigListing.emit(sendData);
4620
+ this.createUpdateConfigListing.emit(this.createUpdateColumnConfig);
4331
4621
  setTimeout(() => {
4332
4622
  const event = {
4333
4623
  obj: {
@@ -4340,11 +4630,11 @@ class DataGridComponent {
4340
4630
  }, 700);
4341
4631
  }
4342
4632
  actionPreset(data, type) {
4343
- data.columns = data.columns.map(({ _id, filterValue, search, column_dropdown_value, query, __typename, ...rest }) => rest);
4633
+ data.columns = data?.columns?.map(({ _id, filterValue, search, column_dropdown_value, query, __typename, ...rest }) => rest);
4344
4634
  this.tableView?.forEach((ele) => { ele.is_temp = false; });
4345
4635
  {
4346
- this.bodyTextFontsSize = data?.config?.bodyTextFontsSize,
4347
- this.fontFaimly = data?.config?.fontFaimly,
4636
+ this.bodyTextFontsSize = data.config.bodyTextFontsSize,
4637
+ this.fontFaimly = data.config.fontFaimly,
4348
4638
  data?.filters?.forEach((element) => {
4349
4639
  delete element.__typename;
4350
4640
  if (element.query) {
@@ -4385,9 +4675,9 @@ class DataGridComponent {
4385
4675
  }));
4386
4676
  this.columns = data.columns;
4387
4677
  {
4388
- this.bodyTextFontsSize = data?.config?.bodyTextFontsSize,
4389
- this.fontFaimly = data?.config?.fontFaimly,
4390
- data?.filters?.forEach((element) => {
4678
+ this.bodyTextFontsSize = data.config.bodyTextFontsSize,
4679
+ this.fontFaimly = data.config.fontFaimly,
4680
+ data.filters.forEach((element) => {
4391
4681
  delete element.__typename;
4392
4682
  if (element.query) {
4393
4683
  delete element.query.__typename;
@@ -4399,9 +4689,9 @@ class DataGridComponent {
4399
4689
  }
4400
4690
  });
4401
4691
  // this.globalSearch = data.config.bodyTextFontsSize,
4402
- this.headerTextFontsSize = data?.config?.headerTextFontsSize,
4403
- this.selectedTableLayout = data?.config?.selectedTableLayout,
4404
- this.showVerticalBorder = data?.config?.showVerticalBorder,
4692
+ this.headerTextFontsSize = data.config.headerTextFontsSize,
4693
+ this.selectedTableLayout = data.config.selectedTableLayout,
4694
+ this.showVerticalBorder = data.config.showVerticalBorder,
4405
4695
  this.currentIdForUpdatePreset = data.id;
4406
4696
  this.curretaTablePresetForUpdate = structuredClone(data);
4407
4697
  this.presetName = data?.name;
@@ -4480,7 +4770,7 @@ class DataGridComponent {
4480
4770
  no_of_records: Number(this.paginationConfig.limit),
4481
4771
  type: this.tableType,
4482
4772
  };
4483
- this.createUpdateConfigListing.emit(sendData);
4773
+ this.createUpdateConfigListing.emit(this.createUpdateColumnConfig);
4484
4774
  setTimeout(() => {
4485
4775
  this.genericEvent.emit(event);
4486
4776
  }, 500);
@@ -4627,9 +4917,12 @@ class DataGridComponent {
4627
4917
  return (parts[0][0] + (parts[1]?.[0] || '')).toUpperCase();
4628
4918
  }
4629
4919
  onRightClick(event, deatilsList) {
4630
- if (deatilsList?.actions?.length) {
4631
- this.actions = deatilsList.actions;
4632
- }
4920
+ // if (deatilsList?.actions?.length) {
4921
+ // this.actions = deatilsList.actions;
4922
+ // }
4923
+ this.actions = this.validateIcon
4924
+ ? this.getValidActions(deatilsList)
4925
+ : (deatilsList?.actions?.length ? deatilsList.actions : []);
4633
4926
  if (!(event instanceof MouseEvent)) {
4634
4927
  event.preventDefault();
4635
4928
  }
@@ -4650,13 +4943,13 @@ class DataGridComponent {
4650
4943
  const menuWidth = menuElement.offsetWidth;
4651
4944
  const menuHeight = menuElement.offsetHeight;
4652
4945
  const viewportWidth = window.innerWidth;
4653
- const viewportHeight = window.innerHeight;
4946
+ const viewportHeight = this.dataGridContainer.nativeElement.offsetHeight;
4654
4947
  let x = (event instanceof MouseEvent) ? event.clientX : event.touches[0].clientX; //event.clientX;
4655
4948
  let y = (event instanceof MouseEvent) ? event.clientY : event.touches[0].clientY; //event.clientY;
4656
4949
  if (x + menuWidth > viewportWidth) {
4657
4950
  x = viewportWidth - menuWidth - 10;
4658
4951
  }
4659
- if (y + menuHeight > viewportHeight) {
4952
+ if (y + menuHeight > this.dataGridContainer.nativeElement.offsetHeight) {
4660
4953
  y = viewportHeight - menuHeight - 10;
4661
4954
  }
4662
4955
  this.xPos = x;
@@ -4681,12 +4974,20 @@ class DataGridComponent {
4681
4974
  this.genericEvent.emit(sendObj);
4682
4975
  }
4683
4976
  onVerifyClick(type) {
4684
- const idsArray = Array.from(this.selectedRows);
4685
4977
  const text = type?.toLowerCase();
4686
- if (text == 'archive' || text == 'unarchive') {
4687
- this.clearSelectionState(this.tableType);
4688
- this.selectedRows.clear();
4978
+ if (text == 'archive' || text == 'unarchive'
4979
+ // || text == 'delete' || text == 'restore' || text == 'remove' || text == 'deactivate' || text == 'activate' || text == 'block' || text == 'unblock'
4980
+ // || text == 'enable' || text == 'disable' || text == 'approve' || text == 'reject' || text == 'publish' || text == 'unpublish' || text == 'lock' || text == 'unlock' || text == 'complete' || text == 'incomplete'
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();
4689
4989
  }
4990
+ const idsArray = Array.from(this.selectedRows);
4690
4991
  const arrayOfObjectsWithTableType = [];
4691
4992
  this.selectedRows.forEach(id => {
4692
4993
  arrayOfObjectsWithTableType.push({
@@ -4705,7 +5006,7 @@ class DataGridComponent {
4705
5006
  this.genericEvent.emit(sendObj);
4706
5007
  }
4707
5008
  getCellClasses(column, value) {
4708
- if (!value || !column?.field)
5009
+ if (!value || !column?.field || column?.cellRenderer)
4709
5010
  return '';
4710
5011
  let val = typeof value === 'object' ? value?.value ?? value : value;
4711
5012
  const field = column.field.toLowerCase();
@@ -4734,7 +5035,7 @@ class DataGridComponent {
4734
5035
  removeColumnFilterFromColumn(column) {
4735
5036
  if (!column)
4736
5037
  return;
4737
- if (column.type === 'dropdown') {
5038
+ if (column.type === 'dropdown' || column.type == 'array') {
4738
5039
  column.query._ids = [];
4739
5040
  }
4740
5041
  else if (['string', 'number', 'date'].includes(column.type)) {
@@ -4766,7 +5067,7 @@ class DataGridComponent {
4766
5067
  no_of_records: Number(this.paginationConfig.limit),
4767
5068
  type: this.tableType,
4768
5069
  };
4769
- this.createUpdateConfigListing.emit(sendData);
5070
+ this.createUpdateConfigListing.emit(this.createUpdateColumnConfig);
4770
5071
  setTimeout(() => {
4771
5072
  const filteredColumns = cleanedFilteredColumns;
4772
5073
  this.filterOptions.emit(filteredColumns);
@@ -4788,7 +5089,7 @@ class DataGridComponent {
4788
5089
  no_of_records: this.paginationConfig.pageSize,
4789
5090
  type: this.tableType,
4790
5091
  };
4791
- this.createUpdateConfigListing.emit(sendData);
5092
+ this.createUpdateConfigListing.emit(this.createUpdateColumnConfig);
4792
5093
  }
4793
5094
  cleanFilterdColumns() {
4794
5095
  const filteredColumns = this.commonSevice.getFiltersFromColumns(this.columns, this.filtersConfig);
@@ -4854,6 +5155,7 @@ class DataGridComponent {
4854
5155
  eventType: 'config'
4855
5156
  };
4856
5157
  this.genericEvent.emit(event);
5158
+ this.createUpdateConfigListing.emit(this.createUpdateColumnConfig);
4857
5159
  }
4858
5160
  onGlobalSearch() {
4859
5161
  const event = {
@@ -4866,6 +5168,7 @@ class DataGridComponent {
4866
5168
  if (this.tableFilterViewId) {
4867
5169
  this.savePreset('mouseUp');
4868
5170
  }
5171
+ this.createUpdateConfigListing.emit(this.createUpdateColumnConfig);
4869
5172
  }
4870
5173
  onSearchInput(event) {
4871
5174
  const value = event.target.value;
@@ -5307,13 +5610,84 @@ class DataGridComponent {
5307
5610
  this.goToFirstPage();
5308
5611
  return;
5309
5612
  }
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
+ }
5310
5628
  if ((event.ctrlKey || event.metaKey) && event.key === '/') {
5311
5629
  event.preventDefault();
5312
5630
  if (this.globalSearchInput) {
5313
- this.globalSearchInput?.nativeElement?.focus();
5631
+ const inputEl = this.globalSearchInput.nativeElement;
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);
5314
5641
  }
5315
5642
  return;
5316
5643
  }
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
+ }
5317
5691
  if (event.altKey) {
5318
5692
  const newLimit = this.pageSizeKeyMap[event.key];
5319
5693
  if (newLimit) {
@@ -5453,6 +5827,8 @@ class DataGridComponent {
5453
5827
  }
5454
5828
  }
5455
5829
  async onPaste(event) {
5830
+ if (!this.enableCut)
5831
+ return;
5456
5832
  const target = event.target;
5457
5833
  const tag = target?.tagName?.toLowerCase();
5458
5834
  if (tag === 'input' || tag === 'textarea' || target?.getAttribute('contenteditable') === 'true') {
@@ -5485,18 +5861,18 @@ class DataGridComponent {
5485
5861
  return new Promise(resolve => {
5486
5862
  const overlay = document.createElement('div');
5487
5863
  overlay.classList.add('custom-overlay-wrapper');
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>
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>
5500
5876
  `;
5501
5877
  document.body.appendChild(overlay);
5502
5878
  const confirmBtn = overlay.querySelector('.btn-confirm');
@@ -5736,8 +6112,8 @@ class DataGridComponent {
5736
6112
  setTimeout(() => {
5737
6113
  // if (this.isOutsideContainer && this.currentDraggingColumn) {
5738
6114
  // this.currentDraggingColumn!.is_visible = false;
5739
- // this.currentDraggingColumn = null;
5740
- // this.isOutsideContainer = false;
6115
+ this.currentDraggingColumn = null;
6116
+ this.isOutsideContainer = false;
5741
6117
  // this.cdr.detectChanges();
5742
6118
  // }
5743
6119
  }, 100);
@@ -5771,7 +6147,7 @@ class DataGridComponent {
5771
6147
  });
5772
6148
  const stringsCurrentPrestCols = JSON.stringify(currentPresetColumns);
5773
6149
  const stringColumns = JSON.stringify(columns);
5774
- const filters = this.filtersConfig?.map((filter) => {
6150
+ const filters = this.filtersConfig.map((filter) => {
5775
6151
  return {
5776
6152
  filed: filter.field,
5777
6153
  query: {
@@ -5797,14 +6173,6 @@ class DataGridComponent {
5797
6173
  // console.log('Current Temp Preset : ', currPreset)
5798
6174
  // console.log('Current Temp Preset Cols columns: ', currentPresetColumns)
5799
6175
  // 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);
5808
6176
  if (!currentPresetColumns)
5809
6177
  return true;
5810
6178
  return (currentPresetColumns && (stringsCurrentPrestCols == stringColumns) && (JSON.stringify(filters) == JSON.stringify(currentPresetFilters)) && (this.fontFaimly == currPreset.config.fontFaimly)
@@ -5830,15 +6198,6 @@ class DataGridComponent {
5830
6198
  };
5831
6199
  this.genericEvent.emit(event);
5832
6200
  }
5833
- createCustomColumn() {
5834
- const event = {
5835
- data: {
5836
- listingType: this.listingType,
5837
- },
5838
- eventType: "createCustomColumn",
5839
- };
5840
- this.genericEvent.emit(event);
5841
- }
5842
6201
  setActiveTab(tab) {
5843
6202
  this.activeTab = tab;
5844
6203
  const allTabs = JSON.parse(localStorage.getItem('activeTabs') || '{}');
@@ -6095,11 +6454,43 @@ class DataGridComponent {
6095
6454
  first?.full_name ??
6096
6455
  '-');
6097
6456
  }
6098
- activeFilter(type) {
6099
- this.activeFilterType = type;
6457
+ finishEdit(event) {
6458
+ console.log('cell editeddddddddddddddd: ', event);
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
+ });
6100
6491
  }
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)\" 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 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>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\">\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\">Newest 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 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=\"\n section == 'center' && (gridType === 'Assets' || gridType === 'Tasks')\n \"\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 class=\"select-all-checkbox-cell 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 class=\"select-all-checkbox-cell\"\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 - 1\"\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 == 'string'\">\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\n <ng-container *ngIf=\"selectedColumnForFilter?.type == 'number'\">\n <option value=\"equal\">Equals To</option>\n <option value=\"before\">Less Then </option>\n <option value=\"after\">Greater Then </option>\n <option value=\"less_then_equal\">less then Equal to</option>\n <option value=\"greater_then_equal\">Greater then Equal to </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 == 'string'\">\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\n <ng-container *ngIf=\"selectedColumnForFilter?.type == 'number'\">\n <option value=\"equal\">Equals To</option>\n <option value=\"before\">Less Then </option>\n <option value=\"after\">Greater Then </option>\n <option value=\"less_then_equal\">less then Equal to</option>\n <option value=\"greater_then_equal\">Greater then Equal to </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 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 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 >\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 btn-light\"\n (click)=\"$event.stopPropagation(); removeSideFilter(col)\"\n >\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>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>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\">\n Are you sure you want to delete <br /><b\n >\u201C{{ table?.name }}\u201D</b\n >?\n </div>\n <div class=\"d-flex gap-2\">\n <button\n class=\"btn btn-sm btn-light me-2\"\n (click)=\"table.confirmDelete = false\"\n >\n Cancel\n </button>\n <button\n class=\"btn btn-sm btn-danger\"\n (click)=\"actionPreset(table, 'deletePreset')\"\n >\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=\"fw-bold fs-14px 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 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=\"btn btn-primary w-100 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-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\">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' || selectedColumnForFilter?.type == 'array'\"\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=\"btn btn-outline-secondary btn-light border 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=\"btn btn-primary w-100 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 == 'string'\">\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\n <ng-container *ngIf=\"selectedColumnForFilter?.type == 'number'\">\n <option value=\"equal\">Equals To</option>\n <option value=\"before\">Less Then </option>\n <option value=\"after\">Greater Then </option>\n <option value=\"less_then_equal\">less then Equal to</option>\n <option value=\"greater_then_equal\">Greater then Equal to </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 == 'string'\">\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 <ng-container *ngIf=\"selectedColumnForFilter?.type == 'number'\">\n <option value=\"equal\">Equals To</option>\n <option value=\"before\">Less Then </option>\n <option value=\"after\">Greater Then </option>\n <option value=\"less_then_equal\">less then Equal to</option>\n <option value=\"greater_then_equal\">Greater then Equal to </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 >\n <button\n [disabled]=\"!currentFilterSelectedIds?.size && !firstValue\"\n type=\"button\"\n style=\"height: 32px\"\n class=\"btn btn-outline-secondary btn-light border w-100 d-flex align-items-center justify-content-center mt-1 btn-light\"\n (click)=\"$event.stopPropagation(); resetTextFilterChanges()\"\n >\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=\"btn btn-primary w-100 d-flex align-items-center justify-content-center mt-1\"\n (click)=\"applyDropdownFilter()\"\n >\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>\n", 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: [
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 }, { token: RowActionService }], target: i0.ɵɵFactoryTarget.Component }); }
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: [
6103
6494
  trigger('accordionToggle', [
6104
6495
  state('collapsed', style({ height: '0px', overflow: 'unset' })),
6105
6496
  state('expanded', style({ height: '*', overflow: 'unset' })),
@@ -6315,8 +6706,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
6315
6706
  ], { optional: true })
6316
6707
  ]),
6317
6708
  ])
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)\" 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 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>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\">\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\">Newest 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 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=\"\n section == 'center' && (gridType === 'Assets' || gridType === 'Tasks')\n \"\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 class=\"select-all-checkbox-cell 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 class=\"select-all-checkbox-cell\"\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 - 1\"\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 == 'string'\">\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\n <ng-container *ngIf=\"selectedColumnForFilter?.type == 'number'\">\n <option value=\"equal\">Equals To</option>\n <option value=\"before\">Less Then </option>\n <option value=\"after\">Greater Then </option>\n <option value=\"less_then_equal\">less then Equal to</option>\n <option value=\"greater_then_equal\">Greater then Equal to </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 == 'string'\">\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\n <ng-container *ngIf=\"selectedColumnForFilter?.type == 'number'\">\n <option value=\"equal\">Equals To</option>\n <option value=\"before\">Less Then </option>\n <option value=\"after\">Greater Then </option>\n <option value=\"less_then_equal\">less then Equal to</option>\n <option value=\"greater_then_equal\">Greater then Equal to </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 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 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 >\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 btn-light\"\n (click)=\"$event.stopPropagation(); removeSideFilter(col)\"\n >\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>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>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\">\n Are you sure you want to delete <br /><b\n >\u201C{{ table?.name }}\u201D</b\n >?\n </div>\n <div class=\"d-flex gap-2\">\n <button\n class=\"btn btn-sm btn-light me-2\"\n (click)=\"table.confirmDelete = false\"\n >\n Cancel\n </button>\n <button\n class=\"btn btn-sm btn-danger\"\n (click)=\"actionPreset(table, 'deletePreset')\"\n >\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=\"fw-bold fs-14px 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 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=\"btn btn-primary w-100 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-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\">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' || selectedColumnForFilter?.type == 'array'\"\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=\"btn btn-outline-secondary btn-light border 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=\"btn btn-primary w-100 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 == 'string'\">\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\n <ng-container *ngIf=\"selectedColumnForFilter?.type == 'number'\">\n <option value=\"equal\">Equals To</option>\n <option value=\"before\">Less Then </option>\n <option value=\"after\">Greater Then </option>\n <option value=\"less_then_equal\">less then Equal to</option>\n <option value=\"greater_then_equal\">Greater then Equal to </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 == 'string'\">\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 <ng-container *ngIf=\"selectedColumnForFilter?.type == 'number'\">\n <option value=\"equal\">Equals To</option>\n <option value=\"before\">Less Then </option>\n <option value=\"after\">Greater Then </option>\n <option value=\"less_then_equal\">less then Equal to</option>\n <option value=\"greater_then_equal\">Greater then Equal to </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 >\n <button\n [disabled]=\"!currentFilterSelectedIds?.size && !firstValue\"\n type=\"button\"\n style=\"height: 32px\"\n class=\"btn btn-outline-secondary btn-light border w-100 d-flex align-items-center justify-content-center mt-1 btn-light\"\n (click)=\"$event.stopPropagation(); resetTextFilterChanges()\"\n >\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=\"btn btn-primary w-100 d-flex align-items-center justify-content-center mt-1\"\n (click)=\"applyDropdownFilter()\"\n >\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>\n", 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: [{
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 }, { type: RowActionService }]; }, propDecorators: { rowAnimation: [{
6320
6711
  type: Input
6321
6712
  }], paginationConfig: [{
6322
6713
  type: Input
@@ -6436,6 +6827,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
6436
6827
  type: Input
6437
6828
  }], nestedTablerowHeight: [{
6438
6829
  type: Input
6830
+ }], packageData: [{
6831
+ type: Input
6832
+ }], showUnLink: [{
6833
+ type: Input
6439
6834
  }], gridType: [{
6440
6835
  type: Input
6441
6836
  }], currencySymbol: [{
@@ -6474,20 +6869,19 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
6474
6869
  type: Input
6475
6870
  }], showCheckboxes: [{
6476
6871
  type: Input
6477
- }], consumerFont: [{
6478
- type: Input
6479
- }], defaultConfig: [{
6872
+ }], pageSizeOptions: [{
6480
6873
  type: Input
6481
6874
  }], resetAllFilters: [{
6482
6875
  type: Input
6876
+ }], defaultConfig: [{
6877
+ type: Input
6483
6878
  }], columnThreedotsMunuConfig: [{
6484
6879
  type: Input
6880
+ }], validateIcon: [{
6881
+ type: Input
6485
6882
  }], cellHosts: [{
6486
6883
  type: ViewChildren,
6487
6884
  args: [CellHostDirective]
6488
- }], globalSearchInput: [{
6489
- type: ViewChild,
6490
- args: ['globalSearchInput']
6491
6885
  }], changeLayout: [{
6492
6886
  type: Output
6493
6887
  }], customCellEvent: [{
@@ -6535,6 +6929,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
6535
6929
  }], rightPinnedHeader: [{
6536
6930
  type: ViewChild,
6537
6931
  args: ['rightPinnedHeader']
6932
+ }], globalSearchInput: [{
6933
+ type: ViewChild,
6934
+ args: ['globalSearchInput']
6538
6935
  }], columnsGroupedBox: [{
6539
6936
  type: ViewChild,
6540
6937
  args: ['columnsGroupedBox']
@@ -6588,79 +6985,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
6588
6985
  args: ['fullscreenImageTemplate']
6589
6986
  }] } });
6590
6987
 
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
-
6664
6988
  // format-index.pipe.ts
6665
6989
  class FormatIndexPipe {
6666
6990
  transform(value) {
@@ -6684,7 +7008,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
6684
7008
 
6685
7009
  class DataGridModule {
6686
7010
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DataGridModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
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] }); }
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, i11.InlineSVGModule, ScrollingModule, TitleCasePipe], exports: [DataGridComponent] }); }
6688
7012
  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] }); }
6689
7013
  }
6690
7014
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DataGridModule, decorators: [{
@@ -6700,7 +7024,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
6700
7024
  /*
6701
7025
  * Public API Surface of data-grid
6702
7026
  */
6703
- // import './lib/styles/styles.css';
6704
7027
 
6705
7028
  /**
6706
7029
  * Generated bundle index. Do not edit.