ms-time-sheet 0.0.13 → 0.0.14

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.
@@ -4,7 +4,7 @@ import * as i6 from 'ngx-bootstrap/datepicker';
4
4
  import { BsDatepickerModule } from 'ngx-bootstrap/datepicker';
5
5
  import * as i5 from '@angular/cdk/drag-drop';
6
6
  import { moveItemInArray, DragDropModule } from '@angular/cdk/drag-drop';
7
- import { trigger, state, transition, style, animate } from '@angular/animations';
7
+ import { trigger, transition, query, style, animate, stagger, state } from '@angular/animations';
8
8
  import * as i3 from '@angular/forms';
9
9
  import { FormsModule } from '@angular/forms';
10
10
  import * as i4 from 'ng-inline-svg';
@@ -1354,6 +1354,33 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
1354
1354
  let VirtualScrollModule = null;
1355
1355
  let DragDropModuleLazy = null;
1356
1356
  let DatePickerModule = null;
1357
+ var RowAnimationType;
1358
+ (function (RowAnimationType) {
1359
+ RowAnimationType["None"] = "none";
1360
+ RowAnimationType["Spread"] = "spreadAnimation";
1361
+ RowAnimationType["Bounce"] = "bounceAnimation";
1362
+ RowAnimationType["SlideUp"] = "slideUpFromBottom";
1363
+ RowAnimationType["Flip"] = "flipAnimation";
1364
+ RowAnimationType["Skew"] = "skewAnimation";
1365
+ RowAnimationType["SlideRight"] = "slideFromRight";
1366
+ })(RowAnimationType || (RowAnimationType = {}));
1367
+ const sortingAnimation = trigger('listSort', [
1368
+ transition('* => *', [
1369
+ // Query all elements entering or leaving
1370
+ query(':enter, :leave', style({ position: 'absolute', width: '100%' }), { optional: true }),
1371
+ // Animate leaving elements upward with fade out
1372
+ query(':leave', [
1373
+ animate('300ms ease-in', style({ transform: 'translateY(-20px)', opacity: 0 }))
1374
+ ], { optional: true }),
1375
+ // Stagger the entering elements for a smoother effect
1376
+ query(':enter', [
1377
+ style({ transform: 'translateY(20px)', opacity: 0 }),
1378
+ stagger(50, [
1379
+ animate('300ms ease-out', style({ transform: 'translateY(0)', opacity: 1 }))
1380
+ ])
1381
+ ], { optional: true })
1382
+ ])
1383
+ ]);
1357
1384
  class TimeSheetComponent {
1358
1385
  // For Short Break Tooltip
1359
1386
  hideShortBreakTooltip() {
@@ -1527,6 +1554,16 @@ class TimeSheetComponent {
1527
1554
  data: breakItem // Include full break item data for tooltip
1528
1555
  }));
1529
1556
  }
1557
+ getShortBreakBadges(shortBreak) {
1558
+ if (!shortBreak || !shortBreak.short_break_duration || shortBreak.short_break_duration <= 0)
1559
+ return [];
1560
+ return [{
1561
+ text: `${shortBreak.short_break_duration}m`,
1562
+ class: this.getBreakColorClass(shortBreak.short_break_name || 'default'),
1563
+ tooltip: `Short Break: ${shortBreak.short_break_duration} minutes`,
1564
+ data: shortBreak
1565
+ }];
1566
+ }
1530
1567
  // Method to transform status strings
1531
1568
  transformStatus(status) {
1532
1569
  if (!status)
@@ -1557,6 +1594,7 @@ class TimeSheetComponent {
1557
1594
  // **************************************//
1558
1595
  // Add a new property to track expanded rows
1559
1596
  this.expandedRows = new Set();
1597
+ this.rowAnimation = RowAnimationType.None;
1560
1598
  this.onShortBreakClick = new EventEmitter();
1561
1599
  this.searchEvent = new EventEmitter();
1562
1600
  // Advanced Performance Optimizations
@@ -1669,6 +1707,7 @@ class TimeSheetComponent {
1669
1707
  this.filtersConfig = [];
1670
1708
  // Applied Filters
1671
1709
  this.loading = false;
1710
+ this.dataSetLoading = false;
1672
1711
  //Vertical Scrollbar style
1673
1712
  this.verticalScrollbarWidth = 'auto';
1674
1713
  //Horizintal Scrollbar style
@@ -2230,6 +2269,11 @@ class TimeSheetComponent {
2230
2269
  // For Detail Row Drag & Drop
2231
2270
  this.currentDetailDraggingColumn = null;
2232
2271
  this.currentDetailRow = null;
2272
+ // Paste Confirmation Modal
2273
+ this.showPasteConfirmationModal = false;
2274
+ this.pendingPasteData = '';
2275
+ this.pendingPasteStartCell = null;
2276
+ this.pastePreviewData = '';
2233
2277
  this.detailsIconPosition = 'start';
2234
2278
  this.detailsPosition = 'top';
2235
2279
  this.detailDragState = {
@@ -2247,6 +2291,18 @@ class TimeSheetComponent {
2247
2291
  this.currentTooltipData = null;
2248
2292
  this.tooltipElement = null;
2249
2293
  this.currentTooltip = null;
2294
+ // getEmployeeNameTitle(row: any): string {
2295
+ // let title = row?.User?.full_name || row?.full_name || row?.name || 'N/A';
2296
+ // if (row.manually_logs && row.manually_logs.length > 0) {
2297
+ // title += '\n\nManual Logs:';
2298
+ // row.manually_logs.forEach((log: any, index: number) => {
2299
+ // const clockIn = log.clock_in?.time ? new Date(log.clock_in.time).toLocaleTimeString() : 'N/A';
2300
+ // const status = log.clock_in?.status || 'N/A';
2301
+ // title += `\n${index + 1}. Clock In: ${clockIn} (${status})`;
2302
+ // });
2303
+ // }
2304
+ // return title;
2305
+ // }
2250
2306
  this.minuteOptions = Array.from({ length: 60 }, (_, i) => i); // 0–59
2251
2307
  this.tooltipMinutes = 0;
2252
2308
  this.formattedDuration = '0m';
@@ -2309,10 +2365,15 @@ class TimeSheetComponent {
2309
2365
  this.exportClicked = new EventEmitter();
2310
2366
  this.exportDailyClicked = new EventEmitter();
2311
2367
  this.deleteClicked = new EventEmitter();
2368
+ this.recentlyClickedButton = null;
2312
2369
  // Map: `${rowId}-${colField}` → { condition, value, secondValue, secondCondition, _ids }
2313
2370
  this.accordionColumnFilters = new Map();
2314
2371
  // Track which filter menu is open (row + column)
2315
2372
  this.activeAccordionFilterMenu = null;
2373
+ this.activePresetDropdownId = null;
2374
+ this.confirmDeletePresetId = null;
2375
+ this.clickTimeout = null;
2376
+ this.clickDelay = 300;
2316
2377
  // Initialize reactive streams for performance optimization
2317
2378
  this.initializeReactiveStreams();
2318
2379
  // Lazy load heavy modules based on usage
@@ -2727,6 +2788,12 @@ class TimeSheetComponent {
2727
2788
  this.cdr.markForCheck();
2728
2789
  this.endPerformanceTimer('filterTime');
2729
2790
  }
2791
+ isColumnGrouped(col) {
2792
+ if (col.children && col.children.length > 0) {
2793
+ return col.children.some((child) => this.groupedColumns.some((grouped) => grouped.field === child.field));
2794
+ }
2795
+ return this.groupedColumns.some((grouped) => grouped.field === col.field);
2796
+ }
2730
2797
  getOptimizedElements(selector, context) {
2731
2798
  const cacheKey = context ? `${selector}:${context.tagName}[${context.className}]` : selector;
2732
2799
  const now = Date.now();
@@ -2982,7 +3049,7 @@ class TimeSheetComponent {
2982
3049
  resolve(prepared);
2983
3050
  });
2984
3051
  this.leftPinnedColumns = left;
2985
- this.centerColumns = center;
3052
+ this.centerColumns = center.filter(col => !this.isColumnGrouped(col));
2986
3053
  this.rightPinnedColumns = right;
2987
3054
  await new Promise(r => setTimeout(r, 0));
2988
3055
  this.cdr.markForCheck();
@@ -2997,7 +3064,7 @@ class TimeSheetComponent {
2997
3064
  resolve(prepared);
2998
3065
  });
2999
3066
  this.previewLeftPinnedColumns = left;
3000
- this.previewCenterColumns = center;
3067
+ this.previewCenterColumns = center.filter(col => !this.isColumnGrouped(col));
3001
3068
  this.previewRightPinnedColumns = right;
3002
3069
  await new Promise(r => setTimeout(r, 10));
3003
3070
  this.cdr.markForCheck();
@@ -3631,6 +3698,8 @@ class TimeSheetComponent {
3631
3698
  this.detailSelectionState.clear();
3632
3699
  this.cdr.detectChanges();
3633
3700
  }
3701
+ this.activePresetDropdownId = null;
3702
+ this.confirmDeletePresetId = null;
3634
3703
  }
3635
3704
  closeThreeDotsMenuFilter() {
3636
3705
  this.isThreeDotsFilterOpen = false;
@@ -3672,15 +3741,24 @@ class TimeSheetComponent {
3672
3741
  if (!element)
3673
3742
  return;
3674
3743
  let leftPos = clickX;
3675
- // If menu overflows right move left
3744
+ let applyLeft = false; // <-- default: don't apply left
3745
+ // If menu overflows right → reposition and apply left
3676
3746
  if (clickX + menuWidth > containerWidth) {
3677
- leftPos = containerWidth - menuWidth - 10; // 10px padding
3747
+ leftPos = containerWidth - menuWidth - 10;
3748
+ applyLeft = true; // <-- only apply left when overflow
3678
3749
  }
3679
- // If menu overflows leftpush to 0
3680
- if (leftPos < 0)
3750
+ // If leftPos < 0 (rare case) fix and apply
3751
+ if (leftPos < 0) {
3681
3752
  leftPos = 0;
3682
- element.style.left = `${leftPos}px`;
3683
- // Top position is handled by CSS or naturally by Angular position
3753
+ applyLeft = true;
3754
+ }
3755
+ // Apply only if needed
3756
+ if (applyLeft) {
3757
+ element.style.left = `${leftPos}px`;
3758
+ }
3759
+ else {
3760
+ element.style.left = ''; // keep natural CSS position
3761
+ }
3684
3762
  this.isMenueHidden = false;
3685
3763
  this.cdr.detectChanges();
3686
3764
  });
@@ -4381,6 +4459,18 @@ class TimeSheetComponent {
4381
4459
  await this.refreshHeaders();
4382
4460
  }
4383
4461
  }
4462
+ async onShortBreakOverflowCountClick(col) {
4463
+ // Increase the width of the short breaks column when overflow count is clicked
4464
+ if (col && col.field === 'short_breaks') {
4465
+ const currentWidth = col.width || 200;
4466
+ const newWidth = Math.min(currentWidth + 100, 500); // Increase by 100px, max 500px
4467
+ col.width = newWidth;
4468
+ // Update the column width in the source
4469
+ this.updateColumnWidthInSourceByField(col.field, newWidth);
4470
+ // Refresh headers to apply changes
4471
+ await this.refreshHeaders();
4472
+ }
4473
+ }
4384
4474
  get hasAnyVisibleColumn() {
4385
4475
  return this.commonSevice.gethasVisibleColumns(this.columns);
4386
4476
  }
@@ -4919,10 +5009,7 @@ class TimeSheetComponent {
4919
5009
  this.updateVisibleRows(this.mainScroll?.nativeElement?.scrollTop);
4920
5010
  await this.refreshHeaders();
4921
5011
  }
4922
- if (this.tableFilterViewId) {
4923
- this.savePreset('mouseUp');
4924
- }
4925
- this.onFontChange();
5012
+ this.emitConfigUpdate();
4926
5013
  }
4927
5014
  get startIndexData() {
4928
5015
  return (this.paginationConfig.page - 1) * this.paginationConfig.limit;
@@ -4966,7 +5053,7 @@ class TimeSheetComponent {
4966
5053
  }
4967
5054
  }
4968
5055
  openFilteronThreeDotsClick(col) {
4969
- if (col.type == 'image' || col.type === '')
5056
+ if (col.type == 'image' || col.type === '' || (col.type === 'date' && this.isSingleDay))
4970
5057
  return;
4971
5058
  this.selectedColumnForFilter = col;
4972
5059
  this.isThreeDotsFilterOpen = true;
@@ -5004,7 +5091,7 @@ class TimeSheetComponent {
5004
5091
  }
5005
5092
  openFilter(col) {
5006
5093
  // Prevent filter opening for columns with empty type or image type
5007
- if (col.type === '' || col.type === 'image')
5094
+ if (col.type === '' || col.type === 'image' || (col.type === 'date' && this.isSingleDay))
5008
5095
  return;
5009
5096
  this.activeFilterCell = col;
5010
5097
  this.activeCol = null;
@@ -5458,6 +5545,13 @@ class TimeSheetComponent {
5458
5545
  control?.control.markAsTouched();
5459
5546
  return;
5460
5547
  }
5548
+ // ✅ CLOSE THE MENU BEFORE EMITTING
5549
+ this.activeTopButton = null;
5550
+ this.activeSubButton = '';
5551
+ this.cdr.markForCheck();
5552
+ // ✅ SET LOADING TRUE
5553
+ this.closeDropdown.preset.loading = true;
5554
+ this.cdr.markForCheck();
5461
5555
  this.presetFilter = this.tableFilterViewId ? true : this.presetFilter;
5462
5556
  let selectedData = this.tableView.find((ele) => ele.id == this.tableFilterViewId);
5463
5557
  let config = {
@@ -5501,10 +5595,32 @@ class TimeSheetComponent {
5501
5595
  filters: this.presetFilter ? cleanedFilters : [],
5502
5596
  config: config,
5503
5597
  id: this.tableFilterViewId && this.tableFilterViewId !== 'default' ? this.tableFilterViewId : null,
5504
- loadingCall: control == 'mouseUp' ? false : true
5598
+ loadingCall: false // we handle loading externally
5505
5599
  },
5506
5600
  eventType: this.tableFilterViewId && this.tableFilterViewId !== 'default' ? 'updatePreset' : 'createPreset'
5507
5601
  };
5602
+ // ✅ LISTEN FOR RESPONSE TO FINALIZE UI
5603
+ const sub = this.genericEvent.subscribe(response => {
5604
+ // Optional: if your API returns the saved preset with `id`, update it
5605
+ // Example: if response contains { id, name }, use it
5606
+ if (response?.eventType === 'presetSaved' || response?.eventType === 'presetUpdated') {
5607
+ const savedPresetId = response?.data?.id || this.tableFilterViewId;
5608
+ if (savedPresetId) {
5609
+ // ✅ SELECT THE NEW/UPDATED PRESET
5610
+ this.tableFilterViewId = savedPresetId;
5611
+ this.presetName = response?.data?.name || this.presetName;
5612
+ // Mark it as temporary selection for UI checkmark
5613
+ this.tableView = this.tableView.map(item => ({
5614
+ ...item,
5615
+ is_temp: item.id === savedPresetId
5616
+ }));
5617
+ }
5618
+ }
5619
+ // ✅ RESET LOADING
5620
+ this.closeDropdown.preset.loading = false;
5621
+ this.cdr.markForCheck();
5622
+ sub.unsubscribe(); // prevent memory leak
5623
+ });
5508
5624
  this.genericEvent.emit(event);
5509
5625
  }
5510
5626
  toggleRowShading() {
@@ -5794,7 +5910,8 @@ class TimeSheetComponent {
5794
5910
  oddRowsBackgroundColor: this.rowShadingEnabled ? this.oddRowsBackgroundColor : undefined,
5795
5911
  showVerticalBorder: this.showVerticalBorder,
5796
5912
  selectedTableLayout: this.selectedTableLayout,
5797
- globalSearch: this.tableSearch
5913
+ globalSearch: this.tableSearch,
5914
+ rowShadingEnabled: this.rowShadingEnabled
5798
5915
  };
5799
5916
  const event = {
5800
5917
  obj: {
@@ -5803,6 +5920,26 @@ class TimeSheetComponent {
5803
5920
  eventType: 'config'
5804
5921
  };
5805
5922
  this.genericEvent.emit(event);
5923
+ // Also emit to createUpdateConfigListing for layout and separator changes
5924
+ const event2 = {
5925
+ columns: this.columns,
5926
+ type: 'createUpdateConfigListing',
5927
+ config: config
5928
+ };
5929
+ this.createUpdateConfigListing.emit(event2);
5930
+ }
5931
+ emitConfigUpdate() {
5932
+ const config = {
5933
+ selectedTableLayout: this.selectedTableLayout,
5934
+ showVerticalBorder: this.showVerticalBorder,
5935
+ rowShadingEnabled: this.rowShadingEnabled
5936
+ };
5937
+ const event = {
5938
+ columns: this.columns,
5939
+ type: 'createUpdateConfigListing',
5940
+ config: config
5941
+ };
5942
+ this.createUpdateConfigListing.emit(event);
5806
5943
  }
5807
5944
  onGlobalSearch() {
5808
5945
  if (this.tableSearch.trim()) {
@@ -6264,7 +6401,41 @@ class TimeSheetComponent {
6264
6401
  console.log('Updated Rows: ', updatedRows);
6265
6402
  }
6266
6403
  getSelectedDataForCopy() {
6267
- return this.copyService.getSelectedDataForCopy(this.visibleRows, this.columns, this.rowSelectedIndexes, this.selectedCells, this.getNestedValue.bind(this));
6404
+ const getFormattedValue = (row, field) => {
6405
+ // Special handling for breaks field
6406
+ if (field === 'breaks') {
6407
+ return this.getDisplayValue(row, field);
6408
+ }
6409
+ // Special handling for short breaks field
6410
+ if (field === 'short_breaks') {
6411
+ return this.getDisplayValue(row, field);
6412
+ }
6413
+ // Special handling for attendance status
6414
+ if (field === 'attendanceStatus') {
6415
+ return this.transformStatus(row[field] || '');
6416
+ }
6417
+ // Special handling for payroll processed
6418
+ if (field === 'is_payroll_processed') {
6419
+ return row[field] ? 'Yes' : 'No';
6420
+ }
6421
+ // Special handling for attendance date
6422
+ if (field === 'attendance_date') {
6423
+ const date = row[field];
6424
+ if (date) {
6425
+ return this.datePipe.transform(date, 'MM/dd/yyyy') || '';
6426
+ }
6427
+ return '';
6428
+ }
6429
+ // Use formatted cell value for other fields
6430
+ const col = this.columns.find(c => c.field === field);
6431
+ if (col) {
6432
+ return this.getFormattedCellValue(row, col) || '';
6433
+ }
6434
+ // Fallback to nested value
6435
+ const value = this.getNestedValue(row, field);
6436
+ return value?.toString() || '';
6437
+ };
6438
+ return this.copyService.getSelectedDataForCopy(this.visibleRows, this.columns, this.rowSelectedIndexes, this.selectedCells, getFormattedValue);
6268
6439
  }
6269
6440
  onKeyDown(event) {
6270
6441
  const focus = this.findFocusedDetailRowAndSection();
@@ -6313,7 +6484,18 @@ class TimeSheetComponent {
6313
6484
  const startCell = this.selectedCells?.[0];
6314
6485
  if (!startCell)
6315
6486
  return;
6316
- const updatedRows = await this.copyService.pasteFromClipboardText(text, this.visibleRows, this.columns, startCell.rowIndex, startCell.colIndex, startCell.subColIndex);
6487
+ // Store paste data and show confirmation modal
6488
+ this.pendingPasteData = text;
6489
+ this.pendingPasteStartCell = startCell;
6490
+ this.pastePreviewData = text.length > 200 ? text.substring(0, 200) + '...' : text;
6491
+ this.showPasteConfirmationModal = true;
6492
+ this.cdr.detectChanges();
6493
+ }
6494
+ // Confirm paste operation
6495
+ async confirmPaste() {
6496
+ if (!this.pendingPasteData || !this.pendingPasteStartCell)
6497
+ return;
6498
+ const updatedRows = await this.copyService.pasteFromClipboardText(this.pendingPasteData, this.visibleRows, this.columns, this.pendingPasteStartCell.rowIndex, this.pendingPasteStartCell.colIndex, this.pendingPasteStartCell.subColIndex);
6317
6499
  console.log("Updated Rows: ", updatedRows);
6318
6500
  if (updatedRows?.length) {
6319
6501
  const sendObj = {
@@ -6322,6 +6504,19 @@ class TimeSheetComponent {
6322
6504
  };
6323
6505
  this.genericEvent.emit(sendObj);
6324
6506
  }
6507
+ // Close modal and clear pending data
6508
+ this.showPasteConfirmationModal = false;
6509
+ this.pendingPasteData = '';
6510
+ this.pendingPasteStartCell = null;
6511
+ this.pastePreviewData = '';
6512
+ this.cdr.detectChanges();
6513
+ }
6514
+ // Cancel paste operation
6515
+ cancelPaste() {
6516
+ this.showPasteConfirmationModal = false;
6517
+ this.pendingPasteData = '';
6518
+ this.pendingPasteStartCell = null;
6519
+ this.pastePreviewData = '';
6325
6520
  this.cdr.detectChanges();
6326
6521
  }
6327
6522
  isDate(value) {
@@ -6373,8 +6568,8 @@ class TimeSheetComponent {
6373
6568
  this.filterDetailDropdownOptions();
6374
6569
  // 🔥 FIXED POSITIONING — open exactly where clicked
6375
6570
  this.detailFilterMenuPosition = {
6376
- x: event.clientX - 150, // move LEFT
6377
- y: event.clientY - 200 // move UP
6571
+ x: event.clientX - 100, // move LEFT
6572
+ y: event.clientY - 80 // move UP
6378
6573
  };
6379
6574
  // Close 3-dot menu
6380
6575
  this.activeDetailCol = null;
@@ -6925,18 +7120,6 @@ class TimeSheetComponent {
6925
7120
  };
6926
7121
  this.tooltipVisible = true;
6927
7122
  }
6928
- getEmployeeNameTitle(row) {
6929
- let title = row?.User?.full_name || row?.full_name || row?.name || 'N/A';
6930
- if (row.manually_logs && row.manually_logs.length > 0) {
6931
- title += '\n\nManual Logs:';
6932
- row.manually_logs.forEach((log, index) => {
6933
- const clockIn = log.clock_in?.time ? new Date(log.clock_in.time).toLocaleTimeString() : 'N/A';
6934
- const status = log.clock_in?.status || 'N/A';
6935
- title += `\n${index + 1}. Clock In: ${clockIn} (${status})`;
6936
- });
6937
- }
6938
- return title;
6939
- }
6940
7123
  enableTooltipEdit() {
6941
7124
  this.tooltipEditing = true;
6942
7125
  this.tooltipMinutes = this.currentTooltipData.duration || 0;
@@ -7220,6 +7403,11 @@ class TimeSheetComponent {
7220
7403
  this.activeDetailRow = null;
7221
7404
  this.cdr.detectChanges();
7222
7405
  }
7406
+ // Paste confirmation modal properties
7407
+ // showPasteConfirmationModal = false;
7408
+ // pastePreviewData: string = '';
7409
+ // pendingPasteData: string = '';
7410
+ // pendingPasteStartCell: any = null;
7223
7411
  openDetailChooseColumns(row) {
7224
7412
  this.currentDetailRowForColumnSelection = row;
7225
7413
  this.showDetailColumnPanel = true;
@@ -8308,6 +8496,8 @@ class TimeSheetComponent {
8308
8496
  onExportDailyClick() { this.exportDailyClicked.emit(); }
8309
8497
  onDeleteClick() { this.deleteClicked.emit(); }
8310
8498
  onActionButtonClick(name) {
8499
+ this.recentlyClickedButton = name;
8500
+ setTimeout(() => this.recentlyClickedButton = null, 100); // Reset after 100ms
8311
8501
  switch (name) {
8312
8502
  case 'Email':
8313
8503
  this.onEmailClick();
@@ -8792,11 +8982,37 @@ class TimeSheetComponent {
8792
8982
  }
8793
8983
  this.cdr.markForCheck();
8794
8984
  }
8985
+ togglePresetDropdown(id) {
8986
+ if (this.activePresetDropdownId === id) {
8987
+ this.activePresetDropdownId = null;
8988
+ this.confirmDeletePresetId = null; // 👈 reset confirmation
8989
+ }
8990
+ else {
8991
+ this.activePresetDropdownId = id;
8992
+ this.confirmDeletePresetId = null; // 👈 don't carry over confirmation
8993
+ }
8994
+ this.cdr.markForCheck();
8995
+ }
8996
+ handleShortBreakClick(row, event) {
8997
+ const mouseEvent = event;
8998
+ mouseEvent.stopPropagation();
8999
+ if (this.clickTimeout) {
9000
+ // Double click detected
9001
+ clearTimeout(this.clickTimeout);
9002
+ this.clickTimeout = null;
9003
+ this.onShortBreakClick.emit(row);
9004
+ return;
9005
+ }
9006
+ this.clickTimeout = setTimeout(() => {
9007
+ this.clickTimeout = null;
9008
+ // Optionally: handle single click (e.g., show tooltip)
9009
+ }, this.clickDelay);
9010
+ }
8795
9011
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: TimeSheetComponent, deps: [{ token: i0.Injector }, { token: i0.ViewContainerRef }, { token: CommonService }], target: i0.ɵɵFactoryTarget.Component }); }
8796
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: TimeSheetComponent, isStandalone: true, selector: "time-sheet", inputs: { 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", headerTextFontsSize: "headerTextFontsSize", bodyTextFontsSize: "bodyTextFontsSize", headerFontWeight: "headerFontWeight", bodyFontWeight: "bodyFontWeight", checkedRowBackgroundColor: "checkedRowBackgroundColor", dropdownsBackgroundColor: "dropdownsBackgroundColor", footerRowHeight: "footerRowHeight", topGroupedBadgesBackgroundColor: "topGroupedBadgesBackgroundColor", showRowsGrouping: "showRowsGrouping", showFilterRow: "showFilterRow", fontFaimly: "fontFaimly", showSideMenu: "showSideMenu", footerPadding: "footerPadding", topFilterRowHeight: "topFilterRowHeight", rowShadingEnabled: "rowShadingEnabled", showSerialNumber: "showSerialNumber", enableExport: "enableExport", 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", selectedPresetId: "selectedPresetId", closeDropdown: "closeDropdown", globalSearchText: "globalSearchText", nestedTablerowFontsize: "nestedTablerowFontsize", nestedTableHeaderRowHeight: "nestedTableHeaderRowHeight", nestedTablerowHeight: "nestedTablerowHeight", gridType: "gridType", isSingleDay: "isSingleDay", leftPinnedBoxshadow: "leftPinnedBoxshadow", rightPinnedBoxshadow: "rightPinnedBoxshadow", enableAccordionShadow: "enableAccordionShadow", enableAccordionSeparators: "enableAccordionSeparators", enableRowShading: "enableRowShading", selectedRowsBackgroundColor: "selectedRowsBackgroundColor", nestedTableHeaderBAckgroundColor: "nestedTableHeaderBAckgroundColor", tableView: "tableView", columnThreedotsMunuConfig: "columnThreedotsMunuConfig", timezonePrefs: "timezonePrefs", enableProgressiveLoading: "enableProgressiveLoading", progressiveChunkSize: "progressiveChunkSize", progressiveDelay: "progressiveDelay", detailsIconPosition: "detailsIconPosition", detailsPosition: "detailsPosition", buttons: "buttons", isStartDateNotEqualToEndDate: "isStartDateNotEqualToEndDate" }, outputs: { onShortBreakClick: "onShortBreakClick", searchEvent: "searchEvent", changeLayout: "changeLayout", filterOptions: "filterOptions", filterCleared: "filterCleared", genericEvent: "genericEvent", tablePresetConfig: "tablePresetConfig", sortingOrderOptions: "sortingOrderOptions", createUpdateConfigListing: "createUpdateConfigListing", loadMore: "loadMore", emailClicked: "emailClicked", addAttendanceClicked: "addAttendanceClicked", backPayClicked: "backPayClicked", grandTotalClicked: "grandTotalClicked", printClicked: "printClicked", exportClicked: "exportClicked", exportDailyClicked: "exportDailyClicked", deleteClicked: "deleteClicked" }, 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: "dataGridContainer", first: true, predicate: ["dataGridContainer"], 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: "headerContainer", first: true, predicate: ["headerContainer"], descendants: true }, { propertyName: "dataContainer", first: true, predicate: ["dataContainer"], descendants: true }, { propertyName: "leftContainer", first: true, predicate: ["leftContainer"], descendants: true }, { propertyName: "rightContainer", first: true, predicate: ["rightContainer"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div class=\"position-relative h-100\">\r\n <!-- <h1>abu </h1> -->\r\n <div\r\n class=\"d-flex justify-content-between mb-3 align-items-center position-relative\"\r\n >\r\n <div class=\"col-4 global-search position-relative\">\r\n\r\n <span\r\n\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 style=\"height: 36px\"\r\n class=\"form-control\"\r\n placeholder=\"Search all columns and press Enter\"\r\n [(ngModel)]=\"tableSearch\"\r\n (keydown.enter)=\"onGlobalSearch()\"\r\n\r\n />\r\n <span\r\n *ngIf=\"tableSearch\"\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/x.svg'\"\r\n class=\"data-grid-svg-icon position-absolute end-0 top-50 translate-middle-y me-2 cursor-pointer\"\r\n (click)=\"onSearchReset()\"\r\n title=\"Clear search\"\r\n ></span>\r\n\r\n </div>\r\n\r\n <!-- Date Picker Buttons -->\r\n <!-- Date Picker Section - Improved Version -->\r\n<div class=\"position-relative d-flex justify-content-center align-items-center ms-2 date-range-container\">\r\n\r\n <!-- Hidden Date Picker Input -->\r\n <input\r\n type=\"text\"\r\n class=\"form-control\"\r\n bsDaterangepicker\r\n #picker=\"bsDaterangepicker\"\r\n [(ngModel)]=\"bsRangeValue\"\r\n [bsConfig]=\"bsConfig\"\r\n (bsValueChange)=\"onRangeSelected($event, picker)\"\r\n style=\"opacity: 0; width: 0; height: 0; position: absolute;\"\r\n />\r\n\r\n <!-- Left Arrow Button -->\r\n <span\r\n class=\"text-primary cursor-pointer me-2 date-range-btn arrow-btn\"\r\n (click)=\"navigateDate('left')\"\r\n title=\"Previous Date Range\"\r\n *ngIf=\"bsRangeValue && bsRangeValue.length > 0\"\r\n >\r\n <span class=\"bi bi-chevron-left\"></span>\r\n </span>\r\n\r\n <!-- Date Range Label -->\r\n <span\r\n *ngIf=\"bsRangeValue && bsRangeValue.length > 0\"\r\n class=\"text-primary date-range-label cursor-pointer\"\r\n (click)=\"togglePicker(picker)\"\r\n title=\"Click to open calendar\"\r\n >\r\n {{ bsRangeValue[0] | timezoneFormat:prefs:'date' }} - {{ bsRangeValue[1] | timezoneFormat:prefs:'date' }}\r\n </span>\r\n\r\n <!-- Right Arrow Button -->\r\n <span\r\n class=\"text-primary cursor-pointer ms-2 date-range-btn arrow-btn\"\r\n (click)=\"navigateDate('right')\"\r\n title=\"Next Date Range\"\r\n *ngIf=\"bsRangeValue && bsRangeValue.length > 0\"\r\n >\r\n <span class=\"bi bi-chevron-right\"></span>\r\n </span>\r\n\r\n\r\n\r\n</div>\r\n\r\n <div class=\"d-flex gap-2 align-items-center table-right-top-actions\">\r\n\r\n <!-- Pivot Mode Button -->\r\n <!-- <a\r\n href=\"JavaScript:void(0)\"\r\n class=\"button button-small btn btn-active-primary border border-primary me-2 header-icon\"\r\n (click)=\"togglePivotMode()\"\r\n [class.active]=\"pivotMode\"\r\n title=\"Toggle Pivot Mode\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/pivot.svg'\"\r\n class=\"svg-icon svg-icon-2\"\r\n ></span>\r\n </a> -->\r\n\r\n <div class=\"action-buttons-row d-flex\">\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 (click)=\"togglePicker(picker)\"\r\n title=\"Select Date Range\"\r\n >\r\n <span class=\"bi bi-calendar3 text-primary\"></span>\r\n <span class=\"label-hidden text-white\">Calendar</span>\r\n </a>\r\n <button\r\n *ngIf=\"bsRangeValue && bsRangeValue.length > 0 && !isDefaultDateRange\"\r\n type=\"button\"\r\n class=\"button button-small btn btn-active-danger border border-danger me-2 p-0 d-flex align-items-center justify-content-center px-3\"\r\n (click)=\"clearDateRange()\"\r\n title=\"Clear Date Range\"\r\n >\r\n <span class=\"bi bi-x-circle text-danger\"></span>\r\n <span class=\"label-hidden text-white\">Clear</span>\r\n </button>\r\n</div>\r\n<ng-container *ngFor=\"let button of buttons\">\r\n <div\r\n class=\"action-buttons-row\"\r\n *ngIf=\"getButtonPermission(button) && (!button.condition || (button.condition === '!isSingleDay' && !isSingleDay) || (button.condition === 'isSingleDay' && isSingleDay))\"\r\n >\r\n <a\r\n href=\"JavaScript:void(0)\"\r\n (click)=\"onActionButtonClick(button.name)\"\r\n class=\"button\"\r\n [title]=\"button.name\"\r\n >\r\n <span\r\n *ngIf=\"button.is_showIcon\"\r\n [inlineSVG]=\"button.iconPath\"\r\n class=\"svg-icon\"\r\n ></span>\r\n <span\r\n class=\"label-hidden\"\r\n >{{ button.name }}</span\r\n >\r\n </a>\r\n </div>\r\n</ng-container>\r\n\r\n<!-- Calendar Button -->\r\n\r\n\r\n<!-- Existing filter, settings, etc. -->\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\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 <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 *ngIf=\"activeFilteredColumns?.length\">\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 >\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 class=\"d-flex gap-2 align-items-center me-5\">\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 <ng-container\r\n *ngFor=\"\r\n let child of groupedColumns;\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 groupedColumns.length > 1 && i != groupedColumns.length - 1\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </div>\r\n\r\n\r\n\r\n\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 class=\"data-grid-header left-pinned\" #leftPinnedHeader>\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]=\"65\"\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</div>\r\n <div\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 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 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: 0.2px\"\r\n [style.background-color]=\"headerBackgroundColor\"\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 [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)=\"onCenterHeaderScroll($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)=\"openThreeDotsMenu($event, 'group')\"\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)=\"onResizeGroupBox($event)\"\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 === 'TimeSheet' && !areDatesSelectedAndEqual\"\r\n >\r\n </span> -->\r\n <div\r\n class=\"dragable-header\"\r\n (cdkDragStarted)=\"\r\n checkColumnGroupingStatus(col); dragStartOnGroup(col)\r\n \"\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 [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: 'centerColumns'\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 *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 *ngIf=\"!areDatesSelectedAndEqual\" class=\"header-cell border-below\" [style.width.px]=\"30\" [style.height.px]=\"headerRowHeight\" [style.backgroundColor]=\"headerBackgroundColor\"></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 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: 'previewRightPinnedColumns'\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 [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: 'centerColumns'\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\"\r\n >\r\n No Record Found\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\"\r\n style=\"\r\n z-index: 999;\r\n background: rgba(255, 255, 255, 0.8);\r\n backdrop-filter: blur(1px);\r\n \"\r\n >\r\n <div class=\"text-center p-2\">\r\n <div class=\"spinner-border text-primary\" role=\"status\"></div> Loading...\r\n</div>\r\n </div>\r\n\r\n <!-- Card View -->\r\n \r\n\r\n <!-- Table View -->\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 *ngIf=\"dataSet.length\"\r\n >\r\n <!-- LEFT PINNED -->\r\n <div [style.height.px]=\"!groupedColumns.length ? originalDataSet.length * rowHeight: 0\"></div>\r\n <div [class.h-100]=\"originalDataSet.length <= 10\">\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]=\"\r\n 'translateY(' + startIndex * rowHeight + 'px)'\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 }\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=\"\"\r\n [style.width.px]=\"centerPinnedHeader.clientWidth\"\r\n >\r\n <div\r\n class=\"data-grid-body center-scrollable\"\r\n\r\n style=\"overflow-y: hidden; overflow-x: auto\"\r\n [style.transform]=\"\r\n 'translateY(' + startIndex * rowHeight + 'px)'\r\n \"\r\n [style.backgroundColor]=\"bodyBackgroundColor\"\r\n #centerScrollableBody\r\n (scroll)=\"onCenterBodyScroll($event)\"\r\n [style.boxShadow]=\"leftPinnedBoxshadow\"\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: previewCenterColumns,\r\n isEven: (startIndex + i) % 2 === 0,\r\n isOdd: (startIndex + i) % 2 !== 0,\r\n section: 'center'\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 <= 10\"\r\n [style.max-width.px]=\"isScrollbarVisible ? rightPinnedHeader.offsetWidth - 15: rightPinnedHeader.offsetWidth\"\r\n >\r\n <div\r\n class=\"data-grid-body right-pinned-body w-100\"\r\n style=\"overflow-y: hidden\"\r\n [style.transform]=\"\r\n 'translateY(' + startIndex * rowHeight + 'px)'\r\n \"\r\n [style.boxShadow]=\"rightPinnedBoxshadow\"\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 }\r\n \"\r\n ></ng-container>\r\n </ng-container>\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 * (paginationConfig.totalResults || flattenedData.length)\"></div>\r\n </div>\r\n </div>\r\n\r\n <!-- Horizintal Fake Scrollbars -->\r\n <div class=\"d-flex justify-content-between\" *ngIf=\"dataSet.length\">\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)=\"onHorizintalFakeScroll($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\"></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 && !hasOpenAccordion\"\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-white]=\"\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-white]=\"\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 [style.height.px]=\"footerRowHeight\" class=\"border-top\">\r\n <!-- Rows: <span class=\"fw-500 ms-1\">{{ dataSet.length }}</span> -->\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.selectedPageSize\"\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=\"\"> per page </span>\r\n </div>\r\n\r\n <div class=\"page-info\">\r\n Results: {{ paginationConfig.page }}-{{\r\n paginationConfig.page * paginationConfig.limit\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-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)=\"onResizeGroup($event, col, pinnedRight)\"\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 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)=\"openThreeDotsMenu($event, child); openFilteronThreeDotsClick(child)\"\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)=\"openThreeDotsMenu($event, child)\"\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 >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n columnMenu;\r\n context: { col: child }\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)=\"onResizeColumn($event, child)\"\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)]=\"col.filterValue\"\r\n (ngModelChange)=\"onFilterChange(col)\"\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 ><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 class=\"group-column-wrapper\">\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\"\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)=\"openThreeDotsMenu($event, col); openFilteronThreeDotsClick(col)\"\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 <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath +\r\n (sortingConfig?.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 mt-1\"\r\n ></span>\r\n </div>\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\"\r\n [style.left.px]=\"\r\n -(!col?.pinned ? centerPinnedHeader.scrollLeft : 0)\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"columnMenu; context: { col: col }\"\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)=\"onResizeColumn($event, col)\"\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 />\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 ><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>\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 border-below d-flex align-items-center\"\r\n [style.height.px]=\"rowHeight\"\r\n [style.width]=\"\r\n section == 'center'\r\n ? centerScrollableBody!.nativeElement?.scrollWidth + '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]=\"65\"\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 >\r\n {{ row.__virtualIndex }}\r\n </div>\r\n <div\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 >\r\n <input style=\"width: 16px; height: 16px\" type=\"checkbox\" />\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 class=\"d-flex align-items-center ps-2 h-100\"\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 * 16 : 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\"\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\">\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 }\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 class=\"d-flex\" [style.height.px]=\"rowHeight\">\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=\"section == 'center' && gridType === 'TimeSheet' && detailsIconPosition === 'start' && !areDatesSelectedAndEqual\"\r\n [ngStyle]=\"{\r\n 'background-color':\r\n hoveredRowId === (row._id || row.id)\r\n ? rowHoverColor\r\n : isRowSelected(row)\r\n ? checkedRowBackgroundColor\r\n : isEven\r\n ? evenRowsBackgroundColor\r\n : oddRowsBackgroundColor\r\n }\"\r\n >\r\n <span\r\n (click)=\"row.isDetailsExpand = !row.isDetailsExpand\"\r\n class=\"data-grid-svg-icon\"\r\n [inlineSVG]=\"\r\n row.isDetailsExpand\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, row?.details?.data?.length ? 'accordion-parent' : 'main')\"\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':\r\n hoveredRowId === (row._id || row.id)\r\n ? rowHoverColor\r\n : isRowSelected(row)\r\n ? checkedRowBackgroundColor\r\n : isEven\r\n ? evenRowsBackgroundColor\r\n : oddRowsBackgroundColor\r\n }\"\r\n ></div>\r\n <div\r\n (contextmenu)=\"onRightClick($event, row, row?.details?.data?.length ? 'accordion-parent' : 'main')\"\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':\r\n hoveredRowId === (row._id || row.id)\r\n ? rowHoverColor\r\n : isRowSelected(row)\r\n ? checkedRowBackgroundColor\r\n : isEven\r\n ? evenRowsBackgroundColor\r\n : oddRowsBackgroundColor\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]=\"65\"\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 >\r\n {{ row.__virtualIndex }}\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\"\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 >\r\n <input\r\n *ngIf=\"hasAnyVisibleColumn\"\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 }\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\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 }\r\n \"\r\n ></ng-container>\r\n </ng-template>\r\n </ng-container>\r\n </div>\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=\"section == 'center' && gridType === 'TimeSheet' && detailsIconPosition === 'end' && !areDatesSelectedAndEqual\"\r\n [ngStyle]=\"{\r\n 'background-color':\r\n hoveredRowId === (row._id || row.id)\r\n ? rowHoverColor\r\n : isRowSelected(row)\r\n ? checkedRowBackgroundColor\r\n : isEven\r\n ? evenRowsBackgroundColor\r\n : oddRowsBackgroundColor\r\n }\"\r\n >\r\n <span\r\n (click)=\"row.isDetailsExpand = !row.isDetailsExpand\"\r\n class=\"data-grid-svg-icon\"\r\n [inlineSVG]=\"\r\n row.isDetailsExpand\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 <!-- LEFT PINNED: Empty table to keep alignment -->\r\n <div *ngIf=\"section === 'left' && row.isDetailsExpand && !isSingleDay\" class=\"accordion-details data-grid-accordion-section\" [style.color]=\"headerTextColor\" style=\"max-height: 350px; min-height: 350px; overflow: hidden;\">\r\n <table class=\"nested-table table table-sm w-100 mb-0 data-grid-accordion-table\" [class.show-shadow]=\"rowShadingEnabled\">\r\n <thead>\r\n <tr [style.height.px]=\"nestedTableHeaderRowHeight\" [style.backgroundColor]=\"headerBackgroundColor\" [style.color]=\"headerTextColor\" [style.fontSize.px]=\"headerTextFontsSize\" [style.fontWeight]=\"headerFontWeight\">\r\n <th *ngFor=\"let _ of [1, 2, 3, 4, 5]\"></th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <tr [style.height.px]=\"nestedTablerowHeight\" *ngFor=\"let _ of row.details.data\" [style.backgroundColor]=\"headerBackgroundColor\">\r\n <td *ngFor=\"let __ of [1, 2, 3, 4, 5]\"></td>\r\n </tr>\r\n </tbody>\r\n </table>\r\n </div>\r\n\r\n<!-- CENTER SECTION: Actual details table -->\r\n\r\n<div *ngIf=\"section === 'center' && row.isDetailsExpand && !isSingleDay\" class=\"accordion-details-wrapper data-grid-accordion\" [style.fontFamily]=\"fontFaimly\" [style.fontSize.px]=\"bodyTextFontsSize\" style=\"display: flex; width: 100%; max-height: 350px; min-height: 350px; overflow: hidden;\">\r\n <!-- LEFT SECTION OF ACCORDION -->\r\n <div #leftContainer class=\"accordion-left-section data-pin-body-wrapper data-grid-accordion-section\" [attr.data-detail-row-id]=\"row._id || row.id\" (scroll)=\"onDetailLeftScroll($event, row)\" style=\"flex-shrink: 0; overflow-y: auto; overflow-x: hidden;\">\r\n <table class=\"nested-table table-sm mb-0 data-grid-accordion-table\" [class.show-borders]=\"showVerticalBorder\" [class.show-shadow]=\"rowShadingEnabled\" style=\"table-layout: fixed; width: auto;\">\r\n <thead>\r\n <tr [style.height.px]=\"nestedTableHeaderRowHeight\" [style.backgroundColor]=\"headerBackgroundColor\" [style.color]=\"headerTextColor\" [style.fontSize.px]=\"headerTextFontsSize\" [style.fontWeight]=\"headerFontWeight\">\r\n <ng-container *ngFor=\"let col of row.details.columns | pinnedColumns:'left'; trackBy: trackByField\">\r\n <th *ngIf=\"col.is_visible !== false\"\r\n class=\"px-4\"\r\n [class.filter-applied]=\"isAccordionColumnFiltered(row, col)\"\r\n [attr.field]=\"col.field\"\r\n [attr.pinned]=\"col.pinned\"\r\n [style.width.px]=\"col.width || 150\"\r\n [style.min-width.px]=\"col.width || 150\">\r\n <div class=\"d-flex justify-content-between align-items-center\" style=\"width: 100%;\">\r\n <span class=\"d-flex align-items-center gap-1\">\r\n <span *ngIf=\"col.pinned\" [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/pin-blue.svg'\" class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"></span>\r\n {{ col.header }}\r\n <span *ngIf=\"isAccordionColumnFiltered(row, col)\"\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\"\r\n class=\"data-grid-svg-icon text-primary ms-1\"\r\n style=\"font-size: 12px;\"></span>\r\n </span>\r\n <span class=\"three-dots p-1\"\r\n (click)=\"openDetailThreeDotsMenus($event, col, row)\"\r\n style=\"cursor: pointer;\">\r\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/three-dots-vertical.svg'\" class=\"data-grid-svg-icon\"></span>\r\n </span>\r\n </div>\r\n <!-- <div class=\"resize-handles\" (mousedown)=\"onResizeDetailColumn($event, row, col)\">\r\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/resize-handle.svg'\" class=\"data-grid-svg-icon text-primary\"></span>\r\n </div> -->\r\n <ng-container *ngIf=\"activeDetailCol?.field == col.field && activeDetailRow === row\">\r\n <div class=\"position-absolute detail-column-menu-wrapper\"\r\n [style.top.px]=\"nestedTableHeaderRowHeight\"\r\n [style.left.px]=\"0\">\r\n <ng-container *ngTemplateOutlet=\"detailColumnMenu; context: { col: col, row: row }\"></ng-container>\r\n </div>\r\n </ng-container>\r\n </th>\r\n </ng-container>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <tr [style.height.px]=\"nestedTablerowHeight\" *ngFor=\"let d of row.details.data; let j = index; trackBy: trackById\">\r\n <ng-container *ngFor=\"let col of row.details.columns | pinnedColumns:'left'; let localK = index; trackBy: trackByField\">\r\n <td *ngIf=\"col.is_visible !== false\"\r\n class=\"px-4\"\r\n (mousedown)=\"startDetailSelection(row, j, localK, col.field, $event, 'left')\"\r\n (mouseenter)=\"extendDetailSelection(row, j, localK, col.field, $event, 'left')\"\r\n [class.selected-cell]=\"isDetailCellSelected(row, j, localK, col.field, 'left')\"\r\n [attr.field]=\"col.field\"\r\n [attr.pinned]=\"col.pinned\"\r\n [style.fontSize.px]=\"nestedTablerowFontsize\"\r\n (dblclick)=\"enableDetailEdits(row, d, col)\"\r\n [class.active-cell-detail]=\"isActiveDetailCell(row, d, col)\">\r\n <!-- Use the same rendering logic as center section -->\r\n <ng-container [ngSwitch]=\"col.field\">\r\n\r\n <ng-container *ngSwitchCase=\"'manually_logs'\" class=\"d-flex justify-content-start align-items-center pointer position-relative\">\r\n <ng-container *ngIf=\"d.manually_logs?.length > 0; else noManualLogsIcon\">\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/eye.svg'\"\r\n class=\"data-grid-svg-icon text-primary\"\r\n style=\"cursor: pointer; font-size: 16px;\"\r\n (mouseenter)=\"showManualLogsTooltip($event, row, d)\"\r\n (mouseleave)=\"hideManualLogsTooltip()\">\r\n </span>\r\n </ng-container>\r\n <ng-template #noManualLogsIcon>\u2013</ng-template>\r\n</ng-container>\r\n <!-- Breaks -->\r\n <ng-container *ngSwitchCase=\"'breaks'\">\r\n <ng-container *ngIf=\"d[col.field]?.length; else noBreaksLeft\">\r\n <app-badge-overflow\r\n [badges]=\"getBreakBadges(d[col.field])\"\r\n [maxWidth]=\"col.width || 200\"\r\n (badgeMouseEnter)=\"showBreakTooltip($event.event, $event.badge.data)\"\r\n (badgeMouseLeave)=\"hideBreakTooltip()\"\r\n (overflowCountClick)=\"onDetailBadgeOverflowCountClick(col, d)\">\r\n</app-badge-overflow>\r\n </ng-container>\r\n <ng-template #noBreaksLeft>\r\n <div >\r\n -\r\n </div>\r\n </ng-template>\r\n </ng-container>\r\n\r\n <!-- Short Breaks -->\r\n <ng-container *ngSwitchCase=\"'short_breaks'\">\r\n <ng-container *ngIf=\"d[col.field]?.duration; else noShortBreakLeft\">\r\n <div class=\"circle-value\"\r\n [ngClass]=\"(d[col.field].type || '').toLowerCase() === 'paid' ? 'break-color-paid' : (d[col.field].type || '').toLowerCase() === 'unpaid' ? 'break-color-unpaid' : (d[col.field].type || '').toLowerCase() === 'lunch' ? 'break-color-lunch' : 'break-color-default'\"\r\n (mouseenter)=\"showShortBreakTooltip($event, d[col.field], 'single_break'); preventCustomTooltipHide()\"\r\n (mouseleave)=\"hideShortBreakTooltip()\"\r\n (dblclick)=\"onShortBreakClick.emit(d)\">\r\n {{ d[col.field].duration }}m\r\n </div>\r\n </ng-container>\r\n <ng-template #noShortBreakLeft>\r\n <div >-</div>\r\n </ng-template>\r\n </ng-container>\r\n\r\n <!-- Short Leave -->\r\n <!-- Short Leave -->\r\n<ng-container *ngSwitchCase=\"'short_leave'\">\r\n <ng-container *ngIf=\"row.short_leave && row.short_leave.length > 0; else noShortLeaveMain\">\r\n <div class=\"w-100 d-flex main-progress-bar justify-content-center align-items-center\" \r\n style=\"background-color: rgb(111, 97, 207); height: 20px; border-radius: 4px; position: relative;\"\r\n (mouseenter)=\"showShortLeaveTooltip($event, row)\"\r\n (mouseleave)=\"hideShortLeaveTooltip()\">\r\n <span class=\"d-block\" [style.min-width.%]=\"row.short_leave[0].short_leave_time_percentage\" \r\n style=\"background-color: rgb(238, 99, 82); height: 100%; border-radius: 4px;\"></span>\r\n <span style=\"position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); color: white; font-size: 12px; font-weight: bold;\">\r\n {{ row.short_leave[0].short_leave_time_percentage }}%\r\n </span>\r\n </div>\r\n </ng-container>\r\n <ng-template #noShortLeaveMain>-</ng-template>\r\n</ng-container>\r\n\r\n<div *ngSwitchCase=\"'is_un_restricted'\" class=\"d-flex justify-content-start flex-column pointer position-relative\" (mouseenter)=\"showRestrictionTooltip($event, row, d); preventRestrictionTooltipHide()\" (mouseleave)=\"hideRestrictionTooltip()\">\r\n <span class=\"\" [class.restriction-indicator]=\"row.attendance_log_detail?.length > 0\">\r\n {{ d.is_un_restricted ? 'Yes' : 'No' }}\r\n </span>\r\n </div>\r\n\r\n <div *ngSwitchCase=\"'is_payroll_processed'\" class=\"d-flex justify-content-start flex-column pointer position-relative\" >\r\n <span class=\"\" >\r\n {{ d.is_payroll_processed ? 'Yes' : 'No' }}\r\n </span>\r\n </div>\r\n\r\n\r\n <!-- Status -->\r\n <ng-container *ngSwitchCase=\"'status'\">\r\n <ng-container *ngIf=\"getNestedValue(d, col.field); else noStatus\">\r\n <span class=\"badge\" [class]=\"getStatusBadgeClass(getNestedValue(d, col.field))\">\r\n {{ transformStatus(getNestedValue(d, col.field)) }}\r\n </span>\r\n </ng-container>\r\n <ng-template #noStatus>-</ng-template>\r\n</ng-container>\r\n\r\n<!-- Attendance Status -->\r\n<ng-container *ngSwitchCase=\"'attendanceStatus'\">\r\n <ng-container *ngIf=\"getNestedValue(d, col.field); else noAttendanceStatus\">\r\n <span class=\"badge\" [class]=\"getAttendanceStatusBadgeClass(getNestedValue(d, col.field))\">\r\n {{ transformStatus(getNestedValue(d, col.field)) }}\r\n </span>\r\n </ng-container>\r\n <ng-template #noAttendanceStatus>-</ng-template>\r\n</ng-container>\r\n\r\n <!-- Default fallback -->\r\n <ng-container *ngSwitchDefault>\r\n {{\r\n col.type === 'date'\r\n ? (getNestedValue(d, col.field) ? (getNestedValue(d, col.field) | timezoneFormat:prefs:'date') : '-')\r\n : col.type === 'time'\r\n ? ((getTimeValue(getNestedValue(d, col.field)) | timezoneFormat:prefs:'time'))\r\n : (getNestedValue(d, col.field)?.value || getNestedValue(d, col.field)?.name || getNestedValue(d, col.field) || '-')\r\n }}\r\n </ng-container>\r\n </ng-container>\r\n </td>\r\n </ng-container>\r\n </tr>\r\n</tbody>\r\n </table>\r\n </div>\r\n\r\n <!-- CENTER SECTION OF ACCORDION (WITH VIRTUAL SCROLL) -->\r\n\r\n<div class=\"accordion-center-section data-grid-accordion-section\" style=\"flex: 1; min-width: 0; display: flex; flex-direction: column; overflow: hidden;\">\r\n <!-- Header Section -->\r\n <div class=\"header-container\" style=\"overflow-x: auto; scrollbar-width: none; -ms-overflow-style: none;\" #headerContainer (scroll)=\"syncScroll($event)\">\r\n <table class=\"nested-table table-sm mb-0 data-grid-accordion-table\" [class.show-borders]=\"showVerticalBorder\" [class.show-shadow]=\"rowShadingEnabled\" style=\"table-layout: fixed; width: 100%;\">\r\n <thead>\r\n <tr\r\n [style.height.px]=\"nestedTableHeaderRowHeight\"\r\n cdkDropList\r\n [cdkDropListData]=\"row?.details.columns\"\r\n cdkDropListOrientation=\"horizontal\"\r\n (cdkDropListDropped)=\"dropColumn($event, row)\">\r\n <ng-container *ngFor=\"let col of row.details.columns; let i = index\">\r\n <th\r\n *ngIf=\"col.is_visible !== false && !col.pinned\"\r\n class=\"px-4\"\r\n cdkDrag\r\n [attr.field]=\"col.field\"\r\n [class.filter-applied]=\"isAccordionColumnFiltered(row, col)\"\r\n [style.width.px]=\"col.width || 150\"\r\n [style.min-width.px]=\"col.width || 150\"\r\n [style.backgroundColor]=\"headerBackgroundColor\"\r\n [style.color]=\"headerTextColor\"\r\n [style.fontSize.px]=\"headerTextFontsSize\"\r\n [style.fontWeight]=\"headerFontWeight\"\r\n style=\"cursor: move; position: relative;\">\r\n <div class=\"d-flex justify-content-between align-items-center\" style=\"width: 100%;\">\r\n <span class=\"d-flex align-items-center gap-1\">\r\n <span *ngIf=\"col.pinned\" [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/pin-blue.svg'\" class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"></span>\r\n {{ col.header }}\r\n <span *ngIf=\"isAccordionColumnFiltered(row, col)\"\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\"\r\n class=\"data-grid-svg-icon text-primary ms-1\"\r\n style=\"font-size: 12px;\"></span>\r\n </span>\r\n <span\r\n class=\"three-dots p-1\"\r\n (click)=\"openDetailThreeDotsMenus($event, col, row); activeDetailCol = col; activeDetailRow = row\"\r\n style=\"cursor: pointer;\">\r\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/three-dots-vertical.svg'\" class=\"data-grid-svg-icon\"></span>\r\n </span>\r\n </div>\r\n <!-- <div class=\"resize-handles\" (mousedown)=\"onResizeDetailColumn($event, row, col)\">\r\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/resize-handle.svg'\" class=\"data-grid-svg-icon text-primary\"></span>\r\n </div> -->\r\n <ng-container *ngIf=\"activeDetailCol?.field == col.field && activeDetailRow === row\">\r\n <div class=\"position-absolute detail-column-menu-wrapper\" [style.top.px]=\"nestedTableHeaderRowHeight\" [style.left.px]=\"0\">\r\n <ng-container *ngTemplateOutlet=\"detailColumnMenu; context: { col: col, row: row }\"></ng-container>\r\n </div>\r\n </ng-container>\r\n </th>\r\n </ng-container>\r\n </tr>\r\n </thead>\r\n </table>\r\n </div>\r\n\r\n <!-- Group Badges (if any) -->\r\n <div *ngIf=\"row.details?.groupedColumns?.length\" class=\"detail-group-badges\">\r\n <span *ngFor=\"let g of row.details.groupedColumns; trackBy: trackByField\" class=\"badge bg-light text-dark me-1\">\r\n {{ g.header }}\r\n <span class=\"ms-1 cursor-pointer\" (click)=\"ungroupDetailColumn(g, row)\" [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/x.svg'\"></span>\r\n </span>\r\n </div>\r\n\r\n <!-- No Data Message when filtered results are empty -->\r\n <div *ngIf=\"row.details.data.length === 0\" class=\"d-flex justify-content-center align-items-center\" style=\"flex: 1; min-height: 200px;\">\r\n <div class=\"text-center text-muted\">\r\n <div class=\"mb-2\">\r\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\" class=\"data-grid-svg-icon text-muted\" style=\"font-size: 24px;\"></span>\r\n </div>\r\n <div class=\"fw-bold\">No records found for this filter.</div>\r\n </div>\r\n </div>\r\n\r\n <!-- Data Table Section with Virtual Scroll -->\r\n <cdk-virtual-scroll-viewport\r\n *ngIf=\"row.details.data.length > 0\"\r\n itemSize=\"{{ nestedTablerowHeight }}\"\r\n minBufferPx=\"200\"\r\n maxBufferPx=\"400\"\r\n class=\"detail-virtual-scroll\"\r\n [attr.data-detail-row-id]=\"row._id || row.id\"\r\n style=\"flex: 1; overflow: auto;\"\r\n #dataContainer\r\n (scroll)=\"syncVerticalScroll($event)\"\r\n (scroll)=\"syncScroll($event)\">\r\n <table class=\"nested-table table-sm mb-0 data-grid-accordion-table\" [class.show-borders]=\"showVerticalBorder\" [class.show-shadow]=\"rowShadingEnabled\" style=\"table-layout: fixed; width: 100%;\">\r\n <tbody>\r\n <tr\r\n class=\"cursor-pointer data-grid-accordion-row\"\r\n *cdkVirtualFor=\"let d of row.details.data; trackBy: trackById; let j = index\"\r\n (contextmenu)=\"onRightClick($event, d, 'accordion-child')\"\r\n [style.height.px]=\"nestedTablerowHeight\">\r\n <ng-container *ngFor=\"let col of row.details.columns; let k = index\">\r\n <td\r\n *ngIf=\"col.is_visible !== false && !col.pinned\"\r\n class=\"px-4\"\r\n (mousedown)=\"startDetailSelection(row, j, k, col.field, $event, 'center')\"\r\n (mouseenter)=\"extendDetailSelection(row, j, k, col.field, $event, 'center')\"\r\n [class.selected-cell]=\"isDetailCellSelected(row, j, k, col.field, 'center')\"\r\n [attr.field]=\"col.field\"\r\n [style.width.px]=\"col.width || 150\"\r\n [style.min-width.px]=\"col.width || 150\"\r\n [style.fontSize.px]=\"bodyTextFontsSize\"\r\n [class.active-cell-detail]=\"isActiveDetailCell(row, d, col)\"\r\n style=\"cursor: pointer; position: relative; overflow: visible; cursor: cell; \">\r\n <div class=\"time-sheet-container\" style=\"overflow: visible; display: flex; gap: 4px; align-items: center; height: 100%; justify-content: center;\">\r\n <ng-container *ngIf=\"col.field === 'breaks' || col.field === 'short_breaks'; else defaultDetailCell\">\r\n <ng-container *ngIf=\"col.field === 'breaks'\">\r\n <ng-container *ngIf=\"d[col.field]?.length; else noBreaks\">\r\n <span *ngFor=\"let breakItem of d[col.field]; let breakIndex = index\"\r\n class=\"circle-value badge-outline break-on text-center\"\r\n [ngClass]=\"(breakItem.break_type?.data_value_name?.toLowerCase() || breakItem.breakType?.toLowerCase()) === 'paid' ? 'break-color-paid' : (breakItem.break_type?.data_value_name?.toLowerCase() || breakItem.breakType?.toLowerCase()) === 'unpaid' ? 'break-color-unpaid' : (breakItem.break_type?.data_value_name?.toLowerCase() || breakItem.breakType?.toLowerCase()) === 'lunch' ? 'break-color-lunch' : 'break-color-default'\"\r\n (mouseenter)=\"showBreakTooltip($event, breakItem)\"\r\n (mouseleave)=\"hideBreakTooltip()\">\r\n {{ breakItem.break_duration }}m\r\n</span>\r\n </ng-container>\r\n <ng-template #noBreaks>\r\n <div\r\n \r\n >\r\n -\r\n</div>\r\n</ng-template>\r\n</ng-container>\r\n <ng-container *ngIf=\"col.field === 'short_breaks' && !isDetailEditing(row, d, col)\">\r\n <div *ngIf=\"d[col.field]?.duration; else noShortBreak\"\r\n class=\"circle-value\"\r\n [ngClass]=\"(d[col.field].type || '').toLowerCase() === 'paid' ? 'break-color-paid' : (d[col.field].type || '').toLowerCase() === 'unpaid' ? 'break-color-unpaid' : (d[col.field].type || '').toLowerCase() === 'lunch' ? 'break-color-lunch' : 'break-color-default'\"\r\n (mouseenter)=\"showShortBreakTooltip($event, d[col.field], 'single_break'); preventCustomTooltipHide()\"\r\n (mouseleave)=\"hideShortBreakTooltip()\"\r\n (dblclick)=\"onShortBreakClick.emit(d)\">\r\n {{ d[col.field].duration }}m\r\n </div>\r\n <ng-template #noShortBreak>\r\n <div >-</div>\r\n </ng-template>\r\n</ng-container>\r\n <ng-container *ngIf=\"isDetailEditing(row, d, col)\">\r\n <input #detailInput type=\"text\" [ngModel]=\"getNestedValue(d, col.field)\" (blur)=\"disableDetailEdits(row, d, col)\" (keydown.enter)=\"disableDetailEdits(row, d, col)\" (keydown.escape)=\"disableDetailEdits(row, d, col)\" [attr.data-edit-key]=\"row._id + '-' + j + '-' + col.field\" class=\"form-control form-control-sm\" style=\"width: 100%; height: auto; position: absolute; top: 0; left: 0; z-index: 10;\" />\r\n </ng-container>\r\n </ng-container>\r\n <ng-template #defaultDetailCell>\r\n <span class=\"d-flex align-items-center h-100\">\r\n <ng-container *ngIf=\"!isDetailEditing(row, d, col)\">\r\n <ng-container [ngSwitch]=\"col.field\">\r\n <!-- \u2705 SHORT LEAVE: Progress bar in detail rows -->\r\n <div *ngSwitchCase=\"'short_leave'\" class=\"position-relative\" style=\"min-width: 100px; width: 150px;\">\r\n <ng-container *ngIf=\"d.short_leave && d.short_leave.length > 0; else noShortLeaveDetail\">\r\n <div\r\n class=\"w-100 d-flex main-progress-bar\"\r\n style=\"background-color: rgb(111, 97, 207); height: 20px; border-radius: 4px; position: relative;\"\r\n (mouseenter)=\"showShortLeaveTooltip($event, d)\"\r\n (mouseleave)=\"hideShortLeaveTooltip()\"\r\n >\r\n <span\r\n class=\"d-block\"\r\n [style.min-width.%]=\"d.short_leave[0].short_leave_time_percentage\"\r\n style=\"background-color: rgb(238, 99, 82); height: 100%; border-radius: 4px;\"\r\n ></span>\r\n <span style=\"position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); color: white; font-size: 12px; font-weight: bold;\">{{ d.short_leave[0].short_leave_time_percentage }}%</span>\r\n </div>\r\n </ng-container>\r\n <ng-template #noShortLeaveDetail>\r\n <div >-</div>\r\n </ng-template>\r\n </div>\r\n\r\n <!-- Status -->\r\n<ng-container *ngSwitchCase=\"'status'\">\r\n <ng-container *ngIf=\"getNestedValue(d, col.field); else noStatus\">\r\n <span class=\"badge\" [class]=\"getStatusBadgeClass(getNestedValue(d, col.field))\">\r\n {{ transformStatus(getNestedValue(d, col.field)) }}\r\n </span>\r\n </ng-container>\r\n <ng-template #noStatus>-</ng-template>\r\n</ng-container>\r\n\r\n<!-- Attendance Status -->\r\n<ng-container *ngSwitchCase=\"'attendanceStatus'\">\r\n <ng-container *ngIf=\"getNestedValue(d, col.field); else noAttendanceStatus\">\r\n <span class=\"badge\" [class]=\"getAttendanceStatusBadgeClass(getNestedValue(d, col.field))\">\r\n {{ transformStatus(getNestedValue(d, col.field)) }}\r\n </span>\r\n </ng-container>\r\n <ng-template #noAttendanceStatus>-</ng-template>\r\n</ng-container>\r\n\r\n <!-- Existing cases -->\r\n <div *ngSwitchCase=\"'is_un_restricted'\" class=\"d-flex justify-content-start flex-column pointer position-relative\" (mouseenter)=\"showRestrictionTooltip($event, row, d); preventRestrictionTooltipHide()\" (mouseleave)=\"hideRestrictionTooltip()\">\r\n <span class=\"popover__wrapper\" [class.restriction-indicator]=\"row.attendance_log_detail?.length > 0\">\r\n {{ d.is_un_restricted ? 'Yes' : 'No' }}\r\n </span>\r\n </div>\r\n\r\n <div *ngSwitchCase=\"'is_payroll_processed'\" class=\"d-flex justify-content-start flex-column pointer position-relative\" >\r\n <span class=\"\" >\r\n {{ d.is_payroll_processed ? 'Yes' : 'No' }}\r\n </span>\r\n </div>\r\n <div *ngSwitchCase=\"'manually_logs'\" class=\"d-flex justify-content-start align-items-center pointer position-relative\">\r\n <ng-container *ngIf=\"d.manually_logs?.length > 0; else noManualLogsIcon\">\r\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/eye.svg'\" class=\"data-grid-svg-icon text-primary\" style=\"cursor: pointer; font-size: 16px;\" (mouseenter)=\"showManualLogsTooltip($event, row, d)\" (mouseleave)=\"hideManualLogsTooltip()\"></span>\r\n </ng-container>\r\n <ng-template #noManualLogsIcon>\r\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/eye-cross.svg'\" class=\"data-grid-svg-icon text-muted\" style=\"font-size: 16px; cursor: not-allowed;\"></span>\r\n </ng-template>\r\n </div>\r\n\r\n <!-- Default fallback -->\r\n <span *ngSwitchDefault>\r\n {{\r\n col.type === 'date'\r\n ? (getNestedValue(d, col.field) ? (getNestedValue(d, col.field) | timezoneFormat:prefs:'date') : '-')\r\n : col.type === 'time'\r\n ? ((getTimeValue(getNestedValue(d, col.field)) | timezoneFormat:prefs:'time'))\r\n : (getNestedValue(d, col.field)?.value || getNestedValue(d, col.field)?.name || getNestedValue(d, col.field) || '-')\r\n }}\r\n </span>\r\n</ng-container>\r\n </ng-container>\r\n <ng-container *ngIf=\"isDetailEditing(row, d, col)\">\r\n <ng-container [ngSwitch]=\"col.type\">\r\n <input *ngSwitchCase=\"'string'\" #detailInput type=\"text\" [ngModel]=\"getNestedValue(d, col.field)\" (blur)=\"disableDetailEdits(row, d, col)\" (keydown.enter)=\"disableDetailEdits(row, d, col)\" (keydown.escape)=\"disableDetailEdits(row, d, col)\" class=\"form-control form-control-sm\" style=\"width: 100%; height: auto;\" />\r\n <input *ngSwitchCase=\"'number'\" #detailInput type=\"number\" [ngModel]=\"getNestedValue(d, col.field)\" (blur)=\"disableDetailEdits(row, d, col)\" (keydown.enter)=\"disableDetailEdits(row, d, col)\" (keydown.escape)=\"disableDetailEdits(row, d, col)\" class=\"form-control form-control-sm\" style=\"width: 100%; height: auto;\" />\r\n <input *ngSwitchCase=\"'date'\" #detailInput type=\"date\" [ngModel]=\"getNestedValue(d, col.field)\" (blur)=\"disableDetailEdits(row, d, col)\" (keydown.enter)=\"disableDetailEdits(row, d, col)\" (keydown.escape)=\"disableDetailEdits(row, d, col)\" class=\"form-control form-control-sm\" style=\"width: 100%; height: auto;\" />\r\n <input *ngSwitchCase=\"'time'\" #detailInput type=\"time\" [ngModel]=\"getNestedValue(d, col.field)\" (blur)=\"disableDetailEdits(row, d, col)\" (keydown.enter)=\"disableDetailEdits(row, d, col)\" (keydown.escape)=\"disableDetailEdits(row, d, col)\" class=\"form-control form-control-sm\" style=\"width: 100%; height: auto;\" />\r\n <input *ngSwitchCase=\"'currency'\" #detailInput type=\"number\" step=\"0.01\" [ngModel]=\"getNestedValue(d, col.field)\" (blur)=\"disableDetailEdits(row, d, col)\" (keydown.enter)=\"disableDetailEdits(row, d, col)\" (keydown.escape)=\"disableDetailEdits(row, d, col)\" class=\"form-control form-control-sm text-end\" style=\"width: 100%; height: auto;\" />\r\n <select *ngSwitchCase=\"'dropdown'\" #detailInput [ngModel]=\"getNestedValue(d, col.field)\" (blur)=\"disableDetailEdits(row, d, col)\" (keydown.enter)=\"disableDetailEdits(row, d, col)\" (keydown.escape)=\"disableDetailEdits(row, d, col)\" class=\"form-control form-control-sm\" style=\"width: 100%; height: auto;\">\r\n <option *ngFor=\"let option of col.column_dropdown_value\" [ngValue]=\"option?.value || option\">\r\n {{ option?.label || option?.name || option }}\r\n </option>\r\n </select>\r\n <input *ngSwitchDefault #detailInput type=\"text\" [ngModel]=\"getNestedValue(d, col.field)\" (blur)=\"disableDetailEdits(row, d, col)\" (keydown.enter)=\"disableDetailEdits(row, d, col)\" (keydown.escape)=\"disableDetailEdits(row, d, col)\" class=\"form-control form-control-sm\" style=\"width: 100%; height: auto;\" />\r\n </ng-container>\r\n </ng-container>\r\n </span>\r\n </ng-template>\r\n </div>\r\n </td>\r\n </ng-container>\r\n </tr>\r\n </tbody>\r\n </table>\r\n </cdk-virtual-scroll-viewport>\r\n</div>\r\n\r\n <!-- RIGHT SECTION OF ACCORDION -->\r\n <div #rightContainer class=\"accordion-right-section data-pin-body-wrapper \" [attr.data-detail-row-id]=\"row._id || row.id\" (scroll)=\"onDetailRightScroll($event, row)\" style=\"flex-shrink: 0; overflow-y: auto; overflow-x: hidden;\">\r\n <table class=\"nested-table table-sm mb-0 data-grid-accordion-table\" [class.show-shadow]=\"rowShadingEnabled\" style=\"table-layout: fixed; width: auto;\">\r\n <thead>\r\n <tr [style.height.px]=\"nestedTableHeaderRowHeight\" [style.backgroundColor]=\"headerBackgroundColor\" [style.color]=\"headerTextColor\" [style.fontSize.px]=\"headerTextFontsSize\" [style.fontWeight]=\"headerFontWeight\">\r\n <ng-container *ngFor=\"let col of row.details.columns | pinnedColumns:'right'; trackBy: trackByField\">\r\n <th *ngIf=\"col.is_visible !== false\"\r\n class=\"px-4\"\r\n [class.filter-applied]=\"isAccordionColumnFiltered(row, col)\"\r\n [style.width.px]=\"col.width || 150\"\r\n [style.min-width.px]=\"col.width || 150\"\r\n [attr.field]=\"col.field\"\r\n [attr.pinned]=\"col.pinned\">\r\n <div class=\"d-flex justify-content-between align-items-center\" style=\"width: 100%;\">\r\n <span class=\"d-flex align-items-center gap-1\">\r\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/pin-blue.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"></span>\r\n {{ col.header }}\r\n <span *ngIf=\"isAccordionColumnFiltered(row, col)\"\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\"\r\n class=\"data-grid-svg-icon text-primary ms-1\"\r\n style=\"font-size: 12px;\"></span>\r\n </span>\r\n <span class=\"three-dots p-1\"\r\n (click)=\"openDetailThreeDotsMenus($event, col, row); activeDetailCol = col; activeDetailRow = row\"\r\n style=\"cursor: pointer;\">\r\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/three-dots-vertical.svg'\" class=\"data-grid-svg-icon\"></span>\r\n </span>\r\n</div>\r\n\r\n <!-- <div class=\"resize-handles\" (mousedown)=\"onResizeDetailColumn($event, row, col)\">\r\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/resize-handle.svg'\" class=\"data-grid-svg-icon text-primary\"></span>\r\n </div> -->\r\n <ng-container *ngIf=\"activeDetailCol?.field == col.field && activeDetailRow === row\">\r\n <div class=\"position-absolute detail-column-menu-wrapper\"\r\n [style.top.px]=\"nestedTableHeaderRowHeight\"\r\n [style.left.px]=\"0\">\r\n <ng-container *ngTemplateOutlet=\"detailColumnMenu; context: { col: col, row: row }\"></ng-container>\r\n </div>\r\n </ng-container>\r\n </th>\r\n </ng-container>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <tr [style.height.px]=\"nestedTablerowHeight\" *ngFor=\"let d of row.details.data; let j = index; trackBy: trackById\">\r\n <ng-container *ngFor=\"let col of row.details.columns | pinnedColumns:'right'; let localK = index; trackBy: trackByField\">\r\n <td *ngIf=\"col.is_visible !== false\"\r\n class=\"px-4\"\r\n [attr.field]=\"col.field\"\r\n [attr.pinned]=\"col.pinned\"\r\n (mousedown)=\"startDetailSelection(row, j, localK, col.field, $event, 'right')\"\r\n (mouseenter)=\"extendDetailSelection(row, j, localK, col.field, $event, 'right')\"\r\n [class.selected-cell]=\"isDetailCellSelected(row, j, localK, col.field, 'right')\"\r\n [style.fontSize.px]=\"bodyTextFontsSize\"\r\n [class.active-cell-detail]=\"isActiveDetailCell(row, d, col)\">\r\n <ng-container [ngSwitch]=\"col.field\">\r\n\r\n <ng-container *ngSwitchCase=\"'manually_logs'\" class=\"d-flex justify-content-start align-items-center pointer position-relative\">\r\n <ng-container *ngIf=\"d.manually_logs?.length > 0; else noManualLogsIcon\">\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/eye.svg'\"\r\n class=\"data-grid-svg-icon text-primary\"\r\n style=\"cursor: pointer; font-size: 16px;\"\r\n (mouseenter)=\"showManualLogsTooltip($event, row, d)\"\r\n (mouseleave)=\"hideManualLogsTooltip()\">\r\n </span>\r\n </ng-container>\r\n <ng-template #noManualLogsIcon>\u2013</ng-template>\r\n</ng-container>\r\n <!-- Breaks -->\r\n <ng-container *ngSwitchCase=\"'breaks'\">\r\n <ng-container *ngIf=\"d[col.field]?.length; else noBreaksLeft\">\r\n <app-badge-overflow\r\n [badges]=\"getBreakBadges(d[col.field])\"\r\n [maxWidth]=\"col.width || 200\"\r\n (badgeMouseEnter)=\"showBreakTooltip($event.event, $event.badge.data)\"\r\n (badgeMouseLeave)=\"hideBreakTooltip()\"\r\n (overflowCountClick)=\"onDetailBadgeOverflowCountClick(col, d)\">\r\n</app-badge-overflow>\r\n </ng-container>\r\n <ng-template #noBreaksLeft>\r\n <div>\r\n -\r\n </div>\r\n </ng-template>\r\n </ng-container>\r\n\r\n <div *ngSwitchCase=\"'is_un_restricted'\" class=\"d-flex justify-content-start flex-column pointer position-relative\" (mouseenter)=\"showRestrictionTooltip($event, row, d); preventRestrictionTooltipHide()\" (mouseleave)=\"hideRestrictionTooltip()\">\r\n <span class=\"\" [class.restriction-indicator]=\"row.attendance_log_detail?.length > 0\">\r\n {{ d.is_un_restricted ? 'Yes' : 'No' }}\r\n </span>\r\n </div>\r\n\r\n <div *ngSwitchCase=\"'is_payroll_processed'\" class=\"d-flex justify-content-start flex-column pointer position-relative\" >\r\n <span class=\"\" >\r\n {{ d.is_payroll_processed ? 'Yes' : 'No' }}\r\n </span>\r\n </div>\r\n\r\n <!-- Short Breaks -->\r\n <ng-container *ngSwitchCase=\"'short_breaks'\">\r\n <ng-container *ngIf=\"d[col.field]?.duration; else noShortBreakLeft\">\r\n <div class=\"circle-value\"\r\n [ngClass]=\"(d[col.field].type || '').toLowerCase() === 'paid' ? 'break-color-paid' : (d[col.field].type || '').toLowerCase() === 'unpaid' ? 'break-color-unpaid' : (d[col.field].type || '').toLowerCase() === 'lunch' ? 'break-color-lunch' : 'break-color-default'\"\r\n (mouseenter)=\"showShortBreakTooltip($event, d[col.field], 'single_break'); preventCustomTooltipHide()\"\r\n (mouseleave)=\"hideShortBreakTooltip()\"\r\n (dblclick)=\"onShortBreakClick.emit(d)\">\r\n {{ d[col.field].duration }}m\r\n </div>\r\n </ng-container>\r\n <ng-template #noShortBreakLeft>\r\n <div >-</div>\r\n </ng-template>\r\n </ng-container>\r\n\r\n <!-- Short Leave -->\r\n <!-- Short Leave -->\r\n<ng-container *ngSwitchCase=\"'short_leave'\">\r\n <ng-container *ngIf=\"row.short_leave && row.short_leave.length > 0; else noShortLeaveMain\">\r\n <div class=\"w-100 d-flex main-progress-bar justify-content-center align-items-center\" \r\n style=\"background-color: rgb(111, 97, 207); height: 20px; border-radius: 4px; position: relative;\"\r\n (mouseenter)=\"showShortLeaveTooltip($event, row)\"\r\n (mouseleave)=\"hideShortLeaveTooltip()\">\r\n <span class=\"d-block\" [style.min-width.%]=\"row.short_leave[0].short_leave_time_percentage\" \r\n style=\"background-color: rgb(238, 99, 82); height: 100%; border-radius: 4px;\"></span>\r\n <span style=\"position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); color: white; font-size: 12px; font-weight: bold;\">\r\n {{ row.short_leave[0].short_leave_time_percentage }}%\r\n </span>\r\n </div>\r\n </ng-container>\r\n <ng-template #noShortLeaveMain>-</ng-template>\r\n</ng-container>\r\n\r\n<ng-container *ngSwitchCase=\"'status'\">\r\n <ng-container *ngIf=\"getNestedValue(d, col.field); else noStatus\">\r\n <span class=\"badge\" [class]=\"getStatusBadgeClass(getNestedValue(d, col.field))\">\r\n {{ transformStatus(getNestedValue(d, col.field)) }}\r\n </span>\r\n </ng-container>\r\n <ng-template #noStatus>-</ng-template>\r\n</ng-container>\r\n\r\n<!-- Attendance Status -->\r\n<ng-container *ngSwitchCase=\"'attendanceStatus'\">\r\n <ng-container *ngIf=\"getNestedValue(d, col.field); else noAttendanceStatus\">\r\n <span class=\"badge\" [class]=\"getAttendanceStatusBadgeClass(getNestedValue(d, col.field))\">\r\n {{ transformStatus(getNestedValue(d, col.field)) }}\r\n </span>\r\n </ng-container>\r\n <ng-template #noAttendanceStatus>-</ng-template>\r\n</ng-container>\r\n\r\n <!-- Default -->\r\n <ng-container *ngSwitchDefault>\r\n {{\r\n col.type === 'date'\r\n ? (getNestedValue(d, col.field) ? (getNestedValue(d, col.field) | timezoneFormat:prefs:'date') : '-')\r\n : col.type === 'time'\r\n ? ((getTimeValue(getNestedValue(d, col.field)) | timezoneFormat:prefs:'time'))\r\n : (getNestedValue(d, col.field)?.value || getNestedValue(d, col.field)?.name || getNestedValue(d, col.field) || '-')\r\n }}\r\n </ng-container>\r\n</ng-container>\r\n </td>\r\n </ng-container>\r\n </tr>\r\n</tbody>\r\n </table>\r\n\r\n </div>\r\n\r\n <!-- DETAIL SIDE MENU (Sticky on right end) -->\r\n <div class=\"detail-side-menu-wrapper\" >\r\n <div style=\"width: 30px\" class=\"d-flex flex-column align-items-center \">\r\n <div (click)=\"toggleDetailSideMenu(row, 'cols')\" [class.bg-white]=\"row.details.sideMenu?.currentTab === 'cols'\" class=\"columns-button d-flex flex-column align-items-center border-below\">\r\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/ui-checks-grid.svg'\" class=\"data-grid-svg-icon\"></span>\r\n <div class=\"side-menue-text\">Columns</div>\r\n </div>\r\n <!-- <div (click)=\"toggleDetailSideMenu(row, 'filtrs')\" [class.bg-white]=\"row.details.sideMenu?.currentTab === 'filtrs'\" class=\"columns-button d-flex flex-column align-items-center\">\r\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\" class=\"data-grid-svg-icon\"></span>\r\n <div class=\"side-menue-text\">Filter</div>\r\n </div> -->\r\n </div>\r\n\r\n <div *ngIf=\"row.details.sideMenu?.currentTab\" class=\"detail-side-menu-content\" [style.backgroundColor]=\"sidemenuBackgroundColor\" style=\"width: 250px; box-shadow: -2px 0 5px rgba(0,0,0,0.1);\">\r\n <!-- COLUMNS TAB -->\r\n <ng-container *ngIf=\"row.details.sideMenu.currentTab === 'cols'\">\r\n <div class=\"px-3 py-2 border-bottom d-flex align-items-center\">\r\n <strong class=\"me-auto\">Columns</strong>\r\n <input type=\"text\" class=\"form-control form-control-sm\" placeholder=\"Search...\" [(ngModel)]=\"row.details.sideMenu.columnSearch\" style=\"width: 120px; font-size: 12px;\" />\r\n </div>\r\n <div class=\"side-menu-scrollable\">\r\n <div *ngFor=\"let col of row.details.columns | filter: row.details.sideMenu.columnSearch:'header'; trackBy: trackByField\" class=\"d-flex align-items-center mb-2\">\r\n <input type=\"checkbox\" class=\"form-check-input me-2\" [(ngModel)]=\"col.is_visible\" (change)=\"onDetailColumnVisibilityChange(row)\" />\r\n <span>{{ col.header }}</span>\r\n </div>\r\n </div>\r\n </ng-container>\r\n\r\n <!-- FILTERS TAB -->\r\n <ng-container *ngIf=\"row.details.sideMenu.currentTab === 'filtrs'\">\r\n <div class=\"px-3 py-2 border-bottom d-flex align-items-center\">\r\n <strong class=\"me-auto\">Filters</strong>\r\n <input type=\"text\" class=\"form-control form-control-sm\" placeholder=\"Search...\" [(ngModel)]=\"row.details.sideMenu.columnSearch\" style=\"width: 120px; font-size: 12px;\" />\r\n </div>\r\n <div class=\"side-menu-scrollable\">\r\n <div *ngFor=\"let col of row.details.columns | filter: row.details.sideMenu.columnSearch:'header'; trackBy: trackByField\" class=\"mb-3\">\r\n <div class=\"d-flex justify-content-between align-items-center cursor-pointer\" (click)=\"col.expandedFilter = !col.expandedFilter\">\r\n <label class=\"mb-0 small\">{{ col.header }}</label>\r\n <span class=\"toggle-icon data-grid-svg-icon\" [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\" [class.rotate]=\"col.expandedFilter\"></span>\r\n </div>\r\n <div *ngIf=\"col.expandedFilter\" class=\"mt-2 filter-input-container ps-3 pe-3\">\r\n <ng-container *ngIf=\"col.type === 'dropdown'; else textFilter\">\r\n <div class=\"p-1\">\r\n <!-- Search -->\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm mb-2\"\r\n placeholder=\"Search...\"\r\n [(ngModel)]=\"col.searchValue\"\r\n />\r\n\r\n <!-- Select All -->\r\n <div class=\"form-check mb-1 ms-1\">\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n [checked]=\"\r\n row.details.filters[col.field]?._ids?.length == col.column_dropdown_value?.length\r\n \"\r\n (change)=\"toggleSelectAllDetailFilters(col, row, $event)\"\r\n id=\"detail_selectAll_{{ col.field }}\"\r\n />\r\n <label class=\"form-check-label\" for=\"detail_selectAll_{{ col.field }}\">\r\n Select All\r\n </label>\r\n </div>\r\n\r\n <!-- Options -->\r\n <div class=\"dropdown-options\">\r\n <div\r\n class=\"form-check mb-1 ms-1\"\r\n *ngFor=\"\r\n let option of col?.column_dropdown_value\r\n | filter : col.searchValue : 'value';\r\n trackBy: trackById\r\n \"\r\n >\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n [value]=\"option\"\r\n [checked]=\"\r\n row.details.filters[col.field]?._ids?.includes(option?._id || option?.id || option)\r\n \"\r\n (change)=\"onDetailOptionToggle(col, option, row)\"\r\n id=\"detail_option_{{ col.field }}_{{\r\n option?.id || option?._id || option\r\n }}\"\r\n />\r\n <label\r\n class=\"form-check-label\"\r\n [for]=\"\r\n 'detail_option_' +\r\n col.field +\r\n '_' +\r\n (option?.id || option?._id || option)\r\n \"\r\n >\r\n {{ option.value || option }}\r\n </label>\r\n </div>\r\n </div>\r\n </div>\r\n </ng-container>\r\n\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)]=\"row.details.filters[col.field].first_condition\"\r\n (ngModelChange)=\"applyDetailRowFilter(row)\"\r\n >\r\n <option value=\"contain\">Contains</option>\r\n <option value=\"equal\">Equals</option>\r\n <option value=\"before\">Begins With</option>\r\n <option value=\"after\">Ends With</option>\r\n </select>\r\n </div>\r\n\r\n <input\r\n [type]=\"col.type == 'date' ? 'date' : 'text'\"\r\n class=\"form-control form-control-sm mb-3\"\r\n placeholder=\"Value\"\r\n [(ngModel)]=\"row.details.filters[col.field].first_value\"\r\n (ngModelChange)=\"applyDetailRowFilter(row)\"\r\n />\r\n\r\n <ng-container *ngIf=\"row.details.filters[col.field]?.first_value\">\r\n <div class=\"form-group mb-2\">\r\n <div class=\"form-check form-check-inline\">\r\n <input\r\n class=\"form-check-input filter-radio-inputs\"\r\n type=\"radio\"\r\n name=\"detail_condition_{{ col.field }}\"\r\n [(ngModel)]=\"row.details.filters[col.field].condition\"\r\n (ngModelChange)=\"applyDetailRowFilter(row)\"\r\n value=\"and\"\r\n id=\"detail_and_{{ col.field }}\"\r\n />\r\n <label class=\"form-check-label\" for=\"detail_and_{{ col.field }}\"\r\n >AND</label\r\n >\r\n </div>\r\n <div class=\"form-check form-check-inline\">\r\n <input\r\n class=\"form-check-input filter-radio-inputs\"\r\n type=\"radio\"\r\n name=\"detail_condition_{{ col.field }}\"\r\n [(ngModel)]=\"row.details.filters[col.field].condition\"\r\n (ngModelChange)=\"applyDetailRowFilter(row)\"\r\n value=\"or\"\r\n id=\"detail_or_{{ col.field }}\"\r\n />\r\n <label class=\"form-check-label\" for=\"detail_or_{{ col.field }}\"\r\n >OR</label\r\n >\r\n </div>\r\n <div class=\"form-check form-check-inline\">\r\n <input\r\n class=\"form-check-input filter-radio-inputs\"\r\n type=\"radio\"\r\n name=\"detail_condition_{{ col.field }}\"\r\n [(ngModel)]=\"row.details.filters[col.field].condition\"\r\n (ngModelChange)=\"applyDetailRowFilter(row)\"\r\n value=\"none\"\r\n id=\"detail_none_{{ col.field }}\"\r\n />\r\n <label class=\"form-check-label\" for=\"detail_none_{{ col.field }}\"\r\n >None</label\r\n >\r\n </div>\r\n </div>\r\n\r\n <ng-container *ngIf=\"row.details.filters[col.field].condition !== 'none'\">\r\n <div class=\"form-group mb-2\">\r\n <select\r\n class=\"form-select form-select-sm\"\r\n [(ngModel)]=\"row.details.filters[col.field].second_condition\"\r\n (ngModelChange)=\"applyDetailRowFilter(row)\"\r\n >\r\n <option value=\"contain\">Contains</option>\r\n <option value=\"equal\">Equals</option>\r\n <option value=\"before\">Begins With</option>\r\n <option value=\"after\">Ends With</option>\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-2\"\r\n placeholder=\"Second Value\"\r\n [(ngModel)]=\"row.details.filters[col.field].second_value\"\r\n (ngModelChange)=\"applyDetailRowFilter(row)\"\r\n />\r\n </ng-container>\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 </div>\r\n </div>\r\n</div>\r\n\r\n<!-- Detail Side Menu -->\r\n\r\n\r\n\r\n<!-- Popover for Restriction Logs (is_un_restricted) -->\r\n<div\r\n *ngIf=\"restrictionTooltipVisible\"\r\n class=\"popover__content m-l-10 popoverRestriction position-absolute border rounded bg-white p-3\"\r\n [style.left.px]=\"restrictionTooltipPosition.x\"\r\n [style.top.px]=\"restrictionTooltipPosition.y\"\r\n (mouseenter)=\"preventRestrictionTooltipHide()\"\r\n (mouseleave)=\"hideRestrictionTooltip()\"\r\n style=\"z-index: 1000; min-width: 300px; font-size: 12px;\"\r\n>\r\n <div class=\"modal-area px-0 py-0\">\r\n <div class=\"table-responsive\">\r\n <table class=\"table table-row-primary-100 gs-0 gy-2 mb-0\">\r\n <thead>\r\n <tr class=\"fw-bolder text-muted bg-light\">\r\n <th class=\"center ps-2\">Clock in</th>\r\n <th class=\"center\">Clock out</th>\r\n <th class=\"center\">Log Hr</th>\r\n <th class=\"center\">Log Min</th>\r\n <th class=\"center pe-2\">Status</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <tr *ngFor=\"let item of currentRestrictionLogs\">\r\n <td class=\"center ps-2\">\r\n <span class=\"text-primary\"> {{ item?.clock_in_time | date:'shortTime'}}</span>\r\n </td>\r\n <td class=\"center\">\r\n <span class=\"text-primary\">{{ item?.clock_out_time | date:'shortTime'}}</span>\r\n </td>\r\n <td class=\"center\">\r\n <span class=\"text-primary\">{{ item?.logged_hours }}</span>\r\n </td>\r\n <td class=\"center\">\r\n <span class=\"text-primary\">{{ item?.logged_minutes }}</span>\r\n </td>\r\n <td class=\"center\">\r\n <span class=\"badge bg-light text-dark border\">\r\n {{ item?.status ? (item.status | titlecase) : 'N/A' }}\r\n </span>\r\n </td>\r\n </tr>\r\n </tbody>\r\n </table>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<!-- Popover for Manual Logs -->\r\n<div\r\n *ngIf=\"manualLogsTooltipVisible\"\r\n class=\"popover__content position-absolute border rounded bg-white p-3\"\r\n [style.left.px]=\"manualLogsTooltipPosition.x\"\r\n [style.top.px]=\"manualLogsTooltipPosition.y\"\r\n (mouseenter)=\"preventManualLogsTooltipHide()\"\r\n (mouseleave)=\"hideManualLogsTooltip()\"\r\n style=\"z-index: 1000; min-width: 500px; font-size: 12px;\"\r\n>\r\n <div class=\"modal-area px-0 py-0\">\r\n <ng-container *ngIf=\"currentManualLogs.length > 0; else noManualLogs\">\r\n <div class=\"table-responsive\">\r\n <table class=\"table table-row-primary-100 gs-0 gy-2 mb-0\">\r\n <thead>\r\n <tr class=\"fw-bolder text-muted bg-light\">\r\n <th class=\"center ps-2\" style=\"width: 18%;\">Name</th>\r\n <th class=\"center\">Date/Time</th>\r\n <th class=\"center\">Previous Time</th>\r\n <th class=\"center\">Updated Time</th>\r\n <th class=\"center\">Status</th>\r\n <th class=\"center pe-2\">Remarks</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <tr *ngFor=\"let log of currentManualLogs\">\r\n <td class=\"center ps-2\">\r\n <span class=\"text-primary\">{{ log.name }}</span>\r\n </td>\r\n <td class=\"center\">\r\n <span class=\"text-primary\">{{ log.date_time }}</span>\r\n </td>\r\n <td class=\"center\">\r\n <span class=\"text-primary\">{{ log.previous_time }}</span>\r\n </td>\r\n <td class=\"center\">\r\n <span class=\"text-primary\">{{ log.updated_time }}</span>\r\n </td>\r\n <td class=\"center\">\r\n <span class=\"badge bg-light text-dark border\">\r\n {{ log.log_status ? (log.log_status | titlecase) : 'N/A' }}\r\n </span>\r\n </td>\r\n <td class=\"center pe-2\">\r\n <span class=\"text-primary\">{{ log.remarks }}</span>\r\n </td>\r\n </tr>\r\n </tbody>\r\n </table>\r\n </div>\r\n </ng-container>\r\n </div>\r\n\r\n <ng-template #noManualLogs>\r\n <div class=\"text-center p-3\">\r\n <p class=\"text-muted mb-0\">No manual logs available for this record.</p>\r\n </div>\r\n </ng-template>\r\n</div>\r\n\r\n\r\n\r\n\r\n<!-- Existing Custom Tooltip for Breaks -->\r\n\r\n\r\n\r\n\r\n\r\n <!-- RIGHT PINNED: Empty table to keep alignment -->\r\n <div *ngIf=\"section === 'right' && row.isDetailsExpand && !isSingleDay\" class=\"accordion-details data-grid-accordion-section\" style=\"max-height: 350px; min-height: 350px; overflow: hidden;\">\r\n <table class=\"nested-table table table-sm w-100 mb-0 data-grid-accordion-table\" [class.show-shadow]=\"rowShadingEnabled\">\r\n <thead>\r\n <tr [style.height.px]=\"nestedTableHeaderRowHeight\" [style.backgroundColor]=\"headerBackgroundColor\">\r\n <th *ngFor=\"let _ of [1, 2, 3, 4, 5]\">&nbsp;</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <tr [style.height.px]=\"nestedTablerowHeight\" *ngFor=\"let _ of row.details.data\" [style.backgroundColor]=\"headerBackgroundColor\">\r\n <td *ngFor=\"let __ of [1, 2, 3, 4, 5]\">&nbsp;</td>\r\n </tr>\r\n </tbody>\r\n </table>\r\n </div>\r\n\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>\r\n <div\r\n (click)=\"disableEdit(row, col); setActiveCell(row, col)\"\r\n [style.fontWeight]=\"bodyFontWeight\"\r\n [class.border-right]=\"showVerticalBorder\"\r\n class=\"cell overflow-visible position-relative\"\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 [class.active-cell]=\"\r\n isActiveCell(row, col) && !isEditing(row, col) && selectedKeys.size == 1\r\n \"\r\n (dblclick)=\"$event.preventDefault(); enableEdit(row, col)\"\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=\"0\"\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 class=\"table-cell\" [class.active-for-editing]=\"isEditing(row, col) && getNestedValue(row, col.field)?.length <= 50\">\r\n <div\r\n (click)=\"$event.stopPropagation()\"\r\n *ngIf=\"isEditing(row, col) && getNestedValue(row, col.field)?.length <= 50; else viewMode\"\r\n >\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 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)\"\r\n autofocus\r\n (keydown.enter)=\"numberRef.blur()\"\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)\"\r\n autofocus\r\n class=\"form-control form-control-sm\"\r\n #dateInput=\"ngModel\"\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\">\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 />\r\n </div>\r\n\r\n <!-- Options -->\r\n <div\r\n class=\"cell-editin-dropdown\"\r\n style=\"max-height: 200px; overflow: auto\"\r\n >\r\n <div\r\n (click)=\"\r\n setNestedValue(row, col, option, true);\r\n disableEdit(row, col)\r\n \"\r\n class=\"px-2 py-1 d-flex align-items-center item\"\r\n *ngFor=\"\r\n let option of col.column_dropdown_value\r\n | filter : editinDropdownSearch : 'value'\r\n \"\r\n >\r\n <label\r\n class=\"form-check-label d-flex align-items-center mb-0\"\r\n [for]=\"col.field + '-' + option.value || option\"\r\n >\r\n {{ option.value || option }}\r\n </label>\r\n </div>\r\n </div>\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)=\"\r\n emailModel.control.markAsTouched(); emailInput.blur()\r\n \"\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 [(ngModel)]=\"row[col.field]\"\r\n name=\"{{ col.field }}\"\r\n required\r\n (blur)=\"disableEdit(row, col, textModel)\"\r\n (keydown.enter)=\"\r\n textModel.control.markAsTouched(); textInput.blur()\r\n \"\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 </div>\r\n\r\n <!-- Display mode -->\r\n <ng-template #viewMode>\r\n <div\r\n class=\"d-flex justify-between items-center w-100\"\r\n [ngClass]=\"getCellClasses(col, getNestedValue(row, col.field))\"\r\n >\r\n <!-- Text cell -->\r\n <div class=\"d-flex align-items-center w-100\">\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(row, col.field) | date : dateFormat)\r\n : getNestedValue(row, col.field)\r\n \"\r\n >\r\n <ng-container *ngIf=\"col.type !== 'image'\">\r\n <ng-container [ngSwitch]=\"col.field\">\r\n <!-- Breaks -->\r\n <ng-container *ngSwitchCase=\"'breaks'\">\r\n <ng-container *ngIf=\"getNestedValue(row, 'breaks')?.length; else noBreaksMain\">\r\n <app-badge-overflow\r\n [badges]=\"getBreakBadges(getNestedValue(row, 'breaks'))\"\r\n [maxWidth]=\"col.width || 200\"\r\n (badgeMouseEnter)=\"showBreakTooltip($event.event, $event.badge.data)\"\r\n (badgeMouseLeave)=\"hideBreakTooltip()\"\r\n (overflowCountClick)=\"onBadgeOverflowCountClick(col)\">\r\n </app-badge-overflow>\r\n </ng-container>\r\n <ng-template #noBreaksMain>\r\n <div >\r\n -\r\n </div>\r\n </ng-template>\r\n </ng-container>\r\n\r\n <!-- Short Breaks -->\r\n <ng-container *ngSwitchCase=\"'short_breaks'\">\r\n <ng-container *ngIf=\"row.short_breaks?.duration && row.short_breaks.duration > 0; else noShortBreak\">\r\n <span class=\"popover__wrapper d-flex justify-content-center align-items-center\" style=\"cursor: pointer;\" (dblclick)=\"onShortBreakClick.emit(row)\" (mouseenter)=\"showShortBreakTooltip($event, row.short_breaks)\" (mouseleave)=\"hideShortBreakTooltip()\">\r\n <span class=\"circle-value badge-outline text-center\" [ngClass]=\"(row.short_breaks.type || '').toLowerCase() === 'paid' ? 'break-color-paid' : (row.short_breaks.type || '').toLowerCase() === 'unpaid' ? 'break-color-unpaid' : (row.short_breaks.type || '').toLowerCase() === 'lunch' ? 'break-color-lunch' : 'break-color-default'\">\r\n {{ row.short_breaks.duration }}m\r\n </span>\r\n </span>\r\n </ng-container>\r\n <ng-template #noShortBreak>\r\n <div >-</div>\r\n </ng-template>\r\n </ng-container>\r\n\r\n <!-- Short Leave -->\r\n <!-- Short Leave -->\r\n<ng-container *ngSwitchCase=\"'short_leave'\">\r\n <ng-container *ngIf=\"row.short_leave && row.short_leave.length > 0; else noShortLeaveMain\">\r\n <div class=\"w-100 d-flex main-progress-bar justify-content-center align-items-center\" \r\n style=\"background-color: rgb(111, 97, 207); height: 20px; border-radius: 4px; position: relative;\"\r\n (mouseenter)=\"showShortLeaveTooltip($event, row)\"\r\n (mouseleave)=\"hideShortLeaveTooltip()\">\r\n <span class=\"d-block\" [style.min-width.%]=\"row.short_leave[0].short_leave_time_percentage\" \r\n style=\"background-color: rgb(238, 99, 82); height: 100%; border-radius: 4px;\"></span>\r\n <span style=\"position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); color: white; font-size: 12px; font-weight: bold;\">\r\n {{ row.short_leave[0].short_leave_time_percentage }}%\r\n </span>\r\n </div>\r\n </ng-container>\r\n <ng-template #noShortLeaveMain>-</ng-template>\r\n</ng-container>\r\n\r\n <!-- Status -->\r\n <ng-container *ngSwitchCase=\"'status'\">\r\n <span class=\"badge\" [class]=\"getStatusBadgeClass(getNestedValue(row, col.field))\">\r\n {{ transformStatus(getNestedValue(row, col.field)) || '-' }}\r\n </span>\r\n </ng-container>\r\n\r\n <!-- Attendance Status -->\r\n <ng-container *ngSwitchCase=\"'attendanceStatus'\">\r\n <span class=\"badge\" [class]=\"getAttendanceStatusBadgeClass(getNestedValue(row, col.field))\">\r\n {{ transformStatus(getNestedValue(row, col.field)) || '-' }}\r\n </span>\r\n </ng-container>\r\n\r\n <!-- Payroll Processed -->\r\n <ng-container *ngSwitchCase=\"'is_payroll_processed'\">\r\n <span class=\"badge\" [class]=\"getNestedValue(row, col.field) ? 'badge-success' : 'badge-secondary'\">\r\n {{ getNestedValue(row, col.field) ? 'Yes' : 'No' }}\r\n </span>\r\n </ng-container>\r\n\r\n <!-- Restriction -->\r\n <ng-container *ngSwitchCase=\"'is_un_restricted'\">\r\n <span class=\"badge\" [class]=\"getNestedValue(row, col.field) ? 'badge-success' : 'badge-secondary'\">\r\n {{ getNestedValue(row, col.field) ? 'Yes' : 'No' }}\r\n </span>\r\n </ng-container>\r\n\r\n <!-- Default -->\r\n <ng-container *ngSwitchDefault>\r\n {{\r\n !isNestedValueArray(row, col.field)\r\n ? col.type === 'date'\r\n ? (isDate(getNestedValue(row, col.field))\r\n ? ((getNestedValue(row, col.field)) | timezoneFormat:prefs:'date' )\r\n : (getNestedValue(row, col.field)?.value ||\r\n getNestedValue(row, col.field)?.name ||\r\n getNestedValue(row, col.field) ||\r\n '-'))\r\n : col.type === 'time'\r\n ? ((getTimeValue(getNestedValue(row, col.field)) | timezoneFormat:prefs:'time'))\r\n : (getNestedValue(row, col.field)?.value ||\r\n getNestedValue(row, col.field)?.name ||\r\n getNestedValue(row, col.field) ||\r\n '-')\r\n : (getNestedValue(row, col.field)?.[0]?.department_name ||\r\n getNestedValue(row, col.field)?.[0]?.roleName ||\r\n '-')\r\n }}\r\n </ng-container>\r\n </ng-container>\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: row,\r\n col: col,\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </div>\r\n\r\n <!-- Active dot and eye icon for employee name -->\r\n <span *ngIf=\"col.field === 'User' && hasManualLogs(row) && !row.isDetailsExpand\" class=\"badge badge-dot badge-success ms-1\" (mouseenter)=\"showManualLogsTooltip($event, row, row)\"></span>\r\n <i *ngIf=\"col.field === 'User' && hasManualLogs(row)\" class=\"bi bi-eye ms-1\" (mouseenter)=\"showManualLogsTooltip($event, row, row)\"></i>\r\n </div>\r\n\r\n <!-- Expand / Collapse icon for multiple data showing in one coll-->\r\n\r\n <!-- <span\r\n *ngIf=\"\r\n (isOverflowing(cellText) &&\r\n showCellDetailsBox &&\r\n getNestedValue(row, col.field)?.length > 50) ||\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 </div>\r\n\r\n <!-- Expanded text -->\r\n <div\r\n class=\"position-absolute w-100\"\r\n *ngIf=\"isExpanded(row, col)\"\r\n [style.zIndex]=\"getZIndex(row, col)\"\r\n style=\"top: 100%; left: 0\"\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\r\n\r\n \r\n\r\n\r\n\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<div\r\n *ngIf=\"currentBreakTooltip\"\r\n class=\"custom-break-tooltip\"\r\n [style.--tooltip-x.px]=\"tooltipPosition.x\"\r\n [style.--tooltip-y.px]=\"tooltipPosition.y\"\r\n>\r\n <div class=\"break-tooltip-header\">\r\n <strong>{{ currentBreakTooltip.break_type?.data_value_name || 'Break' }}</strong>\r\n <span class=\"text-muted ms-2\">\r\n {{ currentBreakTooltip.breakInstatus === 'breakOut' ? 'Taken' : 'On Break' }}\r\n </span>\r\n </div>\r\n\r\n <div class=\"break-tooltip-body\">\r\n <div>\r\n <i class=\"bi bi-play-circle\"></i>\r\n In: {{ getTimeValue(currentBreakTooltip.break_in_time) | timezoneFormat:prefs:'time' }}\r\n </div>\r\n\r\n <div>\r\n <i class=\"bi bi-stop-circle\"></i>\r\n Out: {{ getTimeValue(currentBreakTooltip.break_out_time) | timezoneFormat:prefs:'time' }}\r\n </div>\r\n\r\n <div>\r\n <i class=\"bi bi-clock\"></i>\r\n Duration: {{ currentBreakTooltip.break_duration }} min\r\n </div>\r\n </div>\r\n</div>\r\n\r\n\r\n\r\n\r\n\r\n<!-- Short Break Tooltip -->\r\n<div\r\n *ngIf=\"currentShortBreakTooltip\"\r\n class=\"custom-break-tooltip\"\r\n [style.--tooltip-x.px]=\"tooltipPosition.x\"\r\n [style.--tooltip-y.px]=\"tooltipPosition.y\"\r\n>\r\n <div class=\"break-tooltip-header\">\r\n <strong>{{ currentShortBreakTooltip.short_break_name || 'Short Break' }}</strong>\r\n </div>\r\n\r\n <div class=\"break-tooltip-body\">\r\n <div>\r\n <i class=\"bi bi-play-circle\"></i>\r\n Start: {{ getTimeValue(currentShortBreakTooltip.start_time) | timezoneFormat:prefs:'time' }}\r\n </div>\r\n\r\n <div>\r\n <i class=\"bi bi-stop-circle\"></i>\r\n End: {{ getTimeValue(currentShortBreakTooltip.end_time) | timezoneFormat:prefs:'time' }}\r\n </div>\r\n\r\n <div>\r\n <i class=\"bi bi-clock\"></i>\r\n Duration: {{ currentShortBreakTooltip.short_break_duration }} min\r\n </div>\r\n </div>\r\n</div>\r\n\r\n\r\n\r\n\r\n<!-- Headers Action List On clicking three dots -->\r\n\r\n<ng-template #columnMenu let-col=\"col\">\r\n <div\r\n class=\"column-menu three-dots-col-menu\"\r\n [class.visually-hidden]=\"isMenueHidden\"\r\n *ngIf=\"activeCol && !isThreeDotsFilterOpen && !loading\"\r\n [style.backgroundColor]=\"dropdownsBackgroundColor\"\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\">\r\n <div\r\n *ngIf=\"columnThreedotsMunuConfig?.showFilter && !(col.is_search_able === false )\"\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)=\"updateColumnPinInSourceByField(activeCol, 'left')\"\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)=\"updateColumnPinInSourceByField(activeCol, 'right')\"\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)=\"updateColumnPinInSourceByField(activeCol, null)\"\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 && !(col.is_groupable === false)\"\r\n class=\"column-menu-item\"\r\n (click)=\"groupBy(activeCol)\"\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 *ngIf=\"isThreeDotsFilterOpen\" class=\"three-dots-col-menu position-relative\" [style.left.px]=\"-140\" >\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\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'; else textFilter\">\r\n <div class=\"filter-dropdown-section p-1\">\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm mb-2\"\r\n placeholder=\"Search...\"\r\n [(ngModel)]=\"addFilterDropdownSearch\"\r\n #filterMenueSearchInput\r\n />\r\n\r\n <div class=\"form-check mb-1\">\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n [checked]=\"isAllSideFilterOptionsSelected(col)\"\r\n (change)=\"toggleSelectAllSideFilters(col, $event)\"\r\n id=\"selectAll_{{ col.field }}\"\r\n />\r\n <label class=\"form-check-label\" for=\"selectAll_{{ col.field }}\">\r\n Select All\r\n </label>\r\n </div>\r\n\r\n <div class=\"dropdown-options\">\r\n <div\r\n class=\"form-check mb-1\"\r\n *ngFor=\"\r\n let option of col?.column_dropdown_value\r\n | filter : addFilterDropdownSearch : 'value';\r\n trackBy: trackById\r\n \"\r\n >\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n [checked]=\"\r\n col.query?._ids?.includes(option?._id || option?.id || option)\r\n \"\r\n [value]=\"option\"\r\n id=\"option_{{ col.field }}_{{\r\n option?.id || option?._id || option\r\n }}\"\r\n (change)=\"onOptionToggle(col, option)\"\r\n />\r\n <label\r\n class=\"form-check-label\"\r\n [for]=\"\r\n 'option_' +\r\n col.field +\r\n '_' +\r\n (option?.id || option?._id || option)\r\n \"\r\n >\r\n {{ option?.value || option }}\r\n </label>\r\n </div>\r\n </div>\r\n </div>\r\n </ng-container>\r\n\r\n <!-- Text Filter Section -->\r\n <ng-template #textFilter>\r\n <div class=\"filter-text-section\">\r\n <div class=\"form-group mb-2\">\r\n <select\r\n class=\"form-select form-select-sm\"\r\n [ngModel]=\"col.query.first_condition || (col.type === 'date' || col.type === 'time' ? 'equal' : 'contain')\"\r\n (ngModelChange)=\"col.query.first_condition = $event\"\r\n >\r\n <ng-container *ngIf=\"col.type === 'date' || col.type === 'time'; else textOptions\">\r\n <option value=\"equal\">Equal 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-template #textOptions>\r\n <option value=\"contain\">Contains</option>\r\n <option value=\"equal\">Equals</option>\r\n <option value=\"before\">Begins With</option>\r\n <option value=\"after\">Ends With</option>\r\n </ng-template>\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)]=\"col.query.first_value\"\r\n [min]=\"col.type == 'number' ? 0 : null\"\r\n (input)=\"col.type == 'number' && $any($event.target).value < 0 ? $any($event.target).value = 0 : null\"\r\n (keydown)=\"col.type == 'number' && $event.key === '-' ? $event.preventDefault() : null\"\r\n [class.number-input]=\"col.type == 'number'\"\r\n #filterMenueTextchInput\r\n />\r\n\r\n <ng-container >\r\n <div class=\"form-group mb-2\">\r\n <div class=\"form-check form-check-inline\">\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 />\r\n <label class=\"form-check-label\" for=\"and_{{ col.field }}\"\r\n >AND</label\r\n >\r\n </div>\r\n <div class=\"form-check form-check-inline\">\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 />\r\n <label class=\"form-check-label\" for=\"or_{{ col.field }}\"\r\n >OR</label\r\n >\r\n </div>\r\n <div class=\"form-check form-check-inline\">\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 />\r\n <label class=\"form-check-label\" for=\"none_{{ col.field }}\"\r\n >None</label\r\n >\r\n </div>\r\n </div>\r\n\r\n <ng-container *ngIf=\"col.query?.first_value && condition !== 'none'\">\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 || (col.type === 'date' || col.type === 'time' ? 'equal' : 'contain')\"\r\n (ngModelChange)=\"col.query.second_condition = $event\"\r\n >\r\n <ng-container *ngIf=\"col.type === 'date' || col.type === 'time'; else textOptionsSecond\">\r\n <option value=\"equal\">Equal 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-template #textOptionsSecond>\r\n <option value=\"contain\">Contains</option>\r\n <option value=\"equal\">Equals</option>\r\n <option value=\"before\">Begins With</option>\r\n <option value=\"after\">Ends With</option>\r\n </ng-template>\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-2\"\r\n placeholder=\"Second Value\"\r\n [(ngModel)]=\"col.query.second_value\"\r\n [min]=\"col.type == 'number' ? 0 : null\"\r\n (input)=\"col.type == 'number' && $any($event.target).value < 0 ? $any($event.target).value = 0 : null\"\r\n (keydown)=\"col.type == 'number' && $event.key === '-' ? $event.preventDefault() : null\"\r\n [class.number-input]=\"col.type == 'number'\"\r\n />\r\n </ng-container>\r\n </ng-container>\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: 22px\"\r\n (click)=\"applyFilterFromFilterRow(col)\"\r\n >\r\n Apply\r\n </div>\r\n <div\r\n class=\"btn btn-sm btn-secondary d-flex justify-content-center align-items-center w-100\"\r\n style=\"height: 22px\"\r\n (click)=\"resetSideFilter(col)\"\r\n >\r\n Reset\r\n </div>\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<!-- Side Menue -->\r\n\r\n<!-- Add this new template for accordion detail column menu -->\r\n<ng-template #detailColumnMenu let-col=\"col\" let-row=\"row\">\r\n <div\r\n class=\"column-menu three-dots-col-menu detail-column-menu\"\r\n [class.visually-hidden]=\"isDetailMenueHidden\"\r\n *ngIf=\"activeDetailCol\"\r\n [style.backgroundColor]=\"dropdownsBackgroundColor\"\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=\"columnThreedotsMunuConfig?.showAscending\"\r\n class=\"column-menu-item\"\r\n (click)=\"sortDetailAsc(activeDetailCol, row)\"\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=\"columnThreedotsMunuConfig?.showDescending\"\r\n class=\"column-menu-item\"\r\n (click)=\"sortDetailDesc(activeDetailCol, row)\"\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=\"col?.sortOrder\"\r\n class=\"column-menu-item\"\r\n (click)=\"resetDetailSort(activeDetailCol, row)\"\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\r\n <div class=\"py-2 border-below\" *ngIf=\"isColumnFilterable(col)\">\r\n <span class=\"muted-text fs-7\" style=\"margin-left: 12px\">Filter</span>\r\n <div\r\n *ngIf=\"columnThreedotsMunuConfig?.showFilter\"\r\n class=\"column-menu-item\"\r\n (click)=\"openDetailFilterMenu($event, col, row)\"\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)=\"updateDetailColumnPin(activeDetailCol, row, 'left')\"\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)=\"updateDetailColumnPin(activeDetailCol, row, 'right')\"\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)=\"updateDetailColumnPin(activeDetailCol, row, null)\"\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)=\"autosizeDetailColumn(activeDetailCol, row)\"\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)=\"autosizeAllDetailColumns(row)\"\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\r\n <!-- Choose Columns -->\r\n <div\r\n *ngIf=\"columnThreedotsMunuConfig?.showChoseColumns\"\r\n class=\"column-menu-item\"\r\n (click)=\"openDetailChooseColumns(row)\"\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)=\"resetDetailColumns(row)\"\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</ng-template>\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\"\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\">\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<!-- 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\">\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\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% - 120px); 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 <!-- Apply and Reset Buttons -->\r\n <!-- <div class=\"d-flex gap-2 mt-3 px-2\">\r\n <button\r\n class=\"btn btn-sm btn-primary d-flex justify-content-center align-items-center flex-fill\"\r\n style=\"height: 32px;\"\r\n (click)=\"applySideMenuFilters()\"\r\n >\r\n Apply\r\n </button>\r\n <button\r\n class=\"btn btn-sm btn-secondary d-flex justify-content-center align-items-center flex-fill\"\r\n style=\"height: 32px;\"\r\n (click)=\"resetSideMenuFilters()\"\r\n >\r\n Reset\r\n </button>\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 class=\"column-group d-flex align-items-center mb-2\">\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\">\r\n <span\r\n class=\"me-2 filter-icon-wrapper me-2\"\r\n (click)=\"col.expandedFilter = !col.expandedFilter\"\r\n >\r\n <span\r\n class=\"toggle-icon data-grid-svg-icon\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\r\n \"\r\n [class.rotate]=\"col.expandedFilter\"\r\n ></span>\r\n </span>\r\n\r\n <label\r\n class=\"d-flex align-items-center mb-0 w-100\"\r\n style=\"cursor: pointer\"\r\n (click)=\"col.expandedFilter = !col.expandedFilter\"\r\n >\r\n <span class=\"text-truncate fw-bold\">{{ col.header }}</span>\r\n </label>\r\n </div>\r\n\r\n <!-- Show filter when expanded -->\r\n <div *ngIf=\"col.expandedFilter\" class=\"ps-4 pe-3\">\r\n <ng-container\r\n *ngTemplateOutlet=\"sideNestedFilter; context: { col: col }\"\r\n ></ng-container>\r\n </div>\r\n </ng-container>\r\n</ng-template>\r\n\r\n<!-- Side Nested Filters -->\r\n<ng-template #sideNestedFilter let-col=\"col\">\r\n <div class=\"\">\r\n <!-- Dropdown Type -->\r\n <ng-container *ngIf=\"col.type === 'dropdown'; else textFilter\">\r\n <div class=\"p-1\">\r\n <!-- Search -->\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm mb-2\"\r\n placeholder=\"Search...\"\r\n [(ngModel)]=\"col.searchValue\"\r\n />\r\n\r\n <!-- Select All -->\r\n <div class=\"form-check mb-1 ms-1\">\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n [checked]=\"\r\n col.query?._ids?.length == col?.column_dropdown_value?.length\r\n \"\r\n (change)=\"toggleSelectAllSideFilters(col, $event)\"\r\n id=\"selectAll_{{ col.field }}\"\r\n />\r\n <label class=\"form-check-label\" for=\"selectAll_{{ col.field }}\">\r\n Select All\r\n </label>\r\n </div>\r\n\r\n <!-- Options -->\r\n <div class=\"dropdown-options\">\r\n <div\r\n class=\"form-check mb-1 ms-1\"\r\n *ngFor=\"\r\n let option of col?.column_dropdown_value\r\n | filter : addFilterDropdownSearch : 'header'\r\n \"\r\n >\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n [value]=\"option\"\r\n [checked]=\"\r\n col.query?._ids?.includes(option?._id || option?.id || option)\r\n \"\r\n (change)=\"onOptionToggle(col, option)\"\r\n id=\"option_{{ col.field }}_{{\r\n option?.id || option?._id || option\r\n }}\"\r\n />\r\n <label\r\n class=\"form-check-label\"\r\n [for]=\"\r\n 'option_' +\r\n col.field +\r\n '_' +\r\n (option?.id || option?._id || option)\r\n \"\r\n >\r\n {{ option.value || option }}\r\n </label>\r\n </div>\r\n </div>\r\n\r\n <!-- Actions -->\r\n <!-- <div class=\"d-flex gap-2 mt-2\">\r\n <div\r\n class=\"btn btn-sm btn-primary d-flex justify-content-center align-items-center\"\r\n style=\"height: 22px;\"\r\n (click)=\"applySideMenuFilters()\"\r\n >\r\n Apply\r\n </div>\r\n <div\r\n class=\"btn btn-sm btn-secondary d-flex justify-content-center align-items-center\"\r\n style=\"height: 22px;\"\r\n (click)=\"resetSideMenuFilters()\"\r\n >\r\n Reset\r\n </div>\r\n </div> -->\r\n </div>\r\n </ng-container>\r\n\r\n <!-- Text Filter Section -->\r\n <ng-template #textFilter>\r\n <div class=\"filter-text-section\">\r\n <div class=\"form-group mb-2\">\r\n <select\r\n class=\"form-select form-select-sm\"\r\n [ngModel]=\"col!.query!.first_condition || (col.type === 'date' || col.type === 'time' ? 'equal' : 'contain')\"\r\n (ngModelChange)=\"col!.query!.first_condition = $event\"\r\n >\r\n <ng-container *ngIf=\"col.type === 'date' || col.type === 'time'; else textOptions\">\r\n <option value=\"equal\">Equal 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-template #textOptions>\r\n <option value=\"contain\">Contains</option>\r\n <option value=\"equal\">Equals</option>\r\n <option value=\"before\">Begins With</option>\r\n <option value=\"after\">Ends With</option>\r\n </ng-template>\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 [min]=\"col.type == 'number' ? 0 : null\"\r\n (input)=\"col.type == 'number' && $any($event.target).value < 0 ? $any($event.target).value = 0 : null\"\r\n (keydown)=\"col.type == 'number' && $event.key === '-' ? $event.preventDefault() : null\"\r\n [class.number-input]=\"col.type == 'number'\"\r\n />\r\n\r\n <ng-container *ngIf=\"col?.query?.first_value && col?.query?.condition !== 'none'\">\r\n <div class=\"form-group mb-2\">\r\n <div class=\"form-check form-check-inline\">\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\" for=\"and_{{ col.field }}\"\r\n >AND</label\r\n >\r\n </div>\r\n <div class=\"form-check form-check-inline\">\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\" for=\"or_{{ col.field }}\"\r\n >OR</label\r\n >\r\n </div>\r\n <div class=\"form-check form-check-inline\">\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 class=\"form-check-label\" for=\"none_{{ col.field }}\"\r\n >None</label\r\n >\r\n </div>\r\n </div>\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 || (col.type === 'date' || col.type === 'time' ? 'equal' : 'contain')\"\r\n (ngModelChange)=\"col!.query.second_condition = $event\"\r\n >\r\n <ng-container *ngIf=\"col.type === 'date' || col.type === 'time'; else textOptionsSecond\">\r\n <option value=\"equal\">Equal 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-template #textOptionsSecond>\r\n <option value=\"contain\">Contains</option>\r\n <option value=\"equal\">Equals</option>\r\n <option value=\"before\">Begins With</option>\r\n <option value=\"after\">Ends With</option>\r\n </ng-template>\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-2\"\r\n placeholder=\"Second Value\"\r\n [(ngModel)]=\"col!.query.second_value\"\r\n [min]=\"col.type == 'number' ? 0 : null\"\r\n (input)=\"col.type == 'number' && $any($event.target).value < 0 ? $any($event.target).value = 0 : null\"\r\n (keydown)=\"col.type == 'number' && $event.key === '-' ? $event.preventDefault() : null\"\r\n [class.number-input]=\"col.type == 'number'\"\r\n />\r\n </ng-container>\r\n\r\n <!-- Apply and Reset Buttons -->\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: 22px\"\r\n (click)=\"applyFilterFromFilterRow(col)\"\r\n >\r\n Apply\r\n </div>\r\n <div\r\n class=\"btn btn-sm btn-secondary d-flex justify-content-center align-items-center w-100\"\r\n style=\"height: 22px\"\r\n (click)=\"resetSideFilter(col)\"\r\n >\r\n Reset\r\n </div>\r\n </div>\r\n </div>\r\n </ng-template>\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\" (click)=\"closeModalColumnPanel()\">\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\">\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 [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 [class.border-right]=\"showVerticalBorder\"\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 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 />\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 rounded-3 bg-white 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>\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 rounded-3 bg-white 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 btn btn-link\"\r\n type=\"button\"\r\n id=\"savePresetDropdown\"\r\n (click)=\"$event.stopPropagation(); toggleSubActions('save-preset')\"\r\n >\r\n Save 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 class=\"\" (click)=\"selectDefault()\">\r\n <div class=\"fw-semibold\">Default View\r\n <span\r\n *ngIf=\"tableFilterViewId === 'default'\"\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/check-blue.svg'\"\r\n class=\"me-2\"\r\n ></span>\r\n </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 === 'default'\"\r\n class=\"badge bg-light text-primary ms-2\"\r\n >Default</span\r\n >\r\n <div\r\n class=\"dropdown d-flex justify-content-end\"\r\n *ngIf=\"tableFilterViewId\"\r\n >\r\n <a\r\n href=\"javascript:void(0)\"\r\n class=\"muted-text\"\r\n data-bs-toggle=\"dropdown\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/horizontal-dots.svg'\r\n \"\r\n class=\"me-2\"\r\n ></span>\r\n </a>\r\n <ul class=\"dropdown-menu dropdown-menu-end\">\r\n <a\r\n (click)=\"actionPreset({ id: 'default' }, 'setPreset')\"\r\n class=\"dropdown-item d-flex align-items-center\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/star.svg'\"\r\n class=\"me-2\"\r\n ></span>\r\n Set as default\r\n </a>\r\n </ul>\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=\"let table of filteredList; trackBy: trackByTable\"\r\n >\r\n <!-- Item -->\r\n <div\r\n class=\"list-group-item px-0 d-flex justify-content-between align-items-center\"\r\n >\r\n <div (click)=\"selectFilter(table)\">\r\n <div class=\"fw-semibold\" style=\"cursor: pointer;\">\r\n {{ table?.name }}\r\n <!-- {{table?.is_temp}} -->\r\n <span\r\n *ngIf=\"table?.is_temp\"\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_deafult\"\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\"\r\n >Created {{ table?.createdAt | timezoneFormat:prefs:'date' }}</small\r\n >\r\n </div>\r\n\r\n <div class=\"d-flex align-items-center\">\r\n <span\r\n *ngIf=\"table?.is_deafult\"\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_deafult\">\r\n <a\r\n href=\"javascript:void(0)\"\r\n class=\"muted-text\"\r\n data-bs-toggle=\"dropdown\"\r\n id=\"dropdownMenuButton2\" data-toggle=\"dropdown\" aria-haspopup=\"true\" aria-expanded=\"false\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/horizontal-dots.svg'\r\n \"\r\n class=\"me-2\"\r\n ></span>\r\n </a>\r\n <ul class=\"dropdown-menu dropdown-menu-end set-default-preset\" aria-labelledby=\"dropdownMenuButton2\">\r\n <a\r\n [class.d-none]=\"confirmDelete\"\r\n (click)=\"actionPreset(table, 'setPreset')\"\r\n class=\"dropdown-item d-flex align-items-center\"\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 </a>\r\n\r\n <!-- Delete with confirmation -->\r\n <ng-container *ngIf=\"!confirmDelete; else confirmBlock\">\r\n <a\r\n (click)=\"confirmDelete = true\"\r\n class=\"dropdown-item d-flex align-items-center text-danger\"\r\n >\r\n <span\r\n style=\"margin-top: -4px\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/trash-red.svg'\r\n \"\r\n class=\"me-2\"\r\n ></span>\r\n Delete\r\n </a>\r\n </ng-container>\r\n\r\n <!-- Confirmation block -->\r\n </ul>\r\n <ng-template #confirmBlock>\r\n <div class=\"dropdown-item\"><b>Delete preset</b></div>\r\n <div class=\"dropdown-item text-center\">\r\n <div class=\"mb-2\">\r\n Are you sure you want to delete the <br />\r\n <b>\u201C{{ table?.name }}\u201D</b> preset?\r\n </div>\r\n <button\r\n class=\"btn btn-sm btn-light me-2\"\r\n (click)=\"confirmDelete = false\"\r\n >\r\n Cancel\r\n </button>\r\n <button\r\n class=\"btn btn-sm btn-danger delete-preset\"\r\n (click)=\"actionPreset(table, 'deletePreset')\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/trash-red.svg'\r\n \"\r\n class=\"confirm-preset-delete\"\r\n ></span>\r\n Delete\r\n </button>\r\n </div>\r\n </ng-template>\r\n </div>\r\n </div>\r\n </div>\r\n <!-- Item End Here -->\r\n </div>\r\n\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\">Save preset</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\">\r\n <ng-container *ngIf=\"!closeDropdown.preset.loading && (!tableFilterViewId || tableFilterViewId === 'default')\"\r\n >Save</ng-container\r\n >\r\n <ng-container *ngIf=\"!closeDropdown.preset.loading && tableFilterViewId && tableFilterViewId !== 'default'\"\r\n >Update</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 </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 rounded-3 bg-white 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\"\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=\"\r\n max-height: calc(100vh - 300px);\r\n overflow: auto;\r\n scrollbar-width: thin;\r\n \"\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 type=\"checkbox\"\r\n id=\"show_hide_all\"\r\n class=\"form-check-input\"\r\n [checked]=\"areAllNonMandatoryVisible()\"\r\n (change)=\"toggleAllVisibleColumns()\"\r\n />\r\n <label for=\"show_hide_all\" class=\"form-check-label fw-semibold\">Show/Hide All</label>\r\n </div>\r\n </div>\r\n <!-- <div class=\"d-flex align-items-center mb-2\" *ngIf=\"hasAnyVisibleColumn\">\r\n <input\r\n type=\"checkbox\"\r\n class=\"form-check-input me-2\"\r\n [checked]=\"areAllNonMandatoryVisible()\"\r\n (change)=\"toggleAllVisibleColumns()\"\r\n />\r\n <label class=\"form-check-label fw-semibold\">Show All</label>\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 && !isMandatory(col)\"\r\n class=\"d-flex align-items-center cursor-pointer\"\r\n (click)=\"toggleColumnVisibility(col, false)\"\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 && isMandatory(col)) || (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\"\r\n *ngIf=\"hasAnyInVisibleColumn\"\r\n >\r\n Hide in table\r\n </div>\r\n <div class=\"d-flex align-items-center mb-2\" *ngIf=\"hasAnyInVisibleColumn\">\r\n <input\r\n type=\"checkbox\"\r\n id=\"hide_show_all\"\r\n class=\"form-check-input me-2\"\r\n [checked]=\"areAllNonMandatoryHidden()\"\r\n (change)=\"toggleAllInvisibleColumns()\"\r\n />\r\n <label class=\"form-check-label fw-semibold\">Hide All</label>\r\n </div> -->\r\n\r\n \r\n\r\n\r\n\r\n <div class=\"muted-text show-hide-table-label d-flex justify-content-between\" *ngIf=\"hasAnyInVisibleColumn\">\r\n Hide in table\r\n <div class=\"form-check\">\r\n <input\r\n type=\"checkbox\"\r\n id=\"hide_show_all\"\r\n class=\"form-check-input\"\r\n [checked]=\"areAllNonMandatoryHidden()\"\r\n (change)=\"toggleAllInvisibleColumns()\"\r\n />\r\n <label for=\"hide_show_all\" class=\"form-check-label fw-semibold\">Hide/Show All</label>\r\n </div>\r\n </div>\r\n <div class=\"list-group list-group-flush\">\r\n <ng-container *ngFor=\"let col of columns; trackBy: trackByField\">\r\n <div\r\n *ngIf=\"!col.is_visible\"\r\n class=\"list-group-item border-0 px-0 d-flex justify-content-between align-items-center\"\r\n >\r\n <div class=\"d-flex gap-1\">\r\n <div>\r\n <span\r\n *ngIf=\"!col?.pinned\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/grip-vertical.svg'\r\n \"\r\n class=\"data-grid-svg-icon cursor-grap\"\r\n (mousedown)=\"$event.preventDefault()\"\r\n ></span>\r\n <span\r\n *ngIf=\"col?.pinned\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/pin-blue.svg'\r\n \"\r\n class=\"data-grid-svg-icon cursor-grap\"\r\n (mousedown)=\"$event.preventDefault()\"\r\n ></span>\r\n </div>\r\n <div class=\"fw-semibold\">\r\n {{ col.header }}\r\n </div>\r\n </div>\r\n <div\r\n class=\"d-flex align-items-center cursor-pointer\"\r\n (click)=\"toggleColumnVisibility(col, true)\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/eye-cross.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n </div>\r\n </div>\r\n </ng-container>\r\n </div>\r\n\r\n <!-- Item End Here -->\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template #filterColumns let-col=\"column\">\r\n <div\r\n @slideToggle\r\n *ngIf=\"!isFilterOpen && activeTopButton == 'filter-columns'\"\r\n (click)=\"$event.stopPropagation()\"\r\n class=\"shadow rounded-3 bg-white actions-dropdown mt-1 show shadow custom-menu table-layout filter-columns\"\r\n style=\"width: 280px; right: unset; max-width: 230px\"\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\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'\"\r\n (click)=\"$event.stopPropagation()\"\r\n class=\"shadow rounded-3 bg-white actions-dropdown mt-1 show shadow custom-menu table-layout filter-columns\"\r\n style=\"width: 280px; right: unset; max-width: 230px\"\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\"\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 (ngModelChange)=\"selectedFilterOptions.length === 0 ? condition = 'none' : null\"\r\n />\r\n </div>\r\n </div>\r\n <div\r\n class=\"list-group list-group-flush\"\r\n style=\"max-height: calc(100vh - 600px); overflow: auto\"\r\n >\r\n <ng-container\r\n *ngFor=\"\r\n let col of selectedColumnForFilter.column_dropdown_value\r\n | filter : searchTextForFilterDropDown : 'value';\r\n let i = index\r\n \"\r\n >\r\n <div\r\n class=\"list-group-item border-0 px-2 d-flex justify-content-between align-items-center dropdown-item cursor-pointer\"\r\n >\r\n <div class=\"form-check\">\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n [id]=\"i\"\r\n [checked]=\"currentFilterSelectedIds.has(col.id || col._id || col)\"\r\n (change)=\"toggleSelectionInFilter(col)\"\r\n />\r\n <label class=\"form-check-label fw-semibold\" [for]=\"i\">\r\n {{ col?.value || col?.name || col }}\r\n </label>\r\n </div>\r\n </div>\r\n </ng-container>\r\n </div>\r\n <div\r\n class=\"d-flex justify-content-center gap-2 px-2 border-top\"\r\n style=\"height: 38px\"\r\n >\r\n <button\r\n type=\"button\"\r\n style=\"height: 32px\"\r\n class=\"btn btn-outline-secondary btn-light border w-100 d-flex align-items-center justify-content-center mt-1 btn-light\"\r\n (click)=\"$event.stopPropagation(); resetFilterChanges()\"\r\n >\r\n <span>Cancel</span>\r\n </button>\r\n <button\r\n type=\"button\"\r\n style=\"height: 32px\"\r\n class=\"btn btn-primary w-100 d-flex align-items-center justify-content-center mt-1\"\r\n (click)=\"applyDropdownFilter()\"\r\n >\r\n <span style=\"margin-top: -2px\">Save</span>\r\n </button>\r\n </div>\r\n </div>\r\n\r\n <!-- For Text fields and number fields-->\r\n\r\n <div\r\n @slideToggle\r\n *ngIf=\"\r\n isFilterOpen &&\r\n (selectedColumnForFilter.type == 'string' ||\r\n selectedColumnForFilter.type == 'number' ||\r\n selectedColumnForFilter.type == 'date')\r\n \"\r\n (click)=\"$event.stopPropagation()\"\r\n class=\"shadow rounded-3 bg-white actions-dropdown mt-1 show shadow custom-menu table-layout filter-columns\"\r\n style=\"width: 280px; right: unset; max-width: 230px\"\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\"\r\n [(ngModel)]=\"firstCondition\"\r\n >\r\n <ng-container *ngIf=\"selectedColumnForFilter.type === 'date' || selectedColumnForFilter.type === 'time'; else textOptions\">\r\n <option value=\"equal\">Equal 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-template #textOptions>\r\n <option value=\"equal\">Equals</option>\r\n <!-- <option value=\"not_equal\">Not Equals</option> -->\r\n <option value=\"contain\">Contains</option>\r\n <option value=\"before\">Begins With</option>\r\n <option value=\"after\">Ends With</option>\r\n </ng-template>\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]=\"\r\n selectedColumnForFilter.type == 'string'\r\n ? 'text'\r\n : selectedColumnForFilter.type\r\n \"\r\n [(ngModel)]=\"firstValue\"\r\n [min]=\"selectedColumnForFilter.type == 'number' ? 0 : null\"\r\n [class.number-input]=\"selectedColumnForFilter.type == 'number'\"\r\n (input)=\"selectedColumnForFilter.type == 'number' && $any($event.target).value < 0 ? $any($event.target).value = 0 : null\"\r\n (ngModelChange)=\"!firstValue ? condition = 'none' : null\"\r\n (keydown)=\"selectedColumnForFilter.type == 'number' && $event.key === '-' ? $event.preventDefault() : null\"\r\n />\r\n </div>\r\n <div class=\"d-flex my-3\">\r\n <div class=\"form-check form-check-inline\">\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\" for=\"logicalAnd\">AND</label>\r\n </div>\r\n\r\n <div class=\"form-check form-check-inline\">\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\" for=\"logicalOr\">OR</label>\r\n </div>\r\n\r\n <div class=\"form-check form-check-inline\">\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\" for=\"logicalNone\">None</label>\r\n </div>\r\n </div>\r\n\r\n <div *ngIf=\"firstValue && condition !== 'none'\">\r\n <div class=\"my-3\">\r\n <!-- Second condition select -->\r\n <select\r\n class=\"form-select form-select-sm\"\r\n [(ngModel)]=\"secondCondition\"\r\n >\r\n <ng-container *ngIf=\"selectedColumnForFilter.type === 'date' || selectedColumnForFilter.type === 'time'; else textOptionsSecond\">\r\n <option value=\"equal\">Equal 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-template #textOptionsSecond>\r\n <option value=\"equal\">Equals</option>\r\n <!-- <option value=\"not_equal\">Not Equals</option> -->\r\n <option value=\"contain\">Contains</option>\r\n <option value=\"before\">Begins With</option>\r\n <option value=\"after\">Ends With</option>\r\n </ng-template>\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 [(ngModel)]=\"secondValue\"\r\n [min]=\"selectedColumnForFilter.type == 'number' ? 0 : null\"\r\n [class.number-input]=\"selectedColumnForFilter.type == 'number'\"\r\n (input)=\"selectedColumnForFilter.type == 'number' && $any($event.target).value < 0 ? $any($event.target).value = 0 : null\"\r\n (keydown)=\"selectedColumnForFilter.type == 'number' && $event.key === '-' ? $event.preventDefault() : null\"\r\n />\r\n </div>\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 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 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</ng-template>\r\n\r\n<!-- Detail Filter Menu -->\r\n <div\r\n *ngIf=\"activeAccordionFilterMenu && detailFilterMenuPosition\"\r\n class=\"position-absolute shadow rounded-3 bg-white detail-filter-menu\"\r\n [style.left.px]=\"detailFilterMenuPosition.x\"\r\n [style.top.px]=\"detailFilterMenuPosition.y\"\r\n (click)=\"$event.stopPropagation()\"\r\n >\r\n <div class=\"px-3 border-below py-1 pb-2 d-flex ps-1\">\r\n <span\r\n (click)=\"closeDetailFilterMenu()\"\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>{{ activeDetailFilterCol?.header }}</b>\r\n </div>\r\n\r\n <!-- Text Filter -->\r\n <div *ngIf=\"detailFilterType === 'string'\" 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\"\r\n [(ngModel)]=\"detailFilterCondition\"\r\n >\r\n <option value=\"contain\">Contains</option>\r\n <option value=\"equal\">Equals</option>\r\n <option value=\"before\">Begins With</option>\r\n <option value=\"after\">Ends With</option>\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 value\"\r\n [(ngModel)]=\"detailFilterValue\"\r\n (keydown.enter)=\"applyDetailFilter()\"\r\n />\r\n </div>\r\n </div>\r\n\r\n <!-- Date Filter -->\r\n <div *ngIf=\"detailFilterType === 'date'\" 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\"\r\n [(ngModel)]=\"detailFilterCondition\"\r\n >\r\n <option value=\"equal\">Equal to</option>\r\n <option value=\"before\">Before</option>\r\n <option value=\"after\">After</option>\r\n </select>\r\n </div>\r\n <div class=\"mb-2\">\r\n <input\r\n type=\"date\"\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Select date\"\r\n [(ngModel)]=\"detailFilterDateValue\"\r\n (keydown.enter)=\"applyDetailFilter()\"\r\n />\r\n </div>\r\n </div>\r\n\r\n <!-- Time Filter -->\r\n <div *ngIf=\"detailFilterType === 'time'\" 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\"\r\n [(ngModel)]=\"detailFilterCondition\"\r\n >\r\n <option value=\"equal\">Equal to</option>\r\n <option value=\"before\">Before</option>\r\n <option value=\"after\">After</option>\r\n </select>\r\n </div>\r\n <div class=\"mb-2\">\r\n <input\r\n type=\"time\"\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Select time\"\r\n [(ngModel)]=\"detailFilterTimeValue\"\r\n (keydown.enter)=\"applyDetailFilter()\"\r\n />\r\n </div>\r\n </div>\r\n\r\n <!-- Dropdown Filter -->\r\n <div *ngIf=\"detailFilterType === 'dropdown'\" class=\"col-12 position-relative p-2 text-filter\">\r\n <div class=\"mb-2\">\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Search options...\"\r\n [(ngModel)]=\"detailFilterSearch\"\r\n (input)=\"filterDetailDropdownOptions()\"\r\n />\r\n </div>\r\n <div class=\"dropdown-options\" style=\"max-height: 150px; overflow-y: auto;\">\r\n <div\r\n *ngFor=\"let option of filteredDetailDropdownOptions; let i = index\"\r\n class=\"form-check mb-1 ms-1\"\r\n >\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n [id]=\"'detail-filter-option-' + i\"\r\n [checked]=\"detailSelectedFilterOptions.includes(option._id || option.id || option.value)\"\r\n (change)=\"toggleDetailFilterOption(option)\"\r\n />\r\n <label\r\n class=\"form-check-label\"\r\n [for]=\"'detail-filter-option-' + i\"\r\n >\r\n {{ option.value || option.name || option }}\r\n </label>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- <div class=\"d-flex gap-2\">\r\n <button\r\n type=\"button\"\r\n class=\"btn btn-primary w-100 d-flex align-items-center justify-content-center mt-1\"\r\n (click)=\"applyDetailFilter()\"\r\n >\r\n <span>Apply</span>\r\n </button>\r\n <button\r\n type=\"button\"\r\n class=\"btn btn-danger w-100 d-flex align-items-center justify-content-center mt-1\"\r\n (click)=\"resetDetailFilter()\"\r\n >\r\n <span>Reset</span>\r\n </button>\r\n \r\n</div> -->\r\n\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: 22px\"\r\n (click)=\"applyDetailFilter()\"\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: 22px\"\r\n (click)=\"resetDetailFilter()\"\r\n >\r\n Reset\r\n </div>\r\n </div>\r\n</div>\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 >\r\n <ng-container *ngIf=\"!isEditing(row, col)\">\r\n <div\r\n *ngIf=\"!isArray\"\r\n class=\"full-text-content\"\r\n (dblclick)=\"$event.stopPropagation(); $event.preventDefault(); enableEdit(row, col)\"\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 {{ item?.department_name || item?.roleName || \"-\" }}\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 #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\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 align-items-center w-100 cell-content image-placeholder cursor-pointer position-relative\"\r\n [title]=\"getEmployeeNameTitle(row)\"\r\n (click)=\"onEmployeeClick(row)\"\r\n >\r\n <!-- Blue dot for manual logs -->\r\n <span\r\n *ngIf=\"row?.manually_logs && row.manually_logs.length > 0\"\r\n class=\"manual-logs-indicator\"\r\n (mouseenter)=\"openManualLogsModal($event, row)\"\r\n (mouseleave)=\"closeManualLogsModal()\"\r\n ></span>\r\n <ng-container\r\n *ngIf=\"\r\n row?.User?.logo || row?.User?.profile_pictures?.length || row?.logo || row?.profile_pictures?.length || row?.assetImage || row?.invoice?.invoice_image;\r\n else placeholder\r\n \"\r\n >\r\n <span class=\"pic\">\r\n <img\r\n [width]=\"rowHeight - 12\"\r\n [height]=\"rowHeight - 12\"\r\n [src]=\"row?.User?.profile_pictures?.[4]?.path || row?.User?.logo || row?.profile_pictures?.[4]?.path || row?.logo || row?.assetImage || row?.invoice?.invoice_image\"\r\n alt=\"icon\"\r\n />\r\n </span>\r\n </ng-container>\r\n\r\n <ng-template #placeholder>\r\n <span\r\n [ngClass]=\"getDynamicClass(row?.User?.full_name || 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 >\r\n {{ getInitials(row?.User?.full_name || row?.full_name) }}\r\n </span>\r\n </ng-template>\r\n </span>\r\n</ng-template>\r\n\r\n<!-- Cell Content Template for Card View -->\r\n<ng-template #cellContent let-row=\"row\" let-parentRow=\"parentRow\" let-col=\"col\">\r\n <ng-container [ngSwitch]=\"col.type\">\r\n <!-- String/Text -->\r\n <ng-container *ngSwitchCase=\"'string'\">\r\n {{ getNestedValue(row, col.field) || getNestedValue(parentRow, col.field) || '-' }}\r\n </ng-container>\r\n\r\n <!-- Number -->\r\n <ng-container *ngSwitchCase=\"'number'\">\r\n {{ getNestedValue(row, col.field) || getNestedValue(parentRow, col.field) || '-' }}\r\n </ng-container>\r\n\r\n <!-- Date -->\r\n <ng-container *ngSwitchCase=\"'date'\">\r\n {{ getNestedValue(row, col.field) || getNestedValue(parentRow, col.field) ? (getNestedValue(row, col.field) || getNestedValue(parentRow, col.field) | timezoneFormat:prefs:'date') : '-' }}\r\n </ng-container>\r\n\r\n <!-- Time -->\r\n <ng-container *ngSwitchCase=\"'time'\">\r\n {{ (getNestedValue(row, col.field) || getNestedValue(parentRow, col.field)) !== null && (getNestedValue(row, col.field) || getNestedValue(parentRow, col.field)) !== undefined ? ((getTimeValue(getNestedValue(row, col.field) || getNestedValue(parentRow, col.field)) | timezoneFormat:prefs:'time')) : '-' }}\r\n </ng-container>\r\n\r\n <!-- Boolean -->\r\n <ng-container *ngSwitchCase=\"'boolean'\">\r\n <span class=\"badge\" [class]=\"(getNestedValue(row, col.field) || getNestedValue(parentRow, col.field) === true || getNestedValue(row, col.field) || getNestedValue(parentRow, col.field) === 'true') ? 'badge-success' : 'badge-secondary'\">\r\n {{ (getNestedValue(row, col.field) || getNestedValue(parentRow, col.field) === true || getNestedValue(row, col.field) || getNestedValue(parentRow, col.field) === 'true') ? 'Yes' : 'No' }}\r\n </span>\r\n </ng-container>\r\n\r\n <!-- <div *ngSwitchCase=\"'is_payroll_processed'\" class=\"d-flex justify-content-start flex-column pointer position-relative\" >\r\n <span class=\"popover__wrapper\" >none\r\n {{ row.is_payroll_processed ? 'Yes' : 'No' }}\r\n </span>\r\n </div> -->\r\n\r\n <!-- Status -->\r\n <ng-container *ngSwitchCase=\"'status'\">\r\n <span class=\"badge\" [class]=\"getStatusBadgeClass(getNestedValue(row, col.field) || getNestedValue(parentRow, col.field))\">\r\n {{ transformStatus(getNestedValue(row, col.field) || getNestedValue(parentRow, col.field)) || '-' }}\r\n </span>\r\n </ng-container>\r\n\r\n <!-- Array -->\r\n <ng-container *ngSwitchCase=\"'array'\">\r\n <ng-container *ngIf=\"isArray(getNestedValue(row, col.field) || getNestedValue(parentRow, col.field))\">\r\n <ng-container *ngIf=\"col.field === 'breaks' || col.header?.toLowerCase().includes('break')\">\r\n <app-badge-overflow\r\n [badges]=\"getBreakBadges(getNestedValue(row, col.field) || getNestedValue(parentRow, col.field) || [])\"\r\n [maxWidth]=\"col.width || 200\"\r\n (badgeMouseEnter)=\"showBreakTooltip($event.event, $event.badge.data)\"\r\n (badgeMouseLeave)=\"hideBreakTooltip()\"\r\n (overflowCountClick)=\"onBadgeOverflowCountClick(col)\">\r\n </app-badge-overflow>\r\n </ng-container>\r\n <ng-container *ngIf=\"!(col.field === 'breaks' || col.header?.toLowerCase().includes('break'))\">\r\n {{ (getNestedValue(row, col.field) || getNestedValue(parentRow, col.field) || []).length }} items\r\n </ng-container>\r\n </ng-container>\r\n <ng-container *ngIf=\"!isArray(getNestedValue(row, col.field) || getNestedValue(parentRow, col.field))\">\r\n {{ getNestedValue(row, col.field) || getNestedValue(parentRow, col.field) || '-' }}\r\n </ng-container>\r\n </ng-container>\r\n\r\n <!-- Default -->\r\n <ng-container *ngSwitchDefault>\r\n {{ getNestedValue(row, col.field) || getNestedValue(parentRow, col.field) || '-' }}\r\n </ng-container>\r\n \r\n </ng-container>\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 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<div\r\n [style.bottom.px]=\"footerRowHeight + 50\"\r\n *ngIf=\"selectedRows.size > 0 && showTaskbar\"\r\n class=\"taskbar\"\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 {{ config?.paginationParams?.totalItems }} Total\r\n </span>\r\n <div class=\"action-buttons\">\r\n <ng-container *ngFor=\"let action of taskbarActions; let i = index\">\r\n <span\r\n class=\"action-btn verified btn {{ action }}\"\r\n (click)=\"action === 'Export' ? onExportClick() : action === 'Delete' ? onDeleteClick() : onVerifyClick(action)\"\r\n >{{ action }}</span\r\n >\r\n <span\r\n *ngIf=\"taskbarActions.length > 1 && i !== taskbarActions.length - 1\"\r\n class=\"separator\"\r\n >|</span\r\n >\r\n </ng-container>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<!-- Detail Row Choose Columns Modal -->\r\n<div *ngIf=\"showDetailColumnPanel\" 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=\"detailModalColumnPannel\"></ng-container>\r\n </div>\r\n</div>\r\n\r\n<!-- Short Leave Tooltip Modal -->\r\n<div *ngIf=\"showShortLeaveTooltipModal\" \r\n class=\"custom-break-tooltips\" \r\n [style.--tooltip-x.px]=\"shortLeaveTooltipPosition.x\" \r\n [style.--tooltip-y.px]=\"shortLeaveTooltipPosition.y\"\r\n (mouseenter)=\"preventShortLeaveTooltipHide()\" \r\n (mouseleave)=\"hideShortLeaveTooltip()\">\r\n <div class=\"modal-body\">\r\n <div class=\"table-responsive\">\r\n <table class=\"table table-striped text-dark\">\r\n <thead>\r\n <tr>\r\n <th>Leave Type</th>\r\n <th>Start Time</th>\r\n <th>End Time</th>\r\n <th>Duration (min)</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <tr *ngFor=\"let item of currentShortLeaveData\">\r\n <td>{{ item.leave_type || 'N/A' }}</td>\r\n <td>{{ item.star_time || 'N/A' }}</td>\r\n <td>{{ item.end_time || 'N/A' }}</td>\r\n <td>{{ item.minutes || 'N/A' }}</td>\r\n </tr>\r\n </tbody>\r\n </table>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<!-- Tooltip for accordion manual logs -->\r\n<!-- Tooltip for accordion manual logs -->\r\n<div *ngIf=\"showManualLogsTooltipModal\" class=\"custom-break-tooltips\"\r\n [style.--tooltip-x.px]=\"manualLogsTooltipPosition.x\"\r\n [style.--tooltip-y.px]=\"manualLogsTooltipPosition.y\"\r\n (mouseenter)=\"preventManualLogsTooltipHide()\"\r\n (mouseleave)=\"hideManualLogsTooltip()\">\r\n\r\n <div class=\"modal-body\">\r\n <div class=\"table-responsive\">\r\n <table class=\"table table-striped text-dark\">\r\n <thead>\r\n <tr>\r\n <th>Name</th>\r\n <th>Date/Time</th>\r\n <th>Previous</th>\r\n <th>Updated</th>\r\n <th>Status</th>\r\n <th>Remarks</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <ng-container *ngFor=\"let item of selectedManualLogs; let i = index\">\r\n <tr>\r\n <td>{{ item?.updated_by?.full_name || selectedManualLogsRow?.User?.full_name }}</td>\r\n <td>{{ item?.log_date && item.log_date !== '--' ? (item.log_date | timezoneFormat:prefs:'date') : (selectedManualLogsRow?.attendanceDate && selectedManualLogsRow?.attendanceDate !== '--' ? (selectedManualLogsRow?.attendanceDate | timezoneFormat:prefs:'date') : '-') }}</td>\r\n <td>{{ formatLogState(item?.log_details?.previous_state) }}</td>\r\n <td>{{ formatLogState(item?.log_details?.updated_state) }}</td>\r\n <td>{{ item?.log_details?.status ? transformStatus(item.log_details.status) : (item.log_details?.status || '-') }}</td>\r\n <td>{{ item?.log_details?.remarks || item?.remarks || selectedManualLogsRow?.message || '-' }}</td>\r\n </tr>\r\n </ng-container>\r\n\r\n <!-- Fallback for empty manual logs -->\r\n <tr *ngIf=\"!selectedManualLogs || selectedManualLogs.length === 0\">\r\n <td colspan=\"6\" class=\"text-center\">No manual logs available</td>\r\n </tr>\r\n </tbody>\r\n </table>\r\n </div>\r\n </div>\r\n </div>\r\n<!-- </div> -->\r\n\r\n<ng-template #detailModalColumnPannel>\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 Detail Columns\r\n <span class=\"filter-icon-wrapper\" (click)=\"closeDetailColumnPanel()\">\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 <input\r\n type=\"checkbox\"\r\n class=\"form-check-input me-2\"\r\n [checked]=\"allDetailColumnsSelected()\"\r\n (change)=\"toggleAllDetailColumnsVisibility()\"\r\n />\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Search detail columns...\"\r\n [(ngModel)]=\"choseColumnsSearch\"\r\n />\r\n </div>\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 (currentDetailRowForColumnSelection?.details?.columns || [])\r\n | filter : choseColumnsSearch : 'header';\r\n trackBy: trackByField\r\n \"\r\n >\r\n <div class=\"d-flex align-items-center mb-2\">\r\n <input\r\n type=\"checkbox\"\r\n class=\"form-check-input me-2\"\r\n [checked]=\"col.is_visible !== false\"\r\n (change)=\"toggleDetailColumnVisibility(col, !col.is_visible)\"\r\n [id]=\"'detail_col_' + col.field\"\r\n />\r\n <label\r\n class=\"d-flex align-items-center mb-0 w-100\"\r\n [for]=\"'detail_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 </div>\r\n </div>\r\n <!-- <div class=\"px-3 py-2 border-top d-flex justify-content-end\">\r\n <button class=\"btn btn-sm btn-link\" (click)=\"resetDetailColumnsInModal()\">Reset</button>\r\n </div> -->\r\n </div>\r\n</ng-template>\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n", styles: ["@charset \"UTF-8\";@keyframes fadeInUp{0%{opacity:0;transform:translateY(8px)}to{opacity:1;transform:translateY(0)}}@keyframes fadeInScale{0%{opacity:0;transform:scale(.95)}to{opacity:1;transform:scale(1)}}@keyframes slideInRight{0%{opacity:0;transform:translate(16px)}to{opacity:1;transform:translate(0)}}@keyframes pulse{0%{transform:scale(1)}50%{transform:scale(1.02)}to{transform:scale(1)}}@keyframes shimmer{0%{background-position:-200px 0}to{background-position:calc(200px + 100%) 0}}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.loading-overlay{animation:fadeInScale .25s cubic-bezier(.4,0,.2,1);transform:translateZ(0)}.loading-overlay .spinner-border{animation:spin 1s linear infinite}.data-grid-table-wrapper{height:100%;width:100%;border:1px solid #d9d9db;border-radius:12px;box-shadow:none!important;position:relative;animation:fadeInScale .35s cubic-bezier(.4,0,.2,1);transform:translateZ(0)}.data-grid-table-wrapper[data-theme=white]{border-color:#d9d9db;background-color:#f6f8ff;color:#000}.data-grid-table-wrapper[data-theme=white] *,.data-grid-table-wrapper[data-theme=white] *:before,.data-grid-table-wrapper[data-theme=white] *:after{color:#000!important}.data-grid-table-wrapper[data-theme=white] ::selection{background-color:#007bff!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=white] ::-moz-selection{background-color:#007bff!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=white] .data-grid-header-wrapper{background-color:#f8f9fa;color:#000!important}.data-grid-table-wrapper[data-theme=white] .data-grid-body-wrapper{background-color:#f6f8ff;box-shadow:none!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .data-grid-row{border-bottom-color:#d9d9db;box-shadow:none!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .data-grid-row:nth-child(2n){background-color:#f8f9fa!important}.data-grid-table-wrapper[data-theme=white] .data-grid-row:nth-child(odd){background-color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=white] .data-grid-row:hover{background-color:#007bff1a!important}.data-grid-table-wrapper[data-theme=white] .selected-cell,.data-grid-table-wrapper[data-theme=white] .row-selected{background-color:#e3f2fd!important}.data-grid-table-wrapper[data-theme=white] .cell,.data-grid-table-wrapper[data-theme=white] .header-cell,.data-grid-table-wrapper[data-theme=white] .data-grid-row,.data-grid-table-wrapper[data-theme=white] .data-grid-header,.data-grid-table-wrapper[data-theme=white] .cell-content,.data-grid-table-wrapper[data-theme=white] .full-text-content,.data-grid-table-wrapper[data-theme=white] .circle-value,.data-grid-table-wrapper[data-theme=white] .pic,.data-grid-table-wrapper[data-theme=white] .image-placeholder,.data-grid-table-wrapper[data-theme=white] .s-no,.data-grid-table-wrapper[data-theme=white] .fw-500{color:#000!important}.data-grid-table-wrapper[data-theme=white] span,.data-grid-table-wrapper[data-theme=white] div,.data-grid-table-wrapper[data-theme=white] p,.data-grid-table-wrapper[data-theme=white] td,.data-grid-table-wrapper[data-theme=white] th,.data-grid-table-wrapper[data-theme=white] label,.data-grid-table-wrapper[data-theme=white] a:not(.text-primary){color:#000!important}.data-grid-table-wrapper[data-theme=white] svg,.data-grid-table-wrapper[data-theme=white] svg path,.data-grid-table-wrapper[data-theme=white] svg circle,.data-grid-table-wrapper[data-theme=white] svg rect,.data-grid-table-wrapper[data-theme=white] svg polygon{color:#000!important;fill:#000!important;stroke:#000!important}.data-grid-table-wrapper[data-theme=white] .data-grid-svg-icon{color:#000!important}.data-grid-table-wrapper[data-theme=white] .data-grid-svg-icon path{stroke:#000!important;fill:#000!important}.data-grid-table-wrapper[data-theme=white] .badge.badge-danger{background-color:#ea5353!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=white] .badge.badge-success{background-color:#84ca81!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=white] .badge.badge-warning{background-color:#fff3dc!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .badge.badge-info{background-color:#e8fbfd!important;color:#00bad1!important}.data-grid-table-wrapper[data-theme=white] .context-menu{background:#f6f8ff;border-color:#d9d9db;color:#000!important}.data-grid-table-wrapper[data-theme=white] .context-menu li{color:#000!important}.data-grid-table-wrapper[data-theme=white] .context-menu li:hover{background-color:#007bff1a!important}.data-grid-table-wrapper[data-theme=white] .custom-tooltip,.data-grid-table-wrapper[data-theme=white] .popover__content,.data-grid-table-wrapper[data-theme=white] .custom-break-tooltip{background:#f6f8ff!important;border-color:#d9d9db!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .actions-dropdown,.data-grid-table-wrapper[data-theme=white] .custom-menu{background-color:#f6f8ff!important;border-color:#d9d9db!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .actions-dropdown .dropdown-item,.data-grid-table-wrapper[data-theme=white] .custom-menu .dropdown-item{color:#000!important}.data-grid-table-wrapper[data-theme=white] .actions-dropdown .dropdown-item:hover,.data-grid-table-wrapper[data-theme=white] .custom-menu .dropdown-item:hover{background-color:#007bff1a!important}.data-grid-table-wrapper[data-theme=white] .taskbar .selected-rows-action-bar{background-color:#343a40!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=white] .taskbar .selected-rows-action-bar .action-btn{color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=white] .manual-logs-modal .modal-header{background:linear-gradient(135deg,#343a40,#495057)!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=white] .manual-logs-modal .modal-header .modal-title{color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=white] .manual-logs-modal .modal-body{background-color:#f6f8ff!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .manual-logs-modal .modal-body .table{color:#000!important}.data-grid-table-wrapper[data-theme=white] .manual-logs-modal .modal-body .table thead th{background:linear-gradient(135deg,#f8f9fa,#e9ecef)!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .manual-logs-modal .modal-body .table tbody tr{color:#000!important}.data-grid-table-wrapper[data-theme=white] .manual-logs-modal .modal-body .table tbody tr:nth-child(2n){background-color:#f8f9fa!important}.data-grid-table-wrapper[data-theme=white] .manual-logs-modal .modal-body .table tbody tr:hover{background-color:#007bff1a!important}.data-grid-table-wrapper[data-theme=white] .manual-logs-modal .modal-body .table tbody tr td{color:#000!important;border-color:#d9d9db!important}.data-grid-table-wrapper[data-theme=white] .form-control,.data-grid-table-wrapper[data-theme=white] .form-select{background-color:#f6f8ff!important;border-color:#d9d9db!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .form-control::placeholder,.data-grid-table-wrapper[data-theme=white] .form-select::placeholder{color:#6c757d!important}.data-grid-table-wrapper[data-theme=white] .form-control option,.data-grid-table-wrapper[data-theme=white] .form-select option{background-color:#f6f8ff!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .filter-serach-inpt{background-color:#f6f8ff!important;border-color:#d9d9db!important}.data-grid-table-wrapper[data-theme=white] .filter-serach-inpt input{background-color:#f6f8ff!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .active-filters{background-color:#f8f9fa!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .custom-modal-overlay .custom-modal-content{background-color:#f6f8ff!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .circle-value{background-color:#f8f9fa!important;border-color:#d9d9db!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .pagination-container,.data-grid-table-wrapper[data-theme=white] .page-size,.data-grid-table-wrapper[data-theme=white] .page-info,.data-grid-table-wrapper[data-theme=white] .page-buttons{color:#000!important}.data-grid-table-wrapper[data-theme=white] .pagination-container select,.data-grid-table-wrapper[data-theme=white] .pagination-container button,.data-grid-table-wrapper[data-theme=white] .pagination-container span,.data-grid-table-wrapper[data-theme=white] .page-size select,.data-grid-table-wrapper[data-theme=white] .page-size button,.data-grid-table-wrapper[data-theme=white] .page-size span,.data-grid-table-wrapper[data-theme=white] .page-info select,.data-grid-table-wrapper[data-theme=white] .page-info button,.data-grid-table-wrapper[data-theme=white] .page-info span,.data-grid-table-wrapper[data-theme=white] .page-buttons select,.data-grid-table-wrapper[data-theme=white] .page-buttons button,.data-grid-table-wrapper[data-theme=white] .page-buttons span{background-color:#f6f8ff!important;border-color:#d9d9db!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .pagination-container button.active,.data-grid-table-wrapper[data-theme=white] .page-size button.active,.data-grid-table-wrapper[data-theme=white] .page-info button.active,.data-grid-table-wrapper[data-theme=white] .page-buttons button.active{background-color:#e3f2fd!important}.data-grid-table-wrapper[data-theme=white] .footer-row{background-color:#f8f9fa!important;border-top-color:#d9d9db!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] ::-webkit-scrollbar{background-color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=white] ::-webkit-scrollbar-thumb{background-color:#d9d9db!important}.data-grid-table-wrapper[data-theme=white] ::-webkit-scrollbar-thumb:hover{background-color:#adb5bd!important}.data-grid-table-wrapper[data-theme=white] ::-webkit-scrollbar-track{background-color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker{background-color:#f6f8ff!important;color:#000!important;border-color:#d9d9db!important}.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker .bs-datepicker-head{background:linear-gradient(135deg,#343a40,#495057)!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker .bs-datepicker-body{background-color:#f6f8ff!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker table td,.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker table th{color:#000!important}.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker table td.is-other-month,.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker table th.is-other-month{color:#6c757d!important}.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker table td.active,.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker table th.active{background-color:#e3f2fd!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker table td span.in-range,.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker table th span.in-range{background-color:#e3f2fd!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker table td:hover:not(.active),.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker table th:hover:not(.active){background-color:#007bff1a!important}.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker .bs-datepicker-buttons{background-color:#f8f9fa!important;border-top-color:#d9d9db!important}.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker .bs-datepicker-buttons .btn-primary{background:linear-gradient(135deg,#007bff,#0056b3)!important;color:#f6f8ff!important;border-color:#007bff!important}.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker .bs-datepicker-buttons .btn-secondary{background-color:#f6f8ff!important;color:#000!important;border-color:#d9d9db!important}.data-grid-table-wrapper[data-theme=white] button,.data-grid-table-wrapper[data-theme=white] .btn,.data-grid-table-wrapper[data-theme=white] .button{background-color:#f6f8ff!important;border-color:#d9d9db!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] button:hover,.data-grid-table-wrapper[data-theme=white] .btn:hover,.data-grid-table-wrapper[data-theme=white] .button:hover{background-color:#007bff1a!important}.data-grid-table-wrapper[data-theme=white] button.btn-primary,.data-grid-table-wrapper[data-theme=white] .btn.btn-primary,.data-grid-table-wrapper[data-theme=white] .button.btn-primary{background-color:#007bff!important;border-color:#007bff!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=white] button.btn-outline-primary,.data-grid-table-wrapper[data-theme=white] .btn.btn-outline-primary,.data-grid-table-wrapper[data-theme=white] .button.btn-outline-primary{border-color:#007bff!important;color:#007bff!important;background-color:transparent!important}.data-grid-table-wrapper[data-theme=white] a:not(.text-primary){color:#007bff!important}.data-grid-table-wrapper[data-theme=white] a:not(.text-primary):hover{color:#0056b3!important}.data-grid-table-wrapper[data-theme=white] .text-primary{color:#007bff!important}.data-grid-table-wrapper[data-theme=white] .text-danger{color:#dc3545!important}.data-grid-table-wrapper[data-theme=white] .text-success{color:#28a745!important}.data-grid-table-wrapper[data-theme=white] .text-warning{color:#ffc107!important}.data-grid-table-wrapper[data-theme=white] .text-info{color:#17a2b8!important}.data-grid-table-wrapper[data-theme=white] .text-muted,.data-grid-table-wrapper[data-theme=white] .muted-text{color:#6c757d!important}.data-grid-table-wrapper[data-theme=white] .border,.data-grid-table-wrapper[data-theme=white] .border-top,.data-grid-table-wrapper[data-theme=white] .border-bottom,.data-grid-table-wrapper[data-theme=white] .border-left,.data-grid-table-wrapper[data-theme=white] .border-right,.data-grid-table-wrapper[data-theme=white] .border-below,.data-grid-table-wrapper[data-theme=white] .border-start,.data-grid-table-wrapper[data-theme=white] .border-end{border-color:#d9d9db!important}.data-grid-table-wrapper[data-theme=white] .accordion-details,.data-grid-table-wrapper[data-theme=white] .nested-table,.data-grid-table-wrapper[data-theme=white] .detail-virtual-scroll{background-color:#f6f8ff!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .accordion-details td,.data-grid-table-wrapper[data-theme=white] .accordion-details th,.data-grid-table-wrapper[data-theme=white] .nested-table td,.data-grid-table-wrapper[data-theme=white] .nested-table th,.data-grid-table-wrapper[data-theme=white] .detail-virtual-scroll td,.data-grid-table-wrapper[data-theme=white] .detail-virtual-scroll th{color:#000!important;border-color:#d9d9db!important}.data-grid-table-wrapper[data-theme=blue]{border-color:#b3d9ff;background-color:#f0f8ff;color:#1e3a5f}.data-grid-table-wrapper[data-theme=blue] *,.data-grid-table-wrapper[data-theme=blue] *:before,.data-grid-table-wrapper[data-theme=blue] *:after{color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] ::selection{background-color:#007cf5!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=blue] ::-moz-selection{background-color:#007cf5!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=blue] .data-grid-header-wrapper{background-color:#e6f3ff;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .data-grid-body-wrapper{background-color:#f0f8ff;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .data-grid-row{border-bottom-color:#b3d9ff;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .data-grid-row:nth-child(2n){background-color:#f0f8ff!important}.data-grid-table-wrapper[data-theme=blue] .data-grid-row:nth-child(odd){background-color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=blue] .data-grid-row:hover{background-color:#1e3a5f1a!important}.data-grid-table-wrapper[data-theme=blue] .selected-cell,.data-grid-table-wrapper[data-theme=blue] .row-selected{background-color:#cce5ff!important}.data-grid-table-wrapper[data-theme=blue] .cell,.data-grid-table-wrapper[data-theme=blue] .header-cell,.data-grid-table-wrapper[data-theme=blue] .data-grid-row,.data-grid-table-wrapper[data-theme=blue] .data-grid-header,.data-grid-table-wrapper[data-theme=blue] .cell-content,.data-grid-table-wrapper[data-theme=blue] .full-text-content,.data-grid-table-wrapper[data-theme=blue] .circle-value,.data-grid-table-wrapper[data-theme=blue] .pic,.data-grid-table-wrapper[data-theme=blue] .image-placeholder,.data-grid-table-wrapper[data-theme=blue] .s-no,.data-grid-table-wrapper[data-theme=blue] .fw-500{color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] span,.data-grid-table-wrapper[data-theme=blue] div,.data-grid-table-wrapper[data-theme=blue] p,.data-grid-table-wrapper[data-theme=blue] td,.data-grid-table-wrapper[data-theme=blue] th,.data-grid-table-wrapper[data-theme=blue] label,.data-grid-table-wrapper[data-theme=blue] a:not(.text-primary){color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] svg,.data-grid-table-wrapper[data-theme=blue] svg path,.data-grid-table-wrapper[data-theme=blue] svg circle,.data-grid-table-wrapper[data-theme=blue] svg rect,.data-grid-table-wrapper[data-theme=blue] svg polygon{color:#1e3a5f!important;fill:#1e3a5f!important;stroke:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .data-grid-svg-icon{color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .data-grid-svg-icon path{stroke:#1e3a5f!important;fill:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .badge.badge-danger{background-color:#ff8787!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=blue] .badge.badge-success{background-color:#69db7c!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=blue] .badge.badge-warning{background-color:#ffd43b!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .badge.badge-info{background-color:#74c0fc!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=blue] .context-menu{background:#e6f3ff;border-color:#b3d9ff;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .context-menu li{color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .context-menu li:hover{background-color:#1e3a5f1a!important}.data-grid-table-wrapper[data-theme=blue] .custom-tooltip,.data-grid-table-wrapper[data-theme=blue] .popover__content,.data-grid-table-wrapper[data-theme=blue] .custom-break-tooltip{background:#e6f3ff!important;border-color:#b3d9ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .actions-dropdown,.data-grid-table-wrapper[data-theme=blue] .custom-menu{background-color:#e6f3ff!important;border-color:#b3d9ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .actions-dropdown .dropdown-item,.data-grid-table-wrapper[data-theme=blue] .custom-menu .dropdown-item{color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .actions-dropdown .dropdown-item:hover,.data-grid-table-wrapper[data-theme=blue] .custom-menu .dropdown-item:hover{background-color:#1e3a5f1a!important}.data-grid-table-wrapper[data-theme=blue] .taskbar .selected-rows-action-bar{background-color:#1e3a5f!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=blue] .taskbar .selected-rows-action-bar .action-btn{color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=blue] .manual-logs-modal .modal-header{background:linear-gradient(135deg,#1e3a5f,#2d4a6b)!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=blue] .manual-logs-modal .modal-header .modal-title{color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=blue] .manual-logs-modal .modal-body{background-color:#f0f8ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .manual-logs-modal .modal-body .table{color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .manual-logs-modal .modal-body .table thead th{background:linear-gradient(135deg,#e6f3ff,#cce5ff)!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .manual-logs-modal .modal-body .table tbody tr{color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .manual-logs-modal .modal-body .table tbody tr:nth-child(2n){background-color:#f0f8ff!important}.data-grid-table-wrapper[data-theme=blue] .manual-logs-modal .modal-body .table tbody tr:hover{background-color:#1e3a5f1a!important}.data-grid-table-wrapper[data-theme=blue] .manual-logs-modal .modal-body .table tbody tr td{color:#1e3a5f!important;border-color:#b3d9ff!important}.data-grid-table-wrapper[data-theme=blue] .form-control,.data-grid-table-wrapper[data-theme=blue] .form-select{background-color:#f6f8ff!important;border-color:#b3d9ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .form-control::placeholder,.data-grid-table-wrapper[data-theme=blue] .form-select::placeholder{color:#888!important}.data-grid-table-wrapper[data-theme=blue] .form-control option,.data-grid-table-wrapper[data-theme=blue] .form-select option{background-color:#f6f8ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .filter-serach-inpt{background-color:#f6f8ff!important;border-color:#b3d9ff!important}.data-grid-table-wrapper[data-theme=blue] .filter-serach-inpt input{background-color:#f6f8ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .active-filters,.data-grid-table-wrapper[data-theme=blue] .custom-modal-overlay .custom-modal-content{background-color:#e6f3ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .circle-value{background-color:#f6f8ff!important;border-color:#b3d9ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .pagination-container,.data-grid-table-wrapper[data-theme=blue] .page-size,.data-grid-table-wrapper[data-theme=blue] .page-info,.data-grid-table-wrapper[data-theme=blue] .page-buttons{color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .pagination-container select,.data-grid-table-wrapper[data-theme=blue] .pagination-container button,.data-grid-table-wrapper[data-theme=blue] .pagination-container span,.data-grid-table-wrapper[data-theme=blue] .page-size select,.data-grid-table-wrapper[data-theme=blue] .page-size button,.data-grid-table-wrapper[data-theme=blue] .page-size span,.data-grid-table-wrapper[data-theme=blue] .page-info select,.data-grid-table-wrapper[data-theme=blue] .page-info button,.data-grid-table-wrapper[data-theme=blue] .page-info span,.data-grid-table-wrapper[data-theme=blue] .page-buttons select,.data-grid-table-wrapper[data-theme=blue] .page-buttons button,.data-grid-table-wrapper[data-theme=blue] .page-buttons span{background-color:#f6f8ff!important;border-color:#b3d9ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .pagination-container button.active,.data-grid-table-wrapper[data-theme=blue] .page-size button.active,.data-grid-table-wrapper[data-theme=blue] .page-info button.active,.data-grid-table-wrapper[data-theme=blue] .page-buttons button.active{background-color:#cce5ff!important}.data-grid-table-wrapper[data-theme=blue] .footer-row{background-color:#e6f3ff!important;border-top-color:#b3d9ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] ::-webkit-scrollbar{background-color:#f0f8ff!important}.data-grid-table-wrapper[data-theme=blue] ::-webkit-scrollbar-thumb{background-color:#b3d9ff!important}.data-grid-table-wrapper[data-theme=blue] ::-webkit-scrollbar-thumb:hover{background-color:#74c0fc!important}.data-grid-table-wrapper[data-theme=blue] ::-webkit-scrollbar-track{background-color:#f0f8ff!important}.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker{background-color:#e6f3ff!important;color:#1e3a5f!important;border-color:#b3d9ff!important}.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker .bs-datepicker-head{background:linear-gradient(135deg,#1e3a5f,#2d4a6b)!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker .bs-datepicker-body{background-color:#f0f8ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker table td,.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker table th{color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker table td.is-other-month,.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker table th.is-other-month{color:#888!important}.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker table td.active,.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker table th.active{background-color:#cce5ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker table td span.in-range,.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker table th span.in-range{background-color:#cce5ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker table td:hover:not(.active),.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker table th:hover:not(.active){background-color:#1e3a5f1a!important}.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker .bs-datepicker-buttons{background-color:#f6f8ff!important;border-top-color:#b3d9ff!important}.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker .bs-datepicker-buttons .btn-primary{background:linear-gradient(135deg,#1e3a5f,#2d4a6b)!important;color:#f6f8ff!important;border-color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker .bs-datepicker-buttons .btn-secondary{background-color:#f0f8ff!important;color:#1e3a5f!important;border-color:#b3d9ff!important}.data-grid-table-wrapper[data-theme=blue] button,.data-grid-table-wrapper[data-theme=blue] .btn,.data-grid-table-wrapper[data-theme=blue] .button{background-color:#f6f8ff!important;border-color:#b3d9ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] button:hover,.data-grid-table-wrapper[data-theme=blue] .btn:hover,.data-grid-table-wrapper[data-theme=blue] .button:hover{background-color:#1e3a5f1a!important}.data-grid-table-wrapper[data-theme=blue] button.btn-primary,.data-grid-table-wrapper[data-theme=blue] .btn.btn-primary,.data-grid-table-wrapper[data-theme=blue] .button.btn-primary{background-color:#007cf5!important;border-color:#007cf5!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=blue] button.btn-outline-primary,.data-grid-table-wrapper[data-theme=blue] .btn.btn-outline-primary,.data-grid-table-wrapper[data-theme=blue] .button.btn-outline-primary{border-color:#007cf5!important;color:#007cf5!important;background-color:transparent!important}.data-grid-table-wrapper[data-theme=blue] a:not(.text-primary){color:#007cf5!important}.data-grid-table-wrapper[data-theme=blue] a:not(.text-primary):hover{color:#0056b3!important}.data-grid-table-wrapper[data-theme=blue] .text-primary{color:#007cf5!important}.data-grid-table-wrapper[data-theme=blue] .text-danger{color:#dc3545!important}.data-grid-table-wrapper[data-theme=blue] .text-success{color:#28a745!important}.data-grid-table-wrapper[data-theme=blue] .text-warning{color:#ffc107!important}.data-grid-table-wrapper[data-theme=blue] .text-info{color:#17a2b8!important}.data-grid-table-wrapper[data-theme=blue] .text-muted,.data-grid-table-wrapper[data-theme=blue] .muted-text{color:#6c757d!important}.data-grid-table-wrapper[data-theme=blue] .border,.data-grid-table-wrapper[data-theme=blue] .border-top,.data-grid-table-wrapper[data-theme=blue] .border-bottom,.data-grid-table-wrapper[data-theme=blue] .border-left,.data-grid-table-wrapper[data-theme=blue] .border-right,.data-grid-table-wrapper[data-theme=blue] .border-below,.data-grid-table-wrapper[data-theme=blue] .border-start,.data-grid-table-wrapper[data-theme=blue] .border-end{border-color:#b3d9ff!important}.data-grid-table-wrapper[data-theme=blue] .accordion-details,.data-grid-table-wrapper[data-theme=blue] .nested-table,.data-grid-table-wrapper[data-theme=blue] .detail-virtual-scroll{background-color:#f0f8ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .accordion-details td,.data-grid-table-wrapper[data-theme=blue] .accordion-details th,.data-grid-table-wrapper[data-theme=blue] .nested-table td,.data-grid-table-wrapper[data-theme=blue] .nested-table th,.data-grid-table-wrapper[data-theme=blue] .detail-virtual-scroll td,.data-grid-table-wrapper[data-theme=blue] .detail-virtual-scroll th{color:#1e3a5f!important;border-color:#b3d9ff!important}.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:30px}.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;position:relative}.resize-handle.resizing{z-index:9999!important;opacity:1!important;background-color:#007bff1a;border-right:2px solid #007bff;box-shadow:0 0 8px #007bff4d;position:relative!important;pointer-events:none!important}.group-header .resize-handle{top:25%}.h-100{height:100%}.data-grid-body{position:relative;overflow-y:auto;overflow-x:hidden;box-shadow:none!important}.cell{padding:8px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;height:100%;display:flex;align-items:center}.data-grid-row{display:flex;min-width:max-content;align-items:center;border-bottom:1px solid #d9d9db;transition:all .25s cubic-bezier(.4,0,.2,1);transform:translateZ(0);will-change:transform,box-shadow;backface-visibility:hidden}.data-grid-row:hover{transform:translate(2px);box-shadow:2px 0 8px #007bff1a}.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;background:#f6f8ff}.right-pinned-header{position:absolute;right:0;border-left:1px solid #d9d9db;z-index:unset}.left-pinned{left:0;border-right:1px solid #d9d9db}.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{display:flex}.data-grid-body-wrapper{scrollbar-width:none;-ms-overflow-style:none}.data-grid-body-wrapper::-webkit-scrollbar{display:none}.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:#f6f8ff;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:-15px;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:16px}.border-below{border-bottom:1px solid #d9d9db!important}.three-dots{width:22px;height:22px;display:flex;justify-content:center;align-items:center;border-radius:6px;margin-right:8px;cursor:pointer;transition:all .25s cubic-bezier(.4,0,.2,1);transform:translateZ(0);position:relative}.three-dots:before{content:\"\";position:absolute;top:50%;left:50%;width:0;height:0;background:#007bff1a;border-radius:50%;transform:translate(-50%,-50%);transition:width .25s,height .25s}.three-dots:hover{background-color:#007bff1a;transform:rotate(90deg)}.three-dots:hover:before{width:28px;height:28px}.three-dots:active{transform:rotate(90deg) scale(.95);transition-duration:.15s}.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:6px;cursor:pointer;transition:all .25s cubic-bezier(.4,0,.2,1);transform:translateZ(0);position:relative}.filter-icon-wrapper:before{content:\"\";position:absolute;top:50%;left:50%;width:0;height:0;background:#007bff1a;border-radius:50%;transform:translate(-50%,-50%);transition:width .25s,height .25s}.filter-icon-wrapper:hover{background-color:#007bff1a;transform:scale(1.05)}.filter-icon-wrapper:hover:before{width:32px;height:32px}.filter-icon-wrapper:active{transform:scale(.95);transition-duration:.15s}.column-panel-item{font-size:.875rem;color:#333;transition:all .25s cubic-bezier(.4,0,.2,1);transform:translateZ(0)}.column-panel-item:hover{background-color:#007bff0d;color:#007bff;transform:translate(2px)}.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:all .25s cubic-bezier(.4,0,.2,1);transform:translateZ(0);border-radius:4px;padding:2px}.toggle-icon:hover{background-color:#007bff1a;transform:scale(1.1)}.toggle-icon:active{transform:scale(.95)}.grab-icon{cursor:grab;color:#6c757d;transition:all .25s cubic-bezier(.4,0,.2,1);transform:translateZ(0)}.grab-icon:hover{color:#007bff;transform:scale(1.1)}.grab-icon:active{cursor:grabbing;transform:scale(.95)}.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:6px;display:flex;justify-content:center;align-items:center;transition:all .25s cubic-bezier(.4,0,.2,1);margin-right:8px;transform:translateZ(0);position:relative}.chevron-wrapper:before{content:\"\";position:absolute;top:50%;left:50%;width:0;height:0;background:#007bff1a;border-radius:50%;transform:translate(-50%,-50%);transition:width .25s,height .25s}.chevron-wrapper:hover{background-color:#007bff1a;transform:scale(1.1)}.chevron-wrapper:hover:before{width:36px;height:36px}.chevron-wrapper:hover i{transform:scale(1.2);transition:transform .25s cubic-bezier(.4,0,.2,1)}.chevron-wrapper:active{transform:scale(.95);transition-duration:.15s}.chevron-wrapper i{font-size:14px;transition:transform .25s cubic-bezier(.4,0,.2,1)}.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;transition:all .25s cubic-bezier(.4,0,.2,1);transform:translateZ(0);border-radius:6px}.columns-button:hover{background-color:#007bff1a;transform:scale(1.05)}.columns-button:active{transform:scale(.95)}.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:fixed;right:200px;z-index:1050;background-color:#fff;cursor:default;animation:slideInRight .25s cubic-bezier(.4,0,.2,1);transform:translateZ(0);border-radius:8px;box-shadow:0 8px 32px #0000001f;backdrop-filter:blur(8px)}.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;transition:all .25s cubic-bezier(.4,0,.2,1);transform:translateZ(0)}.action-button:hover{transform:translateY(-1px);box-shadow:0 4px 12px #007cf54d}.action-button:active{transform:translateY(0);transition-duration:.15s}.global-search{max-width:380px!important}.global-search span{margin-top:2px}.global-search input{padding-left:28px;border-radius:8px!important;transition:all .25s cubic-bezier(.4,0,.2,1);transform:translateZ(0)}.global-search input:focus{outline:none!important;box-shadow:0 0 0 3px #007bff1a!important;border-color:#007bff!important;transform:scale(1.02)}.active .top-icon ::ng-deep svg path{stroke:#007cf5!important}.custom-menu{width:220px;border-radius:8px;padding:4px 0}.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}.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;transition:all .25s cubic-bezier(.4,0,.2,1);transform:translateZ(0)}.page-buttons button:hover:not(:disabled){background-color:#007bff1a;border-color:#007bff;transform:translateY(-1px)}.page-buttons button:active:not(:disabled){transform:translateY(0) scale(.98)}.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!important}.text-filter select option{font-size:14px;font-weight:500}.text-filter select:focus{border:0!important}.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;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-width:600px;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{letter-spacing:.5px}.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;bottom:0;left:45%;display:flex;justify-content:center;z-index:1000;padding:36px}.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{font-size:14px;padding:6px 12px;border-radius:6px;text-align:center;height:auto;min-height:28px;display:inline-flex;align-items:center;justify-content:center;font-weight:500;line-height:1.5;white-space:nowrap;transition:all .2s cubic-bezier(.4,0,.2,1);will-change:transform,opacity;backface-visibility:hidden;transform:translateZ(0)}.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}.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;animation:pulse .25s cubic-bezier(.4,0,.2,1);transform:translateZ(0);position:relative}.selected-cell:before,.row-selected:before{content:\"\";position:absolute;inset:0;background:linear-gradient(45deg,transparent,rgba(255,255,255,.1),transparent);animation:shimmer 1.5s ease-in-out infinite}.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}.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.dragging th,.accordion-details.dragging td{pointer-events:none}.accordion-details.dragging th{z-index:2}.drag-handle{cursor:move;opacity:.5;transition:opacity .2s}.drag-handle:hover{opacity:1}.detail-edit-input{z-index:100;position:relative}.detail-filter-menu{position:absolute;background:#fff;border:1px solid #ddd;border-radius:4px;padding:10px;z-index:1000;box-shadow:0 2px 8px #00000026}.detail-filter-menu-positioned{width:280px;right:unset;max-width:230px;z-index:99;left:375px;top:225px}.resize-handle{cursor:col-resize;opacity:.5;width:8px;display:flex;align-items:center;justify-content:center}.resize-handle:hover{opacity:1;background-color:#f0f0f0}.detail-header-row{transition:all .3s ease}.detail-header-row.dragging{opacity:.7;transform:translate(5px)}.detail-cell{transition:background-color .2s ease,transform .3s ease}.detail-cell.active-drag{background-color:#f0f0f0;transform:scale(1.02)}.break-color-paid{background-color:#4caf50!important}.break-color-unpaid{background-color:#f44336!important}.break-color-lunch{background-color:#2196f3!important}.break-color-default{background-color:#f44336!important}.circle-value{display:flex;align-items:center;justify-content:center;width:32px;height:32px;border-radius:50%;background-color:#f8f9fa;border:2px solid #d9d9db;font-size:12px;font-weight:600;color:#000;text-align:center;line-height:1;vertical-align:middle;box-sizing:border-box;white-space:nowrap;overflow:hidden;cursor:pointer;transition:all .3s cubic-bezier(.4,0,.2,1);transform:translateZ(0);will-change:transform,box-shadow,background-color;backface-visibility:hidden}.circle-value:hover{background-color:#e9ecef;box-shadow:0 6px 16px #007bff40;transform:scale(1.15) translateY(-2px);border-color:#007bff}.circle-value:active{transform:scale(1.08) translateY(-1px);transition-duration:.15s}.break-tooltip-wrapper{position:relative;display:inline-block}.break-tooltip-wrapper:hover .custom-break-tooltip{opacity:1;visibility:visible}.circle-value[title]{position:relative}.circle-value[title]:after{content:attr(title);position:absolute;bottom:100%;left:50%;transform:translate(-50%);background-color:#333;color:#fff;padding:4px 8px;border-radius:4px;font-size:12px;white-space:nowrap;opacity:0;transition:opacity .2s ease;pointer-events:none}.circle-value[title]:hover:after{opacity:1}.custom-tooltip{position:fixed;background:#fff;border:1px solid #dcdcdc;border-radius:8px;padding:12px 16px;max-width:300px;z-index:9999;font-size:13px;animation:fadeIn .2s ease-in-out}.tooltip-title{font-size:14px;font-weight:600;margin-bottom:8px;color:#333}.tooltip-list{margin:0;padding-left:16px;list-style-type:disc}.tooltip-list li{margin-bottom:4px;line-height:1.4;color:#444}.tooltip-total{font-weight:700;margin-top:8px;color:#222}@keyframes fadeIn{0%{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:translateY(0)}}.restriction-indicator{position:absolute;display:inline-block;padding-right:10px}.restriction-indicator:after{content:\"\";position:absolute;top:0;right:0;width:8px;height:8px;background-color:#0d6efd;border-radius:50%}.manual-logs-indicator{position:absolute;top:2px;right:2px;width:8px;height:8px;background-color:#0d6efd;border-radius:50%;border:1px solid #fff;box-shadow:0 0 2px #0d6efd80;cursor:pointer;z-index:10;transition:all .2s ease}.manual-logs-indicator:hover{transform:scale(1.2);box-shadow:0 0 4px #0d6efdcc}.manual-logs-table-tooltip{background:#fff!important;border:1px solid #dcdcdc!important;border-radius:8px!important;box-shadow:0 4px 12px #00000026!important;font-size:13px!important;animation:fadeIn .2s ease-in-out!important;display:block!important;visibility:visible!important;opacity:1!important}.manual-logs-table-tooltip .popover__content,.manual-logs-table-tooltip .modal-area{padding:0!important;display:block!important;visibility:visible!important}.manual-logs-table-tooltip .table-responsive{max-height:300px;overflow-y:auto;display:block!important;visibility:visible!important}.manual-logs-table-tooltip table{margin:0!important;border-collapse:collapse!important;display:table!important;visibility:visible!important}.manual-logs-table-tooltip table th,.manual-logs-table-tooltip table td{padding:6px 8px!important;border:1px solid #f1f1f1!important;text-align:center!important;vertical-align:middle!important;display:table-cell!important;visibility:visible!important}.manual-logs-table-tooltip table th{background-color:#f8f9fa!important;font-weight:600!important;color:#495057!important;position:sticky!important;top:0!important;z-index:1!important}.manual-logs-table-tooltip table tbody tr:nth-child(2n){background-color:#f8f9fa!important}.manual-logs-table-tooltip table tbody tr:hover{background-color:#e3f2fd!important}.manual-logs-table-tooltip table .text-primary{color:#0d6efd!important;text-decoration:none!important}.manual-logs-table-tooltip table .capitalize{text-transform:capitalize!important}@keyframes fadeIn{0%{opacity:0;transform:translate(-50%) translateY(-110%)}to{opacity:1;transform:translate(-50%) translateY(-100%)}}.detail-column-menu{max-height:250px;overflow-y:auto;overflow-x:auto;white-space:nowrap;padding:8px 0;border-radius:6px;scrollbar-width:thin}.detail-column-menu-wrapper{z-index:1001;position:absolute}.accordion-details{position:relative;z-index:999}.detail-column-menu .column-menu-item{padding:8px 12px;cursor:pointer;display:flex;align-items:center;transition:all .25s cubic-bezier(.4,0,.2,1);font-size:14px;transform:translateZ(0);border-radius:4px}.detail-column-menu .column-menu-item:hover{background-color:#007bff1a;transform:translate(2px);color:#007bff}.detail-column-menu .column-menu-item:active{transform:translate(0) scale(.98)}.detail-column-menu .column-menu-item:hover{background-color:#deebf7}.nested-table th[pinned=left],.nested-table td[pinned=left]{border-right:2px solid #ccc;border-left:none;border-bottom:2px solid #ccc}.nested-table th[pinned=right],.nested-table td[pinned=right]{border-left:2px solid #ccc;border-right:none;border-bottom:2px solid #ccc}.data-grid-accordion-table.show-borders{border:1px solid #d9d9db;border-collapse:collapse}.data-grid-accordion-table.show-borders th,.data-grid-accordion-table.show-borders td{border:1px solid #d9d9db}.data-grid-accordion-table.show-shadow tbody tr:hover{box-shadow:0 4px 8px #0000001a;transition:box-shadow .3s ease}.data-grid-accordion-table tbody tr:hover{background-color:#deebf7;transition:background-color .3s ease}.data-grid-pin-icon{display:inline-block;vertical-align:middle;margin-left:4px}.accordion-details.center-section{position:relative;display:flex}.detail-side-menu-wrapper{display:flex;flex-shrink:0;position:sticky;right:0;top:0;height:100%;max-height:275px}.detail-side-menu-content{width:250px;box-shadow:-2px 0 5px #0000001a;display:flex;flex-direction:column}.side-menu-scrollable{flex:1;overflow-y:auto;padding:0 12px 12px;max-height:calc(100% - 40px)}.filter-input-container{padding:8px;background:#f9f9f9;border-radius:4px}.toggle-icon.rotate{transform:rotate(90deg)}.resize-handle{top:0;right:3px;bottom:0;width:8px;cursor:col-resize;z-index:10;display:flex;align-items:center;justify-content:center;opacity:1.4;transition:all .25s cubic-bezier(.4,0,.2,1);background:transparent;transform:translateZ(0)}.resize-handle:hover{opacity:1;background:#007bff1a}.resize-handle:active{opacity:1;background:#007bff33;transform:scaleX(1.2)}th:hover .resize-handle{opacity:40}.resize-handles{top:0;right:3px;bottom:0;width:8px;cursor:col-resize;z-index:10;display:flex;align-items:center;justify-content:center;position:absolute;opacity:1.4;transition:all .25s cubic-bezier(.4,0,.2,1);background:transparent;transform:translateZ(0)}.resize-handles:hover{opacity:1;background:#007bff1a}.resize-handles:active{opacity:1;background:#007bff33;transform:scaleX(1.2)}.resize-handles.resizing{z-index:9999!important;opacity:1!important;background-color:#007bff1a;border-right:2px solid #007bff;box-shadow:0 0 8px #007bff4d;pointer-events:none!important}th:hover .resize-handles{opacity:40}.resizing-highlight{background-color:#007bff1a!important}.accordion-details-wrapper{display:flex;width:100%;max-height:350px;overflow:hidden}.accordion-details.show-borders,.accordion-details-wrapper.show-borders{border:1px solid #d9d9db;border-radius:4px}.accordion-left-section,.accordion-right-section,.detail-side-menu-wrapper{flex-shrink:0;max-height:350px;overflow:hidden;height:fit-content}.accordion-center-section{flex:1;min-width:0;overflow:auto;max-height:350px}.detail-virtual-scroll{display:block;width:100%;height:250px;overflow:auto}.detail-virtual-scroll table{table-layout:fixed;width:100%}.detail-virtual-scroll td,.detail-virtual-scroll th{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.detail-header-scroll-container{scrollbar-width:none}.detail-header-scroll-container::-webkit-scrollbar{display:none}.accordion-left-section thead th,.accordion-right-section thead th{position:sticky;top:0;z-index:2}.data-pin-body-wrapper{-webkit-user-select:none;user-select:none;display:flex}.data-pin-body-wrapper{scrollbar-width:none;-ms-overflow-style:none}.data-pin-body-wrapper::-webkit-scrollbar{display:none}.detail-virtual-scroll .selected-cell,.accordion-left-section .selected-cell,.accordion-right-section .selected-cell{background-color:#cce5ff!important}.custom-datepicker-buttons button{height:28px;padding:0 10px;font-size:12px}.manual-logs-modal{max-width:800px;max-height:80vh;overflow:hidden;border-radius:12px;box-shadow:0 10px 40px #0003}.manual-logs-modal .modal-header{background:linear-gradient(135deg,#4361ee,#3a0ca3);color:#fff;padding:16px 20px;border-bottom:none;border-radius:12px 12px 0 0}.manual-logs-modal .modal-header .modal-title{font-weight:600;font-size:18px;margin:0}.manual-logs-modal .modal-header .btn-close{background:#fff3;border:none;border-radius:50%;width:32px;height:32px;display:flex;align-items:center;justify-content:center;color:#fff;opacity:.8;transition:all .25s cubic-bezier(.4,0,.2,1);transform:translateZ(0)}.manual-logs-modal .modal-header .btn-close:hover{background:#ffffff4d;opacity:1;transform:scale(1.1) rotate(90deg)}.manual-logs-modal .modal-header .btn-close:active{transform:scale(.95) rotate(90deg)}.manual-logs-modal .modal-body{padding:20px;max-height:calc(80vh - 80px);overflow-y:auto}.manual-logs-modal .modal-body .table-responsive{border-radius:8px;overflow:hidden;box-shadow:0 2px 8px #0000001a}.manual-logs-modal .modal-body .table-responsive .table{margin-bottom:0;font-size:14px}.manual-logs-modal .modal-body .table-responsive .table thead th{background:linear-gradient(135deg,#f8f9fa,#e9ecef);border-bottom:2px solid #dee2e6;font-weight:600;color:#495057;padding:12px 16px;position:sticky;top:0;z-index:10}.manual-logs-modal .modal-body .table-responsive .table tbody tr{transition:background-color .2s ease}.manual-logs-modal .modal-body .table-responsive .table tbody tr:hover{background-color:#f8f9fa}.manual-logs-modal .modal-body .table-responsive .table tbody tr:nth-child(2n){background-color:#f8f9fa}.manual-logs-modal .modal-body .table-responsive .table tbody tr td{padding:10px 16px;vertical-align:middle;border-color:#e9ecef}.manual-logs-modal .modal-body .table-responsive .table tbody tr td .text-primary{color:#0d6efd!important;font-weight:500;text-decoration:none}.manual-logs-modal .modal-body .table-responsive .table tbody tr td .text-primary:hover{text-decoration:underline}.manual-logs-modal .modal-body .table-responsive .table tbody tr td .capitalize{text-transform:capitalize}::ng-deep bs-daterangepicker-container .bs-datepicker{border-radius:4px!important;box-shadow:0 2px 8px #0000001a!important;font-size:14px!important;display:flex!important;align-items:flex-start!important;left:142px!important}::ng-deep .bs-datepicker-head{background:#f8f9fa!important;color:#495057!important;border-bottom:1px solid #dee2e6!important;padding:8px 12px!important;border-radius:4px 4px 0 0!important}::ng-deep .bs-datepicker-head .current{font-weight:600!important;color:#495057!important;font-size:13px!important}::ng-deep .bs-datepicker-head .previous,::ng-deep .bs-datepicker-head .next{background:#fff!important;color:#495057!important;border:1px solid #dee2e6!important;width:24px!important;border-radius:4px!important;font-size:12px!important}::ng-deep .bs-datepicker-head .previous:hover,::ng-deep .bs-datepicker-head .next:hover{background:#e9ecef!important}::ng-deep .bs-datepicker .bs-datepicker-buttons{padding:8px!important;background:#f8f9fa!important;border-top:1px solid #dee2e6!important;border-radius:0 0 4px 4px!important}::ng-deep .bs-datepicker .bs-datepicker-buttons .btn-primary{background:#007bff!important;color:#fff!important;border:1px solid #007bff!important;font-weight:500!important;padding:4px 8px!important;border-radius:4px!important;font-size:12px!important}::ng-deep .bs-datepicker .bs-datepicker-buttons .btn-primary:hover{background:#0056b3!important;border-color:#0056b3!important}::ng-deep .bs-datepicker .bs-datepicker-buttons .btn-secondary{background:#fff!important;color:#495057!important;border:1px solid #dee2e6!important;font-weight:500!important;padding:4px 8px!important;border-radius:4px!important;font-size:12px!important}::ng-deep .bs-datepicker .bs-datepicker-buttons .btn-secondary:hover{background:#e9ecef!important}::ng-deep .bs-datepicker-body{background:#fff!important;padding:6px!important}::ng-deep .bs-datepicker-body table{background:#fff!important;border-collapse:separate!important;border-spacing:1px!important}::ng-deep .bs-datepicker-body table th,::ng-deep .bs-datepicker-body table td{border:1px solid #dee2e6!important;border-radius:4px!important;text-align:center!important;font-weight:500!important;color:#495057!important;cursor:pointer!important;transition:all .2s ease!important;font-size:12px!important;width:32px!important;height:32px!important;line-height:24px!important}::ng-deep .bs-datepicker-body table th{background:#f8f9fa!important;font-weight:600!important;font-size:11px!important;padding:2px!important;height:24px!important;line-height:20px!important}::ng-deep .bs-datepicker-body table td:hover:not(.disabled){background:#e9ecef!important}::ng-deep .bs-datepicker-body table td.active{background:#007bff!important;color:#fff!important;border-color:#007bff!important}::ng-deep .bs-datepicker-body table td.is-other-month{color:#6c757d!important;background:#f8f9fa!important}::ng-deep .bs-datepicker-body table td.disabled{color:#adb5bd!important;background:#e9ecef!important;cursor:not-allowed!important}::ng-deep .bs-datepicker-custom-range{background:transparent!important;border-right:1px solid #dee2e6!important;padding:6px!important;width:130px!important;margin-right:8px!important;align-self:flex-start!important}::ng-deep .bs-datepicker-predefined-btns{display:flex!important;flex-direction:column!important;gap:2px!important}::ng-deep .bs-datepicker-predefined-btns button{background:transparent!important;color:#495057!important;border:1px solid #dee2e6!important;border-radius:4px!important;padding:4px 6px!important;font-size:11px!important;font-weight:500!important;text-align:left!important;cursor:pointer!important;transition:all .2s ease!important;width:100%!important;margin:0!important}::ng-deep .bs-datepicker-predefined-btns button:hover{background:#e9ecef!important;border-color:#adb5bd!important}::ng-deep .bs-datepicker-predefined-btns button:active,::ng-deep .bs-datepicker-predefined-btns button:focus{outline:none!important;box-shadow:0 0 0 2px #007bff40!important;background:#007bff!important;color:#fff!important;border-color:#007bff!important}.manual-logs-modal-overlay{position:fixed;top:0;left:0;width:100%;height:100%;background-color:#00000080;display:flex;justify-content:center;align-items:center;z-index:9999}.manual-logs-modal-content{background:#fff;border-radius:8px;max-width:800px;max-height:80vh;overflow:auto;box-shadow:0 4px 8px #0000001a}.popover__wrapper{position:relative;display:inline-block}.popover__content{position:absolute;bottom:100%;left:50%;transform:translate(-50%);background:#fff;border:1px solid #ccc;border-radius:8px;padding:12px;box-shadow:0 4px 12px #00000026;z-index:1000;opacity:0;visibility:hidden;transition:opacity .3s ease,visibility .3s ease;min-width:250px;max-width:400px;font-size:14px}.popover__wrapper:hover .popover__content{opacity:1;visibility:visible}.popover__content .modal-area{padding:0}.popover__content h4{margin:0 0 8px;font-size:16px;font-weight:600;color:#333}.popover__content .break-status{font-size:12px;color:#666;margin-bottom:8px}.popover__content .d-flex{gap:12px}.popover__content p{margin:0 0 4px;font-size:12px;color:#666}.popover__content h5{margin:0;font-size:14px;font-weight:500;color:#333}.popover__content .break-footer{border-top:1px solid #eee;margin-top:8px;padding-top:8px}.popover__content .break-footer p{font-size:12px;color:#666;margin:0}.custom-break-tooltip{position:fixed;z-index:1000;background:#fff;border:1px solid #ddd;border-radius:8px;box-shadow:0 4px 12px #00000026;padding:12px;font-size:13px;max-width:220px;pointer-events:none;top:0;left:0;transform:translate(var(--tooltip-x, 0px),var(--tooltip-y, 0px))}.custom-break-tooltips{position:fixed;z-index:1000;background:#fff;border:1px solid #ddd;border-radius:8px;box-shadow:0 4px 12px #00000026;padding:8px;font-size:12px;max-width:500px;max-height:300px;top:0;left:0;transform:translate(var(--tooltip-x, 0px),var(--tooltip-y, 0px))}.custom-break-tooltips .modal-body{max-height:250px!important;overflow-y:auto;padding:0}.custom-break-tooltips .table-responsive{max-height:250px}.custom-break-tooltips thead th{position:sticky;top:0;background:#f8f9fa;z-index:10;border-bottom:2px solid #dee2e6;font-size:11px;padding:4px 8px;font-weight:600}.custom-break-tooltips table{font-size:11px;margin-bottom:0}.custom-break-tooltips table td{padding:4px 8px;white-space:nowrap}.custom-break-tooltips .table-striped tbody tr:nth-of-type(odd){background-color:#00000005}.popver_content_progress_bar{visibility:hidden}.badge-overflow-container{display:flex;flex-wrap:nowrap;gap:4px;align-items:center;min-width:0;overflow:hidden;width:100%}.badge-overflow-container .badge{flex-shrink:0;white-space:nowrap;font-size:12px;padding:4px 8px;border-radius:50%;display:inline-flex;align-items:center;justify-content:center;font-weight:600;line-height:1;text-transform:uppercase;letter-spacing:.5px;transition:all .3s cubic-bezier(.4,0,.2,1);border:2px solid transparent;width:32px;height:32px;box-sizing:border-box;cursor:pointer;transform:translateZ(0);will-change:transform,box-shadow,background-color;backface-visibility:hidden}.badge-overflow-container .badge:hover{transform:scale(1.15) translateY(-2px);box-shadow:0 6px 16px #007bff40}.badge-overflow-container .badge:active{transform:scale(1.08) translateY(-1px);transition-duration:.15s}.badge-overflow-container .badge-overflow-count{background-color:#6c757d!important;color:#fff!important;cursor:pointer;border:2px solid #6c757d!important;flex-shrink:0;border-radius:50%;width:32px;height:32px;display:inline-flex;align-items:center;justify-content:center;font-weight:600;transition:all .3s cubic-bezier(.4,0,.2,1);transform:translateZ(0);will-change:transform,box-shadow,background-color;backface-visibility:hidden}.badge-overflow-container .badge-overflow-count:hover{background-color:#5a6268!important;border-color:#5a6268!important;transform:scale(1.15) translateY(-2px);box-shadow:0 6px 16px #007bff40}.badge-overflow-container .badge-overflow-count:active{transform:scale(1.08) translateY(-1px);transition-duration:.15s}.timeline-view-container{padding:1rem;background-color:#f8f9fa}.timeline-view-container .timeline-header{margin-bottom:2rem}.timeline-view-container .timeline-header h5{color:#495057;font-weight:600;margin-bottom:1rem}.timeline-view-container .timeline-header .timeline-hours{display:flex;justify-content:space-between;padding:.5rem 0;border-bottom:1px solid #dee2e6;margin-bottom:1rem;background:#fff;border-radius:8px;padding:1rem}.timeline-view-container .timeline-header .timeline-hours .timeline-hour{font-size:.8rem;color:#6c757d;font-weight:500;min-width:40px;text-align:center;padding:.5rem;border-radius:4px;background:#f8f9fa}.timeline-view-container .timeline-body .timeline-row{background:#fff;border:1px solid #dee2e6;border-radius:8px;margin-bottom:1rem;padding:1rem;box-shadow:0 2px 4px #0000001a;transition:box-shadow .2s ease}.timeline-view-container .timeline-body .timeline-row:hover{box-shadow:0 4px 8px #00000026}.timeline-view-container .timeline-body .timeline-row .timeline-employee{margin-bottom:1rem}.timeline-view-container .timeline-body .timeline-row .timeline-employee .employee-name{font-weight:600;color:#495057;font-size:1.1rem}.timeline-view-container .timeline-body .timeline-row .timeline-track{position:relative;height:40px;background:#f8f9fa;border-radius:4px;border:1px solid #e9ecef}.timeline-view-container .timeline-body .timeline-row .timeline-track .work-duration-bar{position:absolute;height:100%;background:linear-gradient(135deg,#28a745,#20c997);border-radius:4px;box-shadow:0 2px 4px #28a7454d;transition:opacity .2s ease}.timeline-view-container .timeline-body .timeline-row .timeline-track .work-duration-bar:hover{opacity:.8}.timeline-view-container .timeline-body .timeline-row .timeline-track .break-bar{position:absolute;height:100%;border-radius:4px;box-shadow:0 2px 4px #0003;border:1px solid rgba(255,255,255,.5);transition:opacity .2s ease}.timeline-view-container .timeline-body .timeline-row .timeline-track .break-bar:hover{opacity:.8}.calendar-view-container .calendar-header{margin-bottom:2rem}.calendar-view-container .calendar-header h5{color:#495057;font-weight:600}.calendar-view-container .calendar-header .calendar-nav button{border:1px solid #dee2e6;background:#fff;color:#495057;padding:.375rem .75rem;border-radius:.375rem;transition:all .2s ease}.calendar-view-container .calendar-header .calendar-nav button:hover{background-color:#f8f9fa;border-color:#adb5bd}.calendar-view-container .calendar-header .calendar-nav button:first-child{border-top-right-radius:0;border-bottom-right-radius:0;border-right:none}.calendar-view-container .calendar-header .calendar-nav button:last-child{border-top-left-radius:0;border-bottom-left-radius:0}.calendar-view-container .calendar-grid .calendar-week-header{display:flex;background-color:#f8f9fa;border:1px solid #dee2e6;border-bottom:none}.calendar-view-container .calendar-grid .calendar-week-header .calendar-day-header{flex:1;padding:.75rem;text-align:center;font-weight:600;color:#495057;border-right:1px solid #dee2e6}.calendar-view-container .calendar-grid .calendar-week-header .calendar-day-header:last-child{border-right:none}.calendar-view-container .calendar-grid .calendar-weeks{border:1px solid #dee2e6;border-top:none}.calendar-view-container .calendar-grid .calendar-weeks .calendar-week{display:flex;border-bottom:1px solid #dee2e6}.calendar-view-container .calendar-grid .calendar-weeks .calendar-week:last-child{border-bottom:none}.calendar-view-container .calendar-grid .calendar-weeks .calendar-week .calendar-day{flex:1;min-height:100px;padding:.5rem;border-right:1px solid #dee2e6;background:#fff}.calendar-view-container .calendar-grid .calendar-weeks .calendar-week .calendar-day:last-child{border-right:none}.calendar-view-container .calendar-grid .calendar-weeks .calendar-week .calendar-day.current-month{background:#fff}.calendar-view-container .calendar-grid .calendar-weeks .calendar-week .calendar-day.today{background-color:#fff3cd;border:2px solid #ffc107}.calendar-view-container .calendar-grid .calendar-weeks .calendar-week .calendar-day .day-number{font-weight:600;color:#495057;margin-bottom:.25rem}.calendar-view-container .calendar-grid .calendar-weeks .calendar-week .calendar-day .day-entries .entry-dot{width:8px;height:8px;border-radius:50%;display:inline-block;margin-right:2px;margin-bottom:2px}.heatmap-view-container .heatmap-header{margin-bottom:2rem}.heatmap-view-container .heatmap-header h5{color:#495057;font-weight:600}.heatmap-view-container .heatmap-header .heatmap-legend .legend-colors{display:flex;margin:0 1rem}.heatmap-view-container .heatmap-header .heatmap-legend .legend-colors .legend-color{width:12px;height:12px;margin-right:2px;border-radius:2px}.heatmap-view-container .heatmap-header .heatmap-legend span{font-size:.875rem;color:#6c757d}.heatmap-view-container .heatmap-grid .heatmap-months{display:flex;margin-bottom:.5rem}.heatmap-view-container .heatmap-grid .heatmap-months .month-label{flex:1;text-align:center;font-size:.8rem;font-weight:600;color:#495057}.heatmap-view-container .heatmap-grid .heatmap-weeks .heatmap-week{display:flex;margin-bottom:2px}.heatmap-view-container .heatmap-grid .heatmap-weeks .heatmap-week .heatmap-day{flex:1;aspect-ratio:1;border-radius:2px;margin-right:2px;transition:opacity .2s ease}.heatmap-view-container .heatmap-grid .heatmap-weeks .heatmap-week .heatmap-day:hover{opacity:.8}.heatmap-view-container .heatmap-grid .heatmap-weeks .heatmap-week .heatmap-day:last-child{margin-right:0}.card-view-container{padding:1rem;height:100%;overflow-y:auto;overflow-x:hidden}.card-view-container[data-theme=white]{background-color:#f6f8ff;color:#000}.card-view-container[data-theme=white] .attendance-card{background-color:#f6f8ff;border-color:#d9d9db;color:#000}.card-view-container[data-theme=white] .attendance-card:hover{background-color:#007bff1a}.card-view-container[data-theme=white] .attendance-card .card-header{background-color:#f8f9fa;color:#000;border-bottom-color:#d9d9db}.card-view-container[data-theme=white] .attendance-card .card-body{background-color:#f6f8ff;color:#000}.card-view-container[data-theme=white] .attendance-card .badge.bg-success{background-color:#84ca81;color:#f6f8ff}.card-view-container[data-theme=white] .attendance-card .badge.bg-danger{background-color:#ea5353;color:#f6f8ff}.card-view-container[data-theme=white] .attendance-card .badge.bg-warning{background-color:#fff3dc;color:#000}.card-view-container[data-theme=white] .attendance-card .badge.bg-info{background-color:#e8fbfd;color:#00bad1}.card-view-container[data-theme=blue]{background-color:#f0f8ff;color:#1e3a5f}.card-view-container[data-theme=blue] .attendance-card{background-color:#f6f8ff;border-color:#b3d9ff;color:#1e3a5f}.card-view-container[data-theme=blue] .attendance-card:hover{background-color:#1e3a5f1a}.card-view-container[data-theme=blue] .attendance-card .card-header{background-color:#e6f3ff;color:#1e3a5f;border-bottom-color:#b3d9ff}.card-view-container[data-theme=blue] .attendance-card .card-body{background-color:#f6f8ff;color:#1e3a5f}.card-view-container[data-theme=blue] .attendance-card .badge.bg-success{background-color:#69db7c;color:#f6f8ff}.card-view-container[data-theme=blue] .attendance-card .badge.bg-danger{background-color:#ff8787;color:#f6f8ff}.card-view-container[data-theme=blue] .attendance-card .badge.bg-warning{background-color:#ffd43b;color:#1e3a5f}.card-view-container[data-theme=blue] .attendance-card .badge.bg-info{background-color:#74c0fc;color:#f6f8ff}.card-view-container .row{margin:0}.card-view-container .row .col-xl-4,.card-view-container .row .col-lg-6,.card-view-container .row .col-md-6,.card-view-container .row .col-sm-12{padding:.5rem}.card-view-container .attendance-card{transition:background-color .2s ease;border:1px solid #d9d9db;border-radius:4px;overflow:hidden;height:100%;display:flex;flex-direction:column;font-family:sans-serif;font-size:16px}.card-view-container .attendance-card:hover{box-shadow:0 2px 4px #0000001a}.card-view-container .attendance-card.expanded .card-body{max-height:none}.card-view-container .attendance-card .card-header{padding:8px;border-bottom:1px solid #d9d9db;flex-shrink:0;font-weight:500}.card-view-container .attendance-card .card-header .employee-avatar{margin-right:.75rem;flex-shrink:0}.card-view-container .attendance-card .card-header .employee-avatar img,.card-view-container .attendance-card .card-header .employee-avatar .avatar-placeholder{border:1px solid #d9d9db;width:40px;height:40px;border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:16px;font-weight:400}.card-view-container .attendance-card .card-header .flex-grow-1{min-width:0}.card-view-container .attendance-card .card-header h6{margin:0;font-weight:500;font-size:16px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.card-view-container .attendance-card .card-header small{opacity:.9;font-weight:400;font-size:16px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.card-view-container .attendance-card .card-header .card-actions{flex-shrink:0}.card-view-container .attendance-card .card-header .card-actions .btn{background-color:transparent;border:1px solid #d9d9db;color:inherit;padding:.25rem .5rem}.card-view-container .attendance-card .card-header .card-actions .btn:hover{background-color:#007bff1a}.card-view-container .attendance-card .card-header .card-actions .btn i{font-size:.8rem}.card-view-container .attendance-card .card-body{padding:8px;flex:1;display:flex;flex-direction:column}.card-view-container .attendance-card .card-body .info-item{text-align:center;margin-bottom:.5rem}.card-view-container .attendance-card .card-body .info-item small{display:block;font-weight:400;color:#6c757d;text-transform:uppercase;font-size:12px;letter-spacing:.5px;margin-bottom:.25rem}.card-view-container .attendance-card .card-body .info-item span{font-size:16px;font-weight:400;color:inherit}.card-view-container .attendance-card .card-body .badge{font-size:12px;padding:.25rem .5rem;border-radius:4px;font-weight:400;text-transform:uppercase;letter-spacing:.5px;border:none}.card-view-container .attendance-card .card-body .badge.bg-success,.card-view-container .attendance-card .card-body .badge.bg-danger{color:#f6f8ff}.card-view-container .attendance-card .card-body .badge.bg-warning{color:#000}.card-view-container .attendance-card .card-body .badge.bg-secondary{color:#f6f8ff}.card-view-container .attendance-card .card-body .card-details{margin-top:1rem}.card-view-container .attendance-card .card-body .card-details .section-title{font-size:14px;font-weight:500;color:inherit;margin-bottom:.75rem;display:flex;align-items:center}.card-view-container .attendance-card .card-body .card-details .section-title i{margin-right:.5rem;opacity:.8}.card-view-container .attendance-card .card-body .card-details .breaks-list .break-item,.card-view-container .attendance-card .card-body .card-details .breaks-list .leave-item,.card-view-container .attendance-card .card-body .card-details .short-leave-list .break-item,.card-view-container .attendance-card .card-body .card-details .short-leave-list .leave-item{background-color:inherit;border:1px solid #d9d9db;border-radius:4px;padding:8px;margin-bottom:.5rem;cursor:pointer;transition:all .25s cubic-bezier(.4,0,.2,1);transform:translateZ(0)}.card-view-container .attendance-card .card-body .card-details .breaks-list .break-item .d-flex,.card-view-container .attendance-card .card-body .card-details .breaks-list .leave-item .d-flex,.card-view-container .attendance-card .card-body .card-details .short-leave-list .break-item .d-flex,.card-view-container .attendance-card .card-body .card-details .short-leave-list .leave-item .d-flex{gap:.75rem;align-items:center}.card-view-container .attendance-card .card-body .card-details .breaks-list .break-item .d-flex small,.card-view-container .attendance-card .card-body .card-details .breaks-list .leave-item .d-flex small,.card-view-container .attendance-card .card-body .card-details .short-leave-list .break-item .d-flex small,.card-view-container .attendance-card .card-body .card-details .short-leave-list .leave-item .d-flex small{font-weight:500;color:inherit;margin-bottom:.25rem}.card-view-container .attendance-card .card-body .card-details .breaks-list .break-item .d-flex .text-muted,.card-view-container .attendance-card .card-body .card-details .breaks-list .leave-item .d-flex .text-muted,.card-view-container .attendance-card .card-body .card-details .short-leave-list .break-item .d-flex .text-muted,.card-view-container .attendance-card .card-body .card-details .short-leave-list .leave-item .d-flex .text-muted{font-size:12px;color:#6c757d}.card-view-container .attendance-card .card-body .card-details .breaks-list .break-item .d-flex .badge,.card-view-container .attendance-card .card-body .card-details .breaks-list .leave-item .d-flex .badge,.card-view-container .attendance-card .card-body .card-details .short-leave-list .break-item .d-flex .badge,.card-view-container .attendance-card .card-body .card-details .short-leave-list .leave-item .d-flex .badge{font-size:10px;padding:.2rem .4rem}.card-view-container .attendance-card .card-body .card-details .additional-details .row .col-6{margin-bottom:.5rem}.card-view-container .attendance-card .card-body .card-details .additional-details .row .col-6 small{font-weight:400;color:#6c757d;text-transform:uppercase;font-size:12px;letter-spacing:.5px;margin-bottom:.25rem}.card-view-container .attendance-card .card-body .card-details .additional-details .row .col-6 span{font-weight:400;color:inherit;font-size:14px}@media (max-width: 1200px){.card-view-container .row .col-xl-4{flex:0 0 50%;max-width:50%}}@media (max-width: 768px){.card-view-container .row .col-xl-4,.card-view-container .col-lg-6,.card-view-container .col-md-6{flex:0 0 100%;max-width:100%}.card-view-container .attendance-card .card-body{padding:8px}.card-view-container .attendance-card .card-body .info-item small{font-size:10px}.card-view-container .attendance-card .card-body .info-item span{font-size:14px}}@media (max-width: 576px){.card-view-container{padding:.5rem}.card-view-container .row .col-sm-12{padding:.25rem}.card-view-container .attendance-card .card-header{padding:8px}.card-view-container .attendance-card .card-header h6,.card-view-container .attendance-card .card-header small{font-size:14px}.card-view-container .attendance-card .card-body{padding:8px}}.btn-xs{padding:.125rem .3rem!important;font-size:.9rem!important;border-radius:.2rem!important;line-height:1.5!important}.form-select.form-select-sm:invalid{border-color:#d9d9db!important}.form-select.form-select-sm:valid{border-color:#d9d9db!important}.date-range-container{gap:8px;flex-wrap:nowrap;align-items:center}.date-range-btn{padding:6px 12px;font-size:14px;font-weight:500;border-radius:6px;transition:all .25s cubic-bezier(.4,0,.2,1);white-space:nowrap;display:inline-flex;align-items:center;justify-content:center;min-height:36px;transform:translateZ(0);position:relative;overflow:hidden}.date-range-btn:before{content:\"\";position:absolute;top:50%;left:50%;width:0;height:0;background:#fff3;border-radius:50%;transform:translate(-50%,-50%);transition:width .25s,height .25s}.date-range-btn:active:before{width:300px;height:300px}.calendar-btn{border-color:#0d6efd;color:#0d6efd;background-color:transparent}.calendar-btn:hover{background-color:#0d6efd;color:#fff;transform:translateY(-1px);box-shadow:0 4px 12px #0d6efd4d}.clear-btn{border-color:#dc3545;color:#dc3545;background-color:transparent}.clear-btn:hover{background-color:#dc3545;color:#fff;transform:translateY(-1px);box-shadow:0 4px 12px #dc35454d}.date-range-label{font-size:14px;font-weight:500;padding:4px 8px;min-width:180px;text-align:center;white-space:nowrap;cursor:pointer}.date-range-btn .bi{font-size:14px;transition:transform .2s ease}.date-range-btn:hover .bi{transform:scale(1.1)}@media (max-width: 768px){.date-range-container{flex-wrap:wrap;justify-content:flex-start}.date-range-label{min-width:100%;margin-top:8px;order:3}}.date-range-btn:focus{outline:none;box-shadow:0 0 0 3px #0d6efd40}.clear-btn:focus{box-shadow:0 0 0 3px #dc354540}.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}.badge-overflow-wrapper{width:100%;min-width:0;display:flex;align-items:center}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i2.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: i2.NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { kind: "directive", type: i2.NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { kind: "directive", type: i2.NgSwitchDefault, selector: "[ngSwitchDefault]" }, { kind: "pipe", type: i2.TitleCasePipe, name: "titlecase" }, { kind: "pipe", type: i2.DatePipe, name: "date" }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i3.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i3.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i3.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: i3.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i3.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i3.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i3.RadioControlValueAccessor, selector: "input[type=radio][formControlName],input[type=radio][formControl],input[type=radio][ngModel]", inputs: ["name", "formControlName", "value"] }, { kind: "directive", type: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i3.PatternValidator, selector: "[pattern][formControlName],[pattern][formControl],[pattern][ngModel]", inputs: ["pattern"] }, { kind: "directive", type: i3.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: InlineSVGModule }, { kind: "directive", type: i4.InlineSVGDirective, selector: "[inlineSVG]", inputs: ["inlineSVG", "resolveSVGUrl", "replaceContents", "prepend", "injectComponent", "cacheSVG", "setSVGAttributes", "removeSVGAttributes", "forceEvalStyles", "evalScripts", "fallbackImgUrl", "fallbackSVG", "onSVGLoaded"], outputs: ["onSVGInserted", "onSVGFailed"] }, { kind: "pipe", type: FilterPipe, name: "filter" }, { kind: "pipe", type: PinnedColumnsPipe, name: "pinnedColumns" }, { kind: "ngmodule", type: DragDropModule }, { kind: "directive", type: i5.CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: i5.CdkDropListGroup, selector: "[cdkDropListGroup]", inputs: ["cdkDropListGroupDisabled"], exportAs: ["cdkDropListGroup"] }, { kind: "directive", type: i5.CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "directive", type: i5.CdkDragHandle, selector: "[cdkDragHandle]", inputs: ["cdkDragHandleDisabled"] }, { kind: "directive", type: i5.CdkDragPreview, selector: "ng-template[cdkDragPreview]", inputs: ["data", "matchSize"] }, { kind: "directive", type: i5.CdkDragPlaceholder, selector: "ng-template[cdkDragPlaceholder]", inputs: ["data"] }, { kind: "ngmodule", type: BsDatepickerModule }, { kind: "directive", type: i6.BsDaterangepickerDirective, selector: "[bsDaterangepicker]", inputs: ["placement", "triggers", "outsideClick", "container", "outsideEsc", "isOpen", "bsValue", "bsConfig", "isDisabled", "minDate", "maxDate", "dateCustomClasses", "daysDisabled", "datesDisabled", "datesEnabled"], outputs: ["onShown", "onHidden", "bsValueChange"], exportAs: ["bsDaterangepicker"] }, { kind: "directive", type: i6.BsDaterangepickerInputDirective, selector: "input[bsDaterangepicker]" }, { kind: "ngmodule", type: ScrollingModule }, { kind: "directive", type: i7.CdkFixedSizeVirtualScroll, selector: "cdk-virtual-scroll-viewport[itemSize]", inputs: ["itemSize", "minBufferPx", "maxBufferPx"] }, { kind: "directive", type: i7.CdkVirtualForOf, selector: "[cdkVirtualFor][cdkVirtualForOf]", inputs: ["cdkVirtualForOf", "cdkVirtualForTrackBy", "cdkVirtualForTemplate", "cdkVirtualForTemplateCacheSize"] }, { kind: "component", type: i7.CdkVirtualScrollViewport, selector: "cdk-virtual-scroll-viewport", inputs: ["orientation", "appendOnly"], outputs: ["scrolledIndexChange"] }, { kind: "component", type: BadgeOverflowComponent, selector: "app-badge-overflow", inputs: ["badges", "maxWidth"], outputs: ["badgeMouseEnter", "badgeMouseLeave", "overflowCountClick"] }, { kind: "pipe", type: TimezoneFormatPipe, name: "timezoneFormat" }], animations: [
9012
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: TimeSheetComponent, isStandalone: true, selector: "time-sheet", 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", headerTextFontsSize: "headerTextFontsSize", bodyTextFontsSize: "bodyTextFontsSize", headerFontWeight: "headerFontWeight", bodyFontWeight: "bodyFontWeight", checkedRowBackgroundColor: "checkedRowBackgroundColor", dropdownsBackgroundColor: "dropdownsBackgroundColor", footerRowHeight: "footerRowHeight", topGroupedBadgesBackgroundColor: "topGroupedBadgesBackgroundColor", showRowsGrouping: "showRowsGrouping", showFilterRow: "showFilterRow", fontFaimly: "fontFaimly", showSideMenu: "showSideMenu", footerPadding: "footerPadding", topFilterRowHeight: "topFilterRowHeight", rowShadingEnabled: "rowShadingEnabled", showSerialNumber: "showSerialNumber", enableExport: "enableExport", singleSpaAssetsPath: "singleSpaAssetsPath", filtersConfig: "filtersConfig", loading: "loading", dataSetLoading: "dataSetLoading", 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", selectedPresetId: "selectedPresetId", closeDropdown: "closeDropdown", globalSearchText: "globalSearchText", nestedTablerowFontsize: "nestedTablerowFontsize", nestedTableHeaderRowHeight: "nestedTableHeaderRowHeight", nestedTablerowHeight: "nestedTablerowHeight", gridType: "gridType", isSingleDay: "isSingleDay", leftPinnedBoxshadow: "leftPinnedBoxshadow", rightPinnedBoxshadow: "rightPinnedBoxshadow", enableAccordionShadow: "enableAccordionShadow", enableAccordionSeparators: "enableAccordionSeparators", enableRowShading: "enableRowShading", selectedRowsBackgroundColor: "selectedRowsBackgroundColor", nestedTableHeaderBAckgroundColor: "nestedTableHeaderBAckgroundColor", tableView: "tableView", columnThreedotsMunuConfig: "columnThreedotsMunuConfig", timezonePrefs: "timezonePrefs", enableProgressiveLoading: "enableProgressiveLoading", progressiveChunkSize: "progressiveChunkSize", progressiveDelay: "progressiveDelay", detailsIconPosition: "detailsIconPosition", detailsPosition: "detailsPosition", buttons: "buttons", isStartDateNotEqualToEndDate: "isStartDateNotEqualToEndDate" }, outputs: { onShortBreakClick: "onShortBreakClick", searchEvent: "searchEvent", changeLayout: "changeLayout", filterOptions: "filterOptions", filterCleared: "filterCleared", genericEvent: "genericEvent", tablePresetConfig: "tablePresetConfig", sortingOrderOptions: "sortingOrderOptions", createUpdateConfigListing: "createUpdateConfigListing", loadMore: "loadMore", emailClicked: "emailClicked", addAttendanceClicked: "addAttendanceClicked", backPayClicked: "backPayClicked", grandTotalClicked: "grandTotalClicked", printClicked: "printClicked", exportClicked: "exportClicked", exportDailyClicked: "exportDailyClicked", deleteClicked: "deleteClicked" }, 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: "dataGridContainer", first: true, predicate: ["dataGridContainer"], 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: "headerContainer", first: true, predicate: ["headerContainer"], descendants: true }, { propertyName: "dataContainer", first: true, predicate: ["dataContainer"], descendants: true }, { propertyName: "leftContainer", first: true, predicate: ["leftContainer"], descendants: true }, { propertyName: "rightContainer", first: true, predicate: ["rightContainer"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div class=\"position-relative h-100\">\r\n <!-- <h1>abu </h1> -->\r\n <div\r\n class=\"d-flex justify-content-between mb-3 align-items-center position-relative\"\r\n >\r\n <div class=\"col-4 global-search position-relative\">\r\n\r\n <span\r\n\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 style=\"height: 36px\"\r\n class=\"form-control\"\r\n placeholder=\"Search all columns and press Enter\"\r\n [(ngModel)]=\"tableSearch\"\r\n (keydown.enter)=\"onGlobalSearch()\"\r\n\r\n />\r\n <span\r\n *ngIf=\"tableSearch\"\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/x.svg'\"\r\n class=\"data-grid-svg-icon position-absolute end-0 top-50 translate-middle-y me-2 cursor-pointer\"\r\n (click)=\"onSearchReset()\"\r\n title=\"Clear search\"\r\n ></span>\r\n\r\n </div>\r\n\r\n <!-- Date Picker Buttons -->\r\n <!-- Date Picker Section - Improved Version -->\r\n<div class=\"position-relative d-flex justify-content-center align-items-center ms-2 date-range-container\">\r\n\r\n <!-- Hidden Date Picker Input -->\r\n <input\r\n type=\"text\"\r\n class=\"form-control\"\r\n bsDaterangepicker\r\n #picker=\"bsDaterangepicker\"\r\n [(ngModel)]=\"bsRangeValue\"\r\n [bsConfig]=\"bsConfig\"\r\n (bsValueChange)=\"onRangeSelected($event, picker)\"\r\n style=\"opacity: 0; width: 0; height: 0; position: absolute;\"\r\n />\r\n\r\n <!-- Left Arrow Button -->\r\n <span\r\n class=\"text-primary cursor-pointer me-2 date-range-btn arrow-btn\"\r\n (click)=\"navigateDate('left')\"\r\n title=\"Previous Date Range\"\r\n *ngIf=\"bsRangeValue && bsRangeValue.length > 0\"\r\n >\r\n <span class=\"bi bi-chevron-left\"></span>\r\n </span>\r\n\r\n <!-- Date Range Label -->\r\n <span\r\n *ngIf=\"bsRangeValue && bsRangeValue.length > 0\"\r\n class=\"text-primary date-range-label cursor-pointer\"\r\n (click)=\"togglePicker(picker)\"\r\n title=\"Click to open calendar\"\r\n >\r\n {{ bsRangeValue[0] | timezoneFormat:prefs:'date' }} - {{ bsRangeValue[1] | timezoneFormat:prefs:'date' }}\r\n </span>\r\n\r\n <!-- Right Arrow Button -->\r\n <span\r\n class=\"text-primary cursor-pointer ms-2 date-range-btn arrow-btn\"\r\n (click)=\"navigateDate('right')\"\r\n title=\"Next Date Range\"\r\n *ngIf=\"bsRangeValue && bsRangeValue.length > 0\"\r\n >\r\n <span class=\"bi bi-chevron-right\"></span>\r\n </span>\r\n\r\n\r\n\r\n</div>\r\n\r\n <div class=\"d-flex gap-2 align-items-center table-right-top-actions\">\r\n\r\n <!-- Pivot Mode Button -->\r\n <!-- <a\r\n href=\"JavaScript:void(0)\"\r\n class=\"button button-small btn btn-active-primary border border-primary me-2 header-icon\"\r\n (click)=\"togglePivotMode()\"\r\n [class.active]=\"pivotMode\"\r\n title=\"Toggle Pivot Mode\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/pivot.svg'\"\r\n class=\"svg-icon svg-icon-2\"\r\n ></span>\r\n </a> -->\r\n\r\n <div class=\"action-buttons-row d-flex gap-2 align-items-center\">\r\n <a\r\n href=\"JavaScript:void(0)\"\r\n class=\"button button-small btn btn-active-primary border border-primary p-0 d-flex align-items-center justify-content-center px-3\"\r\n (click)=\"togglePicker(picker)\"\r\n title=\"Select Date Range\"\r\n >\r\n <span class=\"bi bi-calendar3 text-primary\"></span>\r\n <span class=\"label-hidden text-white\">Calendar</span>\r\n </a>\r\n <button\r\n *ngIf=\"bsRangeValue && bsRangeValue.length > 0 && !isDefaultDateRange\"\r\n type=\"button\"\r\n class=\"button button-small btn btn-active-danger border border-danger p-0 d-flex align-items-center justify-content-center px-3\"\r\n (click)=\"clearDateRange()\"\r\n title=\"Clear Date Range\"\r\n >\r\n <span class=\"bi bi-x-circle text-danger\"></span>\r\n <span class=\"label-hidden text-white\">Clear</span>\r\n </button>\r\n</div>\r\n<ng-container *ngFor=\"let button of buttons\">\r\n <div\r\n class=\"action-buttons-row d-flex align-items-center\"\r\n *ngIf=\"getButtonPermission(button) && (!button.condition || (button.condition === '!isSingleDay' && !isSingleDay) || (button.condition === 'isSingleDay' && isSingleDay))\"\r\n >\r\n <a\r\n href=\"JavaScript:void(0)\"\r\n (click)=\"onActionButtonClick(button.name)\"\r\n class=\"button\"\r\n [title]=\"button.name\"\r\n >\r\n <span\r\n *ngIf=\"button.is_showIcon\"\r\n [inlineSVG]=\"button.iconPath\"\r\n class=\"svg-icon\"\r\n ></span>\r\n <span\r\n class=\"label-hidden\"\r\n >{{ button.name }}</span\r\n >\r\n </a>\r\n </div>\r\n</ng-container>\r\n\r\n<!-- Calendar Button -->\r\n\r\n\r\n<!-- Existing filter, settings, etc. -->\r\n <div\r\n *ngIf=\"!showFilterRow\"\r\n class=\"cursor-pointer position-relative action-buttons-row d-flex align-items-center\"\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 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 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\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 <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 *ngIf=\"activeFilteredColumns?.length\">\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 >\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 class=\"d-flex gap-2 align-items-center me-5\">\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 <ng-container\r\n *ngFor=\"\r\n let child of groupedColumns;\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 groupedColumns.length > 1 && i != groupedColumns.length - 1\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </div>\r\n\r\n\r\n\r\n\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 class=\"data-grid-header left-pinned\" #leftPinnedHeader>\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]=\"65\"\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</div>\r\n <div\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 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 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: 0.2px\"\r\n [style.background-color]=\"headerBackgroundColor\"\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 [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)=\"onCenterHeaderScroll($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)=\"openThreeDotsMenu($event, 'group')\"\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)=\"onResizeGroupBox($event)\"\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 === 'TimeSheet' && !areDatesSelectedAndEqual\"\r\n >\r\n </span> -->\r\n <div\r\n class=\"dragable-header\"\r\n (cdkDragStarted)=\"\r\n checkColumnGroupingStatus(col); dragStartOnGroup(col)\r\n \"\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 [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: 'centerColumns'\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 *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 *ngIf=\"!areDatesSelectedAndEqual\" class=\"header-cell border-below\" [style.width.px]=\"30\" [style.height.px]=\"headerRowHeight\" [style.backgroundColor]=\"headerBackgroundColor\"></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 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: 'previewRightPinnedColumns'\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 [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: 'centerColumns'\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\"\r\n >\r\n No Record Found\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\"\r\n style=\"\r\n z-index: 999;\r\n background: rgba(255, 255, 255, 0.8);\r\n backdrop-filter: blur(1px);\r\n \"\r\n >\r\n <div class=\"text-center p-2\">\r\n <div class=\"spinner-border text-primary\" role=\"status\"></div> Loading...\r\n</div>\r\n </div>\r\n\r\n <!-- Card View -->\r\n \r\n\r\n <!-- Table View -->\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 *ngIf=\"dataSet.length\"\r\n >\r\n <!-- LEFT PINNED -->\r\n <div [style.height.px]=\"!groupedColumns.length ? originalDataSet.length * rowHeight: 0\"></div>\r\n <div [class.h-100]=\"originalDataSet.length <= 10\">\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 *ngIf=\"!loading && !dataSetLoading\"\r\n [@rowDynamic]=\"rowAnimation\"\r\n [style.transform]=\"\r\n 'translateY(' + startIndex * rowHeight + 'px)'\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 }\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=\"\"\r\n [style.width.px]=\"centerPinnedHeader.clientWidth\"\r\n >\r\n <div\r\n class=\"data-grid-body center-scrollable\"\r\n [@rowDynamic]=\"rowAnimation\" *ngIf=\"!loading && !dataSetLoading\"\r\n style=\"overflow-y: hidden; overflow-x: auto\"\r\n [style.transform]=\"\r\n 'translateY(' + startIndex * rowHeight + 'px)'\r\n \"\r\n [style.backgroundColor]=\"bodyBackgroundColor\"\r\n #centerScrollableBody\r\n (scroll)=\"onCenterBodyScroll($event)\"\r\n [style.boxShadow]=\"leftPinnedBoxshadow\"\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: previewCenterColumns,\r\n isEven: (startIndex + i) % 2 === 0,\r\n isOdd: (startIndex + i) % 2 !== 0,\r\n section: 'center'\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 <= 10\"\r\n [style.max-width.px]=\"isScrollbarVisible ? rightPinnedHeader.offsetWidth - 15: rightPinnedHeader.offsetWidth\"\r\n >\r\n <div\r\n class=\"data-grid-body right-pinned-body w-100\"\r\n style=\"overflow-y: hidden\"\r\n [style.transform]=\"\r\n 'translateY(' + startIndex * rowHeight + 'px)'\r\n \"\r\n [style.boxShadow]=\"rightPinnedBoxshadow\"\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 }\r\n \"\r\n ></ng-container>\r\n </ng-container>\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 * (paginationConfig.totalResults || flattenedData.length)\"></div>\r\n </div>\r\n </div>\r\n\r\n <!-- Horizintal Fake Scrollbars -->\r\n <div class=\"d-flex justify-content-between\" *ngIf=\"dataSet.length\">\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)=\"onHorizintalFakeScroll($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\"></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 && !hasOpenAccordion\"\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-white]=\"\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-white]=\"\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 [style.height.px]=\"footerRowHeight\" class=\"border-top\">\r\n <!-- Rows: <span class=\"fw-500 ms-1\">{{ dataSet.length }}</span> -->\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.selectedPageSize\"\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=\"\"> per page </span>\r\n </div>\r\n\r\n <div class=\"page-info\">\r\n Results: {{ paginationConfig.page }}-{{\r\n paginationConfig.page * paginationConfig.limit\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-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)=\"onResizeGroup($event, col, pinnedRight)\"\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 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)=\"openThreeDotsMenu($event, child); openFilteronThreeDotsClick(child)\"\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)=\"openThreeDotsMenu($event, child)\"\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 >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n columnMenu;\r\n context: { col: child }\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)=\"onResizeColumn($event, child)\"\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)]=\"col.filterValue\"\r\n (ngModelChange)=\"onFilterChange(col)\"\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 ><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 class=\"group-column-wrapper\">\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\"\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)=\"openThreeDotsMenu($event, col); openFilteronThreeDotsClick(col)\"\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 <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath +\r\n (sortingConfig?.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 mt-1\"\r\n ></span>\r\n </div>\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\"\r\n [style.left.px]=\"\r\n -(!col?.pinned ? centerPinnedHeader.scrollLeft : 0)\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"columnMenu; context: { col: col }\"\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)=\"onResizeColumn($event, col)\"\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 />\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 ><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>\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 border-below d-flex align-items-center\"\r\n [style.height.px]=\"rowHeight\"\r\n [style.width]=\"\r\n section == 'center'\r\n ? centerScrollableBody?.nativeElement?.scrollWidth + '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]=\"65\"\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 >\r\n {{ row.__virtualIndex }}\r\n </div>\r\n <div\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 >\r\n <input style=\"width: 16px; height: 16px\" type=\"checkbox\" />\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 class=\"d-flex align-items-center ps-2 h-100\"\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 * 16 : 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\"\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\">\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 }\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 class=\"d-flex\" [style.height.px]=\"rowHeight\">\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=\"section == 'center' && gridType === 'TimeSheet' && detailsIconPosition === 'start' && !areDatesSelectedAndEqual\"\r\n [ngStyle]=\"{\r\n 'background-color':\r\n hoveredRowId === (row._id || row.id)\r\n ? rowHoverColor\r\n : isRowSelected(row)\r\n ? checkedRowBackgroundColor\r\n : isEven\r\n ? evenRowsBackgroundColor\r\n : oddRowsBackgroundColor\r\n }\"\r\n (click)=\"row.isDetailsExpand = !row.isDetailsExpand\"\r\n >\r\n <span\r\n class=\"data-grid-svg-icon\"\r\n [inlineSVG]=\"\r\n row.isDetailsExpand\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, row?.details?.data?.length ? 'accordion-parent' : 'main')\"\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':\r\n hoveredRowId === (row._id || row.id)\r\n ? rowHoverColor\r\n : isRowSelected(row)\r\n ? checkedRowBackgroundColor\r\n : isEven\r\n ? evenRowsBackgroundColor\r\n : oddRowsBackgroundColor\r\n }\"\r\n ></div>\r\n <div\r\n (contextmenu)=\"onRightClick($event, row, row?.details?.data?.length ? 'accordion-parent' : 'main')\"\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':\r\n hoveredRowId === (row._id || row.id)\r\n ? rowHoverColor\r\n : isRowSelected(row)\r\n ? checkedRowBackgroundColor\r\n : isEven\r\n ? evenRowsBackgroundColor\r\n : oddRowsBackgroundColor\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]=\"65\"\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 >\r\n {{ row.__virtualIndex }}\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\"\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 >\r\n <input\r\n *ngIf=\"hasAnyVisibleColumn\"\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 }\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\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 }\r\n \"\r\n ></ng-container>\r\n </ng-template>\r\n </ng-container>\r\n </div>\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=\"section == 'center' && gridType === 'TimeSheet' && detailsIconPosition === 'end' && !areDatesSelectedAndEqual\"\r\n [ngStyle]=\"{\r\n 'background-color':\r\n hoveredRowId === (row._id || row.id)\r\n ? rowHoverColor\r\n : isRowSelected(row)\r\n ? checkedRowBackgroundColor\r\n : isEven\r\n ? evenRowsBackgroundColor\r\n : oddRowsBackgroundColor\r\n }\"\r\n (click)=\"row.isDetailsExpand = !row.isDetailsExpand\"\r\n >\r\n <span\r\n class=\"data-grid-svg-icon\"\r\n [inlineSVG]=\"\r\n row.isDetailsExpand\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 <!-- LEFT PINNED: Empty table to keep alignment -->\r\n <div *ngIf=\"section === 'left' && row.isDetailsExpand && !isSingleDay\" class=\"accordion-details data-grid-accordion-section\" [style.color]=\"headerTextColor\" style=\"max-height: 350px; min-height: 150px ; overflow: hidden;\">\r\n <table class=\"nested-table table table-sm w-100 mb-0 data-grid-accordion-table\" [class.show-shadow]=\"rowShadingEnabled\">\r\n <thead>\r\n <tr [style.height.px]=\"nestedTableHeaderRowHeight\" [style.backgroundColor]=\"headerBackgroundColor\" [style.color]=\"headerTextColor\" [style.fontSize.px]=\"headerTextFontsSize\" [style.fontWeight]=\"headerFontWeight\">\r\n <th *ngFor=\"let _ of [1, 2, 3, 4, 5]\"></th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <tr [style.height.px]=\"nestedTablerowHeight\" *ngFor=\"let _ of row.details.data\" [style.backgroundColor]=\"headerBackgroundColor\">\r\n <td *ngFor=\"let __ of [1, 2, 3, 4, 5]\"></td>\r\n </tr>\r\n </tbody>\r\n </table>\r\n </div>\r\n\r\n<!-- CENTER SECTION: Actual details table -->\r\n\r\n<div *ngIf=\"section === 'center' && row.isDetailsExpand && !isSingleDay\" class=\"accordion-details-wrapper data-grid-accordion\" [style.fontFamily]=\"fontFaimly\" [style.fontSize.px]=\"bodyTextFontsSize\" style=\"display: flex; width: 100%; max-height: 350px; min-height: 150px ; overflow: hidden ; \">\r\n <!-- LEFT SECTION OF ACCORDION -->\r\n <div #leftContainer class=\"accordion-left-section data-pin-body-wrapper data-grid-accordion-section\" [attr.data-detail-row-id]=\"row._id || row.id\" (scroll)=\"onDetailLeftScroll($event, row)\" style=\"flex-shrink: 0; overflow-y: auto; overflow-x: hidden;\">\r\n <table class=\"nested-table table-sm mb-0 data-grid-accordion-table\" [class.show-borders]=\"showVerticalBorder\" [class.show-shadow]=\"rowShadingEnabled\" style=\"table-layout: fixed; width: auto;\">\r\n <thead>\r\n <tr [style.height.px]=\"nestedTableHeaderRowHeight\" [style.backgroundColor]=\"headerBackgroundColor\" [style.color]=\"headerTextColor\" [style.fontSize.px]=\"headerTextFontsSize\" [style.fontWeight]=\"headerFontWeight\">\r\n <ng-container *ngFor=\"let col of row.details.columns | pinnedColumns:'left'; trackBy: trackByField\">\r\n <th *ngIf=\"col.is_visible !== false\"\r\n class=\"px-4\"\r\n [class.filter-applied]=\"isAccordionColumnFiltered(row, col)\"\r\n [attr.field]=\"col.field\"\r\n [attr.pinned]=\"col.pinned\"\r\n [style.width.px]=\"col.width || 150\"\r\n [style.min-width.px]=\"col.width || 150\">\r\n <div class=\"d-flex justify-content-between align-items-center\" style=\"width: 100%;\">\r\n <span class=\"d-flex align-items-center gap-1\">\r\n <span *ngIf=\"col.pinned\" [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/pin-blue.svg'\" class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"></span>\r\n {{ col.header }}\r\n <span *ngIf=\"isAccordionColumnFiltered(row, col)\"\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\"\r\n class=\"data-grid-svg-icon text-primary ms-1\"\r\n style=\"font-size: 12px;\"></span>\r\n </span>\r\n <span class=\"three-dots p-1\"\r\n (click)=\"openDetailThreeDotsMenus($event, col, row)\"\r\n style=\"cursor: pointer;\">\r\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/three-dots-vertical.svg'\" class=\"data-grid-svg-icon\"></span>\r\n </span>\r\n </div>\r\n <!-- <div class=\"resize-handles\" (mousedown)=\"onResizeDetailColumn($event, row, col)\">\r\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/resize-handle.svg'\" class=\"data-grid-svg-icon text-primary\"></span>\r\n </div> -->\r\n <ng-container *ngIf=\"activeDetailCol?.field == col.field && activeDetailRow === row\">\r\n <div class=\"position-absolute detail-column-menu-wrapper\"\r\n [style.top.px]=\"nestedTableHeaderRowHeight\"\r\n [style.left.px]=\"0\">\r\n <ng-container *ngTemplateOutlet=\"detailColumnMenu; context: { col: col, row: row }\"></ng-container>\r\n </div>\r\n </ng-container>\r\n </th>\r\n </ng-container>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <tr [style.height.px]=\"nestedTablerowHeight\" *ngFor=\"let d of row.details.data; let j = index; trackBy: trackById\">\r\n <ng-container *ngFor=\"let col of row.details.columns | pinnedColumns:'left'; let localK = index; trackBy: trackByField\">\r\n <td *ngIf=\"col.is_visible !== false\"\r\n class=\"px-4\"\r\n (mousedown)=\"startDetailSelection(row, j, localK, col.field, $event, 'left')\"\r\n (mouseenter)=\"extendDetailSelection(row, j, localK, col.field, $event, 'left')\"\r\n [class.selected-cell]=\"isDetailCellSelected(row, j, localK, col.field, 'left')\"\r\n [attr.field]=\"col.field\"\r\n [attr.pinned]=\"col.pinned\"\r\n [style.fontSize.px]=\"nestedTablerowFontsize\"\r\n (dblclick)=\"enableDetailEdits(row, d, col)\"\r\n [class.active-cell-detail]=\"isActiveDetailCell(row, d, col)\">\r\n <!-- Use the same rendering logic as center section -->\r\n <ng-container [ngSwitch]=\"col.field\">\r\n\r\n <ng-container *ngSwitchCase=\"'manually_logs'\" class=\"d-flex justify-content-start align-items-center pointer position-relative\">\r\n <ng-container *ngIf=\"d.manually_logs?.length > 0; else noManualLogsIcon\">\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/eye.svg'\"\r\n class=\"data-grid-svg-icon text-primary\"\r\n style=\"cursor: pointer; font-size: 16px;\"\r\n (mouseenter)=\"showManualLogsTooltip($event, row, d)\"\r\n (mouseleave)=\"hideManualLogsTooltip()\">\r\n </span>\r\n </ng-container>\r\n <ng-template #noManualLogsIcon>\u2013</ng-template>\r\n</ng-container>\r\n <!-- Breaks -->\r\n <ng-container *ngSwitchCase=\"'breaks'\">\r\n <ng-container *ngIf=\"d[col.field]?.length; else noBreaksLeft\">\r\n <app-badge-overflow\r\n [badges]=\"getBreakBadges(d[col.field])\"\r\n [maxWidth]=\"col.width || 200\"\r\n (badgeMouseEnter)=\"showBreakTooltip($event.event, $event.badge.data)\"\r\n (badgeMouseLeave)=\"hideBreakTooltip()\"\r\n (overflowCountClick)=\"onDetailBadgeOverflowCountClick(col, d)\">\r\n</app-badge-overflow>\r\n </ng-container>\r\n <ng-template #noBreaksLeft>\r\n <div >\r\n -\r\n </div>\r\n </ng-template>\r\n </ng-container>\r\n\r\n <!-- Short Breaks -->\r\n <ng-container *ngSwitchCase=\"'short_breaks'\">\r\n <ng-container *ngIf=\"d[col.field]?.short_break_duration; else noShortBreakLeft\">\r\n <div (dblclick)=\"onShortBreakClick.emit(d)\">\r\n <app-badge-overflow\r\n [badges]=\"getShortBreakBadges(d[col.field])\"\r\n [maxWidth]=\"col.width || 200\"\r\n (badgeMouseEnter)=\"showShortBreakTooltip($event.event, $event.badge.data)\"\r\n (badgeMouseLeave)=\"hideShortBreakTooltip()\"\r\n (badgeClick)=\"handleShortBreakClick(d, $event)\"\r\n (overflowCountClick)=\"onDetailBadgeOverflowCountClick(col, d)\">\r\n </app-badge-overflow>\r\n </div>\r\n </ng-container>\r\n <ng-template #noShortBreakLeft>\r\n <div >-</div>\r\n </ng-template>\r\n </ng-container>\r\n\r\n <!-- Short Leave -->\r\n <!-- Short Leave -->\r\n<ng-container *ngSwitchCase=\"'short_leave'\">\r\n <ng-container *ngIf=\"row.short_leave && row.short_leave.length > 0; else noShortLeaveMain\">\r\n <div class=\"w-100 d-flex main-progress-bar justify-content-center align-items-center\" \r\n style=\"background-color: rgb(111, 97, 207); height: 20px; border-radius: 4px; position: relative;\"\r\n (mouseenter)=\"showShortLeaveTooltip($event, row)\"\r\n (mouseleave)=\"hideShortLeaveTooltip()\">\r\n <span class=\"d-block\" [style.min-width.%]=\"row.short_leave[0].short_leave_time_percentage\" \r\n style=\"background-color: rgb(238, 99, 82); height: 100%; border-radius: 4px;\"></span>\r\n <span style=\"position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); color: white; font-size: 12px; font-weight: bold;\">\r\n {{ row.short_leave[0].short_leave_time_percentage }}%\r\n </span>\r\n </div>\r\n </ng-container>\r\n <ng-template #noShortLeaveMain>-</ng-template>\r\n</ng-container>\r\n\r\n<div *ngSwitchCase=\"'is_un_restricted'\" class=\"d-flex justify-content-start flex-column pointer position-relative\" (mouseenter)=\"showRestrictionTooltip($event, row, d); preventRestrictionTooltipHide()\" (mouseleave)=\"hideRestrictionTooltip()\">\r\n <span class=\"\" [class.restriction-indicator]=\"row.attendance_log_detail?.length > 0\">\r\n {{ d.is_un_restricted ? 'Yes' : 'No' }}\r\n </span>\r\n </div>\r\n\r\n <div *ngSwitchCase=\"'is_payroll_processed'\" class=\"d-flex justify-content-start flex-column pointer position-relative\" >\r\n <span class=\"\" >\r\n {{ d.is_payroll_processed ? 'Yes' : 'No' }}\r\n </span>\r\n </div>\r\n\r\n\r\n <!-- Status -->\r\n <ng-container *ngSwitchCase=\"'status'\">\r\n <ng-container *ngIf=\"getNestedValue(d, col.field); else noStatus\">\r\n <span class=\"badge\" [class]=\"getStatusBadgeClass(getNestedValue(d, col.field))\">\r\n {{ transformStatus(getNestedValue(d, col.field)) }}\r\n </span>\r\n </ng-container>\r\n <ng-template #noStatus>-</ng-template>\r\n</ng-container>\r\n\r\n<!-- Attendance Status -->\r\n<ng-container *ngSwitchCase=\"'attendanceStatus'\">\r\n <ng-container *ngIf=\"getNestedValue(d, col.field); else noAttendanceStatus\">\r\n <span class=\"badge\" [class]=\"getAttendanceStatusBadgeClass(getNestedValue(d, col.field))\">\r\n {{ transformStatus(getNestedValue(d, col.field)) }}\r\n </span>\r\n </ng-container>\r\n <ng-template #noAttendanceStatus>-</ng-template>\r\n</ng-container>\r\n\r\n <!-- Default fallback -->\r\n <ng-container *ngSwitchDefault>\r\n {{\r\n col.type === 'date'\r\n ? (getNestedValue(d, col.field) ? (getNestedValue(d, col.field) | timezoneFormat:prefs:'date') : '-')\r\n : col.type === 'time'\r\n ? ((getTimeValue(getNestedValue(d, col.field)) | timezoneFormat:prefs:'time'))\r\n : (getNestedValue(d, col.field)?.value || getNestedValue(d, col.field)?.name || getNestedValue(d, col.field) || '-')\r\n }}\r\n </ng-container>\r\n </ng-container>\r\n </td>\r\n </ng-container>\r\n </tr>\r\n</tbody>\r\n </table>\r\n </div>\r\n\r\n <!-- CENTER SECTION OF ACCORDION (WITH VIRTUAL SCROLL) -->\r\n\r\n<div class=\"accordion-center-section data-grid-accordion-section\" style=\"flex: 1; min-width: 0; display: flex; flex-direction: column; overflow: hidden;\">\r\n <!-- Header Section -->\r\n <div class=\"header-container\" style=\"overflow-x: auto; scrollbar-width: none; -ms-overflow-style: none;\" #headerContainer (scroll)=\"syncScroll($event)\">\r\n <table class=\"nested-table table-sm mb-0 data-grid-accordion-table\" [class.show-borders]=\"showVerticalBorder\" [class.show-shadow]=\"rowShadingEnabled\" style=\"table-layout: fixed; width: 100%;\">\r\n <thead>\r\n <tr\r\n [style.height.px]=\"nestedTableHeaderRowHeight\"\r\n cdkDropList\r\n [cdkDropListData]=\"row?.details.columns\"\r\n cdkDropListOrientation=\"horizontal\"\r\n (cdkDropListDropped)=\"dropColumn($event, row)\">\r\n <ng-container *ngFor=\"let col of row.details.columns; let i = index\">\r\n <th\r\n *ngIf=\"col.is_visible !== false && !col.pinned\"\r\n class=\"px-4\"\r\n cdkDrag\r\n [attr.field]=\"col.field\"\r\n [class.filter-applied]=\"isAccordionColumnFiltered(row, col)\"\r\n [style.width.px]=\"col.width || 150\"\r\n [style.min-width.px]=\"col.width || 150\"\r\n [style.backgroundColor]=\"headerBackgroundColor\"\r\n [style.color]=\"headerTextColor\"\r\n [style.fontSize.px]=\"headerTextFontsSize\"\r\n [style.fontWeight]=\"headerFontWeight\"\r\n style=\"cursor: move; position: relative;\">\r\n <div class=\"d-flex justify-content-between align-items-center\" style=\"width: 100%;\">\r\n <span class=\"d-flex align-items-center gap-1\">\r\n <span *ngIf=\"col.pinned\" [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/pin-blue.svg'\" class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"></span>\r\n {{ col.header }}\r\n <span *ngIf=\"isAccordionColumnFiltered(row, col)\"\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\"\r\n class=\"data-grid-svg-icon text-primary ms-1\"\r\n style=\"font-size: 12px;\"></span>\r\n </span>\r\n <span\r\n class=\"three-dots p-1\"\r\n (click)=\"openDetailThreeDotsMenus($event, col, row); activeDetailCol = col; activeDetailRow = row\"\r\n style=\"cursor: pointer;\">\r\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/three-dots-vertical.svg'\" class=\"data-grid-svg-icon\"></span>\r\n </span>\r\n </div>\r\n <!-- <div class=\"resize-handles\" (mousedown)=\"onResizeDetailColumn($event, row, col)\">\r\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/resize-handle.svg'\" class=\"data-grid-svg-icon text-primary\"></span>\r\n </div> -->\r\n <ng-container *ngIf=\"activeDetailCol?.field == col.field && activeDetailRow === row\">\r\n <div class=\"position-absolute detail-column-menu-wrapper\" [style.top.px]=\"nestedTableHeaderRowHeight\" [style.left.px]=\"0\">\r\n <ng-container *ngTemplateOutlet=\"detailColumnMenu; context: { col: col, row: row }\"></ng-container>\r\n </div>\r\n </ng-container>\r\n </th>\r\n </ng-container>\r\n </tr>\r\n </thead>\r\n </table>\r\n </div>\r\n\r\n <!-- Group Badges (if any) -->\r\n <div *ngIf=\"row.details?.groupedColumns?.length\" class=\"detail-group-badges\">\r\n <span *ngFor=\"let g of row.details.groupedColumns; trackBy: trackByField\" class=\"badge bg-light text-dark me-1\">\r\n {{ g.header }}\r\n <span class=\"ms-1 cursor-pointer\" (click)=\"ungroupDetailColumn(g, row)\" [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/x.svg'\"></span>\r\n </span>\r\n </div>\r\n\r\n <!-- No Data Message when filtered results are empty -->\r\n <div *ngIf=\"row.details.data.length === 0\" class=\"d-flex justify-content-center align-items-center\" style=\"flex: 1; min-height: 104px ;\">\r\n <div class=\"text-center text-muted\">\r\n <div class=\"mb-2\">\r\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\" class=\"data-grid-svg-icon text-muted\" style=\"font-size: 24px;\"></span>\r\n </div>\r\n <div class=\"fw-bold\">No records found for this filter.</div>\r\n </div>\r\n </div>\r\n\r\n <!-- Data Table Section with Virtual Scroll -->\r\n <cdk-virtual-scroll-viewport\r\n *ngIf=\"row.details.data.length > 0\"\r\n itemSize=\"{{ nestedTablerowHeight }}\"\r\n minBufferPx=\"200\"\r\n maxBufferPx=\"400\"\r\n class=\"detail-virtual-scroll\"\r\n [attr.data-detail-row-id]=\"row._id || row.id\"\r\n style=\"flex: 1; overflow: auto;\"\r\n #dataContainer\r\n (scroll)=\"syncVerticalScroll($event)\"\r\n (scroll)=\"syncScroll($event)\">\r\n <table class=\"nested-table table-sm mb-0 data-grid-accordion-table\" [class.show-borders]=\"showVerticalBorder\" [class.show-shadow]=\"rowShadingEnabled\" style=\"table-layout: fixed; width: 100%;\">\r\n <tbody>\r\n <tr\r\n class=\"cursor-pointer data-grid-accordion-row\"\r\n *cdkVirtualFor=\"let d of row.details.data; trackBy: trackById; let j = index\"\r\n (contextmenu)=\"onRightClick($event, d, 'accordion-child')\"\r\n [style.height.px]=\"nestedTablerowHeight\">\r\n <ng-container *ngFor=\"let col of row.details.columns; let k = index\">\r\n <td\r\n *ngIf=\"col.is_visible !== false && !col.pinned\"\r\n class=\"px-4\"\r\n (mousedown)=\"startDetailSelection(row, j, k, col.field, $event, 'center')\"\r\n (mouseenter)=\"extendDetailSelection(row, j, k, col.field, $event, 'center')\"\r\n [class.selected-cell]=\"isDetailCellSelected(row, j, k, col.field, 'center')\"\r\n [attr.field]=\"col.field\"\r\n [style.width.px]=\"col.width || 150\"\r\n [style.min-width.px]=\"col.width || 150\"\r\n [style.fontSize.px]=\"bodyTextFontsSize\"\r\n [class.active-cell-detail]=\"isActiveDetailCell(row, d, col)\"\r\n style=\"cursor: pointer; position: relative; overflow: visible; cursor: cell; \">\r\n <div class=\"time-sheet-container\" style=\"overflow: visible; display: flex; gap: 4px; align-items: center; height: 100%; justify-content: center;\">\r\n <ng-container *ngIf=\"col.field === 'breaks' || col.field === 'short_breaks'; else defaultDetailCell\">\r\n <ng-container *ngIf=\"col.field === 'breaks'\">\r\n <ng-container *ngIf=\"d[col.field]?.length; else noBreaks\">\r\n <span *ngFor=\"let breakItem of d[col.field]; let breakIndex = index\"\r\n class=\"circle-value badge-outline break-on text-center\"\r\n [ngClass]=\"(breakItem.break_type?.data_value_name?.toLowerCase() || breakItem.breakType?.toLowerCase()) === 'paid' ? 'break-color-paid' : (breakItem.break_type?.data_value_name?.toLowerCase() || breakItem.breakType?.toLowerCase()) === 'unpaid' ? 'break-color-unpaid' : (breakItem.break_type?.data_value_name?.toLowerCase() || breakItem.breakType?.toLowerCase()) === 'lunch' ? 'break-color-lunch' : 'break-color-default'\"\r\n (mouseenter)=\"showBreakTooltip($event, breakItem)\"\r\n (mouseleave)=\"hideBreakTooltip()\">\r\n {{ breakItem.break_duration }}m\r\n</span>\r\n </ng-container>\r\n <ng-template #noBreaks>\r\n <div\r\n \r\n >\r\n -\r\n</div>\r\n</ng-template>\r\n</ng-container>\r\n <ng-container *ngIf=\"col.field === 'short_breaks' && !isDetailEditing(row, d, col)\">\r\n <ng-container *ngIf=\"d[col.field]?.short_break_duration; else noShortBreak\">\r\n <div (dblclick)=\"onShortBreakClick.emit(d)\">\r\n <app-badge-overflow\r\n [badges]=\"getShortBreakBadges(d[col.field])\"\r\n [maxWidth]=\"col.width || 200\"\r\n (badgeMouseEnter)=\"showShortBreakTooltip($event.event, $event.badge.data)\"\r\n (badgeMouseLeave)=\"hideShortBreakTooltip()\"\r\n (badgeClick)=\"handleShortBreakClick(d, $event)\"\r\n (overflowCountClick)=\"onDetailBadgeOverflowCountClick(col, d)\">\r\n </app-badge-overflow>\r\n </div>\r\n </ng-container>\r\n <ng-template #noShortBreak>\r\n <div >-</div>\r\n </ng-template>\r\n</ng-container>\r\n <ng-container *ngIf=\"isDetailEditing(row, d, col)\">\r\n <input #detailInput type=\"text\" [ngModel]=\"getNestedValue(d, col.field)\" (blur)=\"disableDetailEdits(row, d, col)\" (keydown.enter)=\"disableDetailEdits(row, d, col)\" (keydown.escape)=\"disableDetailEdits(row, d, col)\" [attr.data-edit-key]=\"row._id + '-' + j + '-' + col.field\" class=\"form-control form-control-sm\" style=\"width: 100%; height: auto; position: absolute; top: 0; left: 0; z-index: 10;\" />\r\n </ng-container>\r\n </ng-container>\r\n <ng-template #defaultDetailCell>\r\n <span class=\"d-flex align-items-center h-100\">\r\n <ng-container *ngIf=\"!isDetailEditing(row, d, col)\">\r\n <ng-container [ngSwitch]=\"col.field\">\r\n <!-- \u2705 SHORT LEAVE: Progress bar in detail rows -->\r\n <div *ngSwitchCase=\"'short_leave'\" class=\"position-relative\" style=\"min-width: 100px; width: 150px;\">\r\n <ng-container *ngIf=\"d.short_leave && d.short_leave.length > 0; else noShortLeaveDetail\">\r\n <div\r\n class=\"w-100 d-flex main-progress-bar\"\r\n style=\"background-color: rgb(111, 97, 207); height: 20px; border-radius: 4px; position: relative;\"\r\n (mouseenter)=\"showShortLeaveTooltip($event, d)\"\r\n (mouseleave)=\"hideShortLeaveTooltip()\"\r\n >\r\n <span\r\n class=\"d-block\"\r\n [style.min-width.%]=\"d.short_leave[0].short_leave_time_percentage\"\r\n style=\"background-color: rgb(238, 99, 82); height: 100%; border-radius: 4px;\"\r\n ></span>\r\n <span style=\"position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); color: white; font-size: 12px; font-weight: bold;\">{{ d.short_leave[0].short_leave_time_percentage }}%</span>\r\n </div>\r\n </ng-container>\r\n <ng-template #noShortLeaveDetail>\r\n <div >-</div>\r\n </ng-template>\r\n </div>\r\n\r\n <!-- Status -->\r\n<ng-container *ngSwitchCase=\"'status'\">\r\n <ng-container *ngIf=\"getNestedValue(d, col.field); else noStatus\">\r\n <span class=\"badge\" [class]=\"getStatusBadgeClass(getNestedValue(d, col.field))\">\r\n {{ transformStatus(getNestedValue(d, col.field)) }}\r\n </span>\r\n </ng-container>\r\n <ng-template #noStatus>-</ng-template>\r\n</ng-container>\r\n\r\n<!-- Attendance Status -->\r\n<ng-container *ngSwitchCase=\"'attendanceStatus'\">\r\n <ng-container *ngIf=\"getNestedValue(d, col.field); else noAttendanceStatus\">\r\n <span class=\"badge\" [class]=\"getAttendanceStatusBadgeClass(getNestedValue(d, col.field))\">\r\n {{ transformStatus(getNestedValue(d, col.field)) }}\r\n </span>\r\n </ng-container>\r\n <ng-template #noAttendanceStatus>-</ng-template>\r\n</ng-container>\r\n\r\n <!-- Existing cases -->\r\n <div *ngSwitchCase=\"'is_un_restricted'\" class=\"d-flex justify-content-start flex-column pointer position-relative\" (mouseenter)=\"showRestrictionTooltip($event, row, d); preventRestrictionTooltipHide()\" (mouseleave)=\"hideRestrictionTooltip()\">\r\n <span class=\"popover__wrapper\" [class.restriction-indicator]=\"row.attendance_log_detail?.length > 0\">\r\n {{ d.is_un_restricted ? 'Yes' : 'No' }}\r\n </span>\r\n </div>\r\n\r\n <div *ngSwitchCase=\"'is_payroll_processed'\" class=\"d-flex justify-content-start flex-column pointer position-relative\" >\r\n <span class=\"\" >\r\n {{ d.is_payroll_processed ? 'Yes' : 'No' }}\r\n </span>\r\n </div>\r\n <div *ngSwitchCase=\"'manually_logs'\" class=\"d-flex justify-content-start align-items-center pointer position-relative\">\r\n <ng-container *ngIf=\"d.manually_logs?.length > 0; else noManualLogsIcon\">\r\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/eye.svg'\" class=\"data-grid-svg-icon text-primary\" style=\"cursor: pointer; font-size: 16px;\" (mouseenter)=\"showManualLogsTooltip($event, row, d)\" (mouseleave)=\"hideManualLogsTooltip()\"></span>\r\n </ng-container>\r\n <ng-template #noManualLogsIcon>\r\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/eye-cross.svg'\" class=\"data-grid-svg-icon text-muted\" style=\"font-size: 16px; cursor: not-allowed;\"></span>\r\n </ng-template>\r\n </div>\r\n\r\n <!-- Default fallback -->\r\n <span *ngSwitchDefault>\r\n {{\r\n col.type === 'date'\r\n ? (getNestedValue(d, col.field) ? (getNestedValue(d, col.field) | timezoneFormat:prefs:'date') : '-')\r\n : col.type === 'time'\r\n ? ((getTimeValue(getNestedValue(d, col.field)) | timezoneFormat:prefs:'time'))\r\n : (getNestedValue(d, col.field)?.value || getNestedValue(d, col.field)?.name || getNestedValue(d, col.field) || '-')\r\n }}\r\n </span>\r\n</ng-container>\r\n </ng-container>\r\n <ng-container *ngIf=\"isDetailEditing(row, d, col)\">\r\n <ng-container [ngSwitch]=\"col.type\">\r\n <input *ngSwitchCase=\"'string'\" #detailInput type=\"text\" [ngModel]=\"getNestedValue(d, col.field)\" (blur)=\"disableDetailEdits(row, d, col)\" (keydown.enter)=\"disableDetailEdits(row, d, col)\" (keydown.escape)=\"disableDetailEdits(row, d, col)\" class=\"form-control form-control-sm\" style=\"width: 100%; height: auto;\" />\r\n <input *ngSwitchCase=\"'number'\" #detailInput type=\"number\" [ngModel]=\"getNestedValue(d, col.field)\" (blur)=\"disableDetailEdits(row, d, col)\" (keydown.enter)=\"disableDetailEdits(row, d, col)\" (keydown.escape)=\"disableDetailEdits(row, d, col)\" class=\"form-control form-control-sm\" style=\"width: 100%; height: auto;\" />\r\n <input *ngSwitchCase=\"'date'\" #detailInput type=\"date\" [ngModel]=\"getNestedValue(d, col.field)\" (blur)=\"disableDetailEdits(row, d, col)\" (keydown.enter)=\"disableDetailEdits(row, d, col)\" (keydown.escape)=\"disableDetailEdits(row, d, col)\" class=\"form-control form-control-sm\" style=\"width: 100%; height: auto;\" />\r\n <input *ngSwitchCase=\"'time'\" #detailInput type=\"time\" [ngModel]=\"getNestedValue(d, col.field)\" (blur)=\"disableDetailEdits(row, d, col)\" (keydown.enter)=\"disableDetailEdits(row, d, col)\" (keydown.escape)=\"disableDetailEdits(row, d, col)\" class=\"form-control form-control-sm\" style=\"width: 100%; height: auto;\" />\r\n <input *ngSwitchCase=\"'currency'\" #detailInput type=\"number\" step=\"0.01\" [ngModel]=\"getNestedValue(d, col.field)\" (blur)=\"disableDetailEdits(row, d, col)\" (keydown.enter)=\"disableDetailEdits(row, d, col)\" (keydown.escape)=\"disableDetailEdits(row, d, col)\" class=\"form-control form-control-sm text-end\" style=\"width: 100%; height: auto;\" />\r\n <select *ngSwitchCase=\"'dropdown'\" #detailInput [ngModel]=\"getNestedValue(d, col.field)\" (blur)=\"disableDetailEdits(row, d, col)\" (keydown.enter)=\"disableDetailEdits(row, d, col)\" (keydown.escape)=\"disableDetailEdits(row, d, col)\" class=\"form-control form-control-sm\" style=\"width: 100%; height: auto;\">\r\n <option *ngFor=\"let option of col.column_dropdown_value\" [ngValue]=\"option?.value || option\">\r\n {{ option?.label || option?.name || option }}\r\n </option>\r\n </select>\r\n <input *ngSwitchDefault #detailInput type=\"text\" [ngModel]=\"getNestedValue(d, col.field)\" (blur)=\"disableDetailEdits(row, d, col)\" (keydown.enter)=\"disableDetailEdits(row, d, col)\" (keydown.escape)=\"disableDetailEdits(row, d, col)\" class=\"form-control form-control-sm\" style=\"width: 100%; height: auto;\" />\r\n </ng-container>\r\n </ng-container>\r\n </span>\r\n </ng-template>\r\n </div>\r\n </td>\r\n </ng-container>\r\n </tr>\r\n </tbody>\r\n </table>\r\n </cdk-virtual-scroll-viewport>\r\n</div>\r\n\r\n <!-- RIGHT SECTION OF ACCORDION -->\r\n <div #rightContainer class=\"accordion-right-section data-pin-body-wrapper \" [attr.data-detail-row-id]=\"row._id || row.id\" (scroll)=\"onDetailRightScroll($event, row)\" style=\"flex-shrink: 0; overflow-y: auto; overflow-x: hidden;\">\r\n <table class=\"nested-table table-sm mb-0 data-grid-accordion-table\" [class.show-shadow]=\"rowShadingEnabled\" style=\"table-layout: fixed; width: auto;\">\r\n <thead>\r\n <tr [style.height.px]=\"nestedTableHeaderRowHeight\" [style.backgroundColor]=\"headerBackgroundColor\" [style.color]=\"headerTextColor\" [style.fontSize.px]=\"headerTextFontsSize\" [style.fontWeight]=\"headerFontWeight\">\r\n <ng-container *ngFor=\"let col of row.details.columns | pinnedColumns:'right'; trackBy: trackByField\">\r\n <th *ngIf=\"col.is_visible !== false\"\r\n class=\"px-4\"\r\n [class.filter-applied]=\"isAccordionColumnFiltered(row, col)\"\r\n [style.width.px]=\"col.width || 150\"\r\n [style.min-width.px]=\"col.width || 150\"\r\n [attr.field]=\"col.field\"\r\n [attr.pinned]=\"col.pinned\">\r\n <div class=\"d-flex justify-content-between align-items-center\" style=\"width: 100%;\">\r\n <span class=\"d-flex align-items-center gap-1\">\r\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/pin-blue.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"></span>\r\n {{ col.header }}\r\n <span *ngIf=\"isAccordionColumnFiltered(row, col)\"\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\"\r\n class=\"data-grid-svg-icon text-primary ms-1\"\r\n style=\"font-size: 12px;\"></span>\r\n </span>\r\n <span class=\"three-dots p-1\"\r\n (click)=\"openDetailThreeDotsMenus($event, col, row); activeDetailCol = col; activeDetailRow = row\"\r\n style=\"cursor: pointer;\">\r\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/three-dots-vertical.svg'\" class=\"data-grid-svg-icon\"></span>\r\n </span>\r\n</div>\r\n\r\n <!-- <div class=\"resize-handles\" (mousedown)=\"onResizeDetailColumn($event, row, col)\">\r\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/resize-handle.svg'\" class=\"data-grid-svg-icon text-primary\"></span>\r\n </div> -->\r\n <ng-container *ngIf=\"activeDetailCol?.field == col.field && activeDetailRow === row\">\r\n <div class=\"position-absolute detail-column-menu-wrapper\"\r\n [style.top.px]=\"nestedTableHeaderRowHeight\"\r\n [style.left.px]=\"0\">\r\n <ng-container *ngTemplateOutlet=\"detailColumnMenu; context: { col: col, row: row }\"></ng-container>\r\n </div>\r\n </ng-container>\r\n </th>\r\n </ng-container>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <tr [style.height.px]=\"nestedTablerowHeight\" *ngFor=\"let d of row.details.data; let j = index; trackBy: trackById\">\r\n <ng-container *ngFor=\"let col of row.details.columns | pinnedColumns:'right'; let localK = index; trackBy: trackByField\">\r\n <td *ngIf=\"col.is_visible !== false\"\r\n class=\"px-4\"\r\n [attr.field]=\"col.field\"\r\n [attr.pinned]=\"col.pinned\"\r\n (mousedown)=\"startDetailSelection(row, j, localK, col.field, $event, 'right')\"\r\n (mouseenter)=\"extendDetailSelection(row, j, localK, col.field, $event, 'right')\"\r\n [class.selected-cell]=\"isDetailCellSelected(row, j, localK, col.field, 'right')\"\r\n [style.fontSize.px]=\"bodyTextFontsSize\"\r\n [class.active-cell-detail]=\"isActiveDetailCell(row, d, col)\">\r\n <ng-container [ngSwitch]=\"col.field\">\r\n\r\n <ng-container *ngSwitchCase=\"'manually_logs'\" class=\"d-flex justify-content-start align-items-center pointer position-relative\">\r\n <ng-container *ngIf=\"d.manually_logs?.length > 0; else noManualLogsIcon\">\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/eye.svg'\"\r\n class=\"data-grid-svg-icon text-primary\"\r\n style=\"cursor: pointer; font-size: 16px;\"\r\n (mouseenter)=\"showManualLogsTooltip($event, row, d)\"\r\n (mouseleave)=\"hideManualLogsTooltip()\">\r\n </span>\r\n </ng-container>\r\n <ng-template #noManualLogsIcon>\u2013</ng-template>\r\n</ng-container>\r\n <!-- Breaks -->\r\n <ng-container *ngSwitchCase=\"'breaks'\">\r\n <ng-container *ngIf=\"d[col.field]?.length; else noBreaksLeft\">\r\n <app-badge-overflow\r\n [badges]=\"getBreakBadges(d[col.field])\"\r\n [maxWidth]=\"col.width || 200\"\r\n (badgeMouseEnter)=\"showBreakTooltip($event.event, $event.badge.data)\"\r\n (badgeMouseLeave)=\"hideBreakTooltip()\"\r\n (overflowCountClick)=\"onDetailBadgeOverflowCountClick(col, d)\">\r\n</app-badge-overflow>\r\n </ng-container>\r\n <ng-template #noBreaksLeft>\r\n <div>\r\n -\r\n </div>\r\n </ng-template>\r\n </ng-container>\r\n\r\n <div *ngSwitchCase=\"'is_un_restricted'\" class=\"d-flex justify-content-start flex-column pointer position-relative\" (mouseenter)=\"showRestrictionTooltip($event, row, d); preventRestrictionTooltipHide()\" (mouseleave)=\"hideRestrictionTooltip()\">\r\n <span class=\"\" [class.restriction-indicator]=\"row.attendance_log_detail?.length > 0\">\r\n {{ d.is_un_restricted ? 'Yes' : 'No' }}\r\n </span>\r\n </div>\r\n\r\n <div *ngSwitchCase=\"'is_payroll_processed'\" class=\"d-flex justify-content-start flex-column pointer position-relative\" >\r\n <span class=\"\" >\r\n {{ d.is_payroll_processed ? 'Yes' : 'No' }}\r\n </span>\r\n </div>\r\n\r\n <!-- Short Breaks -->\r\n <ng-container *ngSwitchCase=\"'short_breaks'\">\r\n <ng-container *ngIf=\"d[col.field]?.short_break_duration; else noShortBreakLeft\">\r\n <div (dblclick)=\"onShortBreakClick.emit(d)\">\r\n <app-badge-overflow\r\n [badges]=\"getShortBreakBadges(d[col.field])\"\r\n [maxWidth]=\"col.width || 200\"\r\n (badgeMouseEnter)=\"showShortBreakTooltip($event.event, $event.badge.data)\"\r\n (badgeMouseLeave)=\"hideShortBreakTooltip()\"\r\n (badgeClick)=\"handleShortBreakClick(d, $event)\"\r\n (overflowCountClick)=\"onDetailBadgeOverflowCountClick(col, d)\">\r\n </app-badge-overflow>\r\n </div>\r\n </ng-container>\r\n <ng-template #noShortBreakLeft>\r\n <div >-</div>\r\n </ng-template>\r\n </ng-container>\r\n\r\n <!-- Short Leave -->\r\n <!-- Short Leave -->\r\n<ng-container *ngSwitchCase=\"'short_leave'\">\r\n <ng-container *ngIf=\"row.short_leave && row.short_leave.length > 0; else noShortLeaveMain\">\r\n <div class=\"w-100 d-flex main-progress-bar justify-content-center align-items-center\" \r\n style=\"background-color: rgb(111, 97, 207); height: 20px; border-radius: 4px; position: relative;\"\r\n (mouseenter)=\"showShortLeaveTooltip($event, row)\"\r\n (mouseleave)=\"hideShortLeaveTooltip()\">\r\n <span class=\"d-block\" [style.min-width.%]=\"row.short_leave[0].short_leave_time_percentage\" \r\n style=\"background-color: rgb(238, 99, 82); height: 100%; border-radius: 4px;\"></span>\r\n <span style=\"position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); color: white; font-size: 12px; font-weight: bold;\">\r\n {{ row.short_leave[0].short_leave_time_percentage }}%\r\n </span>\r\n </div>\r\n </ng-container>\r\n <ng-template #noShortLeaveMain>-</ng-template>\r\n</ng-container>\r\n\r\n<ng-container *ngSwitchCase=\"'status'\">\r\n <ng-container *ngIf=\"getNestedValue(d, col.field); else noStatus\">\r\n <span class=\"badge\" [class]=\"getStatusBadgeClass(getNestedValue(d, col.field))\">\r\n {{ transformStatus(getNestedValue(d, col.field)) }}\r\n </span>\r\n </ng-container>\r\n <ng-template #noStatus>-</ng-template>\r\n</ng-container>\r\n\r\n<!-- Attendance Status -->\r\n<ng-container *ngSwitchCase=\"'attendanceStatus'\">\r\n <ng-container *ngIf=\"getNestedValue(d, col.field); else noAttendanceStatus\">\r\n <span class=\"badge\" [class]=\"getAttendanceStatusBadgeClass(getNestedValue(d, col.field))\">\r\n {{ transformStatus(getNestedValue(d, col.field)) }}\r\n </span>\r\n </ng-container>\r\n <ng-template #noAttendanceStatus>-</ng-template>\r\n</ng-container>\r\n\r\n <!-- Default -->\r\n <ng-container *ngSwitchDefault>\r\n {{\r\n col.type === 'date'\r\n ? (getNestedValue(d, col.field) ? (getNestedValue(d, col.field) | timezoneFormat:prefs:'date') : '-')\r\n : col.type === 'time'\r\n ? ((getTimeValue(getNestedValue(d, col.field)) | timezoneFormat:prefs:'time'))\r\n : (getNestedValue(d, col.field)?.value || getNestedValue(d, col.field)?.name || getNestedValue(d, col.field) || '-')\r\n }}\r\n </ng-container>\r\n</ng-container>\r\n </td>\r\n </ng-container>\r\n </tr>\r\n</tbody>\r\n </table>\r\n\r\n </div>\r\n\r\n <!-- DETAIL SIDE MENU (Sticky on right end) -->\r\n <!-- <div class=\"detail-side-menu-wrapper\" >\r\n <div style=\"width: 30px\" class=\"d-flex flex-column align-items-center \">\r\n <div (click)=\"toggleDetailSideMenu(row, 'cols')\" [class.bg-white]=\"row.details.sideMenu?.currentTab === 'cols'\" class=\"columns-button d-flex flex-column align-items-center border-below\">\r\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/ui-checks-grid.svg'\" class=\"data-grid-svg-icon\"></span>\r\n <div class=\"side-menue-text\">Columns</div>\r\n </div>\r\n \r\n </div>\r\n\r\n <div *ngIf=\"row.details.sideMenu?.currentTab\" class=\"detail-side-menu-content\" [style.backgroundColor]=\"sidemenuBackgroundColor\" style=\"width: 250px; box-shadow: -2px 0 5px rgba(0,0,0,0.1);\">\r\n <ng-container *ngIf=\"row.details.sideMenu.currentTab === 'cols'\">\r\n <div class=\"px-3 py-2 border-bottom d-flex align-items-center\">\r\n <strong class=\"me-auto\">Columns</strong>\r\n <input type=\"text\" class=\"form-control form-control-sm\" placeholder=\"Search...\" [(ngModel)]=\"row.details.sideMenu.columnSearch\" style=\"width: 120px; font-size: 12px;\" />\r\n </div>\r\n <div class=\"side-menu-scrollable\">\r\n <div *ngFor=\"let col of row.details.columns | filter: row.details.sideMenu.columnSearch:'header'; trackBy: trackByField\" class=\"d-flex align-items-center mb-2\">\r\n <input type=\"checkbox\" class=\"form-check-input me-2\" [(ngModel)]=\"col.is_visible\" (change)=\"onDetailColumnVisibilityChange(row)\" />\r\n <span>{{ col.header }}</span>\r\n </div>\r\n </div>\r\n </ng-container>\r\n\r\n <ng-container *ngIf=\"row.details.sideMenu.currentTab === 'filtrs'\">\r\n <div class=\"px-3 py-2 border-bottom d-flex align-items-center\">\r\n <strong class=\"me-auto\">Filters</strong>\r\n <input type=\"text\" class=\"form-control form-control-sm\" placeholder=\"Search...\" [(ngModel)]=\"row.details.sideMenu.columnSearch\" style=\"width: 120px; font-size: 12px;\" />\r\n </div>\r\n <div class=\"side-menu-scrollable\">\r\n <div *ngFor=\"let col of row.details.columns | filter: row.details.sideMenu.columnSearch:'header'; trackBy: trackByField\" class=\"mb-3\">\r\n <div class=\"d-flex justify-content-between align-items-center cursor-pointer\" (click)=\"col.expandedFilter = !col.expandedFilter\">\r\n <label class=\"mb-0 small\">{{ col.header }}</label>\r\n <span class=\"toggle-icon data-grid-svg-icon\" [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\" [class.rotate]=\"col.expandedFilter\"></span>\r\n </div>\r\n <div *ngIf=\"col.expandedFilter\" class=\"mt-2 filter-input-container ps-3 pe-3\">\r\n <ng-container *ngIf=\"col.type === 'dropdown'; else textFilter\">\r\n <div class=\"p-1\">\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm mb-2\"\r\n placeholder=\"Search...\"\r\n [(ngModel)]=\"col.searchValue\"\r\n />\r\n\r\n <div class=\"form-check mb-1 ms-1\">\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n [checked]=\"\r\n row.details.filters[col.field]?._ids?.length == col.column_dropdown_value?.length\r\n \"\r\n (change)=\"toggleSelectAllDetailFilters(col, row, $event)\"\r\n id=\"detail_selectAll_{{ col.field }}\"\r\n />\r\n <label class=\"form-check-label\" for=\"detail_selectAll_{{ col.field }}\">\r\n Select All\r\n </label>\r\n </div>\r\n\r\n <div class=\"dropdown-options\">\r\n <div\r\n class=\"form-check mb-1 ms-1\"\r\n *ngFor=\"\r\n let option of col?.column_dropdown_value\r\n | filter : col.searchValue : 'value';\r\n trackBy: trackById\r\n \"\r\n >\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n [value]=\"option\"\r\n [checked]=\"\r\n row.details.filters[col.field]?._ids?.includes(option?._id || option?.id || option)\r\n \"\r\n (change)=\"onDetailOptionToggle(col, option, row)\"\r\n id=\"detail_option_{{ col.field }}_{{\r\n option?.id || option?._id || option\r\n }}\"\r\n />\r\n <label\r\n class=\"form-check-label\"\r\n [for]=\"\r\n 'detail_option_' +\r\n col.field +\r\n '_' +\r\n (option?.id || option?._id || option)\r\n \"\r\n >\r\n {{ option.value || option }}\r\n </label>\r\n </div>\r\n </div>\r\n </div>\r\n </ng-container>\r\n\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)]=\"row.details.filters[col.field].first_condition\"\r\n (ngModelChange)=\"applyDetailRowFilter(row)\"\r\n >\r\n <option value=\"contain\">Contains</option>\r\n <option value=\"equal\">Equals</option>\r\n <option value=\"before\">Begins With</option>\r\n <option value=\"after\">Ends With</option>\r\n </select>\r\n </div>\r\n\r\n <input\r\n [type]=\"col.type == 'date' ? 'date' : 'text'\"\r\n class=\"form-control form-control-sm mb-3\"\r\n placeholder=\"Value\"\r\n [(ngModel)]=\"row.details.filters[col.field].first_value\"\r\n (ngModelChange)=\"applyDetailRowFilter(row)\"\r\n />\r\n\r\n <ng-container *ngIf=\"row.details.filters[col.field]?.first_value\">\r\n <div class=\"form-group mb-2\">\r\n <div class=\"form-check form-check-inline\">\r\n <input\r\n class=\"form-check-input filter-radio-inputs\"\r\n type=\"radio\"\r\n name=\"detail_condition_{{ col.field }}\"\r\n [(ngModel)]=\"row.details.filters[col.field].condition\"\r\n (ngModelChange)=\"applyDetailRowFilter(row)\"\r\n value=\"and\"\r\n id=\"detail_and_{{ col.field }}\"\r\n />\r\n <label class=\"form-check-label\" for=\"detail_and_{{ col.field }}\"\r\n >AND</label\r\n >\r\n </div>\r\n <div class=\"form-check form-check-inline\">\r\n <input\r\n class=\"form-check-input filter-radio-inputs\"\r\n type=\"radio\"\r\n name=\"detail_condition_{{ col.field }}\"\r\n [(ngModel)]=\"row.details.filters[col.field].condition\"\r\n (ngModelChange)=\"applyDetailRowFilter(row)\"\r\n value=\"or\"\r\n id=\"detail_or_{{ col.field }}\"\r\n />\r\n <label class=\"form-check-label\" for=\"detail_or_{{ col.field }}\"\r\n >OR</label\r\n >\r\n </div>\r\n <div class=\"form-check form-check-inline\">\r\n <input\r\n class=\"form-check-input filter-radio-inputs\"\r\n type=\"radio\"\r\n name=\"detail_condition_{{ col.field }}\"\r\n [(ngModel)]=\"row.details.filters[col.field].condition\"\r\n (ngModelChange)=\"applyDetailRowFilter(row)\"\r\n value=\"none\"\r\n id=\"detail_none_{{ col.field }}\"\r\n />\r\n <label class=\"form-check-label\" for=\"detail_none_{{ col.field }}\"\r\n >None</label\r\n >\r\n </div>\r\n </div>\r\n\r\n <ng-container *ngIf=\"row.details.filters[col.field].condition !== 'none'\">\r\n <div class=\"form-group mb-2\">\r\n <select\r\n class=\"form-select form-select-sm\"\r\n [(ngModel)]=\"row.details.filters[col.field].second_condition\"\r\n (ngModelChange)=\"applyDetailRowFilter(row)\"\r\n >\r\n <option value=\"contain\">Contains</option>\r\n <option value=\"equal\">Equals</option>\r\n <option value=\"before\">Begins With</option>\r\n <option value=\"after\">Ends With</option>\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-2\"\r\n placeholder=\"Second Value\"\r\n [(ngModel)]=\"row.details.filters[col.field].second_value\"\r\n (ngModelChange)=\"applyDetailRowFilter(row)\"\r\n />\r\n </ng-container>\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 </div>\r\n </div> -->\r\n</div>\r\n\r\n<!-- Detail Side Menu -->\r\n\r\n\r\n\r\n<!-- Popover for Restriction Logs (is_un_restricted) -->\r\n<div\r\n *ngIf=\"restrictionTooltipVisible\"\r\n class=\"popover__content m-l-10 popoverRestriction position-absolute border rounded bg-white p-3\"\r\n [style.left.px]=\"restrictionTooltipPosition.x\"\r\n [style.top.px]=\"restrictionTooltipPosition.y\"\r\n (mouseenter)=\"preventRestrictionTooltipHide()\"\r\n (mouseleave)=\"hideRestrictionTooltip()\"\r\n style=\"z-index: 1000; min-width: 300px; font-size: 12px;\"\r\n>\r\n <div class=\"modal-area px-0 py-0\">\r\n <div class=\"table-responsive\">\r\n <table class=\"table table-row-primary-100 gs-0 gy-2 mb-0\">\r\n <thead>\r\n <tr class=\"fw-bolder text-muted bg-light\">\r\n <th class=\"center ps-2\">Clock in</th>\r\n <th class=\"center\">Clock out</th>\r\n <th class=\"center\">Log Hr</th>\r\n <th class=\"center\">Log Min</th>\r\n <th class=\"center pe-2\">Status</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <tr *ngFor=\"let item of currentRestrictionLogs\">\r\n <td class=\"center ps-2\">\r\n <span class=\"text-primary\"> {{ item?.clock_in_time | date:'shortTime'}}</span>\r\n </td>\r\n <td class=\"center\">\r\n <span class=\"text-primary\">{{ item?.clock_out_time | date:'shortTime'}}</span>\r\n </td>\r\n <td class=\"center\">\r\n <span class=\"text-primary\">{{ item?.logged_hours }}</span>\r\n </td>\r\n <td class=\"center\">\r\n <span class=\"text-primary\">{{ item?.logged_minutes }}</span>\r\n </td>\r\n <td class=\"center\">\r\n <span class=\"badge bg-light text-dark border\">\r\n {{ item?.status ? (item.status | titlecase) : 'N/A' }}\r\n </span>\r\n </td>\r\n </tr>\r\n </tbody>\r\n </table>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<!-- Popover for Manual Logs -->\r\n<div\r\n *ngIf=\"manualLogsTooltipVisible\"\r\n class=\"popover__content position-absolute border rounded bg-white p-3\"\r\n [style.left.px]=\"manualLogsTooltipPosition.x\"\r\n [style.top.px]=\"manualLogsTooltipPosition.y\"\r\n (mouseenter)=\"preventManualLogsTooltipHide()\"\r\n (mouseleave)=\"hideManualLogsTooltip()\"\r\n style=\"z-index: 1000; min-width: 500px; font-size: 12px;\"\r\n>\r\n <div class=\"modal-area px-0 py-0\">\r\n <ng-container *ngIf=\"currentManualLogs.length > 0; else noManualLogs\">\r\n <div class=\"table-responsive\">\r\n <table class=\"table table-row-primary-100 gs-0 gy-2 mb-0\">\r\n <thead>\r\n <tr class=\"fw-bolder text-muted bg-light\">\r\n <th class=\"center ps-2\" style=\"width: 18%;\">Name</th>\r\n <th class=\"center\">Date/Time</th>\r\n <th class=\"center\">Previous Time</th>\r\n <th class=\"center\">Updated Time</th>\r\n <th class=\"center\">Status</th>\r\n <th class=\"center pe-2\">Remarks</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <tr *ngFor=\"let log of currentManualLogs\">\r\n <td class=\"center ps-2\">\r\n <span class=\"text-primary\">{{ log.name }}</span>\r\n </td>\r\n <td class=\"center\">\r\n <span class=\"text-primary\">{{ log.date_time }}</span>\r\n </td>\r\n <td class=\"center\">\r\n <span class=\"text-primary\">{{ log.previous_time }}</span>\r\n </td>\r\n <td class=\"center\">\r\n <span class=\"text-primary\">{{ log.updated_time }}</span>\r\n </td>\r\n <td class=\"center\">\r\n <span class=\"badge bg-light text-dark border\">\r\n {{ log.log_status ? (log.log_status | titlecase) : 'N/A' }}\r\n </span>\r\n </td>\r\n <td class=\"center pe-2\">\r\n <span class=\"text-primary\">{{ log.remarks }}</span>\r\n </td>\r\n </tr>\r\n </tbody>\r\n </table>\r\n </div>\r\n </ng-container>\r\n </div>\r\n\r\n <ng-template #noManualLogs>\r\n <div class=\"text-center p-3\">\r\n <p class=\"text-muted mb-0\">No manual logs available for this record.</p>\r\n </div>\r\n </ng-template>\r\n</div>\r\n\r\n\r\n\r\n\r\n<!-- Existing Custom Tooltip for Breaks -->\r\n\r\n\r\n\r\n\r\n\r\n <!-- RIGHT PINNED: Empty table to keep alignment -->\r\n <div *ngIf=\"section === 'right' && row.isDetailsExpand && !isSingleDay\" class=\"accordion-details data-grid-accordion-section\" style=\"max-height: 350px; min-height: 150px ; overflow: hidden;\">\r\n <table class=\"nested-table table table-sm w-100 mb-0 data-grid-accordion-table\" [class.show-shadow]=\"rowShadingEnabled\">\r\n <thead>\r\n <tr [style.height.px]=\"nestedTableHeaderRowHeight\" [style.backgroundColor]=\"headerBackgroundColor\">\r\n <th *ngFor=\"let _ of [1, 2, 3, 4, 5]\">&nbsp;</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <tr [style.height.px]=\"nestedTablerowHeight\" *ngFor=\"let _ of row.details.data\" [style.backgroundColor]=\"headerBackgroundColor\">\r\n <td *ngFor=\"let __ of [1, 2, 3, 4, 5]\">&nbsp;</td>\r\n </tr>\r\n </tbody>\r\n </table>\r\n </div>\r\n\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>\r\n <div\r\n (click)=\"disableEdit(row, col); setActiveCell(row, col)\"\r\n [style.fontWeight]=\"bodyFontWeight\"\r\n [class.border-right]=\"showVerticalBorder\"\r\n class=\"cell overflow-visible position-relative\"\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 [class.active-cell]=\"\r\n isActiveCell(row, col) && !isEditing(row, col) && selectedKeys.size == 1\r\n \"\r\n (dblclick)=\"$event.preventDefault(); enableEdit(row, col)\"\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=\"0\"\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 class=\"table-cell\" [class.active-for-editing]=\"isEditing(row, col) && getNestedValue(row, col.field)?.length <= 50\">\r\n <div\r\n (click)=\"$event.stopPropagation()\"\r\n *ngIf=\"isEditing(row, col) && getNestedValue(row, col.field)?.length <= 50; else viewMode\"\r\n >\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 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)\"\r\n autofocus\r\n (keydown.enter)=\"numberRef.blur()\"\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)\"\r\n autofocus\r\n class=\"form-control form-control-sm\"\r\n #dateInput=\"ngModel\"\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\">\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 />\r\n </div>\r\n\r\n <!-- Options -->\r\n <div\r\n class=\"cell-editin-dropdown\"\r\n style=\"max-height: 200px; overflow: auto\"\r\n >\r\n <div\r\n (click)=\"\r\n setNestedValue(row, col, option, true);\r\n disableEdit(row, col)\r\n \"\r\n class=\"px-2 py-1 d-flex align-items-center item\"\r\n *ngFor=\"\r\n let option of col.column_dropdown_value\r\n | filter : editinDropdownSearch : 'value'\r\n \"\r\n >\r\n <label\r\n class=\"form-check-label d-flex align-items-center mb-0\"\r\n [for]=\"col.field + '-' + option.value || option\"\r\n >\r\n {{ option.value || option }}\r\n </label>\r\n </div>\r\n </div>\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)=\"\r\n emailModel.control.markAsTouched(); emailInput.blur()\r\n \"\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 [(ngModel)]=\"row[col.field]\"\r\n name=\"{{ col.field }}\"\r\n required\r\n (blur)=\"disableEdit(row, col, textModel)\"\r\n (keydown.enter)=\"\r\n textModel.control.markAsTouched(); textInput.blur()\r\n \"\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 </div>\r\n\r\n <!-- Display mode -->\r\n <ng-template #viewMode>\r\n <div\r\n class=\"d-flex justify-between items-center w-100\"\r\n [ngClass]=\"getCellClasses(col, getNestedValue(row, col.field))\"\r\n >\r\n <!-- Text cell -->\r\n <div class=\"d-flex align-items-center w-100\">\r\n <div\r\n #cellText\r\n class=\"text-ellipsis flex-grow-1\"\r\n \r\n >\r\n <ng-container *ngIf=\"col.type !== 'image'\">\r\n <ng-container [ngSwitch]=\"col.field\">\r\n <!-- Breaks -->\r\n <ng-container *ngSwitchCase=\"'breaks'\">\r\n <ng-container *ngIf=\"getNestedValue(row, 'breaks')?.length; else noBreaksMain\">\r\n <app-badge-overflow\r\n [badges]=\"getBreakBadges(getNestedValue(row, 'breaks'))\"\r\n [maxWidth]=\"col.width || 200\"\r\n (badgeMouseEnter)=\"showBreakTooltip($event.event, $event.badge.data)\"\r\n (badgeMouseLeave)=\"hideBreakTooltip()\"\r\n (overflowCountClick)=\"onBadgeOverflowCountClick(col)\">\r\n </app-badge-overflow>\r\n </ng-container>\r\n <ng-template #noBreaksMain>\r\n <div >\r\n -\r\n </div>\r\n </ng-template>\r\n </ng-container>\r\n\r\n <!-- Short Breaks -->\r\n <ng-container *ngSwitchCase=\"'short_breaks'\">\r\n <ng-container *ngIf=\"row.short_breaks?.short_break_duration && row.short_breaks.short_break_duration > 0; else noShortBreak\">\r\n <div (dblclick)=\"onShortBreakClick.emit(row)\"> <app-badge-overflow\r\n [badges]=\"getShortBreakBadges(row.short_breaks)\"\r\n [maxWidth]=\"col.width || 200\"\r\n (badgeMouseEnter)=\"showShortBreakTooltip($event.event, $event.badge.data)\"\r\n (badgeMouseLeave)=\"hideShortBreakTooltip()\"\r\n (badgeClick)=\"handleShortBreakClick(row, $event)\"\r\n (overflowCountClick)=\"onShortBreakOverflowCountClick(col)\">\r\n </app-badge-overflow> </div>\r\n \r\n \r\n </ng-container>\r\n <ng-template #noShortBreak>\r\n <div >-</div>\r\n </ng-template>\r\n </ng-container>\r\n\r\n <!-- Short Leave -->\r\n <!-- Short Leave -->\r\n<ng-container *ngSwitchCase=\"'short_leave'\">\r\n <ng-container *ngIf=\"row.short_leave && row.short_leave.length > 0; else noShortLeaveMain\">\r\n <div class=\"w-100 d-flex main-progress-bar justify-content-center align-items-center\" \r\n style=\"background-color: rgb(111, 97, 207); height: 20px; border-radius: 4px; position: relative;\"\r\n (mouseenter)=\"showShortLeaveTooltip($event, row)\"\r\n (mouseleave)=\"hideShortLeaveTooltip()\">\r\n <span class=\"d-block\" [style.min-width.%]=\"row.short_leave[0].short_leave_time_percentage\" \r\n style=\"background-color: rgb(238, 99, 82); height: 100%; border-radius: 4px;\"></span>\r\n <span style=\"position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); color: white; font-size: 12px; font-weight: bold;\">\r\n {{ row.short_leave[0].short_leave_time_percentage }}%\r\n </span>\r\n </div>\r\n </ng-container>\r\n <ng-template #noShortLeaveMain>-</ng-template>\r\n</ng-container>\r\n\r\n <!-- Status -->\r\n <ng-container *ngSwitchCase=\"'status'\">\r\n <span class=\"badge\" [class]=\"getStatusBadgeClass(getNestedValue(row, col.field))\">\r\n {{ transformStatus(getNestedValue(row, col.field)) || '-' }}\r\n </span>\r\n </ng-container>\r\n\r\n <!-- Attendance Status -->\r\n <ng-container *ngSwitchCase=\"'attendanceStatus'\">\r\n <span class=\"badge\" [class]=\"getAttendanceStatusBadgeClass(getNestedValue(row, col.field))\">\r\n {{ transformStatus(getNestedValue(row, col.field)) || '-' }}\r\n </span>\r\n </ng-container>\r\n\r\n <!-- Payroll Processed -->\r\n <ng-container *ngSwitchCase=\"'is_payroll_processed'\">\r\n <span class=\"badge\" [class]=\"getNestedValue(row, col.field) ? 'badge-success' : 'badge-secondary'\">\r\n {{ getNestedValue(row, col.field) ? 'Yes' : 'No' }}\r\n </span>\r\n </ng-container>\r\n\r\n <!-- Restriction -->\r\n <ng-container *ngSwitchCase=\"'is_un_restricted'\">\r\n <span class=\"badge\" [class]=\"getNestedValue(row, col.field) ? 'badge-success' : 'badge-secondary'\">\r\n {{ getNestedValue(row, col.field) ? 'Yes' : 'No' }}\r\n </span>\r\n </ng-container>\r\n\r\n <!-- Default -->\r\n <ng-container *ngSwitchDefault>\r\n {{\r\n !isNestedValueArray(row, col.field)\r\n ? col.type === 'date'\r\n ? (isDate(getNestedValue(row, col.field))\r\n ? ((getNestedValue(row, col.field)) | timezoneFormat:prefs:'date' )\r\n : (getNestedValue(row, col.field)?.value ||\r\n getNestedValue(row, col.field)?.name ||\r\n getNestedValue(row, col.field) ||\r\n '-'))\r\n : col.type === 'time'\r\n ? ((getTimeValue(getNestedValue(row, col.field)) | timezoneFormat:prefs:'time'))\r\n : (getNestedValue(row, col.field)?.value ||\r\n getNestedValue(row, col.field)?.name ||\r\n getNestedValue(row, col.field) ||\r\n '-')\r\n : (getNestedValue(row, col.field)?.[0]?.department_name ||\r\n getNestedValue(row, col.field)?.[0]?.roleName ||\r\n '-')\r\n }}\r\n </ng-container>\r\n </ng-container>\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: row,\r\n col: col,\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </div>\r\n\r\n <!-- Active dot and eye icon for employee name -->\r\n <span *ngIf=\"col.field === 'User' && hasManualLogs(row) && !row.isDetailsExpand\" class=\"badge badge-dot badge-success ms-1\" (mouseenter)=\"showManualLogsTooltip($event, row, row)\"></span>\r\n <i *ngIf=\"col.field === 'User' && hasManualLogs(row)\" class=\"bi bi-eye ms-1\" (mouseenter)=\"showManualLogsTooltip($event, row, row)\"></i>\r\n </div>\r\n\r\n <!-- Expand / Collapse icon for multiple data showing in one coll-->\r\n\r\n <!-- <span\r\n *ngIf=\"\r\n (isOverflowing(cellText) &&\r\n showCellDetailsBox &&\r\n getNestedValue(row, col.field)?.length > 50) ||\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 </div>\r\n\r\n <!-- Expanded text -->\r\n <div\r\n class=\"position-absolute w-100\"\r\n *ngIf=\"isExpanded(row, col)\"\r\n [style.zIndex]=\"getZIndex(row, col)\"\r\n style=\"top: 100%; left: 0\"\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\r\n\r\n \r\n\r\n\r\n\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<div\r\n *ngIf=\"currentBreakTooltip\"\r\n class=\"custom-break-tooltip\"\r\n [style.--tooltip-x.px]=\"tooltipPosition.x\"\r\n [style.--tooltip-y.px]=\"tooltipPosition.y\"\r\n>\r\n <div class=\"break-tooltip-header\">\r\n <strong>{{ currentBreakTooltip.break_type?.data_value_name || 'Break' }}</strong>\r\n <span class=\"text-muted ms-2\">\r\n {{ currentBreakTooltip.breakInstatus === 'breakOut' ? 'Taken' : 'On Break' }}\r\n </span>\r\n </div>\r\n\r\n <div class=\"break-tooltip-body\">\r\n <div>\r\n <i class=\"bi bi-play-circle\"></i>\r\n In: {{ getTimeValue(currentBreakTooltip.break_in_time) | timezoneFormat:prefs:'time' }}\r\n </div>\r\n\r\n <div>\r\n <i class=\"bi bi-stop-circle\"></i>\r\n Out: {{ getTimeValue(currentBreakTooltip.break_out_time) | timezoneFormat:prefs:'time' }}\r\n </div>\r\n\r\n <div>\r\n <i class=\"bi bi-clock\"></i>\r\n Duration: {{ currentBreakTooltip.break_duration }} min\r\n </div>\r\n </div>\r\n</div>\r\n\r\n\r\n\r\n\r\n\r\n<!-- Short Break Tooltip -->\r\n<div\r\n *ngIf=\"currentShortBreakTooltip\"\r\n class=\"custom-break-tooltip\"\r\n [style.--tooltip-x.px]=\"tooltipPosition.x\"\r\n [style.--tooltip-y.px]=\"tooltipPosition.y\"\r\n>\r\n <div class=\"break-tooltip-header\">\r\n <strong>{{ currentShortBreakTooltip.short_break_name || 'Short Break' }}</strong>\r\n </div>\r\n\r\n <div class=\"break-tooltip-body\">\r\n <div>\r\n <i class=\"bi bi-play-circle\"></i>\r\n Start: {{ getTimeValue(currentShortBreakTooltip.start_time) | timezoneFormat:prefs:'time' }}\r\n </div>\r\n\r\n <div>\r\n <i class=\"bi bi-stop-circle\"></i>\r\n End: {{ getTimeValue(currentShortBreakTooltip.end_time) | timezoneFormat:prefs:'time' }}\r\n </div>\r\n\r\n <div>\r\n <i class=\"bi bi-clock\"></i>\r\n Duration: {{ currentShortBreakTooltip.short_break_duration }} min\r\n </div>\r\n </div>\r\n</div>\r\n\r\n\r\n\r\n\r\n<!-- Headers Action List On clicking three dots -->\r\n\r\n<ng-template #columnMenu let-col=\"col\">\r\n <div\r\n class=\"column-menu three-dots-col-menu\"\r\n [class.visually-hidden]=\"isMenueHidden\"\r\n *ngIf=\"activeCol && !isThreeDotsFilterOpen && !loading\"\r\n [style.backgroundColor]=\"dropdownsBackgroundColor\"\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\">\r\n <div\r\n *ngIf=\"columnThreedotsMunuConfig?.showFilter && !(col.is_search_able === false )\"\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)=\"updateColumnPinInSourceByField(activeCol, 'left')\"\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)=\"updateColumnPinInSourceByField(activeCol, 'right')\"\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)=\"updateColumnPinInSourceByField(activeCol, null)\"\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 && !(col.is_groupable === false)\"\r\n class=\"column-menu-item\"\r\n (click)=\"groupBy(activeCol)\"\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 *ngIf=\"isThreeDotsFilterOpen\" class=\"three-dots-col-menu position-relative\" [style.left.px]=\"-140\" >\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\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'; else textFilter\">\r\n <div class=\"filter-dropdown-section p-1\">\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm mb-2\"\r\n placeholder=\"Search...\"\r\n [(ngModel)]=\"addFilterDropdownSearch\"\r\n #filterMenueSearchInput\r\n />\r\n\r\n <div class=\"form-check mb-1\">\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n [checked]=\"isAllSideFilterOptionsSelected(col)\"\r\n (change)=\"toggleSelectAllSideFilters(col, $event)\"\r\n id=\"selectAll_{{ col.field }}\"\r\n />\r\n <label class=\"form-check-label\" for=\"selectAll_{{ col.field }}\">\r\n Select All\r\n </label>\r\n </div>\r\n\r\n <div class=\"dropdown-options\">\r\n <div\r\n class=\"form-check mb-1\"\r\n *ngFor=\"\r\n let option of col?.column_dropdown_value\r\n | filter : addFilterDropdownSearch : 'value';\r\n trackBy: trackById\r\n \"\r\n >\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n [checked]=\"\r\n col.query?._ids?.includes(option?._id || option?.id || option)\r\n \"\r\n [value]=\"option\"\r\n id=\"option_{{ col.field }}_{{\r\n option?.id || option?._id || option\r\n }}\"\r\n (change)=\"onOptionToggle(col, option)\"\r\n />\r\n <label\r\n class=\"form-check-label\"\r\n [for]=\"\r\n 'option_' +\r\n col.field +\r\n '_' +\r\n (option?.id || option?._id || option)\r\n \"\r\n >\r\n {{ option?.value || option }}\r\n </label>\r\n </div>\r\n </div>\r\n </div>\r\n </ng-container>\r\n\r\n <!-- Text Filter Section -->\r\n <ng-template #textFilter>\r\n <div class=\"filter-text-section\">\r\n <div class=\"form-group mb-2\">\r\n <select\r\n class=\"form-select form-select-sm\"\r\n [ngModel]=\"col.query.first_condition || (col.type === 'date' || col.type === 'time' ? 'equal' : 'contain')\"\r\n (ngModelChange)=\"col.query.first_condition = $event\"\r\n >\r\n <ng-container *ngIf=\"col.type === 'date' || col.type === 'time'; else textOptions\">\r\n <option value=\"equal\">Equal 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-template #textOptions>\r\n <option value=\"contain\">Contains</option>\r\n <option value=\"equal\">Equals</option>\r\n <option value=\"before\">Begins With</option>\r\n <option value=\"after\">Ends With</option>\r\n </ng-template>\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)]=\"col.query.first_value\"\r\n [min]=\"col.type == 'number' ? 0 : null\"\r\n (input)=\"col.type == 'number' && $any($event.target).value < 0 ? $any($event.target).value = 0 : null\"\r\n (keydown)=\"col.type == 'number' && $event.key === '-' ? $event.preventDefault() : null\"\r\n [class.number-input]=\"col.type == 'number'\"\r\n #filterMenueTextchInput\r\n />\r\n\r\n <ng-container >\r\n <div class=\"form-group mb-2\">\r\n <div class=\"form-check form-check-inline\">\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 />\r\n <label class=\"form-check-label\" for=\"and_{{ col.field }}\"\r\n >AND</label\r\n >\r\n </div>\r\n <div class=\"form-check form-check-inline\">\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 />\r\n <label class=\"form-check-label\" for=\"or_{{ col.field }}\"\r\n >OR</label\r\n >\r\n </div>\r\n <div class=\"form-check form-check-inline\">\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 />\r\n <label class=\"form-check-label\" for=\"none_{{ col.field }}\"\r\n >None</label\r\n >\r\n </div>\r\n </div>\r\n\r\n <ng-container *ngIf=\"col.query?.first_value && condition !== 'none'\">\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 || (col.type === 'date' || col.type === 'time' ? 'equal' : 'contain')\"\r\n (ngModelChange)=\"col.query.second_condition = $event\"\r\n >\r\n <ng-container *ngIf=\"col.type === 'date' || col.type === 'time'; else textOptionsSecond\">\r\n <option value=\"equal\">Equal 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-template #textOptionsSecond>\r\n <option value=\"contain\">Contains</option>\r\n <option value=\"equal\">Equals</option>\r\n <option value=\"before\">Begins With</option>\r\n <option value=\"after\">Ends With</option>\r\n </ng-template>\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-2\"\r\n placeholder=\"Second Value\"\r\n [(ngModel)]=\"col.query.second_value\"\r\n [min]=\"col.type == 'number' ? 0 : null\"\r\n (input)=\"col.type == 'number' && $any($event.target).value < 0 ? $any($event.target).value = 0 : null\"\r\n (keydown)=\"col.type == 'number' && $event.key === '-' ? $event.preventDefault() : null\"\r\n [class.number-input]=\"col.type == 'number'\"\r\n />\r\n </ng-container>\r\n </ng-container>\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: 22px\"\r\n (click)=\"applyFilterFromFilterRow(col)\"\r\n >\r\n Apply\r\n </div>\r\n <div\r\n class=\"btn btn-sm btn-secondary d-flex justify-content-center align-items-center w-100\"\r\n style=\"height: 22px\"\r\n (click)=\"resetSideFilter(col)\"\r\n >\r\n Reset\r\n </div>\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<!-- Side Menue -->\r\n\r\n<!-- Add this new template for accordion detail column menu -->\r\n<ng-template #detailColumnMenu let-col=\"col\" let-row=\"row\">\r\n <div\r\n class=\"column-menu three-dots-col-menu detail-column-menu\"\r\n [class.visually-hidden]=\"isDetailMenueHidden\"\r\n *ngIf=\"activeDetailCol\"\r\n [style.backgroundColor]=\"dropdownsBackgroundColor\"\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=\"columnThreedotsMunuConfig?.showAscending\"\r\n class=\"column-menu-item\"\r\n (click)=\"sortDetailAsc(activeDetailCol, row)\"\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=\"columnThreedotsMunuConfig?.showDescending\"\r\n class=\"column-menu-item\"\r\n (click)=\"sortDetailDesc(activeDetailCol, row)\"\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=\"col?.sortOrder\"\r\n class=\"column-menu-item\"\r\n (click)=\"resetDetailSort(activeDetailCol, row)\"\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\r\n <div class=\"py-2 border-below\" *ngIf=\"isColumnFilterable(col)\">\r\n <span class=\"muted-text fs-7\" style=\"margin-left: 12px\">Filter</span>\r\n <div\r\n *ngIf=\"columnThreedotsMunuConfig?.showFilter\"\r\n class=\"column-menu-item\"\r\n (click)=\"openDetailFilterMenu($event, col, row)\"\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)=\"updateDetailColumnPin(activeDetailCol, row, 'left')\"\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)=\"updateDetailColumnPin(activeDetailCol, row, 'right')\"\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)=\"updateDetailColumnPin(activeDetailCol, row, null)\"\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)=\"autosizeDetailColumn(activeDetailCol, row)\"\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)=\"autosizeAllDetailColumns(row)\"\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\r\n <!-- Choose Columns -->\r\n <div\r\n *ngIf=\"columnThreedotsMunuConfig?.showChoseColumns\"\r\n class=\"column-menu-item\"\r\n (click)=\"openDetailChooseColumns(row)\"\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)=\"resetDetailColumns(row)\"\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</ng-template>\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\"\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\">\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<!-- 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\">\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\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% - 120px); 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 <!-- Apply and Reset Buttons -->\r\n <!-- <div class=\"d-flex gap-2 mt-3 px-2\">\r\n <button\r\n class=\"btn btn-sm btn-primary d-flex justify-content-center align-items-center flex-fill\"\r\n style=\"height: 32px;\"\r\n (click)=\"applySideMenuFilters()\"\r\n >\r\n Apply\r\n </button>\r\n <button\r\n class=\"btn btn-sm btn-secondary d-flex justify-content-center align-items-center flex-fill\"\r\n style=\"height: 32px;\"\r\n (click)=\"resetSideMenuFilters()\"\r\n >\r\n Reset\r\n </button>\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 class=\"column-group d-flex align-items-center mb-2\">\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\">\r\n <span\r\n class=\"me-2 filter-icon-wrapper me-2\"\r\n (click)=\"col.expandedFilter = !col.expandedFilter\"\r\n >\r\n <span\r\n class=\"toggle-icon data-grid-svg-icon\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\r\n \"\r\n [class.rotate]=\"col.expandedFilter\"\r\n ></span>\r\n </span>\r\n\r\n <label\r\n class=\"d-flex align-items-center mb-0 w-100\"\r\n style=\"cursor: pointer\"\r\n (click)=\"col.expandedFilter = !col.expandedFilter\"\r\n >\r\n <span class=\"text-truncate fw-bold\">{{ col.header }}</span>\r\n </label>\r\n </div>\r\n\r\n <!-- Show filter when expanded -->\r\n <div *ngIf=\"col.expandedFilter\" class=\"ps-4 pe-3\">\r\n <ng-container\r\n *ngTemplateOutlet=\"sideNestedFilter; context: { col: col }\"\r\n ></ng-container>\r\n </div>\r\n </ng-container>\r\n</ng-template>\r\n\r\n<!-- Side Nested Filters -->\r\n<ng-template #sideNestedFilter let-col=\"col\">\r\n <div class=\"\">\r\n <!-- Dropdown Type -->\r\n <ng-container *ngIf=\"col.type === 'dropdown'; else textFilter\">\r\n <div class=\"p-1\">\r\n <!-- Search -->\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm mb-2\"\r\n placeholder=\"Search...\"\r\n [(ngModel)]=\"col.searchValue\"\r\n />\r\n\r\n <!-- Select All -->\r\n <div class=\"form-check mb-1 ms-1\">\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n [checked]=\"\r\n col.query?._ids?.length == col?.column_dropdown_value?.length\r\n \"\r\n (change)=\"toggleSelectAllSideFilters(col, $event)\"\r\n id=\"selectAll_{{ col.field }}\"\r\n />\r\n <label class=\"form-check-label\" for=\"selectAll_{{ col.field }}\">\r\n Select All\r\n </label>\r\n </div>\r\n\r\n <!-- Options -->\r\n <div class=\"dropdown-options\">\r\n <div\r\n class=\"form-check mb-1 ms-1\"\r\n *ngFor=\"\r\n let option of col?.column_dropdown_value\r\n | filter : addFilterDropdownSearch : 'header'\r\n \"\r\n >\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n [value]=\"option\"\r\n [checked]=\"\r\n col.query?._ids?.includes(option?._id || option?.id || option)\r\n \"\r\n (change)=\"onOptionToggle(col, option)\"\r\n id=\"option_{{ col.field }}_{{\r\n option?.id || option?._id || option\r\n }}\"\r\n />\r\n <label\r\n class=\"form-check-label\"\r\n [for]=\"\r\n 'option_' +\r\n col.field +\r\n '_' +\r\n (option?.id || option?._id || option)\r\n \"\r\n >\r\n {{ option.value || option }}\r\n </label>\r\n </div>\r\n </div>\r\n\r\n <!-- Actions -->\r\n <!-- <div class=\"d-flex gap-2 mt-2\">\r\n <div\r\n class=\"btn btn-sm btn-primary d-flex justify-content-center align-items-center\"\r\n style=\"height: 22px;\"\r\n (click)=\"applySideMenuFilters()\"\r\n >\r\n Apply\r\n </div>\r\n <div\r\n class=\"btn btn-sm btn-secondary d-flex justify-content-center align-items-center\"\r\n style=\"height: 22px;\"\r\n (click)=\"resetSideMenuFilters()\"\r\n >\r\n Reset\r\n </div>\r\n </div> -->\r\n </div>\r\n </ng-container>\r\n\r\n <!-- Text Filter Section -->\r\n <ng-template #textFilter>\r\n <div class=\"filter-text-section\">\r\n <div class=\"form-group mb-2\">\r\n <select\r\n class=\"form-select form-select-sm\"\r\n [ngModel]=\"col!.query!.first_condition || (col.type === 'date' || col.type === 'time' ? 'equal' : 'contain')\"\r\n (ngModelChange)=\"col!.query!.first_condition = $event\"\r\n >\r\n <ng-container *ngIf=\"col.type === 'date' || col.type === 'time'; else textOptions\">\r\n <option value=\"equal\">Equal 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-template #textOptions>\r\n <option value=\"contain\">Contains</option>\r\n <option value=\"equal\">Equals</option>\r\n <option value=\"before\">Begins With</option>\r\n <option value=\"after\">Ends With</option>\r\n </ng-template>\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 [min]=\"col.type == 'number' ? 0 : null\"\r\n (input)=\"col.type == 'number' && $any($event.target).value < 0 ? $any($event.target).value = 0 : null\"\r\n (keydown)=\"col.type == 'number' && $event.key === '-' ? $event.preventDefault() : null\"\r\n [class.number-input]=\"col.type == 'number'\"\r\n />\r\n\r\n <ng-container *ngIf=\"col?.query?.first_value && col?.query?.condition !== 'none'\">\r\n <div class=\"form-group mb-2\">\r\n <div class=\"form-check form-check-inline\">\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\" for=\"and_{{ col.field }}\"\r\n >AND</label\r\n >\r\n </div>\r\n <div class=\"form-check form-check-inline\">\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\" for=\"or_{{ col.field }}\"\r\n >OR</label\r\n >\r\n </div>\r\n <div class=\"form-check form-check-inline\">\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 class=\"form-check-label\" for=\"none_{{ col.field }}\"\r\n >None</label\r\n >\r\n </div>\r\n </div>\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 || (col.type === 'date' || col.type === 'time' ? 'equal' : 'contain')\"\r\n (ngModelChange)=\"col!.query.second_condition = $event\"\r\n >\r\n <ng-container *ngIf=\"col.type === 'date' || col.type === 'time'; else textOptionsSecond\">\r\n <option value=\"equal\">Equal 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-template #textOptionsSecond>\r\n <option value=\"contain\">Contains</option>\r\n <option value=\"equal\">Equals</option>\r\n <option value=\"before\">Begins With</option>\r\n <option value=\"after\">Ends With</option>\r\n </ng-template>\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-2\"\r\n placeholder=\"Second Value\"\r\n [(ngModel)]=\"col!.query.second_value\"\r\n [min]=\"col.type == 'number' ? 0 : null\"\r\n (input)=\"col.type == 'number' && $any($event.target).value < 0 ? $any($event.target).value = 0 : null\"\r\n (keydown)=\"col.type == 'number' && $event.key === '-' ? $event.preventDefault() : null\"\r\n [class.number-input]=\"col.type == 'number'\"\r\n />\r\n </ng-container>\r\n\r\n <!-- Apply and Reset Buttons -->\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: 22px\"\r\n (click)=\"applyFilterFromFilterRow(col)\"\r\n >\r\n Apply\r\n </div>\r\n <div\r\n class=\"btn btn-sm btn-secondary d-flex justify-content-center align-items-center w-100\"\r\n style=\"height: 22px\"\r\n (click)=\"resetSideFilter(col)\"\r\n >\r\n Reset\r\n </div>\r\n </div>\r\n </div>\r\n </ng-template>\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\" (click)=\"closeModalColumnPanel()\">\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\">\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 [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 [class.border-right]=\"showVerticalBorder\"\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 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 />\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 rounded-3 bg-white 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)=\"emitConfigUpdate()\"\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>\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 rounded-3 bg-white 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 btn btn-link\"\r\n type=\"button\"\r\n id=\"savePresetDropdown\"\r\n (click)=\"$event.stopPropagation(); toggleSubActions('save-preset')\"\r\n >\r\n Save 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 class=\"\" (click)=\"selectDefault()\">\r\n <div class=\"fw-semibold\">Default View\r\n <span\r\n *ngIf=\"tableFilterViewId === 'default'\"\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/check-blue.svg'\"\r\n class=\"me-2\"\r\n ></span>\r\n </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 === 'default'\"\r\n class=\"badge bg-light text-primary ms-2\"\r\n >Default</span\r\n >\r\n <div\r\n class=\"dropdown d-flex justify-content-end\"\r\n *ngIf=\"tableFilterViewId\"\r\n >\r\n <a\r\n href=\"javascript:void(0)\"\r\n class=\"muted-text\"\r\n data-bs-toggle=\"dropdown\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/horizontal-dots.svg'\r\n \"\r\n class=\"me-2\"\r\n ></span>\r\n </a>\r\n <ul class=\"dropdown-menu dropdown-menu-end\">\r\n <a\r\n (click)=\"actionPreset({ id: 'default' }, 'setPreset')\"\r\n class=\"dropdown-item d-flex align-items-center\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/star.svg'\"\r\n class=\"me-2\"\r\n ></span>\r\n Set as default\r\n </a>\r\n </ul>\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=\"let table of filteredList; trackBy: trackByTable\"\r\n >\r\n <!-- Item -->\r\n <div\r\n class=\"list-group-item px-0 d-flex justify-content-between align-items-center\"\r\n >\r\n <div (click)=\"selectFilter(table)\">\r\n <div class=\"fw-semibold\" style=\"cursor: pointer;\">\r\n {{ table?.name }}\r\n <!-- {{table?.is_temp}} -->\r\n <span\r\n *ngIf=\"table?.is_temp\"\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_deafult\"\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\"\r\n >Created {{ table?.createdAt | timezoneFormat:prefs:'date' }}</small\r\n >\r\n </div>\r\n\r\n <div class=\"d-flex align-items-center\">\r\n <span\r\n *ngIf=\"table?.is_deafult\"\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 position-relative\" *ngIf=\"!table?.is_deafult\">\r\n <a href=\"javascript:void(0)\" class=\"muted-text\" (click)=\"togglePresetDropdown(table.id)\">\r\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/horizontal-dots.svg'\" class=\"me-2\"></span>\r\n </a>\r\n\r\n <div\r\n *ngIf=\"activePresetDropdownId === table.id\"\r\n class=\"dropdown-menu dropdown-menu-end show position-absolute\"\r\n style=\"z-index: 1000; top: 100%; right: 0; min-width: 180px\"\r\n (click)=\"$event.stopPropagation()\"\r\n >\r\n <a\r\n [class.d-none]=\"confirmDeletePresetId === table.id\"\r\n (click)=\"actionPreset(table, 'setPreset'); activePresetDropdownId = null;\"\r\n class=\"dropdown-item d-flex align-items-center\"\r\n >\r\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/star.svg'\" class=\"me-2\"></span>\r\n Set as default\r\n </a>\r\n\r\n <ng-container *ngIf=\"confirmDeletePresetId !== table.id; else confirmBlock\">\r\n <a\r\n (click)=\"confirmDeletePresetId = table.id\"\r\n class=\"dropdown-item d-flex align-items-center text-danger\"\r\n >\r\n <span style=\"margin-top: -4px\" [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/trash-red.svg'\" class=\"me-2\"></span>\r\n Delete\r\n </a>\r\n </ng-container>\r\n\r\n <ng-template #confirmBlock>\r\n <div class=\"dropdown-item\"><b>Delete preset</b></div>\r\n <div class=\"dropdown-item text-center\">\r\n <div class=\"mb-2\">\r\n Are you sure you want to delete the <br />\r\n <b>\u201C{{ table?.name }}\u201D</b> preset?\r\n </div>\r\n <button\r\n class=\"btn btn-sm btn-light me-2\"\r\n (click)=\"confirmDeletePresetId = null\"\r\n >\r\n Cancel\r\n </button>\r\n <button\r\n class=\"btn btn-sm btn-danger delete-preset\"\r\n (click)=\"actionPreset(table, 'deletePreset'); confirmDeletePresetId = null; activePresetDropdownId = null;\"\r\n >\r\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/trash-red.svg'\" class=\"confirm-preset-delete\"></span>\r\n Delete\r\n </button>\r\n </div>\r\n </ng-template>\r\n </div>\r\n</div>\r\n </div>\r\n </div>\r\n <!-- Item End Here -->\r\n </div>\r\n\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\">Save preset</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\">\r\n <ng-container *ngIf=\"!closeDropdown.preset.loading && (!tableFilterViewId || tableFilterViewId === 'default')\"\r\n >Save</ng-container\r\n >\r\n <ng-container *ngIf=\"!closeDropdown.preset.loading && tableFilterViewId && tableFilterViewId !== 'default'\"\r\n >Update</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 </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 rounded-3 bg-white 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\"\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=\"\r\n max-height: calc(100vh - 300px);\r\n overflow: auto;\r\n scrollbar-width: thin;\r\n \"\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 type=\"checkbox\"\r\n id=\"show_hide_all\"\r\n class=\"form-check-input\"\r\n [checked]=\"areAllNonMandatoryVisible()\"\r\n (change)=\"toggleAllVisibleColumns()\"\r\n />\r\n <label for=\"show_hide_all\" class=\"form-check-label fw-semibold\">Show/Hide All</label>\r\n </div>\r\n </div>\r\n <!-- <div class=\"d-flex align-items-center mb-2\" *ngIf=\"hasAnyVisibleColumn\">\r\n <input\r\n type=\"checkbox\"\r\n class=\"form-check-input me-2\"\r\n [checked]=\"areAllNonMandatoryVisible()\"\r\n (change)=\"toggleAllVisibleColumns()\"\r\n />\r\n <label class=\"form-check-label fw-semibold\">Show All</label>\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 && !isMandatory(col)\"\r\n class=\"d-flex align-items-center cursor-pointer\"\r\n (click)=\"toggleColumnVisibility(col, false)\"\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 && isMandatory(col)) || (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\"\r\n *ngIf=\"hasAnyInVisibleColumn\"\r\n >\r\n Hide in table\r\n </div>\r\n <div class=\"d-flex align-items-center mb-2\" *ngIf=\"hasAnyInVisibleColumn\">\r\n <input\r\n type=\"checkbox\"\r\n id=\"hide_show_all\"\r\n class=\"form-check-input me-2\"\r\n [checked]=\"areAllNonMandatoryHidden()\"\r\n (change)=\"toggleAllInvisibleColumns()\"\r\n />\r\n <label class=\"form-check-label fw-semibold\">Hide All</label>\r\n </div> -->\r\n\r\n \r\n\r\n\r\n\r\n <div class=\"muted-text show-hide-table-label d-flex justify-content-between\" *ngIf=\"hasAnyInVisibleColumn\">\r\n Hide in table\r\n <div class=\"form-check\">\r\n <input\r\n type=\"checkbox\"\r\n id=\"hide_show_all\"\r\n class=\"form-check-input\"\r\n [checked]=\"areAllNonMandatoryHidden()\"\r\n (change)=\"toggleAllInvisibleColumns()\"\r\n />\r\n <label for=\"hide_show_all\" class=\"form-check-label fw-semibold\">Hide/Show All</label>\r\n </div>\r\n </div>\r\n <div class=\"list-group list-group-flush\">\r\n <ng-container *ngFor=\"let col of columns; trackBy: trackByField\">\r\n <div\r\n *ngIf=\"!col.is_visible\"\r\n class=\"list-group-item border-0 px-0 d-flex justify-content-between align-items-center\"\r\n >\r\n <div class=\"d-flex gap-1\">\r\n <div>\r\n <span\r\n *ngIf=\"!col?.pinned\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/grip-vertical.svg'\r\n \"\r\n class=\"data-grid-svg-icon cursor-grap\"\r\n (mousedown)=\"$event.preventDefault()\"\r\n ></span>\r\n <span\r\n *ngIf=\"col?.pinned\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/pin-blue.svg'\r\n \"\r\n class=\"data-grid-svg-icon cursor-grap\"\r\n (mousedown)=\"$event.preventDefault()\"\r\n ></span>\r\n </div>\r\n <div class=\"fw-semibold\">\r\n {{ col.header }}\r\n </div>\r\n </div>\r\n <div\r\n class=\"d-flex align-items-center cursor-pointer\"\r\n (click)=\"toggleColumnVisibility(col, true)\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/eye-cross.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n </div>\r\n </div>\r\n </ng-container>\r\n </div>\r\n\r\n <!-- Item End Here -->\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template #filterColumns let-col=\"column\">\r\n <div\r\n @slideToggle\r\n *ngIf=\"!isFilterOpen && activeTopButton == 'filter-columns'\"\r\n (click)=\"$event.stopPropagation()\"\r\n class=\"shadow rounded-3 bg-white actions-dropdown mt-1 show shadow custom-menu table-layout filter-columns\"\r\n style=\"width: 280px; right: unset; max-width: 230px\"\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\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'\"\r\n (click)=\"$event.stopPropagation()\"\r\n class=\"shadow rounded-3 bg-white actions-dropdown mt-1 show shadow custom-menu table-layout filter-columns\"\r\n style=\"width: 280px; right: unset; max-width: 230px\"\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\"\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 (ngModelChange)=\"selectedFilterOptions.length === 0 ? condition = 'none' : null\"\r\n />\r\n </div>\r\n </div>\r\n <div\r\n class=\"list-group list-group-flush\"\r\n style=\"max-height: calc(100vh - 600px); overflow: auto\"\r\n >\r\n <ng-container\r\n *ngFor=\"\r\n let col of selectedColumnForFilter.column_dropdown_value\r\n | filter : searchTextForFilterDropDown : 'value';\r\n let i = index\r\n \"\r\n >\r\n <div\r\n class=\"list-group-item border-0 px-2 d-flex justify-content-between align-items-center dropdown-item cursor-pointer\"\r\n >\r\n <div class=\"form-check\">\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n [id]=\"i\"\r\n [checked]=\"currentFilterSelectedIds.has(col.id || col._id || col)\"\r\n (change)=\"toggleSelectionInFilter(col)\"\r\n />\r\n <label class=\"form-check-label fw-semibold\" [for]=\"i\">\r\n {{ col?.value || col?.name || col }}\r\n </label>\r\n </div>\r\n </div>\r\n </ng-container>\r\n </div>\r\n <div\r\n class=\"d-flex justify-content-center gap-2 px-2 border-top\"\r\n style=\"height: 38px\"\r\n >\r\n <button\r\n type=\"button\"\r\n style=\"height: 32px\"\r\n class=\"btn btn-outline-secondary btn-light border w-100 d-flex align-items-center justify-content-center mt-1 btn-light\"\r\n (click)=\"$event.stopPropagation(); resetFilterChanges()\"\r\n >\r\n <span>Cancel</span>\r\n </button>\r\n <button\r\n type=\"button\"\r\n style=\"height: 32px\"\r\n class=\"btn btn-primary w-100 d-flex align-items-center justify-content-center mt-1\"\r\n (click)=\"applyDropdownFilter()\"\r\n >\r\n <span style=\"margin-top: -2px\">Save</span>\r\n </button>\r\n </div>\r\n </div>\r\n\r\n <!-- For Text fields and number fields-->\r\n\r\n <div\r\n @slideToggle\r\n *ngIf=\"\r\n isFilterOpen &&\r\n (selectedColumnForFilter.type == 'string' ||\r\n selectedColumnForFilter.type == 'number' ||\r\n selectedColumnForFilter.type == 'date')\r\n \"\r\n (click)=\"$event.stopPropagation()\"\r\n class=\"shadow rounded-3 bg-white actions-dropdown mt-1 show shadow custom-menu table-layout filter-columns\"\r\n style=\"width: 280px; right: unset; max-width: 230px\"\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\"\r\n [(ngModel)]=\"firstCondition\"\r\n >\r\n <ng-container *ngIf=\"selectedColumnForFilter.type === 'date' || selectedColumnForFilter.type === 'time'; else textOptions\">\r\n <option value=\"equal\">Equal 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-template #textOptions>\r\n <option value=\"equal\">Equals</option>\r\n <!-- <option value=\"not_equal\">Not Equals</option> -->\r\n <option value=\"contain\">Contains</option>\r\n <option value=\"before\">Begins With</option>\r\n <option value=\"after\">Ends With</option>\r\n </ng-template>\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]=\"\r\n selectedColumnForFilter.type == 'string'\r\n ? 'text'\r\n : selectedColumnForFilter.type\r\n \"\r\n [(ngModel)]=\"firstValue\"\r\n [min]=\"selectedColumnForFilter.type == 'number' ? 0 : null\"\r\n [class.number-input]=\"selectedColumnForFilter.type == 'number'\"\r\n (input)=\"selectedColumnForFilter.type == 'number' && $any($event.target).value < 0 ? $any($event.target).value = 0 : null\"\r\n (ngModelChange)=\"!firstValue ? condition = 'none' : null\"\r\n (keydown)=\"selectedColumnForFilter.type == 'number' && $event.key === '-' ? $event.preventDefault() : null\"\r\n />\r\n </div>\r\n <div class=\"d-flex my-3\">\r\n <div class=\"form-check form-check-inline\">\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\" for=\"logicalAnd\">AND</label>\r\n </div>\r\n\r\n <div class=\"form-check form-check-inline\">\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\" for=\"logicalOr\">OR</label>\r\n </div>\r\n\r\n <div class=\"form-check form-check-inline\">\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\" for=\"logicalNone\">None</label>\r\n </div>\r\n </div>\r\n\r\n <div *ngIf=\"firstValue && condition !== 'none'\">\r\n <div class=\"my-3\">\r\n <!-- Second condition select -->\r\n <select\r\n class=\"form-select form-select-sm\"\r\n [(ngModel)]=\"secondCondition\"\r\n >\r\n <ng-container *ngIf=\"selectedColumnForFilter.type === 'date' || selectedColumnForFilter.type === 'time'; else textOptionsSecond\">\r\n <option value=\"equal\">Equal 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-template #textOptionsSecond>\r\n <option value=\"equal\">Equals</option>\r\n <!-- <option value=\"not_equal\">Not Equals</option> -->\r\n <option value=\"contain\">Contains</option>\r\n <option value=\"before\">Begins With</option>\r\n <option value=\"after\">Ends With</option>\r\n </ng-template>\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 [(ngModel)]=\"secondValue\"\r\n [min]=\"selectedColumnForFilter.type == 'number' ? 0 : null\"\r\n [class.number-input]=\"selectedColumnForFilter.type == 'number'\"\r\n (input)=\"selectedColumnForFilter.type == 'number' && $any($event.target).value < 0 ? $any($event.target).value = 0 : null\"\r\n (keydown)=\"selectedColumnForFilter.type == 'number' && $event.key === '-' ? $event.preventDefault() : null\"\r\n />\r\n </div>\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 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 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</ng-template>\r\n\r\n<!-- Detail Filter Menu -->\r\n <div\r\n *ngIf=\"activeAccordionFilterMenu && detailFilterMenuPosition\"\r\n class=\"detail-filter-menu\"\r\n [style.backgroundColor]=\"dropdownsBackgroundColor\"\r\n [style.left.px]=\"detailFilterMenuPosition.x\"\r\n [style.top.px]=\"detailFilterMenuPosition.y\"\r\n (click)=\"$event.stopPropagation()\"\r\n >\r\n <div class=\"px-3 border-below py-1 pb-2 d-flex ps-1\">\r\n <span\r\n (click)=\"closeDetailFilterMenu()\"\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>{{ activeDetailFilterCol?.header }}</b>\r\n </div>\r\n\r\n <!-- Text Filter -->\r\n <div *ngIf=\"detailFilterType === 'string'\" 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\"\r\n [(ngModel)]=\"detailFilterCondition\"\r\n >\r\n <option value=\"contain\">Contains</option>\r\n <option value=\"equal\">Equals</option>\r\n <option value=\"before\">Begins With</option>\r\n <option value=\"after\">Ends With</option>\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 value\"\r\n [(ngModel)]=\"detailFilterValue\"\r\n (keydown.enter)=\"applyDetailFilter()\"\r\n />\r\n </div>\r\n </div>\r\n\r\n <!-- Date Filter -->\r\n <div *ngIf=\"detailFilterType === 'date'\" 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\"\r\n [(ngModel)]=\"detailFilterCondition\"\r\n >\r\n <option value=\"equal\">Equal to</option>\r\n <option value=\"before\">Before</option>\r\n <option value=\"after\">After</option>\r\n </select>\r\n </div>\r\n <div class=\"mb-2\">\r\n <input\r\n type=\"date\"\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Select date\"\r\n [(ngModel)]=\"detailFilterDateValue\"\r\n (keydown.enter)=\"applyDetailFilter()\"\r\n />\r\n <small class=\"text-muted d-block mt-1\">{{ detailFilterDateValue | timezoneFormat:prefs:'date' }}</small>\r\n </div>\r\n </div>\r\n\r\n <!-- Time Filter -->\r\n <div *ngIf=\"detailFilterType === 'time'\" 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\"\r\n [(ngModel)]=\"detailFilterCondition\"\r\n >\r\n <option value=\"equal\">Equal to</option>\r\n <option value=\"before\">Before</option>\r\n <option value=\"after\">After</option>\r\n </select>\r\n </div>\r\n <div class=\"mb-2\">\r\n <input\r\n type=\"time\"\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Select time\"\r\n [(ngModel)]=\"detailFilterTimeValue\"\r\n (keydown.enter)=\"applyDetailFilter()\"\r\n />\r\n </div>\r\n </div>\r\n\r\n <!-- Dropdown Filter -->\r\n <div *ngIf=\"detailFilterType === 'dropdown'\" class=\"col-12 position-relative p-2 text-filter\">\r\n <div class=\"mb-2\">\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Search options...\"\r\n [(ngModel)]=\"detailFilterSearch\"\r\n (input)=\"filterDetailDropdownOptions()\"\r\n />\r\n </div>\r\n <div class=\"dropdown-options\" style=\"max-height: 150px; overflow-y: auto;\">\r\n <div\r\n *ngFor=\"let option of filteredDetailDropdownOptions; let i = index\"\r\n class=\"form-check mb-1 ms-1\"\r\n >\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n [id]=\"'detail-filter-option-' + i\"\r\n [checked]=\"detailSelectedFilterOptions.includes(option._id || option.id || option.value)\"\r\n (change)=\"toggleDetailFilterOption(option)\"\r\n />\r\n <label\r\n class=\"form-check-label\"\r\n [for]=\"'detail-filter-option-' + i\"\r\n >\r\n {{ option.value || option.name || option }}\r\n </label>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- <div class=\"d-flex gap-2\">\r\n <button\r\n type=\"button\"\r\n class=\"btn btn-primary w-100 d-flex align-items-center justify-content-center mt-1\"\r\n (click)=\"applyDetailFilter()\"\r\n >\r\n <span>Apply</span>\r\n </button>\r\n <button\r\n type=\"button\"\r\n class=\"btn btn-danger w-100 d-flex align-items-center justify-content-center mt-1\"\r\n (click)=\"resetDetailFilter()\"\r\n >\r\n <span>Reset</span>\r\n </button>\r\n \r\n</div> -->\r\n\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: 22px\"\r\n (click)=\"applyDetailFilter()\"\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: 22px\"\r\n (click)=\"resetDetailFilter()\"\r\n >\r\n Reset\r\n </div>\r\n </div>\r\n</div>\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 >\r\n <ng-container *ngIf=\"!isEditing(row, col)\">\r\n <div\r\n *ngIf=\"!isArray\"\r\n class=\"full-text-content\"\r\n (dblclick)=\"$event.stopPropagation(); $event.preventDefault(); enableEdit(row, col)\"\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 {{ item?.department_name || item?.roleName || \"-\" }}\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 #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\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 align-items-center w-100 cell-content image-placeholder cursor-pointer position-relative\"\r\n \r\n (click)=\"onEmployeeClick(row)\"\r\n >\r\n <!-- Blue dot for manual logs -->\r\n <span\r\n *ngIf=\"row?.manually_logs && row.manually_logs.length > 0\"\r\n class=\"manual-logs-indicator\"\r\n (mouseenter)=\"openManualLogsModal($event, row)\"\r\n (mouseleave)=\"closeManualLogsModal()\"\r\n ></span>\r\n <ng-container\r\n *ngIf=\"\r\n row?.User?.logo || row?.User?.profile_pictures?.length || row?.logo || row?.profile_pictures?.length || row?.assetImage || row?.invoice?.invoice_image;\r\n else placeholder\r\n \"\r\n >\r\n <span class=\"pic\">\r\n <img\r\n [width]=\"rowHeight - 12\"\r\n [height]=\"rowHeight - 12\"\r\n [src]=\"row?.User?.profile_pictures?.[4]?.path || row?.User?.logo || row?.profile_pictures?.[4]?.path || row?.logo || row?.assetImage || row?.invoice?.invoice_image\"\r\n alt=\"icon\"\r\n />\r\n </span>\r\n </ng-container>\r\n\r\n <ng-template #placeholder>\r\n <span\r\n [ngClass]=\"getDynamicClass(row?.User?.full_name || 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 >\r\n {{ getInitials(row?.User?.full_name || row?.full_name) }}\r\n </span>\r\n </ng-template>\r\n </span>\r\n</ng-template>\r\n\r\n<!-- Cell Content Template for Card View -->\r\n<ng-template #cellContent let-row=\"row\" let-parentRow=\"parentRow\" let-col=\"col\">\r\n <ng-container [ngSwitch]=\"col.type\">\r\n <!-- String/Text -->\r\n <ng-container *ngSwitchCase=\"'string'\">\r\n {{ getNestedValue(row, col.field) || getNestedValue(parentRow, col.field) || '-' }}\r\n </ng-container>\r\n\r\n <!-- Number -->\r\n <ng-container *ngSwitchCase=\"'number'\">\r\n {{ getNestedValue(row, col.field) || getNestedValue(parentRow, col.field) || '-' }}\r\n </ng-container>\r\n\r\n <!-- Date -->\r\n <ng-container *ngSwitchCase=\"'date'\">\r\n {{ getNestedValue(row, col.field) || getNestedValue(parentRow, col.field) ? (getNestedValue(row, col.field) || getNestedValue(parentRow, col.field) | timezoneFormat:prefs:'date') : '-' }}\r\n </ng-container>\r\n\r\n <!-- Time -->\r\n <ng-container *ngSwitchCase=\"'time'\">\r\n {{ (getNestedValue(row, col.field) || getNestedValue(parentRow, col.field)) !== null && (getNestedValue(row, col.field) || getNestedValue(parentRow, col.field)) !== undefined ? ((getTimeValue(getNestedValue(row, col.field) || getNestedValue(parentRow, col.field)) | timezoneFormat:prefs:'time')) : '-' }}\r\n </ng-container>\r\n\r\n <!-- Boolean -->\r\n <ng-container *ngSwitchCase=\"'boolean'\">\r\n <span class=\"badge\" [class]=\"(getNestedValue(row, col.field) || getNestedValue(parentRow, col.field) === true || getNestedValue(row, col.field) || getNestedValue(parentRow, col.field) === 'true') ? 'badge-success' : 'badge-secondary'\">\r\n {{ (getNestedValue(row, col.field) || getNestedValue(parentRow, col.field) === true || getNestedValue(row, col.field) || getNestedValue(parentRow, col.field) === 'true') ? 'Yes' : 'No' }}\r\n </span>\r\n </ng-container>\r\n\r\n <!-- <div *ngSwitchCase=\"'is_payroll_processed'\" class=\"d-flex justify-content-start flex-column pointer position-relative\" >\r\n <span class=\"popover__wrapper\" >none\r\n {{ row.is_payroll_processed ? 'Yes' : 'No' }}\r\n </span>\r\n </div> -->\r\n\r\n <!-- Status -->\r\n <ng-container *ngSwitchCase=\"'status'\">\r\n <span class=\"badge\" [class]=\"getStatusBadgeClass(getNestedValue(row, col.field) || getNestedValue(parentRow, col.field))\">\r\n {{ transformStatus(getNestedValue(row, col.field) || getNestedValue(parentRow, col.field)) || '-' }}\r\n </span>\r\n </ng-container>\r\n\r\n <!-- Array -->\r\n <ng-container *ngSwitchCase=\"'array'\">\r\n <ng-container *ngIf=\"isArray(getNestedValue(row, col.field) || getNestedValue(parentRow, col.field))\">\r\n <ng-container *ngIf=\"col.field === 'breaks' || col.header?.toLowerCase().includes('break')\">\r\n <app-badge-overflow\r\n [badges]=\"getBreakBadges(getNestedValue(row, col.field) || getNestedValue(parentRow, col.field) || [])\"\r\n [maxWidth]=\"col.width || 200\"\r\n (badgeMouseEnter)=\"showBreakTooltip($event.event, $event.badge.data)\"\r\n (badgeMouseLeave)=\"hideBreakTooltip()\"\r\n (overflowCountClick)=\"onBadgeOverflowCountClick(col)\">\r\n </app-badge-overflow>\r\n </ng-container>\r\n <ng-container *ngIf=\"!(col.field === 'breaks' || col.header?.toLowerCase().includes('break'))\">\r\n {{ (getNestedValue(row, col.field) || getNestedValue(parentRow, col.field) || []).length }} items\r\n </ng-container>\r\n </ng-container>\r\n <ng-container *ngIf=\"!isArray(getNestedValue(row, col.field) || getNestedValue(parentRow, col.field))\">\r\n {{ getNestedValue(row, col.field) || getNestedValue(parentRow, col.field) || '-' }}\r\n </ng-container>\r\n </ng-container>\r\n\r\n <!-- Default -->\r\n <ng-container *ngSwitchDefault>\r\n {{ getNestedValue(row, col.field) || getNestedValue(parentRow, col.field) || '-' }}\r\n </ng-container>\r\n \r\n </ng-container>\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 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<div\r\n [style.bottom.px]=\"footerRowHeight + 50\"\r\n *ngIf=\"selectedRows.size > 0 && showTaskbar\"\r\n class=\"taskbar\"\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 {{ config?.paginationParams?.totalItems }} Total\r\n </span>\r\n <div class=\"action-buttons\">\r\n <ng-container *ngFor=\"let action of taskbarActions; let i = index\">\r\n <span\r\n class=\"action-btn verified btn {{ action }}\"\r\n (click)=\"action === 'Export' ? onExportClick() : action === 'Delete' ? onDeleteClick() : onVerifyClick(action)\"\r\n >{{ action }}</span\r\n >\r\n <span\r\n *ngIf=\"taskbarActions.length > 1 && i !== taskbarActions.length - 1\"\r\n class=\"separator\"\r\n >|</span\r\n >\r\n </ng-container>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<!-- Detail Row Choose Columns Modal -->\r\n<div *ngIf=\"showDetailColumnPanel\" 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=\"detailModalColumnPannel\"></ng-container>\r\n </div>\r\n</div>\r\n\r\n<!-- Paste Confirmation Modal -->\r\n<div *ngIf=\"showPasteConfirmationModal\" class=\"custom-modal-overlay\" (click)=\"cancelPaste()\">\r\n <div class=\"custom-modal-content\" [style.backgroundColor]=\"dropdownsBackgroundColor\" (click)=\"$event.stopPropagation()\">\r\n <div class=\"column-panel-header\">\r\n <div class=\"d-flex justify-content-between align-items-center px-2 ps-3 rounded-top-2 moda-header\" style=\"height: 48px;\">\r\n Confirm Paste Operation\r\n <span class=\"filter-icon-wrapper\" (click)=\"cancelPaste()\">\r\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/x.svg'\" class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"></span>\r\n </span>\r\n </div>\r\n <hr class=\"my-0\" />\r\n <div class=\"p-3\">\r\n <div class=\"mb-3\">\r\n <h6 class=\"mb-3\">You are about to paste the following data:</h6>\r\n <div class=\"border rounded p-3 bg-light\">\r\n <pre class=\"mb-0 text-dark small\">{{ pastePreviewData }}</pre>\r\n </div>\r\n </div>\r\n <div class=\"alert alert-warning\" role=\"alert\">\r\n <strong>Warning:</strong> This action will overwrite existing data in the selected cells. This cannot be undone.\r\n </div>\r\n <div class=\"d-flex justify-content-end gap-2 mt-4\">\r\n <button type=\"button\" class=\"btn btn-secondary\" (click)=\"cancelPaste()\">Cancel</button>\r\n <button type=\"button\" class=\"btn btn-primary\" (click)=\"confirmPaste()\">Confirm Paste</button>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<!-- Short Leave Tooltip Modal -->\r\n<div *ngIf=\"showShortLeaveTooltipModal\"\r\n class=\"custom-break-tooltips\"\r\n [style.--tooltip-x.px]=\"shortLeaveTooltipPosition.x\"\r\n [style.--tooltip-y.px]=\"shortLeaveTooltipPosition.y\"\r\n (mouseenter)=\"preventShortLeaveTooltipHide()\"\r\n (mouseleave)=\"hideShortLeaveTooltip()\">\r\n <div class=\"modal-body\">\r\n <div class=\"table-responsive\">\r\n <table class=\"table table-striped text-dark\">\r\n <thead>\r\n <tr>\r\n <th>Leave Type</th>\r\n <th>Start Time</th>\r\n <th>End Time</th>\r\n <th>Duration (min)</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <tr *ngFor=\"let item of currentShortLeaveData\">\r\n <td>{{ item.leave_type || 'N/A' }}</td>\r\n <td>{{ item.star_time || 'N/A' }}</td>\r\n <td>{{ item.end_time || 'N/A' }}</td>\r\n <td>{{ item.minutes || 'N/A' }}</td>\r\n </tr>\r\n </tbody>\r\n </table>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n<!-- Paste Confirmation Modal -->\r\n<div *ngIf=\"showPasteConfirmationModal\" class=\"custom-modal-overlay\" (click)=\"cancelPaste()\">\r\n <div class=\"custom-modal-content\" [style.backgroundColor]=\"dropdownsBackgroundColor\" (click)=\"$event.stopPropagation()\">\r\n <div class=\"column-panel-header\">\r\n <div class=\"d-flex justify-content-between align-items-center px-2 ps-3 rounded-top-2 moda-header\" style=\"height: 48px;\">\r\n <span class=\"fw-bold\">Confirm Paste</span>\r\n <span class=\"filter-icon-wrapper\" (click)=\"cancelPaste()\">\r\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/x.svg'\" class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"></span>\r\n </span>\r\n </div>\r\n <hr class=\"my-0\" />\r\n <div class=\"p-3\">\r\n <div class=\"mb-3\">\r\n <p class=\"mb-2\">Are you sure you want to paste the following data?</p>\r\n <div class=\"border rounded p-2 bg-light\">\r\n <small class=\"text-muted\">{{ pastePreviewData }}</small>\r\n </div>\r\n </div>\r\n <div class=\"d-flex gap-2 justify-content-end\">\r\n <button type=\"button\" class=\"btn btn-secondary\" (click)=\"cancelPaste()\">Cancel</button>\r\n <button type=\"button\" class=\"btn btn-primary\" (click)=\"confirmPaste()\">Confirm Paste</button>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<!-- Paste Confirmation Modal -->\r\n<div *ngIf=\"showPasteConfirmationModal\" class=\"custom-modal-overlay\" (click)=\"cancelPaste()\">\r\n <div class=\"custom-modal-content\" [style.backgroundColor]=\"dropdownsBackgroundColor\" (click)=\"$event.stopPropagation()\">\r\n <div class=\"modal-header d-flex justify-content-between align-items-center p-3\">\r\n <h5 class=\"modal-title mb-0\">Confirm Paste</h5>\r\n <button type=\"button\" class=\"btn-close\" (click)=\"cancelPaste()\"></button>\r\n </div>\r\n <div class=\"modal-body p-3\">\r\n <p class=\"mb-3\">Are you sure you want to paste the clipboard data into the selected cells?</p>\r\n <div class=\"alert alert-info\" *ngIf=\"pastePreviewData\">\r\n <strong>Paste Preview:</strong>\r\n <pre class=\"mt-2\">{{ pastePreviewData }}</pre>\r\n </div>\r\n </div>\r\n <div class=\"modal-footer p-3\">\r\n <button type=\"button\" class=\"btn btn-secondary\" (click)=\"cancelPaste()\">Cancel</button>\r\n <button type=\"button\" class=\"btn btn-primary\" (click)=\"confirmPaste()\">Paste</button>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<!-- Tooltip for accordion manual logs -->\r\n<!-- Tooltip for accordion manual logs -->\r\n<div *ngIf=\"showManualLogsTooltipModal\" class=\"custom-break-tooltips\"\r\n [style.--tooltip-x.px]=\"manualLogsTooltipPosition.x\"\r\n [style.--tooltip-y.px]=\"manualLogsTooltipPosition.y\"\r\n (mouseenter)=\"preventManualLogsTooltipHide()\"\r\n (mouseleave)=\"hideManualLogsTooltip()\">\r\n\r\n <div class=\"modal-body\">\r\n <div class=\"table-responsive\">\r\n <table class=\"table table-striped text-dark\">\r\n <thead>\r\n <tr>\r\n <th>Name</th>\r\n <th>Date/Time</th>\r\n <th>Previous</th>\r\n <th>Updated</th>\r\n <th>Status</th>\r\n <th>Remarks</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <ng-container *ngFor=\"let item of selectedManualLogs; let i = index\">\r\n <tr>\r\n <td>{{ item?.updated_by?.full_name || selectedManualLogsRow?.User?.full_name }}</td>\r\n <td>{{ item?.log_date && item.log_date !== '--' ? (item.log_date | timezoneFormat:prefs:'datetime') : (selectedManualLogsRow?.attendanceDate && selectedManualLogsRow?.attendanceDate !== '--' ? (selectedManualLogsRow?.attendanceDate | timezoneFormat:prefs:'datetime') : '-') }}</td>\r\n <td>{{ formatLogState(item?.log_details?.previous_state) }}</td>\r\n <td>{{ formatLogState(item?.log_details?.updated_state) }}</td>\r\n <td>{{ item?.log_details?.status ? transformStatus(item.log_details.status) : (item.log_details?.status || '-') }}</td>\r\n <td>{{ item?.log_details?.remarks || item?.remarks || selectedManualLogsRow?.message || '-' }}</td>\r\n </tr>\r\n </ng-container>\r\n\r\n <!-- Fallback for empty manual logs -->\r\n <tr *ngIf=\"!selectedManualLogs || selectedManualLogs.length === 0\">\r\n <td colspan=\"6\" class=\"text-center\">No manual logs available</td>\r\n </tr>\r\n </tbody>\r\n </table>\r\n </div>\r\n </div>\r\n </div>\r\n<!-- </div> -->\r\n\r\n<ng-template #detailModalColumnPannel>\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 Detail Columns\r\n <span class=\"filter-icon-wrapper\" (click)=\"closeDetailColumnPanel()\">\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 <input\r\n type=\"checkbox\"\r\n class=\"form-check-input me-2\"\r\n [checked]=\"allDetailColumnsSelected()\"\r\n (change)=\"toggleAllDetailColumnsVisibility()\"\r\n />\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Search detail columns...\"\r\n [(ngModel)]=\"choseColumnsSearch\"\r\n />\r\n </div>\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 (currentDetailRowForColumnSelection?.details?.columns || [])\r\n | filter : choseColumnsSearch : 'header';\r\n trackBy: trackByField\r\n \"\r\n >\r\n <div class=\"d-flex align-items-center mb-2\">\r\n <input\r\n type=\"checkbox\"\r\n class=\"form-check-input me-2\"\r\n [checked]=\"col.is_visible !== false\"\r\n (change)=\"toggleDetailColumnVisibility(col, !col.is_visible)\"\r\n [id]=\"'detail_col_' + col.field\"\r\n />\r\n <label\r\n class=\"d-flex align-items-center mb-0 w-100\"\r\n [for]=\"'detail_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 </div>\r\n </div>\r\n <!-- <div class=\"px-3 py-2 border-top d-flex justify-content-end\">\r\n <button class=\"btn btn-sm btn-link\" (click)=\"resetDetailColumnsInModal()\">Reset</button>\r\n </div> -->\r\n </div>\r\n</ng-template>\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n", styles: ["@charset \"UTF-8\";@keyframes fadeInUp{0%{opacity:0;transform:translateY(8px)}to{opacity:1;transform:translateY(0)}}@keyframes fadeInScale{0%{opacity:0;transform:scale(.95)}to{opacity:1;transform:scale(1)}}@keyframes slideInRight{0%{opacity:0;transform:translate(16px)}to{opacity:1;transform:translate(0)}}@keyframes pulse{0%{transform:scale(1)}50%{transform:scale(1.02)}to{transform:scale(1)}}@keyframes shimmer{0%{background-position:-200px 0}to{background-position:calc(200px + 100%) 0}}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.loading-overlay{animation:fadeInScale .25s cubic-bezier(.4,0,.2,1);transform:translateZ(0)}.loading-overlay .spinner-border{animation:spin 1s linear infinite}.data-grid-table-wrapper{height:100%;width:100%;border:1px solid #d9d9db;border-radius:12px;box-shadow:none!important;position:relative;animation:fadeInScale .35s cubic-bezier(.4,0,.2,1);transform:translateZ(0)}.data-grid-table-wrapper[data-theme=white]{border-color:#d9d9db;background-color:#f6f8ff;color:#000}.data-grid-table-wrapper[data-theme=white] *,.data-grid-table-wrapper[data-theme=white] *:before,.data-grid-table-wrapper[data-theme=white] *:after{color:#000!important}.data-grid-table-wrapper[data-theme=white] ::selection{background-color:#007bff!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=white] ::-moz-selection{background-color:#007bff!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=white] .data-grid-header-wrapper{background-color:#f8f9fa;color:#000!important}.data-grid-table-wrapper[data-theme=white] .data-grid-body-wrapper{background-color:#f6f8ff;box-shadow:none!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .data-grid-row{border-bottom-color:#d9d9db;box-shadow:none!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .data-grid-row:nth-child(2n){background-color:#f8f9fa!important}.data-grid-table-wrapper[data-theme=white] .data-grid-row:nth-child(odd){background-color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=white] .data-grid-row:hover{background-color:#007bff1a!important}.data-grid-table-wrapper[data-theme=white] .selected-cell,.data-grid-table-wrapper[data-theme=white] .row-selected{background-color:#e3f2fd!important}.data-grid-table-wrapper[data-theme=white] .cell,.data-grid-table-wrapper[data-theme=white] .header-cell,.data-grid-table-wrapper[data-theme=white] .data-grid-row,.data-grid-table-wrapper[data-theme=white] .data-grid-header,.data-grid-table-wrapper[data-theme=white] .cell-content,.data-grid-table-wrapper[data-theme=white] .full-text-content,.data-grid-table-wrapper[data-theme=white] .circle-value,.data-grid-table-wrapper[data-theme=white] .pic,.data-grid-table-wrapper[data-theme=white] .image-placeholder,.data-grid-table-wrapper[data-theme=white] .s-no,.data-grid-table-wrapper[data-theme=white] .fw-500{color:#000!important}.data-grid-table-wrapper[data-theme=white] span,.data-grid-table-wrapper[data-theme=white] div,.data-grid-table-wrapper[data-theme=white] p,.data-grid-table-wrapper[data-theme=white] td,.data-grid-table-wrapper[data-theme=white] th,.data-grid-table-wrapper[data-theme=white] label,.data-grid-table-wrapper[data-theme=white] a:not(.text-primary){color:#000!important}.data-grid-table-wrapper[data-theme=white] svg,.data-grid-table-wrapper[data-theme=white] svg path,.data-grid-table-wrapper[data-theme=white] svg circle,.data-grid-table-wrapper[data-theme=white] svg rect,.data-grid-table-wrapper[data-theme=white] svg polygon{color:#000!important;fill:#000!important;stroke:#000!important}.data-grid-table-wrapper[data-theme=white] .data-grid-svg-icon{color:#000!important}.data-grid-table-wrapper[data-theme=white] .data-grid-svg-icon path{stroke:#000!important;fill:#000!important}.data-grid-table-wrapper[data-theme=white] .badge.badge-danger{background-color:#ea5353!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=white] .badge.badge-success{background-color:#84ca81!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=white] .badge.badge-warning{background-color:#fff3dc!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .badge.badge-info{background-color:#e8fbfd!important;color:#00bad1!important}.data-grid-table-wrapper[data-theme=white] .context-menu{background:#f6f8ff;border-color:#d9d9db;color:#000!important}.data-grid-table-wrapper[data-theme=white] .context-menu li{color:#000!important}.data-grid-table-wrapper[data-theme=white] .context-menu li:hover{background-color:#007bff1a!important}.data-grid-table-wrapper[data-theme=white] .custom-tooltip,.data-grid-table-wrapper[data-theme=white] .popover__content,.data-grid-table-wrapper[data-theme=white] .custom-break-tooltip{background:#f6f8ff!important;border-color:#d9d9db!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .actions-dropdown,.data-grid-table-wrapper[data-theme=white] .custom-menu{background-color:#f6f8ff!important;border-color:#d9d9db!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .actions-dropdown .dropdown-item,.data-grid-table-wrapper[data-theme=white] .custom-menu .dropdown-item{color:#000!important}.data-grid-table-wrapper[data-theme=white] .actions-dropdown .dropdown-item:hover,.data-grid-table-wrapper[data-theme=white] .custom-menu .dropdown-item:hover{background-color:#007bff1a!important}.data-grid-table-wrapper[data-theme=white] .taskbar .selected-rows-action-bar{background-color:#343a40!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=white] .taskbar .selected-rows-action-bar .action-btn{color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=white] .manual-logs-modal .modal-header{background:linear-gradient(135deg,#343a40,#495057)!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=white] .manual-logs-modal .modal-header .modal-title{color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=white] .manual-logs-modal .modal-body{background-color:#f6f8ff!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .manual-logs-modal .modal-body .table{color:#000!important}.data-grid-table-wrapper[data-theme=white] .manual-logs-modal .modal-body .table thead th{background:linear-gradient(135deg,#f8f9fa,#e9ecef)!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .manual-logs-modal .modal-body .table tbody tr{color:#000!important}.data-grid-table-wrapper[data-theme=white] .manual-logs-modal .modal-body .table tbody tr:nth-child(2n){background-color:#f8f9fa!important}.data-grid-table-wrapper[data-theme=white] .manual-logs-modal .modal-body .table tbody tr:hover{background-color:#007bff1a!important}.data-grid-table-wrapper[data-theme=white] .manual-logs-modal .modal-body .table tbody tr td{color:#000!important;border-color:#d9d9db!important}.data-grid-table-wrapper[data-theme=white] .form-control,.data-grid-table-wrapper[data-theme=white] .form-select{background-color:#f6f8ff!important;border-color:#d9d9db!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .form-control::placeholder,.data-grid-table-wrapper[data-theme=white] .form-select::placeholder{color:#6c757d!important}.data-grid-table-wrapper[data-theme=white] .form-control option,.data-grid-table-wrapper[data-theme=white] .form-select option{background-color:#f6f8ff!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .filter-serach-inpt{background-color:#f6f8ff!important;border-color:#d9d9db!important}.data-grid-table-wrapper[data-theme=white] .filter-serach-inpt input{background-color:#f6f8ff!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .active-filters{background-color:#f8f9fa!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .custom-modal-overlay .custom-modal-content{background-color:#f6f8ff!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .circle-value{background-color:#f8f9fa!important;border-color:#d9d9db!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .pagination-container,.data-grid-table-wrapper[data-theme=white] .page-size,.data-grid-table-wrapper[data-theme=white] .page-info,.data-grid-table-wrapper[data-theme=white] .page-buttons{color:#000!important}.data-grid-table-wrapper[data-theme=white] .pagination-container select,.data-grid-table-wrapper[data-theme=white] .pagination-container button,.data-grid-table-wrapper[data-theme=white] .pagination-container span,.data-grid-table-wrapper[data-theme=white] .page-size select,.data-grid-table-wrapper[data-theme=white] .page-size button,.data-grid-table-wrapper[data-theme=white] .page-size span,.data-grid-table-wrapper[data-theme=white] .page-info select,.data-grid-table-wrapper[data-theme=white] .page-info button,.data-grid-table-wrapper[data-theme=white] .page-info span,.data-grid-table-wrapper[data-theme=white] .page-buttons select,.data-grid-table-wrapper[data-theme=white] .page-buttons button,.data-grid-table-wrapper[data-theme=white] .page-buttons span{background-color:#f6f8ff!important;border-color:#d9d9db!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .pagination-container button.active,.data-grid-table-wrapper[data-theme=white] .page-size button.active,.data-grid-table-wrapper[data-theme=white] .page-info button.active,.data-grid-table-wrapper[data-theme=white] .page-buttons button.active{background-color:#e3f2fd!important}.data-grid-table-wrapper[data-theme=white] .footer-row{background-color:#f8f9fa!important;border-top-color:#d9d9db!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] ::-webkit-scrollbar{background-color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=white] ::-webkit-scrollbar-thumb{background-color:#d9d9db!important}.data-grid-table-wrapper[data-theme=white] ::-webkit-scrollbar-thumb:hover{background-color:#adb5bd!important}.data-grid-table-wrapper[data-theme=white] ::-webkit-scrollbar-track{background-color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker{background-color:#f6f8ff!important;color:#000!important;border-color:#d9d9db!important}.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker .bs-datepicker-head{background:linear-gradient(135deg,#343a40,#495057)!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker .bs-datepicker-body{background-color:#f6f8ff!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker table td,.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker table th{color:#000!important}.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker table td.is-other-month,.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker table th.is-other-month{color:#6c757d!important}.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker table td.active,.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker table th.active{background-color:#e3f2fd!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker table td span.in-range,.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker table th span.in-range{background-color:#e3f2fd!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker table td:hover:not(.active),.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker table th:hover:not(.active){background-color:#007bff1a!important}.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker .bs-datepicker-buttons{background-color:#f8f9fa!important;border-top-color:#d9d9db!important}.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker .bs-datepicker-buttons .btn-primary{background:linear-gradient(135deg,#007bff,#0056b3)!important;color:#f6f8ff!important;border-color:#007bff!important}.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker .bs-datepicker-buttons .btn-secondary{background-color:#f6f8ff!important;color:#000!important;border-color:#d9d9db!important}.data-grid-table-wrapper[data-theme=white] button,.data-grid-table-wrapper[data-theme=white] .btn,.data-grid-table-wrapper[data-theme=white] .button{background-color:#f6f8ff!important;border-color:#d9d9db!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] button:hover,.data-grid-table-wrapper[data-theme=white] .btn:hover,.data-grid-table-wrapper[data-theme=white] .button:hover{background-color:#007bff1a!important}.data-grid-table-wrapper[data-theme=white] button.btn-primary,.data-grid-table-wrapper[data-theme=white] .btn.btn-primary,.data-grid-table-wrapper[data-theme=white] .button.btn-primary{background-color:#007bff!important;border-color:#007bff!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=white] button.btn-outline-primary,.data-grid-table-wrapper[data-theme=white] .btn.btn-outline-primary,.data-grid-table-wrapper[data-theme=white] .button.btn-outline-primary{border-color:#007bff!important;color:#007bff!important;background-color:transparent!important}.data-grid-table-wrapper[data-theme=white] a:not(.text-primary){color:#007bff!important}.data-grid-table-wrapper[data-theme=white] a:not(.text-primary):hover{color:#0056b3!important}.data-grid-table-wrapper[data-theme=white] .text-primary{color:#007bff!important}.data-grid-table-wrapper[data-theme=white] .text-danger{color:#dc3545!important}.data-grid-table-wrapper[data-theme=white] .text-success{color:#28a745!important}.data-grid-table-wrapper[data-theme=white] .text-warning{color:#ffc107!important}.data-grid-table-wrapper[data-theme=white] .text-info{color:#17a2b8!important}.data-grid-table-wrapper[data-theme=white] .text-muted,.data-grid-table-wrapper[data-theme=white] .muted-text{color:#6c757d!important}.data-grid-table-wrapper[data-theme=white] .border,.data-grid-table-wrapper[data-theme=white] .border-top,.data-grid-table-wrapper[data-theme=white] .border-bottom,.data-grid-table-wrapper[data-theme=white] .border-left,.data-grid-table-wrapper[data-theme=white] .border-right,.data-grid-table-wrapper[data-theme=white] .border-below,.data-grid-table-wrapper[data-theme=white] .border-start,.data-grid-table-wrapper[data-theme=white] .border-end{border-color:#d9d9db!important}.data-grid-table-wrapper[data-theme=white] .accordion-details,.data-grid-table-wrapper[data-theme=white] .nested-table,.data-grid-table-wrapper[data-theme=white] .detail-virtual-scroll{background-color:#f6f8ff!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .accordion-details td,.data-grid-table-wrapper[data-theme=white] .accordion-details th,.data-grid-table-wrapper[data-theme=white] .nested-table td,.data-grid-table-wrapper[data-theme=white] .nested-table th,.data-grid-table-wrapper[data-theme=white] .detail-virtual-scroll td,.data-grid-table-wrapper[data-theme=white] .detail-virtual-scroll th{color:#000!important;border-color:#d9d9db!important}.data-grid-table-wrapper[data-theme=blue]{border-color:#b3d9ff;background-color:#f0f8ff;color:#1e3a5f}.data-grid-table-wrapper[data-theme=blue] *,.data-grid-table-wrapper[data-theme=blue] *:before,.data-grid-table-wrapper[data-theme=blue] *:after{color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] ::selection{background-color:#007cf5!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=blue] ::-moz-selection{background-color:#007cf5!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=blue] .data-grid-header-wrapper{background-color:#e6f3ff;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .data-grid-body-wrapper{background-color:#f0f8ff;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .data-grid-row{border-bottom-color:#b3d9ff;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .data-grid-row:nth-child(2n){background-color:#f0f8ff!important}.data-grid-table-wrapper[data-theme=blue] .data-grid-row:nth-child(odd){background-color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=blue] .data-grid-row:hover{background-color:#1e3a5f1a!important}.data-grid-table-wrapper[data-theme=blue] .selected-cell,.data-grid-table-wrapper[data-theme=blue] .row-selected{background-color:#cce5ff!important}.data-grid-table-wrapper[data-theme=blue] .cell,.data-grid-table-wrapper[data-theme=blue] .header-cell,.data-grid-table-wrapper[data-theme=blue] .data-grid-row,.data-grid-table-wrapper[data-theme=blue] .data-grid-header,.data-grid-table-wrapper[data-theme=blue] .cell-content,.data-grid-table-wrapper[data-theme=blue] .full-text-content,.data-grid-table-wrapper[data-theme=blue] .circle-value,.data-grid-table-wrapper[data-theme=blue] .pic,.data-grid-table-wrapper[data-theme=blue] .image-placeholder,.data-grid-table-wrapper[data-theme=blue] .s-no,.data-grid-table-wrapper[data-theme=blue] .fw-500{color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] span,.data-grid-table-wrapper[data-theme=blue] div,.data-grid-table-wrapper[data-theme=blue] p,.data-grid-table-wrapper[data-theme=blue] td,.data-grid-table-wrapper[data-theme=blue] th,.data-grid-table-wrapper[data-theme=blue] label,.data-grid-table-wrapper[data-theme=blue] a:not(.text-primary){color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] svg,.data-grid-table-wrapper[data-theme=blue] svg path,.data-grid-table-wrapper[data-theme=blue] svg circle,.data-grid-table-wrapper[data-theme=blue] svg rect,.data-grid-table-wrapper[data-theme=blue] svg polygon{color:#1e3a5f!important;fill:#1e3a5f!important;stroke:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .data-grid-svg-icon{color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .data-grid-svg-icon path{stroke:#1e3a5f!important;fill:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .badge.badge-danger{background-color:#ff8787!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=blue] .badge.badge-success{background-color:#69db7c!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=blue] .badge.badge-warning{background-color:#ffd43b!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .badge.badge-info{background-color:#74c0fc!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=blue] .context-menu{background:#e6f3ff;border-color:#b3d9ff;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .context-menu li{color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .context-menu li:hover{background-color:#1e3a5f1a!important}.data-grid-table-wrapper[data-theme=blue] .custom-tooltip,.data-grid-table-wrapper[data-theme=blue] .popover__content,.data-grid-table-wrapper[data-theme=blue] .custom-break-tooltip{background:#e6f3ff!important;border-color:#b3d9ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .actions-dropdown,.data-grid-table-wrapper[data-theme=blue] .custom-menu{background-color:#e6f3ff!important;border-color:#b3d9ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .actions-dropdown .dropdown-item,.data-grid-table-wrapper[data-theme=blue] .custom-menu .dropdown-item{color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .actions-dropdown .dropdown-item:hover,.data-grid-table-wrapper[data-theme=blue] .custom-menu .dropdown-item:hover{background-color:#1e3a5f1a!important}.data-grid-table-wrapper[data-theme=blue] .taskbar .selected-rows-action-bar{background-color:#1e3a5f!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=blue] .taskbar .selected-rows-action-bar .action-btn{color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=blue] .manual-logs-modal .modal-header{background:linear-gradient(135deg,#1e3a5f,#2d4a6b)!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=blue] .manual-logs-modal .modal-header .modal-title{color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=blue] .manual-logs-modal .modal-body{background-color:#f0f8ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .manual-logs-modal .modal-body .table{color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .manual-logs-modal .modal-body .table thead th{background:linear-gradient(135deg,#e6f3ff,#cce5ff)!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .manual-logs-modal .modal-body .table tbody tr{color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .manual-logs-modal .modal-body .table tbody tr:nth-child(2n){background-color:#f0f8ff!important}.data-grid-table-wrapper[data-theme=blue] .manual-logs-modal .modal-body .table tbody tr:hover{background-color:#1e3a5f1a!important}.data-grid-table-wrapper[data-theme=blue] .manual-logs-modal .modal-body .table tbody tr td{color:#1e3a5f!important;border-color:#b3d9ff!important}.data-grid-table-wrapper[data-theme=blue] .form-control,.data-grid-table-wrapper[data-theme=blue] .form-select{background-color:#f6f8ff!important;border-color:#b3d9ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .form-control::placeholder,.data-grid-table-wrapper[data-theme=blue] .form-select::placeholder{color:#888!important}.data-grid-table-wrapper[data-theme=blue] .form-control option,.data-grid-table-wrapper[data-theme=blue] .form-select option{background-color:#f6f8ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .filter-serach-inpt{background-color:#f6f8ff!important;border-color:#b3d9ff!important}.data-grid-table-wrapper[data-theme=blue] .filter-serach-inpt input{background-color:#f6f8ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .active-filters,.data-grid-table-wrapper[data-theme=blue] .custom-modal-overlay .custom-modal-content{background-color:#e6f3ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .circle-value{background-color:#f6f8ff!important;border-color:#b3d9ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .pagination-container,.data-grid-table-wrapper[data-theme=blue] .page-size,.data-grid-table-wrapper[data-theme=blue] .page-info,.data-grid-table-wrapper[data-theme=blue] .page-buttons{color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .pagination-container select,.data-grid-table-wrapper[data-theme=blue] .pagination-container button,.data-grid-table-wrapper[data-theme=blue] .pagination-container span,.data-grid-table-wrapper[data-theme=blue] .page-size select,.data-grid-table-wrapper[data-theme=blue] .page-size button,.data-grid-table-wrapper[data-theme=blue] .page-size span,.data-grid-table-wrapper[data-theme=blue] .page-info select,.data-grid-table-wrapper[data-theme=blue] .page-info button,.data-grid-table-wrapper[data-theme=blue] .page-info span,.data-grid-table-wrapper[data-theme=blue] .page-buttons select,.data-grid-table-wrapper[data-theme=blue] .page-buttons button,.data-grid-table-wrapper[data-theme=blue] .page-buttons span{background-color:#f6f8ff!important;border-color:#b3d9ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .pagination-container button.active,.data-grid-table-wrapper[data-theme=blue] .page-size button.active,.data-grid-table-wrapper[data-theme=blue] .page-info button.active,.data-grid-table-wrapper[data-theme=blue] .page-buttons button.active{background-color:#cce5ff!important}.data-grid-table-wrapper[data-theme=blue] .footer-row{background-color:#e6f3ff!important;border-top-color:#b3d9ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] ::-webkit-scrollbar{background-color:#f0f8ff!important}.data-grid-table-wrapper[data-theme=blue] ::-webkit-scrollbar-thumb{background-color:#b3d9ff!important}.data-grid-table-wrapper[data-theme=blue] ::-webkit-scrollbar-thumb:hover{background-color:#74c0fc!important}.data-grid-table-wrapper[data-theme=blue] ::-webkit-scrollbar-track{background-color:#f0f8ff!important}.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker{background-color:#e6f3ff!important;color:#1e3a5f!important;border-color:#b3d9ff!important}.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker .bs-datepicker-head{background:linear-gradient(135deg,#1e3a5f,#2d4a6b)!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker .bs-datepicker-body{background-color:#f0f8ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker table td,.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker table th{color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker table td.is-other-month,.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker table th.is-other-month{color:#888!important}.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker table td.active,.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker table th.active{background-color:#cce5ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker table td span.in-range,.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker table th span.in-range{background-color:#cce5ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker table td:hover:not(.active),.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker table th:hover:not(.active){background-color:#1e3a5f1a!important}.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker .bs-datepicker-buttons{background-color:#f6f8ff!important;border-top-color:#b3d9ff!important}.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker .bs-datepicker-buttons .btn-primary{background:linear-gradient(135deg,#1e3a5f,#2d4a6b)!important;color:#f6f8ff!important;border-color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker .bs-datepicker-buttons .btn-secondary{background-color:#f0f8ff!important;color:#1e3a5f!important;border-color:#b3d9ff!important}.data-grid-table-wrapper[data-theme=blue] button,.data-grid-table-wrapper[data-theme=blue] .btn,.data-grid-table-wrapper[data-theme=blue] .button{background-color:#f6f8ff!important;border-color:#b3d9ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] button:hover,.data-grid-table-wrapper[data-theme=blue] .btn:hover,.data-grid-table-wrapper[data-theme=blue] .button:hover{background-color:#1e3a5f1a!important}.data-grid-table-wrapper[data-theme=blue] button.btn-primary,.data-grid-table-wrapper[data-theme=blue] .btn.btn-primary,.data-grid-table-wrapper[data-theme=blue] .button.btn-primary{background-color:#007cf5!important;border-color:#007cf5!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=blue] button.btn-outline-primary,.data-grid-table-wrapper[data-theme=blue] .btn.btn-outline-primary,.data-grid-table-wrapper[data-theme=blue] .button.btn-outline-primary{border-color:#007cf5!important;color:#007cf5!important;background-color:transparent!important}.data-grid-table-wrapper[data-theme=blue] a:not(.text-primary){color:#007cf5!important}.data-grid-table-wrapper[data-theme=blue] a:not(.text-primary):hover{color:#0056b3!important}.data-grid-table-wrapper[data-theme=blue] .text-primary{color:#007cf5!important}.data-grid-table-wrapper[data-theme=blue] .text-danger{color:#dc3545!important}.data-grid-table-wrapper[data-theme=blue] .text-success{color:#28a745!important}.data-grid-table-wrapper[data-theme=blue] .text-warning{color:#ffc107!important}.data-grid-table-wrapper[data-theme=blue] .text-info{color:#17a2b8!important}.data-grid-table-wrapper[data-theme=blue] .text-muted,.data-grid-table-wrapper[data-theme=blue] .muted-text{color:#6c757d!important}.data-grid-table-wrapper[data-theme=blue] .border,.data-grid-table-wrapper[data-theme=blue] .border-top,.data-grid-table-wrapper[data-theme=blue] .border-bottom,.data-grid-table-wrapper[data-theme=blue] .border-left,.data-grid-table-wrapper[data-theme=blue] .border-right,.data-grid-table-wrapper[data-theme=blue] .border-below,.data-grid-table-wrapper[data-theme=blue] .border-start,.data-grid-table-wrapper[data-theme=blue] .border-end{border-color:#b3d9ff!important}.data-grid-table-wrapper[data-theme=blue] .accordion-details,.data-grid-table-wrapper[data-theme=blue] .nested-table,.data-grid-table-wrapper[data-theme=blue] .detail-virtual-scroll{background-color:#f0f8ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .accordion-details td,.data-grid-table-wrapper[data-theme=blue] .accordion-details th,.data-grid-table-wrapper[data-theme=blue] .nested-table td,.data-grid-table-wrapper[data-theme=blue] .nested-table th,.data-grid-table-wrapper[data-theme=blue] .detail-virtual-scroll td,.data-grid-table-wrapper[data-theme=blue] .detail-virtual-scroll th{color:#1e3a5f!important;border-color:#b3d9ff!important}.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:30px}.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;position:relative}.resize-handle.resizing{z-index:9999!important;opacity:1!important;background-color:#007bff1a;border-right:2px solid #007bff;box-shadow:0 0 8px #007bff4d;position:relative!important;pointer-events:none!important}.group-header .resize-handle{top:25%}.h-100{height:100%}.data-grid-body{position:relative;overflow-y:auto;overflow-x:hidden;box-shadow:none!important}.cell{padding:8px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;height:100%;display:flex;align-items:center}.data-grid-row{display:flex;min-width:max-content;align-items:center;border-bottom:1px solid #d9d9db;transition:all .25s cubic-bezier(.4,0,.2,1);transform:translateZ(0);will-change:transform,box-shadow;backface-visibility:hidden}.data-grid-row:hover{transform:translate(2px);box-shadow:2px 0 8px #007bff1a}.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;background:#f6f8ff}.right-pinned-header{position:absolute;right:0;border-left:1px solid #d9d9db;z-index:unset}.left-pinned{left:0;border-right:1px solid #d9d9db}.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{display:flex}.data-grid-body-wrapper{scrollbar-width:none;-ms-overflow-style:none}.data-grid-body-wrapper::-webkit-scrollbar{display:none}.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:#f6f8ff;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:-15px;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:16px}.border-below{border-bottom:1px solid #d9d9db!important}.three-dots{width:22px;height:22px;display:flex;justify-content:center;align-items:center;border-radius:6px;margin-right:8px;cursor:pointer;transition:all .25s cubic-bezier(.4,0,.2,1);transform:translateZ(0);position:relative}.three-dots:before{content:\"\";position:absolute;top:50%;left:50%;width:0;height:0;background:#007bff1a;border-radius:50%;transform:translate(-50%,-50%);transition:width .25s,height .25s}.three-dots:hover{background-color:#007bff1a;transform:rotate(90deg)}.three-dots:hover:before{width:28px;height:28px}.three-dots:active{transform:rotate(90deg) scale(.95);transition-duration:.15s}.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:6px;cursor:pointer;transition:all .25s cubic-bezier(.4,0,.2,1);transform:translateZ(0);position:relative}.filter-icon-wrapper:before{content:\"\";position:absolute;top:50%;left:50%;width:0;height:0;background:#007bff1a;border-radius:50%;transform:translate(-50%,-50%);transition:width .25s,height .25s}.filter-icon-wrapper:hover{background-color:#007bff1a;transform:scale(1.05)}.filter-icon-wrapper:hover:before{width:32px;height:32px}.filter-icon-wrapper:active{transform:scale(.95);transition-duration:.15s}.column-panel-item{font-size:.875rem;color:#333;transition:all .25s cubic-bezier(.4,0,.2,1);transform:translateZ(0)}.column-panel-item:hover{background-color:#007bff0d;color:#007bff;transform:translate(2px)}.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:all .25s cubic-bezier(.4,0,.2,1);transform:translateZ(0);border-radius:4px;padding:2px}.toggle-icon:hover{background-color:#007bff1a;transform:scale(1.1)}.toggle-icon:active{transform:scale(.95)}.grab-icon{cursor:grab;color:#6c757d;transition:all .25s cubic-bezier(.4,0,.2,1);transform:translateZ(0)}.grab-icon:hover{color:#007bff;transform:scale(1.1)}.grab-icon:active{cursor:grabbing;transform:scale(.95)}.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:6px;display:flex;justify-content:center;align-items:center;transition:all .25s cubic-bezier(.4,0,.2,1);margin-right:8px;transform:translateZ(0);position:relative}.chevron-wrapper:before{content:\"\";position:absolute;top:50%;left:50%;width:0;height:0;background:#007bff1a;border-radius:50%;transform:translate(-50%,-50%);transition:width .25s,height .25s}.chevron-wrapper:hover{background-color:#007bff1a;transform:scale(1.1)}.chevron-wrapper:hover:before{width:36px;height:36px}.chevron-wrapper:hover i{transform:scale(1.2);transition:transform .25s cubic-bezier(.4,0,.2,1)}.chevron-wrapper:active{transform:scale(.95);transition-duration:.15s}.chevron-wrapper i{font-size:14px;transition:transform .25s cubic-bezier(.4,0,.2,1)}.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;transition:all .25s cubic-bezier(.4,0,.2,1);transform:translateZ(0);border-radius:6px}.columns-button:hover{background-color:#007bff1a;transform:scale(1.05)}.columns-button:active{transform:scale(.95)}.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:fixed;right:200px;z-index:1050;background-color:#fff;cursor:default;animation:slideInRight .25s cubic-bezier(.4,0,.2,1);transform:translateZ(0);border-radius:8px;box-shadow:0 8px 32px #0000001f;backdrop-filter:blur(8px)}.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;transition:all .25s cubic-bezier(.4,0,.2,1);transform:translateZ(0)}.action-button:hover{transform:translateY(-1px);box-shadow:0 4px 12px #007cf54d}.action-button:active{transform:translateY(0);transition-duration:.15s}.global-search{max-width:380px!important}.global-search span{margin-top:2px}.global-search input{padding-left:28px;border-radius:8px!important;transition:all .25s cubic-bezier(.4,0,.2,1);transform:translateZ(0)}.global-search input:focus{outline:none!important;box-shadow:0 0 0 3px #007bff1a!important;border-color:#007bff!important;transform:scale(1.02)}.active .top-icon ::ng-deep svg path{stroke:#007cf5!important}.custom-menu{width:220px;border-radius:8px;padding:4px 0}.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}.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;transition:all .25s cubic-bezier(.4,0,.2,1);transform:translateZ(0)}.page-buttons button:hover:not(:disabled){background-color:#007bff1a;border-color:#007bff;transform:translateY(-1px)}.page-buttons button:active:not(:disabled){transform:translateY(0) scale(.98)}.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!important}.text-filter select option{font-size:14px;font-weight:500}.text-filter select:focus{border:0!important}.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;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-width:600px;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{letter-spacing:.5px}.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;bottom:0;left:45%;display:flex;justify-content:center;z-index:1000;padding:36px}.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{font-size:14px;padding:6px 12px;border-radius:6px;text-align:center;height:auto;min-height:28px;display:inline-flex;align-items:center;justify-content:center;font-weight:500;line-height:1.5;white-space:nowrap;transition:all .2s cubic-bezier(.4,0,.2,1);will-change:transform,opacity;backface-visibility:hidden;transform:translateZ(0)}.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}.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;animation:pulse .25s cubic-bezier(.4,0,.2,1);transform:translateZ(0);position:relative}.selected-cell:before,.row-selected:before{content:\"\";position:absolute;inset:0;background:linear-gradient(45deg,transparent,rgba(255,255,255,.1),transparent);animation:shimmer 1.5s ease-in-out infinite}.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}.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.dragging th,.accordion-details.dragging td{pointer-events:none}.accordion-details.dragging th{z-index:2}.drag-handle{cursor:move;opacity:.5;transition:opacity .2s}.drag-handle:hover{opacity:1}.detail-edit-input{z-index:100;position:relative}.detail-filter-menu{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}.detail-filter-menu-positioned{width:280px;right:unset;max-width:230px;z-index:99;left:375px;top:225px}.resize-handle{cursor:col-resize;opacity:.5;width:8px;display:flex;align-items:center;justify-content:center}.resize-handle:hover{opacity:1;background-color:#f0f0f0}.detail-header-row{transition:all .3s ease}.detail-header-row.dragging{opacity:.7;transform:translate(5px)}.detail-cell{transition:background-color .2s ease,transform .3s ease}.detail-cell.active-drag{background-color:#f0f0f0;transform:scale(1.02)}.break-color-paid{background-color:#4caf50!important}.break-color-unpaid{background-color:#f44336!important}.break-color-lunch{background-color:#2196f3!important}.break-color-default{background-color:#f44336!important}.circle-value{display:flex;align-items:center;justify-content:center;width:32px;height:32px;border-radius:50%;background-color:#f8f9fa;border:2px solid #d9d9db;font-size:12px;font-weight:600;color:#000;text-align:center;line-height:1;vertical-align:middle;box-sizing:border-box;white-space:nowrap;overflow:hidden;cursor:pointer;transition:all .3s cubic-bezier(.4,0,.2,1);transform:translateZ(0);will-change:transform,box-shadow,background-color;backface-visibility:hidden}.circle-value:hover{background-color:#e9ecef;box-shadow:0 6px 16px #007bff40;transform:scale(1.15) translateY(-2px);border-color:#007bff}.circle-value:active{transform:scale(1.08) translateY(-1px);transition-duration:.15s}.break-tooltip-wrapper{position:relative;display:inline-block}.break-tooltip-wrapper:hover .custom-break-tooltip{opacity:1;visibility:visible}.circle-value[title]{position:relative}.circle-value[title]:after{content:attr(title);position:absolute;bottom:100%;left:50%;transform:translate(-50%);background-color:#333;color:#fff;padding:4px 8px;border-radius:4px;font-size:12px;white-space:nowrap;opacity:0;transition:opacity .2s ease;pointer-events:none}.circle-value[title]:hover:after{opacity:1}.custom-tooltip{position:fixed;background:#fff;border:1px solid #dcdcdc;border-radius:8px;padding:12px 16px;max-width:300px;z-index:9999;font-size:13px;animation:fadeIn .2s ease-in-out}.tooltip-title{font-size:14px;font-weight:600;margin-bottom:8px;color:#333}.tooltip-list{margin:0;padding-left:16px;list-style-type:disc}.tooltip-list li{margin-bottom:4px;line-height:1.4;color:#444}.tooltip-total{font-weight:700;margin-top:8px;color:#222}@keyframes fadeIn{0%{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:translateY(0)}}.restriction-indicator{position:absolute;display:inline-block;padding-right:10px}.restriction-indicator:after{content:\"\";position:absolute;top:0;right:0;width:8px;height:8px;background-color:#0d6efd;border-radius:50%}.manual-logs-indicator{position:absolute;top:2px;right:2px;width:8px;height:8px;background-color:#0d6efd;border-radius:50%;border:1px solid #fff;box-shadow:0 0 2px #0d6efd80;cursor:pointer;z-index:10;transition:all .2s ease}.manual-logs-indicator:hover{transform:scale(1.2);box-shadow:0 0 4px #0d6efdcc}.manual-logs-table-tooltip{background:#fff!important;border:1px solid #dcdcdc!important;border-radius:8px!important;box-shadow:0 4px 12px #00000026!important;font-size:13px!important;animation:fadeIn .2s ease-in-out!important;display:block!important;visibility:visible!important;opacity:1!important}.manual-logs-table-tooltip .popover__content,.manual-logs-table-tooltip .modal-area{padding:0!important;display:block!important;visibility:visible!important}.manual-logs-table-tooltip .table-responsive{max-height:300px;overflow-y:auto;display:block!important;visibility:visible!important}.manual-logs-table-tooltip table{margin:0!important;border-collapse:collapse!important;display:table!important;visibility:visible!important}.manual-logs-table-tooltip table th,.manual-logs-table-tooltip table td{padding:6px 8px!important;border:1px solid #f1f1f1!important;text-align:center!important;vertical-align:middle!important;display:table-cell!important;visibility:visible!important}.manual-logs-table-tooltip table th{background-color:#f8f9fa!important;font-weight:600!important;color:#495057!important;position:sticky!important;top:0!important;z-index:1!important}.manual-logs-table-tooltip table tbody tr:nth-child(2n){background-color:#f8f9fa!important}.manual-logs-table-tooltip table tbody tr:hover{background-color:#e3f2fd!important}.manual-logs-table-tooltip table .text-primary{color:#0d6efd!important;text-decoration:none!important}.manual-logs-table-tooltip table .capitalize{text-transform:capitalize!important}@keyframes fadeIn{0%{opacity:0;transform:translate(-50%) translateY(-110%)}to{opacity:1;transform:translate(-50%) translateY(-100%)}}.detail-column-menu{max-height:250px;overflow-y:auto;overflow-x:auto;white-space:nowrap;padding:8px 0;border-radius:6px;scrollbar-width:thin}.detail-column-menu-wrapper{z-index:1001;position:absolute}.accordion-details{position:relative;z-index:999}.detail-column-menu .column-menu-item{padding:8px 12px;cursor:pointer;display:flex;align-items:center;transition:all .25s cubic-bezier(.4,0,.2,1);font-size:14px;transform:translateZ(0);border-radius:4px}.detail-column-menu .column-menu-item:hover{background-color:#007bff1a;transform:translate(2px);color:#007bff}.detail-column-menu .column-menu-item:active{transform:translate(0) scale(.98)}.detail-column-menu .column-menu-item:hover{background-color:#deebf7}.nested-table th[pinned=left],.nested-table td[pinned=left]{border-right:2px solid #ccc;border-left:none;border-bottom:2px solid #ccc}.nested-table th[pinned=right],.nested-table td[pinned=right]{border-left:2px solid #ccc;border-right:none;border-bottom:2px solid #ccc}.data-grid-accordion-table.show-borders{border:1px solid #d9d9db;border-collapse:collapse}.data-grid-accordion-table.show-borders th,.data-grid-accordion-table.show-borders td{border:1px solid #d9d9db}.data-grid-accordion-table.show-shadow tbody tr:hover{box-shadow:0 4px 8px #0000001a;transition:box-shadow .3s ease}.data-grid-accordion-table tbody tr:hover{background-color:#deebf7;transition:background-color .3s ease}.data-grid-pin-icon{display:inline-block;vertical-align:middle;margin-left:4px}.accordion-details.center-section{position:relative;display:flex}.detail-side-menu-wrapper{display:flex;flex-shrink:0;position:sticky;right:0;top:0;height:100%;max-height:275px}.detail-side-menu-content{width:250px;box-shadow:-2px 0 5px #0000001a;display:flex;flex-direction:column}.side-menu-scrollable{flex:1;overflow-y:auto;padding:0 12px 12px;max-height:calc(100% - 40px)}.filter-input-container{padding:8px;background:#f9f9f9;border-radius:4px}.toggle-icon.rotate{transform:rotate(90deg)}.resize-handle{top:0;right:3px;bottom:0;width:8px;cursor:col-resize;z-index:10;display:flex;align-items:center;justify-content:center;opacity:1.4;transition:all .25s cubic-bezier(.4,0,.2,1);background:transparent;transform:translateZ(0)}.resize-handle:hover{opacity:1;background:#007bff1a}.resize-handle:active{opacity:1;background:#007bff33;transform:scaleX(1.2)}th:hover .resize-handle{opacity:40}.resize-handles{top:0;right:3px;bottom:0;width:8px;cursor:col-resize;z-index:10;display:flex;align-items:center;justify-content:center;position:absolute;opacity:1.4;transition:all .25s cubic-bezier(.4,0,.2,1);background:transparent;transform:translateZ(0)}.resize-handles:hover{opacity:1;background:#007bff1a}.resize-handles:active{opacity:1;background:#007bff33;transform:scaleX(1.2)}.resize-handles.resizing{z-index:9999!important;opacity:1!important;background-color:#007bff1a;border-right:2px solid #007bff;box-shadow:0 0 8px #007bff4d;pointer-events:none!important}th:hover .resize-handles{opacity:40}.resizing-highlight{background-color:#007bff1a!important}.accordion-details-wrapper{display:flex;width:100%;max-height:350px;overflow:hidden}.accordion-details.show-borders,.accordion-details-wrapper.show-borders{border:1px solid #d9d9db;border-radius:4px}.accordion-left-section,.accordion-right-section,.detail-side-menu-wrapper{flex-shrink:0;max-height:350px;overflow:hidden;height:fit-content}.accordion-center-section{flex:1;min-width:0;overflow:auto;max-height:350px}.detail-virtual-scroll{display:block;width:100%;height:250px;overflow:auto}.detail-virtual-scroll table{table-layout:fixed;width:100%}.detail-virtual-scroll td,.detail-virtual-scroll th{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.detail-header-scroll-container{scrollbar-width:none}.detail-header-scroll-container::-webkit-scrollbar{display:none}.accordion-left-section thead th,.accordion-right-section thead th{position:sticky;top:0;z-index:2}.data-pin-body-wrapper{-webkit-user-select:none;user-select:none;display:flex}.data-pin-body-wrapper{scrollbar-width:none;-ms-overflow-style:none}.data-pin-body-wrapper::-webkit-scrollbar{display:none}.detail-virtual-scroll .selected-cell,.accordion-left-section .selected-cell,.accordion-right-section .selected-cell{background-color:#cce5ff!important}.custom-datepicker-buttons button{height:28px;padding:0 10px;font-size:12px}.manual-logs-modal{max-width:800px;max-height:80vh;overflow:hidden;border-radius:12px;box-shadow:0 10px 40px #0003}.manual-logs-modal .modal-header{background:linear-gradient(135deg,#4361ee,#3a0ca3);color:#fff;padding:16px 20px;border-bottom:none;border-radius:12px 12px 0 0}.manual-logs-modal .modal-header .modal-title{font-weight:600;font-size:18px;margin:0}.manual-logs-modal .modal-header .btn-close{background:#fff3;border:none;border-radius:50%;width:32px;height:32px;display:flex;align-items:center;justify-content:center;color:#fff;opacity:.8;transition:all .25s cubic-bezier(.4,0,.2,1);transform:translateZ(0)}.manual-logs-modal .modal-header .btn-close:hover{background:#ffffff4d;opacity:1;transform:scale(1.1) rotate(90deg)}.manual-logs-modal .modal-header .btn-close:active{transform:scale(.95) rotate(90deg)}.manual-logs-modal .modal-body{padding:20px;max-height:calc(80vh - 80px);overflow-y:auto}.manual-logs-modal .modal-body .table-responsive{border-radius:8px;overflow:hidden;box-shadow:0 2px 8px #0000001a}.manual-logs-modal .modal-body .table-responsive .table{margin-bottom:0;font-size:14px}.manual-logs-modal .modal-body .table-responsive .table thead th{background:linear-gradient(135deg,#f8f9fa,#e9ecef);border-bottom:2px solid #dee2e6;font-weight:600;color:#495057;padding:12px 16px;position:sticky;top:0;z-index:10}.manual-logs-modal .modal-body .table-responsive .table tbody tr{transition:background-color .2s ease}.manual-logs-modal .modal-body .table-responsive .table tbody tr:hover{background-color:#f8f9fa}.manual-logs-modal .modal-body .table-responsive .table tbody tr:nth-child(2n){background-color:#f8f9fa}.manual-logs-modal .modal-body .table-responsive .table tbody tr td{padding:10px 16px;vertical-align:middle;border-color:#e9ecef}.manual-logs-modal .modal-body .table-responsive .table tbody tr td .text-primary{color:#0d6efd!important;font-weight:500;text-decoration:none}.manual-logs-modal .modal-body .table-responsive .table tbody tr td .text-primary:hover{text-decoration:underline}.manual-logs-modal .modal-body .table-responsive .table tbody tr td .capitalize{text-transform:capitalize}::ng-deep bs-daterangepicker-container .bs-datepicker{border-radius:4px!important;box-shadow:0 2px 8px #0000001a!important;font-size:14px!important;display:flex!important;align-items:flex-start!important;left:142px!important}::ng-deep .bs-datepicker-head{background:#f8f9fa!important;color:#495057!important;border-bottom:1px solid #dee2e6!important;padding:8px 12px!important;border-radius:4px 4px 0 0!important}::ng-deep .bs-datepicker-head .current{font-weight:600!important;color:#495057!important;font-size:13px!important}::ng-deep .bs-datepicker-head .previous,::ng-deep .bs-datepicker-head .next{background:#fff!important;color:#495057!important;border:1px solid #dee2e6!important;width:24px!important;border-radius:4px!important;font-size:12px!important}::ng-deep .bs-datepicker-head .previous:hover,::ng-deep .bs-datepicker-head .next:hover{background:#e9ecef!important}::ng-deep .bs-datepicker .bs-datepicker-buttons{padding:8px!important;background:#f8f9fa!important;border-top:1px solid #dee2e6!important;border-radius:0 0 4px 4px!important}::ng-deep .bs-datepicker .bs-datepicker-buttons .btn-primary{background:#007bff!important;color:#fff!important;border:1px solid #007bff!important;font-weight:500!important;padding:4px 8px!important;border-radius:4px!important;font-size:12px!important}::ng-deep .bs-datepicker .bs-datepicker-buttons .btn-primary:hover{background:#0056b3!important;border-color:#0056b3!important}::ng-deep .bs-datepicker .bs-datepicker-buttons .btn-secondary{background:#fff!important;color:#495057!important;border:1px solid #dee2e6!important;font-weight:500!important;padding:4px 8px!important;border-radius:4px!important;font-size:12px!important}::ng-deep .bs-datepicker .bs-datepicker-buttons .btn-secondary:hover{background:#e9ecef!important}::ng-deep .bs-datepicker-body{background:#fff!important;padding:6px!important}::ng-deep .bs-datepicker-body table{background:#fff!important;border-collapse:separate!important;border-spacing:1px!important}::ng-deep .bs-datepicker-body table th,::ng-deep .bs-datepicker-body table td{border:1px solid #dee2e6!important;border-radius:4px!important;text-align:center!important;font-weight:500!important;color:#495057!important;cursor:pointer!important;transition:all .2s ease!important;font-size:12px!important;width:32px!important;height:32px!important;line-height:24px!important}::ng-deep .bs-datepicker-body table th{background:#f8f9fa!important;font-weight:600!important;font-size:11px!important;padding:2px!important;height:24px!important;line-height:20px!important}::ng-deep .bs-datepicker-body table td:hover:not(.disabled){background:#e9ecef!important}::ng-deep .bs-datepicker-body table td.active{background:#007bff!important;color:#fff!important;border-color:#007bff!important}::ng-deep .bs-datepicker-body table td.is-other-month{color:#6c757d!important;background:#f8f9fa!important}::ng-deep .bs-datepicker-body table td.disabled{color:#adb5bd!important;background:#e9ecef!important;cursor:not-allowed!important}::ng-deep .bs-datepicker-custom-range{background:transparent!important;border-right:1px solid #dee2e6!important;padding:6px!important;width:130px!important;margin-right:8px!important;align-self:flex-start!important}::ng-deep .bs-datepicker-predefined-btns{display:flex!important;flex-direction:column!important;gap:2px!important}::ng-deep .bs-datepicker-predefined-btns button{background:transparent!important;color:#495057!important;border:1px solid #dee2e6!important;border-radius:4px!important;padding:4px 6px!important;font-size:11px!important;font-weight:500!important;text-align:left!important;cursor:pointer!important;transition:all .2s ease!important;width:100%!important;margin:0!important}::ng-deep .bs-datepicker-predefined-btns button:hover{background:#e9ecef!important;border-color:#adb5bd!important}::ng-deep .bs-datepicker-predefined-btns button:active,::ng-deep .bs-datepicker-predefined-btns button:focus{outline:none!important;box-shadow:0 0 0 2px #007bff40!important;background:#007bff!important;color:#fff!important;border-color:#007bff!important}.manual-logs-modal-overlay{position:fixed;top:0;left:0;width:100%;height:100%;background-color:#00000080;display:flex;justify-content:center;align-items:center;z-index:9999}.manual-logs-modal-content{background:#fff;border-radius:8px;max-width:800px;max-height:80vh;overflow:auto;box-shadow:0 4px 8px #0000001a}.popover__wrapper{position:relative;display:inline-block}.popover__content{position:absolute;bottom:100%;left:50%;transform:translate(-50%);background:#fff;border:1px solid #ccc;border-radius:8px;padding:12px;box-shadow:0 4px 12px #00000026;z-index:1000;opacity:0;visibility:hidden;transition:opacity .3s ease,visibility .3s ease;min-width:250px;max-width:400px;font-size:14px}.popover__wrapper:hover .popover__content{opacity:1;visibility:visible}.popover__content .modal-area{padding:0}.popover__content h4{margin:0 0 8px;font-size:16px;font-weight:600;color:#333}.popover__content .break-status{font-size:12px;color:#666;margin-bottom:8px}.popover__content .d-flex{gap:12px}.popover__content p{margin:0 0 4px;font-size:12px;color:#666}.popover__content h5{margin:0;font-size:14px;font-weight:500;color:#333}.popover__content .break-footer{border-top:1px solid #eee;margin-top:8px;padding-top:8px}.popover__content .break-footer p{font-size:12px;color:#666;margin:0}.custom-break-tooltip{position:fixed;z-index:1000;background:#fff;border:1px solid #ddd;border-radius:8px;box-shadow:0 4px 12px #00000026;padding:12px;font-size:13px;max-width:220px;pointer-events:none;top:0;left:0;transform:translate(var(--tooltip-x, 0px),var(--tooltip-y, 0px))}.custom-break-tooltips{position:fixed;z-index:1000;background:#fff;border:1px solid #ddd;border-radius:8px;box-shadow:0 4px 12px #00000026;padding:8px;font-size:12px;max-width:500px;max-height:300px;top:0;left:0;transform:translate(var(--tooltip-x, 0px),var(--tooltip-y, 0px))}.custom-break-tooltips .modal-body{max-height:250px!important;overflow-y:auto;padding:0}.custom-break-tooltips .table-responsive{max-height:250px}.custom-break-tooltips thead th{position:sticky;top:0;background:#f8f9fa;z-index:10;border-bottom:2px solid #dee2e6;font-size:11px;padding:4px 8px;font-weight:600}.custom-break-tooltips table{font-size:11px;margin-bottom:0}.custom-break-tooltips table td{padding:4px 8px;white-space:nowrap}.custom-break-tooltips .table-striped tbody tr:nth-of-type(odd){background-color:#00000005}.popver_content_progress_bar{visibility:hidden}.badge-overflow-container{display:flex;flex-wrap:nowrap;gap:4px;align-items:center;min-width:0;overflow:hidden;width:100%}.badge-overflow-container .badge{flex-shrink:0;white-space:nowrap;font-size:12px;padding:4px 8px;border-radius:50%;display:inline-flex;align-items:center;justify-content:center;font-weight:600;line-height:1;text-transform:uppercase;letter-spacing:.5px;transition:all .3s cubic-bezier(.4,0,.2,1);border:2px solid transparent;width:32px;height:32px;box-sizing:border-box;cursor:pointer;transform:translateZ(0);will-change:transform,box-shadow,background-color;backface-visibility:hidden}.badge-overflow-container .badge:hover{transform:scale(1.15) translateY(-2px);box-shadow:0 6px 16px #007bff40}.badge-overflow-container .badge:active{transform:scale(1.08) translateY(-1px);transition-duration:.15s}.badge-overflow-container .badge-overflow-count{background-color:#6c757d!important;color:#fff!important;cursor:pointer;border:2px solid #6c757d!important;flex-shrink:0;border-radius:50%;width:32px;height:32px;display:inline-flex;align-items:center;justify-content:center;font-weight:600;transition:all .3s cubic-bezier(.4,0,.2,1);transform:translateZ(0);will-change:transform,box-shadow,background-color;backface-visibility:hidden}.badge-overflow-container .badge-overflow-count:hover{background-color:#5a6268!important;border-color:#5a6268!important;transform:scale(1.15) translateY(-2px);box-shadow:0 6px 16px #007bff40}.badge-overflow-container .badge-overflow-count:active{transform:scale(1.08) translateY(-1px);transition-duration:.15s}.timeline-view-container{padding:1rem;background-color:#f8f9fa}.timeline-view-container .timeline-header{margin-bottom:2rem}.timeline-view-container .timeline-header h5{color:#495057;font-weight:600;margin-bottom:1rem}.timeline-view-container .timeline-header .timeline-hours{display:flex;justify-content:space-between;padding:.5rem 0;border-bottom:1px solid #dee2e6;margin-bottom:1rem;background:#fff;border-radius:8px;padding:1rem}.timeline-view-container .timeline-header .timeline-hours .timeline-hour{font-size:.8rem;color:#6c757d;font-weight:500;min-width:40px;text-align:center;padding:.5rem;border-radius:4px;background:#f8f9fa}.timeline-view-container .timeline-body .timeline-row{background:#fff;border:1px solid #dee2e6;border-radius:8px;margin-bottom:1rem;padding:1rem;box-shadow:0 2px 4px #0000001a;transition:box-shadow .2s ease}.timeline-view-container .timeline-body .timeline-row:hover{box-shadow:0 4px 8px #00000026}.timeline-view-container .timeline-body .timeline-row .timeline-employee{margin-bottom:1rem}.timeline-view-container .timeline-body .timeline-row .timeline-employee .employee-name{font-weight:600;color:#495057;font-size:1.1rem}.timeline-view-container .timeline-body .timeline-row .timeline-track{position:relative;height:40px;background:#f8f9fa;border-radius:4px;border:1px solid #e9ecef}.timeline-view-container .timeline-body .timeline-row .timeline-track .work-duration-bar{position:absolute;height:100%;background:linear-gradient(135deg,#28a745,#20c997);border-radius:4px;box-shadow:0 2px 4px #28a7454d;transition:opacity .2s ease}.timeline-view-container .timeline-body .timeline-row .timeline-track .work-duration-bar:hover{opacity:.8}.timeline-view-container .timeline-body .timeline-row .timeline-track .break-bar{position:absolute;height:100%;border-radius:4px;box-shadow:0 2px 4px #0003;border:1px solid rgba(255,255,255,.5);transition:opacity .2s ease}.timeline-view-container .timeline-body .timeline-row .timeline-track .break-bar:hover{opacity:.8}.calendar-view-container .calendar-header{margin-bottom:2rem}.calendar-view-container .calendar-header h5{color:#495057;font-weight:600}.calendar-view-container .calendar-header .calendar-nav button{border:1px solid #dee2e6;background:#fff;color:#495057;padding:.375rem .75rem;border-radius:.375rem;transition:all .2s ease}.calendar-view-container .calendar-header .calendar-nav button:hover{background-color:#f8f9fa;border-color:#adb5bd}.calendar-view-container .calendar-header .calendar-nav button:first-child{border-top-right-radius:0;border-bottom-right-radius:0;border-right:none}.calendar-view-container .calendar-header .calendar-nav button:last-child{border-top-left-radius:0;border-bottom-left-radius:0}.calendar-view-container .calendar-grid .calendar-week-header{display:flex;background-color:#f8f9fa;border:1px solid #dee2e6;border-bottom:none}.calendar-view-container .calendar-grid .calendar-week-header .calendar-day-header{flex:1;padding:.75rem;text-align:center;font-weight:600;color:#495057;border-right:1px solid #dee2e6}.calendar-view-container .calendar-grid .calendar-week-header .calendar-day-header:last-child{border-right:none}.calendar-view-container .calendar-grid .calendar-weeks{border:1px solid #dee2e6;border-top:none}.calendar-view-container .calendar-grid .calendar-weeks .calendar-week{display:flex;border-bottom:1px solid #dee2e6}.calendar-view-container .calendar-grid .calendar-weeks .calendar-week:last-child{border-bottom:none}.calendar-view-container .calendar-grid .calendar-weeks .calendar-week .calendar-day{flex:1;min-height:100px;padding:.5rem;border-right:1px solid #dee2e6;background:#fff}.calendar-view-container .calendar-grid .calendar-weeks .calendar-week .calendar-day:last-child{border-right:none}.calendar-view-container .calendar-grid .calendar-weeks .calendar-week .calendar-day.current-month{background:#fff}.calendar-view-container .calendar-grid .calendar-weeks .calendar-week .calendar-day.today{background-color:#fff3cd;border:2px solid #ffc107}.calendar-view-container .calendar-grid .calendar-weeks .calendar-week .calendar-day .day-number{font-weight:600;color:#495057;margin-bottom:.25rem}.calendar-view-container .calendar-grid .calendar-weeks .calendar-week .calendar-day .day-entries .entry-dot{width:8px;height:8px;border-radius:50%;display:inline-block;margin-right:2px;margin-bottom:2px}.heatmap-view-container .heatmap-header{margin-bottom:2rem}.heatmap-view-container .heatmap-header h5{color:#495057;font-weight:600}.heatmap-view-container .heatmap-header .heatmap-legend .legend-colors{display:flex;margin:0 1rem}.heatmap-view-container .heatmap-header .heatmap-legend .legend-colors .legend-color{width:12px;height:12px;margin-right:2px;border-radius:2px}.heatmap-view-container .heatmap-header .heatmap-legend span{font-size:.875rem;color:#6c757d}.heatmap-view-container .heatmap-grid .heatmap-months{display:flex;margin-bottom:.5rem}.heatmap-view-container .heatmap-grid .heatmap-months .month-label{flex:1;text-align:center;font-size:.8rem;font-weight:600;color:#495057}.heatmap-view-container .heatmap-grid .heatmap-weeks .heatmap-week{display:flex;margin-bottom:2px}.heatmap-view-container .heatmap-grid .heatmap-weeks .heatmap-week .heatmap-day{flex:1;aspect-ratio:1;border-radius:2px;margin-right:2px;transition:opacity .2s ease}.heatmap-view-container .heatmap-grid .heatmap-weeks .heatmap-week .heatmap-day:hover{opacity:.8}.heatmap-view-container .heatmap-grid .heatmap-weeks .heatmap-week .heatmap-day:last-child{margin-right:0}.card-view-container{padding:1rem;height:100%;overflow-y:auto;overflow-x:hidden}.card-view-container[data-theme=white]{background-color:#f6f8ff;color:#000}.card-view-container[data-theme=white] .attendance-card{background-color:#f6f8ff;border-color:#d9d9db;color:#000}.card-view-container[data-theme=white] .attendance-card:hover{background-color:#007bff1a}.card-view-container[data-theme=white] .attendance-card .card-header{background-color:#f8f9fa;color:#000;border-bottom-color:#d9d9db}.card-view-container[data-theme=white] .attendance-card .card-body{background-color:#f6f8ff;color:#000}.card-view-container[data-theme=white] .attendance-card .badge.bg-success{background-color:#84ca81;color:#f6f8ff}.card-view-container[data-theme=white] .attendance-card .badge.bg-danger{background-color:#ea5353;color:#f6f8ff}.card-view-container[data-theme=white] .attendance-card .badge.bg-warning{background-color:#fff3dc;color:#000}.card-view-container[data-theme=white] .attendance-card .badge.bg-info{background-color:#e8fbfd;color:#00bad1}.card-view-container[data-theme=blue]{background-color:#f0f8ff;color:#1e3a5f}.card-view-container[data-theme=blue] .attendance-card{background-color:#f6f8ff;border-color:#b3d9ff;color:#1e3a5f}.card-view-container[data-theme=blue] .attendance-card:hover{background-color:#1e3a5f1a}.card-view-container[data-theme=blue] .attendance-card .card-header{background-color:#e6f3ff;color:#1e3a5f;border-bottom-color:#b3d9ff}.card-view-container[data-theme=blue] .attendance-card .card-body{background-color:#f6f8ff;color:#1e3a5f}.card-view-container[data-theme=blue] .attendance-card .badge.bg-success{background-color:#69db7c;color:#f6f8ff}.card-view-container[data-theme=blue] .attendance-card .badge.bg-danger{background-color:#ff8787;color:#f6f8ff}.card-view-container[data-theme=blue] .attendance-card .badge.bg-warning{background-color:#ffd43b;color:#1e3a5f}.card-view-container[data-theme=blue] .attendance-card .badge.bg-info{background-color:#74c0fc;color:#f6f8ff}.card-view-container .row{margin:0}.card-view-container .row .col-xl-4,.card-view-container .row .col-lg-6,.card-view-container .row .col-md-6,.card-view-container .row .col-sm-12{padding:.5rem}.card-view-container .attendance-card{transition:background-color .2s ease;border:1px solid #d9d9db;border-radius:4px;overflow:hidden;height:100%;display:flex;flex-direction:column;font-family:sans-serif;font-size:16px}.card-view-container .attendance-card:hover{box-shadow:0 2px 4px #0000001a}.card-view-container .attendance-card.expanded .card-body{max-height:none}.card-view-container .attendance-card .card-header{padding:8px;border-bottom:1px solid #d9d9db;flex-shrink:0;font-weight:500}.card-view-container .attendance-card .card-header .employee-avatar{margin-right:.75rem;flex-shrink:0}.card-view-container .attendance-card .card-header .employee-avatar img,.card-view-container .attendance-card .card-header .employee-avatar .avatar-placeholder{border:1px solid #d9d9db;width:40px;height:40px;border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:16px;font-weight:400}.card-view-container .attendance-card .card-header .flex-grow-1{min-width:0}.card-view-container .attendance-card .card-header h6{margin:0;font-weight:500;font-size:16px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.card-view-container .attendance-card .card-header small{opacity:.9;font-weight:400;font-size:16px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.card-view-container .attendance-card .card-header .card-actions{flex-shrink:0}.card-view-container .attendance-card .card-header .card-actions .btn{background-color:transparent;border:1px solid #d9d9db;color:inherit;padding:.25rem .5rem}.card-view-container .attendance-card .card-header .card-actions .btn:hover{background-color:#007bff1a}.card-view-container .attendance-card .card-header .card-actions .btn i{font-size:.8rem}.card-view-container .attendance-card .card-body{padding:8px;flex:1;display:flex;flex-direction:column}.card-view-container .attendance-card .card-body .info-item{text-align:center;margin-bottom:.5rem}.card-view-container .attendance-card .card-body .info-item small{display:block;font-weight:400;color:#6c757d;text-transform:uppercase;font-size:12px;letter-spacing:.5px;margin-bottom:.25rem}.card-view-container .attendance-card .card-body .info-item span{font-size:16px;font-weight:400;color:inherit}.card-view-container .attendance-card .card-body .badge{font-size:12px;padding:.25rem .5rem;border-radius:4px;font-weight:400;text-transform:uppercase;letter-spacing:.5px;border:none}.card-view-container .attendance-card .card-body .badge.bg-success,.card-view-container .attendance-card .card-body .badge.bg-danger{color:#f6f8ff}.card-view-container .attendance-card .card-body .badge.bg-warning{color:#000}.card-view-container .attendance-card .card-body .badge.bg-secondary{color:#f6f8ff}.card-view-container .attendance-card .card-body .card-details{margin-top:1rem}.card-view-container .attendance-card .card-body .card-details .section-title{font-size:14px;font-weight:500;color:inherit;margin-bottom:.75rem;display:flex;align-items:center}.card-view-container .attendance-card .card-body .card-details .section-title i{margin-right:.5rem;opacity:.8}.card-view-container .attendance-card .card-body .card-details .breaks-list .break-item,.card-view-container .attendance-card .card-body .card-details .breaks-list .leave-item,.card-view-container .attendance-card .card-body .card-details .short-leave-list .break-item,.card-view-container .attendance-card .card-body .card-details .short-leave-list .leave-item{background-color:inherit;border:1px solid #d9d9db;border-radius:4px;padding:8px;margin-bottom:.5rem;cursor:pointer;transition:all .25s cubic-bezier(.4,0,.2,1);transform:translateZ(0)}.card-view-container .attendance-card .card-body .card-details .breaks-list .break-item .d-flex,.card-view-container .attendance-card .card-body .card-details .breaks-list .leave-item .d-flex,.card-view-container .attendance-card .card-body .card-details .short-leave-list .break-item .d-flex,.card-view-container .attendance-card .card-body .card-details .short-leave-list .leave-item .d-flex{gap:.75rem;align-items:center}.card-view-container .attendance-card .card-body .card-details .breaks-list .break-item .d-flex small,.card-view-container .attendance-card .card-body .card-details .breaks-list .leave-item .d-flex small,.card-view-container .attendance-card .card-body .card-details .short-leave-list .break-item .d-flex small,.card-view-container .attendance-card .card-body .card-details .short-leave-list .leave-item .d-flex small{font-weight:500;color:inherit;margin-bottom:.25rem}.card-view-container .attendance-card .card-body .card-details .breaks-list .break-item .d-flex .text-muted,.card-view-container .attendance-card .card-body .card-details .breaks-list .leave-item .d-flex .text-muted,.card-view-container .attendance-card .card-body .card-details .short-leave-list .break-item .d-flex .text-muted,.card-view-container .attendance-card .card-body .card-details .short-leave-list .leave-item .d-flex .text-muted{font-size:12px;color:#6c757d}.card-view-container .attendance-card .card-body .card-details .breaks-list .break-item .d-flex .badge,.card-view-container .attendance-card .card-body .card-details .breaks-list .leave-item .d-flex .badge,.card-view-container .attendance-card .card-body .card-details .short-leave-list .break-item .d-flex .badge,.card-view-container .attendance-card .card-body .card-details .short-leave-list .leave-item .d-flex .badge{font-size:10px;padding:.2rem .4rem}.card-view-container .attendance-card .card-body .card-details .additional-details .row .col-6{margin-bottom:.5rem}.card-view-container .attendance-card .card-body .card-details .additional-details .row .col-6 small{font-weight:400;color:#6c757d;text-transform:uppercase;font-size:12px;letter-spacing:.5px;margin-bottom:.25rem}.card-view-container .attendance-card .card-body .card-details .additional-details .row .col-6 span{font-weight:400;color:inherit;font-size:14px}@media (max-width: 1200px){.card-view-container .row .col-xl-4{flex:0 0 50%;max-width:50%}}@media (max-width: 768px){.card-view-container .row .col-xl-4,.card-view-container .col-lg-6,.card-view-container .col-md-6{flex:0 0 100%;max-width:100%}.card-view-container .attendance-card .card-body{padding:8px}.card-view-container .attendance-card .card-body .info-item small{font-size:10px}.card-view-container .attendance-card .card-body .info-item span{font-size:14px}}@media (max-width: 576px){.card-view-container{padding:.5rem}.card-view-container .row .col-sm-12{padding:.25rem}.card-view-container .attendance-card .card-header{padding:8px}.card-view-container .attendance-card .card-header h6,.card-view-container .attendance-card .card-header small{font-size:14px}.card-view-container .attendance-card .card-body{padding:8px}}.btn-xs{padding:.125rem .3rem!important;font-size:.9rem!important;border-radius:.2rem!important;line-height:1.5!important}.form-select.form-select-sm:invalid{border-color:#d9d9db!important}.form-select.form-select-sm:valid{border-color:#d9d9db!important}.date-range-container{gap:8px;flex-wrap:nowrap;align-items:center}.date-range-btn{padding:6px 12px;font-size:14px;font-weight:500;border-radius:6px;transition:all .25s cubic-bezier(.4,0,.2,1);white-space:nowrap;display:inline-flex;align-items:center;justify-content:center;min-height:36px;transform:translateZ(0);position:relative;overflow:hidden}.date-range-btn:before{content:\"\";position:absolute;top:50%;left:50%;width:0;height:0;background:#fff3;border-radius:50%;transform:translate(-50%,-50%);transition:width .25s,height .25s}.date-range-btn:active:before{width:300px;height:300px}.calendar-btn{border-color:#0d6efd;color:#0d6efd;background-color:transparent}.calendar-btn:hover{background-color:#0d6efd;color:#fff;transform:translateY(-1px);box-shadow:0 4px 12px #0d6efd4d}.clear-btn{border-color:#dc3545;color:#dc3545;background-color:transparent}.clear-btn:hover{background-color:#dc3545;color:#fff;transform:translateY(-1px);box-shadow:0 4px 12px #dc35454d}.date-range-label{font-size:14px;font-weight:500;padding:4px 8px;min-width:180px;text-align:center;white-space:nowrap;cursor:pointer}.date-range-btn .bi{font-size:14px;transition:transform .2s ease}.date-range-btn:hover .bi{transform:scale(1.1)}@media (max-width: 768px){.date-range-container{flex-wrap:wrap;justify-content:flex-start}.date-range-label{min-width:100%;margin-top:8px;order:3}}.date-range-btn:focus{outline:none;box-shadow:0 0 0 3px #0d6efd40}.clear-btn:focus{box-shadow:0 0 0 3px #dc354540}.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}.action-buttons-row ::ng-deep .button:active .svg-icon svg path{stroke:#6f61cf!important}.action-buttons-row ::ng-deep .button:focus .svg-icon svg path{stroke:#6f61cf!important}.badge-overflow-wrapper{width:100%;min-width:0;display:flex;align-items:center}.custom-overlay-wrapper{position:fixed;top:0;left:0;width:100%;height:100%;background-color:#00000080;display:flex;justify-content:center;align-items:center;z-index:9999}.custom-overlay{background:#fff;border-radius:8px;box-shadow:0 4px 12px #00000026;min-width:300px;max-width:400px}.custom-modal-body{padding:20px;text-align:center}.custom-modal-body .modal-message{font-size:16px;margin-bottom:20px;color:#333}.custom-modal-body .modal-actions{display:flex;gap:10px;justify-content:center}.custom-modal-body .modal-actions button{padding:8px 16px;border:none;border-radius:4px;cursor:pointer;font-size:14px;transition:background-color .2s ease}.custom-modal-body .modal-actions button.btn-confirm{background-color:#007bff;color:#fff}.custom-modal-body .modal-actions button.btn-confirm:hover{background-color:#0056b3}.custom-modal-body .modal-actions button.btn-cancel{background-color:#6c757d;color:#fff}.custom-modal-body .modal-actions button.btn-cancel:hover{background-color:#545b62}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i2.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: i2.NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { kind: "directive", type: i2.NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { kind: "directive", type: i2.NgSwitchDefault, selector: "[ngSwitchDefault]" }, { kind: "pipe", type: i2.TitleCasePipe, name: "titlecase" }, { kind: "pipe", type: i2.DatePipe, name: "date" }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i3.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i3.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i3.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: i3.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i3.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i3.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i3.RadioControlValueAccessor, selector: "input[type=radio][formControlName],input[type=radio][formControl],input[type=radio][ngModel]", inputs: ["name", "formControlName", "value"] }, { kind: "directive", type: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i3.PatternValidator, selector: "[pattern][formControlName],[pattern][formControl],[pattern][ngModel]", inputs: ["pattern"] }, { kind: "directive", type: i3.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: InlineSVGModule }, { kind: "directive", type: i4.InlineSVGDirective, selector: "[inlineSVG]", inputs: ["inlineSVG", "resolveSVGUrl", "replaceContents", "prepend", "injectComponent", "cacheSVG", "setSVGAttributes", "removeSVGAttributes", "forceEvalStyles", "evalScripts", "fallbackImgUrl", "fallbackSVG", "onSVGLoaded"], outputs: ["onSVGInserted", "onSVGFailed"] }, { kind: "pipe", type: FilterPipe, name: "filter" }, { kind: "pipe", type: PinnedColumnsPipe, name: "pinnedColumns" }, { kind: "ngmodule", type: DragDropModule }, { kind: "directive", type: i5.CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: i5.CdkDropListGroup, selector: "[cdkDropListGroup]", inputs: ["cdkDropListGroupDisabled"], exportAs: ["cdkDropListGroup"] }, { kind: "directive", type: i5.CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "directive", type: i5.CdkDragHandle, selector: "[cdkDragHandle]", inputs: ["cdkDragHandleDisabled"] }, { kind: "directive", type: i5.CdkDragPreview, selector: "ng-template[cdkDragPreview]", inputs: ["data", "matchSize"] }, { kind: "directive", type: i5.CdkDragPlaceholder, selector: "ng-template[cdkDragPlaceholder]", inputs: ["data"] }, { kind: "ngmodule", type: BsDatepickerModule }, { kind: "directive", type: i6.BsDaterangepickerDirective, selector: "[bsDaterangepicker]", inputs: ["placement", "triggers", "outsideClick", "container", "outsideEsc", "isOpen", "bsValue", "bsConfig", "isDisabled", "minDate", "maxDate", "dateCustomClasses", "daysDisabled", "datesDisabled", "datesEnabled"], outputs: ["onShown", "onHidden", "bsValueChange"], exportAs: ["bsDaterangepicker"] }, { kind: "directive", type: i6.BsDaterangepickerInputDirective, selector: "input[bsDaterangepicker]" }, { kind: "ngmodule", type: ScrollingModule }, { kind: "directive", type: i7.CdkFixedSizeVirtualScroll, selector: "cdk-virtual-scroll-viewport[itemSize]", inputs: ["itemSize", "minBufferPx", "maxBufferPx"] }, { kind: "directive", type: i7.CdkVirtualForOf, selector: "[cdkVirtualFor][cdkVirtualForOf]", inputs: ["cdkVirtualForOf", "cdkVirtualForTrackBy", "cdkVirtualForTemplate", "cdkVirtualForTemplateCacheSize"] }, { kind: "component", type: i7.CdkVirtualScrollViewport, selector: "cdk-virtual-scroll-viewport", inputs: ["orientation", "appendOnly"], outputs: ["scrolledIndexChange"] }, { kind: "component", type: BadgeOverflowComponent, selector: "app-badge-overflow", inputs: ["badges", "maxWidth"], outputs: ["badgeMouseEnter", "badgeMouseLeave", "overflowCountClick"] }, { kind: "pipe", type: TimezoneFormatPipe, name: "timezoneFormat" }], animations: [
8797
9013
  trigger('accordionToggle', [
8798
- state('collapsed', style({ height: '0px', overflow: 'hidden' })),
8799
- state('expanded', style({ height: '*', overflow: 'visible' })),
9014
+ state('collapsed', style({ height: '0px', overflow: 'unset' })),
9015
+ state('expanded', style({ height: '*', overflow: 'unset' })),
8800
9016
  transition('collapsed <=> expanded', animate('300ms ease-in')),
8801
9017
  ]),
8802
9018
  trigger('slideToggle', [
@@ -8814,6 +9030,90 @@ class TimeSheetComponent {
8814
9030
  state('*', style({ transform: 'translateY(0)', opacity: 1 })),
8815
9031
  transition('void => *', animate('300ms ease-out')),
8816
9032
  transition('* => void', animate('300ms ease-in')),
9033
+ ]),
9034
+ trigger('rowDynamic', [
9035
+ /* -------------------- SPREAD -------------------- */
9036
+ transition('* => spreadAnimation', [
9037
+ query(':enter', [
9038
+ style({ opacity: 0, transform: 'scaleX(0.7)' }),
9039
+ stagger(60, [
9040
+ animate('350ms ease-out', style({ opacity: 1, transform: 'scaleX(1)' }))
9041
+ ])
9042
+ ], { optional: true }),
9043
+ query(':leave', [
9044
+ stagger(40, [
9045
+ animate('220ms ease-in', style({ opacity: 0, transform: 'scaleX(0.7)' }))
9046
+ ])
9047
+ ], { optional: true })
9048
+ ]),
9049
+ /* -------------------- BOUNCE -------------------- */
9050
+ transition('* => bounceAnimation', [
9051
+ query(':enter', [
9052
+ style({ opacity: 0, transform: 'translateY(-10px)' }),
9053
+ stagger(45, [
9054
+ animate('500ms cubic-bezier(.68,-0.55,.27,1.55)', style({ opacity: 1, transform: 'translateY(0)' }))
9055
+ ])
9056
+ ], { optional: true }),
9057
+ query(':leave', [
9058
+ stagger(40, [
9059
+ animate('200ms ease-in', style({ opacity: 0, transform: 'translateY(10px)' }))
9060
+ ])
9061
+ ], { optional: true })
9062
+ ]),
9063
+ /* -------------------- NEW 1: FLIP -------------------- */
9064
+ transition('* => flipAnimation', [
9065
+ query(':enter', [
9066
+ style({ opacity: 0, transform: 'rotateX(-80deg)' }),
9067
+ stagger(70, [
9068
+ animate('450ms ease-out', style({ opacity: 1, transform: 'rotateX(0)' }))
9069
+ ])
9070
+ ], { optional: true }),
9071
+ query(':leave', [
9072
+ stagger(50, [
9073
+ animate('250ms ease-in', style({ opacity: 0, transform: 'rotateX(80deg)' }))
9074
+ ])
9075
+ ], { optional: true })
9076
+ ]),
9077
+ /* -------------------- NEW 2: SKEW -------------------- */
9078
+ transition('* => skewAnimation', [
9079
+ query(':enter', [
9080
+ style({ opacity: 0, transform: 'skewY(6deg) translateY(8px)' }),
9081
+ stagger(60, [
9082
+ animate('320ms ease-out', style({ opacity: 1, transform: 'skewY(0deg) translateY(0)' }))
9083
+ ])
9084
+ ], { optional: true }),
9085
+ query(':leave', [
9086
+ stagger(40, [
9087
+ animate('220ms ease-in', style({ opacity: 0, transform: 'skewY(-6deg) translateY(-8px)' }))
9088
+ ])
9089
+ ], { optional: true })
9090
+ ]),
9091
+ transition('* => slideUpFromBottom', [
9092
+ query(':enter', [
9093
+ style({ opacity: 0, transform: 'translateY(100vh)' }),
9094
+ stagger(60, [
9095
+ animate('500ms cubic-bezier(0.25, 0.8, 0.25, 1)', style({ opacity: 1, transform: 'translateY(0)' }))
9096
+ ])
9097
+ ], { optional: true }),
9098
+ query(':leave', [
9099
+ stagger(40, [
9100
+ animate('300ms ease-in', style({ opacity: 0, transform: 'translateY(-50px)' }))
9101
+ ])
9102
+ ], { optional: true })
9103
+ ]),
9104
+ transition('* => slideFromRight', [
9105
+ query(':enter', [
9106
+ style({ opacity: 0, transform: 'translateX(100vw)' }),
9107
+ stagger(60, [
9108
+ animate('500ms cubic-bezier(0.25, 0.8, 0.25, 1)', style({ opacity: 1, transform: 'translateX(0)' }))
9109
+ ])
9110
+ ], { optional: true }),
9111
+ query(':leave', [
9112
+ stagger(40, [
9113
+ animate('300ms ease-in', style({ opacity: 0, transform: 'translateX(50px)' }))
9114
+ ])
9115
+ ], { optional: true })
9116
+ ]),
8817
9117
  ])
8818
9118
  ], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
8819
9119
  }
@@ -8821,8 +9121,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
8821
9121
  type: Component,
8822
9122
  args: [{ selector: 'time-sheet', standalone: true, imports: [CommonModule, FormsModule, InlineSVGModule, FilterPipe, PinnedColumnsPipe, DragDropModule, BsDatepickerModule, ScrollingModule, BadgeOverflowComponent, DatePipe, TimezoneFormatPipe], changeDetection: ChangeDetectionStrategy.OnPush, animations: [
8823
9123
  trigger('accordionToggle', [
8824
- state('collapsed', style({ height: '0px', overflow: 'hidden' })),
8825
- state('expanded', style({ height: '*', overflow: 'visible' })),
9124
+ state('collapsed', style({ height: '0px', overflow: 'unset' })),
9125
+ state('expanded', style({ height: '*', overflow: 'unset' })),
8826
9126
  transition('collapsed <=> expanded', animate('300ms ease-in')),
8827
9127
  ]),
8828
9128
  trigger('slideToggle', [
@@ -8840,9 +9140,95 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
8840
9140
  state('*', style({ transform: 'translateY(0)', opacity: 1 })),
8841
9141
  transition('void => *', animate('300ms ease-out')),
8842
9142
  transition('* => void', animate('300ms ease-in')),
9143
+ ]),
9144
+ trigger('rowDynamic', [
9145
+ /* -------------------- SPREAD -------------------- */
9146
+ transition('* => spreadAnimation', [
9147
+ query(':enter', [
9148
+ style({ opacity: 0, transform: 'scaleX(0.7)' }),
9149
+ stagger(60, [
9150
+ animate('350ms ease-out', style({ opacity: 1, transform: 'scaleX(1)' }))
9151
+ ])
9152
+ ], { optional: true }),
9153
+ query(':leave', [
9154
+ stagger(40, [
9155
+ animate('220ms ease-in', style({ opacity: 0, transform: 'scaleX(0.7)' }))
9156
+ ])
9157
+ ], { optional: true })
9158
+ ]),
9159
+ /* -------------------- BOUNCE -------------------- */
9160
+ transition('* => bounceAnimation', [
9161
+ query(':enter', [
9162
+ style({ opacity: 0, transform: 'translateY(-10px)' }),
9163
+ stagger(45, [
9164
+ animate('500ms cubic-bezier(.68,-0.55,.27,1.55)', style({ opacity: 1, transform: 'translateY(0)' }))
9165
+ ])
9166
+ ], { optional: true }),
9167
+ query(':leave', [
9168
+ stagger(40, [
9169
+ animate('200ms ease-in', style({ opacity: 0, transform: 'translateY(10px)' }))
9170
+ ])
9171
+ ], { optional: true })
9172
+ ]),
9173
+ /* -------------------- NEW 1: FLIP -------------------- */
9174
+ transition('* => flipAnimation', [
9175
+ query(':enter', [
9176
+ style({ opacity: 0, transform: 'rotateX(-80deg)' }),
9177
+ stagger(70, [
9178
+ animate('450ms ease-out', style({ opacity: 1, transform: 'rotateX(0)' }))
9179
+ ])
9180
+ ], { optional: true }),
9181
+ query(':leave', [
9182
+ stagger(50, [
9183
+ animate('250ms ease-in', style({ opacity: 0, transform: 'rotateX(80deg)' }))
9184
+ ])
9185
+ ], { optional: true })
9186
+ ]),
9187
+ /* -------------------- NEW 2: SKEW -------------------- */
9188
+ transition('* => skewAnimation', [
9189
+ query(':enter', [
9190
+ style({ opacity: 0, transform: 'skewY(6deg) translateY(8px)' }),
9191
+ stagger(60, [
9192
+ animate('320ms ease-out', style({ opacity: 1, transform: 'skewY(0deg) translateY(0)' }))
9193
+ ])
9194
+ ], { optional: true }),
9195
+ query(':leave', [
9196
+ stagger(40, [
9197
+ animate('220ms ease-in', style({ opacity: 0, transform: 'skewY(-6deg) translateY(-8px)' }))
9198
+ ])
9199
+ ], { optional: true })
9200
+ ]),
9201
+ transition('* => slideUpFromBottom', [
9202
+ query(':enter', [
9203
+ style({ opacity: 0, transform: 'translateY(100vh)' }),
9204
+ stagger(60, [
9205
+ animate('500ms cubic-bezier(0.25, 0.8, 0.25, 1)', style({ opacity: 1, transform: 'translateY(0)' }))
9206
+ ])
9207
+ ], { optional: true }),
9208
+ query(':leave', [
9209
+ stagger(40, [
9210
+ animate('300ms ease-in', style({ opacity: 0, transform: 'translateY(-50px)' }))
9211
+ ])
9212
+ ], { optional: true })
9213
+ ]),
9214
+ transition('* => slideFromRight', [
9215
+ query(':enter', [
9216
+ style({ opacity: 0, transform: 'translateX(100vw)' }),
9217
+ stagger(60, [
9218
+ animate('500ms cubic-bezier(0.25, 0.8, 0.25, 1)', style({ opacity: 1, transform: 'translateX(0)' }))
9219
+ ])
9220
+ ], { optional: true }),
9221
+ query(':leave', [
9222
+ stagger(40, [
9223
+ animate('300ms ease-in', style({ opacity: 0, transform: 'translateX(50px)' }))
9224
+ ])
9225
+ ], { optional: true })
9226
+ ]),
8843
9227
  ])
8844
- ], template: "<div class=\"position-relative h-100\">\r\n <!-- <h1>abu </h1> -->\r\n <div\r\n class=\"d-flex justify-content-between mb-3 align-items-center position-relative\"\r\n >\r\n <div class=\"col-4 global-search position-relative\">\r\n\r\n <span\r\n\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 style=\"height: 36px\"\r\n class=\"form-control\"\r\n placeholder=\"Search all columns and press Enter\"\r\n [(ngModel)]=\"tableSearch\"\r\n (keydown.enter)=\"onGlobalSearch()\"\r\n\r\n />\r\n <span\r\n *ngIf=\"tableSearch\"\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/x.svg'\"\r\n class=\"data-grid-svg-icon position-absolute end-0 top-50 translate-middle-y me-2 cursor-pointer\"\r\n (click)=\"onSearchReset()\"\r\n title=\"Clear search\"\r\n ></span>\r\n\r\n </div>\r\n\r\n <!-- Date Picker Buttons -->\r\n <!-- Date Picker Section - Improved Version -->\r\n<div class=\"position-relative d-flex justify-content-center align-items-center ms-2 date-range-container\">\r\n\r\n <!-- Hidden Date Picker Input -->\r\n <input\r\n type=\"text\"\r\n class=\"form-control\"\r\n bsDaterangepicker\r\n #picker=\"bsDaterangepicker\"\r\n [(ngModel)]=\"bsRangeValue\"\r\n [bsConfig]=\"bsConfig\"\r\n (bsValueChange)=\"onRangeSelected($event, picker)\"\r\n style=\"opacity: 0; width: 0; height: 0; position: absolute;\"\r\n />\r\n\r\n <!-- Left Arrow Button -->\r\n <span\r\n class=\"text-primary cursor-pointer me-2 date-range-btn arrow-btn\"\r\n (click)=\"navigateDate('left')\"\r\n title=\"Previous Date Range\"\r\n *ngIf=\"bsRangeValue && bsRangeValue.length > 0\"\r\n >\r\n <span class=\"bi bi-chevron-left\"></span>\r\n </span>\r\n\r\n <!-- Date Range Label -->\r\n <span\r\n *ngIf=\"bsRangeValue && bsRangeValue.length > 0\"\r\n class=\"text-primary date-range-label cursor-pointer\"\r\n (click)=\"togglePicker(picker)\"\r\n title=\"Click to open calendar\"\r\n >\r\n {{ bsRangeValue[0] | timezoneFormat:prefs:'date' }} - {{ bsRangeValue[1] | timezoneFormat:prefs:'date' }}\r\n </span>\r\n\r\n <!-- Right Arrow Button -->\r\n <span\r\n class=\"text-primary cursor-pointer ms-2 date-range-btn arrow-btn\"\r\n (click)=\"navigateDate('right')\"\r\n title=\"Next Date Range\"\r\n *ngIf=\"bsRangeValue && bsRangeValue.length > 0\"\r\n >\r\n <span class=\"bi bi-chevron-right\"></span>\r\n </span>\r\n\r\n\r\n\r\n</div>\r\n\r\n <div class=\"d-flex gap-2 align-items-center table-right-top-actions\">\r\n\r\n <!-- Pivot Mode Button -->\r\n <!-- <a\r\n href=\"JavaScript:void(0)\"\r\n class=\"button button-small btn btn-active-primary border border-primary me-2 header-icon\"\r\n (click)=\"togglePivotMode()\"\r\n [class.active]=\"pivotMode\"\r\n title=\"Toggle Pivot Mode\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/pivot.svg'\"\r\n class=\"svg-icon svg-icon-2\"\r\n ></span>\r\n </a> -->\r\n\r\n <div class=\"action-buttons-row d-flex\">\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 (click)=\"togglePicker(picker)\"\r\n title=\"Select Date Range\"\r\n >\r\n <span class=\"bi bi-calendar3 text-primary\"></span>\r\n <span class=\"label-hidden text-white\">Calendar</span>\r\n </a>\r\n <button\r\n *ngIf=\"bsRangeValue && bsRangeValue.length > 0 && !isDefaultDateRange\"\r\n type=\"button\"\r\n class=\"button button-small btn btn-active-danger border border-danger me-2 p-0 d-flex align-items-center justify-content-center px-3\"\r\n (click)=\"clearDateRange()\"\r\n title=\"Clear Date Range\"\r\n >\r\n <span class=\"bi bi-x-circle text-danger\"></span>\r\n <span class=\"label-hidden text-white\">Clear</span>\r\n </button>\r\n</div>\r\n<ng-container *ngFor=\"let button of buttons\">\r\n <div\r\n class=\"action-buttons-row\"\r\n *ngIf=\"getButtonPermission(button) && (!button.condition || (button.condition === '!isSingleDay' && !isSingleDay) || (button.condition === 'isSingleDay' && isSingleDay))\"\r\n >\r\n <a\r\n href=\"JavaScript:void(0)\"\r\n (click)=\"onActionButtonClick(button.name)\"\r\n class=\"button\"\r\n [title]=\"button.name\"\r\n >\r\n <span\r\n *ngIf=\"button.is_showIcon\"\r\n [inlineSVG]=\"button.iconPath\"\r\n class=\"svg-icon\"\r\n ></span>\r\n <span\r\n class=\"label-hidden\"\r\n >{{ button.name }}</span\r\n >\r\n </a>\r\n </div>\r\n</ng-container>\r\n\r\n<!-- Calendar Button -->\r\n\r\n\r\n<!-- Existing filter, settings, etc. -->\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\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 <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 *ngIf=\"activeFilteredColumns?.length\">\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 >\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 class=\"d-flex gap-2 align-items-center me-5\">\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 <ng-container\r\n *ngFor=\"\r\n let child of groupedColumns;\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 groupedColumns.length > 1 && i != groupedColumns.length - 1\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </div>\r\n\r\n\r\n\r\n\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 class=\"data-grid-header left-pinned\" #leftPinnedHeader>\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]=\"65\"\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</div>\r\n <div\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 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 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: 0.2px\"\r\n [style.background-color]=\"headerBackgroundColor\"\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 [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)=\"onCenterHeaderScroll($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)=\"openThreeDotsMenu($event, 'group')\"\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)=\"onResizeGroupBox($event)\"\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 === 'TimeSheet' && !areDatesSelectedAndEqual\"\r\n >\r\n </span> -->\r\n <div\r\n class=\"dragable-header\"\r\n (cdkDragStarted)=\"\r\n checkColumnGroupingStatus(col); dragStartOnGroup(col)\r\n \"\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 [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: 'centerColumns'\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 *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 *ngIf=\"!areDatesSelectedAndEqual\" class=\"header-cell border-below\" [style.width.px]=\"30\" [style.height.px]=\"headerRowHeight\" [style.backgroundColor]=\"headerBackgroundColor\"></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 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: 'previewRightPinnedColumns'\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 [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: 'centerColumns'\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\"\r\n >\r\n No Record Found\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\"\r\n style=\"\r\n z-index: 999;\r\n background: rgba(255, 255, 255, 0.8);\r\n backdrop-filter: blur(1px);\r\n \"\r\n >\r\n <div class=\"text-center p-2\">\r\n <div class=\"spinner-border text-primary\" role=\"status\"></div> Loading...\r\n</div>\r\n </div>\r\n\r\n <!-- Card View -->\r\n \r\n\r\n <!-- Table View -->\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 *ngIf=\"dataSet.length\"\r\n >\r\n <!-- LEFT PINNED -->\r\n <div [style.height.px]=\"!groupedColumns.length ? originalDataSet.length * rowHeight: 0\"></div>\r\n <div [class.h-100]=\"originalDataSet.length <= 10\">\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]=\"\r\n 'translateY(' + startIndex * rowHeight + 'px)'\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 }\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=\"\"\r\n [style.width.px]=\"centerPinnedHeader.clientWidth\"\r\n >\r\n <div\r\n class=\"data-grid-body center-scrollable\"\r\n\r\n style=\"overflow-y: hidden; overflow-x: auto\"\r\n [style.transform]=\"\r\n 'translateY(' + startIndex * rowHeight + 'px)'\r\n \"\r\n [style.backgroundColor]=\"bodyBackgroundColor\"\r\n #centerScrollableBody\r\n (scroll)=\"onCenterBodyScroll($event)\"\r\n [style.boxShadow]=\"leftPinnedBoxshadow\"\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: previewCenterColumns,\r\n isEven: (startIndex + i) % 2 === 0,\r\n isOdd: (startIndex + i) % 2 !== 0,\r\n section: 'center'\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 <= 10\"\r\n [style.max-width.px]=\"isScrollbarVisible ? rightPinnedHeader.offsetWidth - 15: rightPinnedHeader.offsetWidth\"\r\n >\r\n <div\r\n class=\"data-grid-body right-pinned-body w-100\"\r\n style=\"overflow-y: hidden\"\r\n [style.transform]=\"\r\n 'translateY(' + startIndex * rowHeight + 'px)'\r\n \"\r\n [style.boxShadow]=\"rightPinnedBoxshadow\"\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 }\r\n \"\r\n ></ng-container>\r\n </ng-container>\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 * (paginationConfig.totalResults || flattenedData.length)\"></div>\r\n </div>\r\n </div>\r\n\r\n <!-- Horizintal Fake Scrollbars -->\r\n <div class=\"d-flex justify-content-between\" *ngIf=\"dataSet.length\">\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)=\"onHorizintalFakeScroll($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\"></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 && !hasOpenAccordion\"\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-white]=\"\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-white]=\"\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 [style.height.px]=\"footerRowHeight\" class=\"border-top\">\r\n <!-- Rows: <span class=\"fw-500 ms-1\">{{ dataSet.length }}</span> -->\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.selectedPageSize\"\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=\"\"> per page </span>\r\n </div>\r\n\r\n <div class=\"page-info\">\r\n Results: {{ paginationConfig.page }}-{{\r\n paginationConfig.page * paginationConfig.limit\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-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)=\"onResizeGroup($event, col, pinnedRight)\"\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 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)=\"openThreeDotsMenu($event, child); openFilteronThreeDotsClick(child)\"\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)=\"openThreeDotsMenu($event, child)\"\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 >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n columnMenu;\r\n context: { col: child }\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)=\"onResizeColumn($event, child)\"\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)]=\"col.filterValue\"\r\n (ngModelChange)=\"onFilterChange(col)\"\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 ><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 class=\"group-column-wrapper\">\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\"\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)=\"openThreeDotsMenu($event, col); openFilteronThreeDotsClick(col)\"\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 <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath +\r\n (sortingConfig?.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 mt-1\"\r\n ></span>\r\n </div>\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\"\r\n [style.left.px]=\"\r\n -(!col?.pinned ? centerPinnedHeader.scrollLeft : 0)\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"columnMenu; context: { col: col }\"\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)=\"onResizeColumn($event, col)\"\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 />\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 ><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>\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 border-below d-flex align-items-center\"\r\n [style.height.px]=\"rowHeight\"\r\n [style.width]=\"\r\n section == 'center'\r\n ? centerScrollableBody!.nativeElement?.scrollWidth + '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]=\"65\"\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 >\r\n {{ row.__virtualIndex }}\r\n </div>\r\n <div\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 >\r\n <input style=\"width: 16px; height: 16px\" type=\"checkbox\" />\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 class=\"d-flex align-items-center ps-2 h-100\"\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 * 16 : 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\"\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\">\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 }\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 class=\"d-flex\" [style.height.px]=\"rowHeight\">\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=\"section == 'center' && gridType === 'TimeSheet' && detailsIconPosition === 'start' && !areDatesSelectedAndEqual\"\r\n [ngStyle]=\"{\r\n 'background-color':\r\n hoveredRowId === (row._id || row.id)\r\n ? rowHoverColor\r\n : isRowSelected(row)\r\n ? checkedRowBackgroundColor\r\n : isEven\r\n ? evenRowsBackgroundColor\r\n : oddRowsBackgroundColor\r\n }\"\r\n >\r\n <span\r\n (click)=\"row.isDetailsExpand = !row.isDetailsExpand\"\r\n class=\"data-grid-svg-icon\"\r\n [inlineSVG]=\"\r\n row.isDetailsExpand\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, row?.details?.data?.length ? 'accordion-parent' : 'main')\"\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':\r\n hoveredRowId === (row._id || row.id)\r\n ? rowHoverColor\r\n : isRowSelected(row)\r\n ? checkedRowBackgroundColor\r\n : isEven\r\n ? evenRowsBackgroundColor\r\n : oddRowsBackgroundColor\r\n }\"\r\n ></div>\r\n <div\r\n (contextmenu)=\"onRightClick($event, row, row?.details?.data?.length ? 'accordion-parent' : 'main')\"\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':\r\n hoveredRowId === (row._id || row.id)\r\n ? rowHoverColor\r\n : isRowSelected(row)\r\n ? checkedRowBackgroundColor\r\n : isEven\r\n ? evenRowsBackgroundColor\r\n : oddRowsBackgroundColor\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]=\"65\"\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 >\r\n {{ row.__virtualIndex }}\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\"\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 >\r\n <input\r\n *ngIf=\"hasAnyVisibleColumn\"\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 }\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\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 }\r\n \"\r\n ></ng-container>\r\n </ng-template>\r\n </ng-container>\r\n </div>\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=\"section == 'center' && gridType === 'TimeSheet' && detailsIconPosition === 'end' && !areDatesSelectedAndEqual\"\r\n [ngStyle]=\"{\r\n 'background-color':\r\n hoveredRowId === (row._id || row.id)\r\n ? rowHoverColor\r\n : isRowSelected(row)\r\n ? checkedRowBackgroundColor\r\n : isEven\r\n ? evenRowsBackgroundColor\r\n : oddRowsBackgroundColor\r\n }\"\r\n >\r\n <span\r\n (click)=\"row.isDetailsExpand = !row.isDetailsExpand\"\r\n class=\"data-grid-svg-icon\"\r\n [inlineSVG]=\"\r\n row.isDetailsExpand\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 <!-- LEFT PINNED: Empty table to keep alignment -->\r\n <div *ngIf=\"section === 'left' && row.isDetailsExpand && !isSingleDay\" class=\"accordion-details data-grid-accordion-section\" [style.color]=\"headerTextColor\" style=\"max-height: 350px; min-height: 350px; overflow: hidden;\">\r\n <table class=\"nested-table table table-sm w-100 mb-0 data-grid-accordion-table\" [class.show-shadow]=\"rowShadingEnabled\">\r\n <thead>\r\n <tr [style.height.px]=\"nestedTableHeaderRowHeight\" [style.backgroundColor]=\"headerBackgroundColor\" [style.color]=\"headerTextColor\" [style.fontSize.px]=\"headerTextFontsSize\" [style.fontWeight]=\"headerFontWeight\">\r\n <th *ngFor=\"let _ of [1, 2, 3, 4, 5]\"></th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <tr [style.height.px]=\"nestedTablerowHeight\" *ngFor=\"let _ of row.details.data\" [style.backgroundColor]=\"headerBackgroundColor\">\r\n <td *ngFor=\"let __ of [1, 2, 3, 4, 5]\"></td>\r\n </tr>\r\n </tbody>\r\n </table>\r\n </div>\r\n\r\n<!-- CENTER SECTION: Actual details table -->\r\n\r\n<div *ngIf=\"section === 'center' && row.isDetailsExpand && !isSingleDay\" class=\"accordion-details-wrapper data-grid-accordion\" [style.fontFamily]=\"fontFaimly\" [style.fontSize.px]=\"bodyTextFontsSize\" style=\"display: flex; width: 100%; max-height: 350px; min-height: 350px; overflow: hidden;\">\r\n <!-- LEFT SECTION OF ACCORDION -->\r\n <div #leftContainer class=\"accordion-left-section data-pin-body-wrapper data-grid-accordion-section\" [attr.data-detail-row-id]=\"row._id || row.id\" (scroll)=\"onDetailLeftScroll($event, row)\" style=\"flex-shrink: 0; overflow-y: auto; overflow-x: hidden;\">\r\n <table class=\"nested-table table-sm mb-0 data-grid-accordion-table\" [class.show-borders]=\"showVerticalBorder\" [class.show-shadow]=\"rowShadingEnabled\" style=\"table-layout: fixed; width: auto;\">\r\n <thead>\r\n <tr [style.height.px]=\"nestedTableHeaderRowHeight\" [style.backgroundColor]=\"headerBackgroundColor\" [style.color]=\"headerTextColor\" [style.fontSize.px]=\"headerTextFontsSize\" [style.fontWeight]=\"headerFontWeight\">\r\n <ng-container *ngFor=\"let col of row.details.columns | pinnedColumns:'left'; trackBy: trackByField\">\r\n <th *ngIf=\"col.is_visible !== false\"\r\n class=\"px-4\"\r\n [class.filter-applied]=\"isAccordionColumnFiltered(row, col)\"\r\n [attr.field]=\"col.field\"\r\n [attr.pinned]=\"col.pinned\"\r\n [style.width.px]=\"col.width || 150\"\r\n [style.min-width.px]=\"col.width || 150\">\r\n <div class=\"d-flex justify-content-between align-items-center\" style=\"width: 100%;\">\r\n <span class=\"d-flex align-items-center gap-1\">\r\n <span *ngIf=\"col.pinned\" [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/pin-blue.svg'\" class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"></span>\r\n {{ col.header }}\r\n <span *ngIf=\"isAccordionColumnFiltered(row, col)\"\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\"\r\n class=\"data-grid-svg-icon text-primary ms-1\"\r\n style=\"font-size: 12px;\"></span>\r\n </span>\r\n <span class=\"three-dots p-1\"\r\n (click)=\"openDetailThreeDotsMenus($event, col, row)\"\r\n style=\"cursor: pointer;\">\r\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/three-dots-vertical.svg'\" class=\"data-grid-svg-icon\"></span>\r\n </span>\r\n </div>\r\n <!-- <div class=\"resize-handles\" (mousedown)=\"onResizeDetailColumn($event, row, col)\">\r\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/resize-handle.svg'\" class=\"data-grid-svg-icon text-primary\"></span>\r\n </div> -->\r\n <ng-container *ngIf=\"activeDetailCol?.field == col.field && activeDetailRow === row\">\r\n <div class=\"position-absolute detail-column-menu-wrapper\"\r\n [style.top.px]=\"nestedTableHeaderRowHeight\"\r\n [style.left.px]=\"0\">\r\n <ng-container *ngTemplateOutlet=\"detailColumnMenu; context: { col: col, row: row }\"></ng-container>\r\n </div>\r\n </ng-container>\r\n </th>\r\n </ng-container>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <tr [style.height.px]=\"nestedTablerowHeight\" *ngFor=\"let d of row.details.data; let j = index; trackBy: trackById\">\r\n <ng-container *ngFor=\"let col of row.details.columns | pinnedColumns:'left'; let localK = index; trackBy: trackByField\">\r\n <td *ngIf=\"col.is_visible !== false\"\r\n class=\"px-4\"\r\n (mousedown)=\"startDetailSelection(row, j, localK, col.field, $event, 'left')\"\r\n (mouseenter)=\"extendDetailSelection(row, j, localK, col.field, $event, 'left')\"\r\n [class.selected-cell]=\"isDetailCellSelected(row, j, localK, col.field, 'left')\"\r\n [attr.field]=\"col.field\"\r\n [attr.pinned]=\"col.pinned\"\r\n [style.fontSize.px]=\"nestedTablerowFontsize\"\r\n (dblclick)=\"enableDetailEdits(row, d, col)\"\r\n [class.active-cell-detail]=\"isActiveDetailCell(row, d, col)\">\r\n <!-- Use the same rendering logic as center section -->\r\n <ng-container [ngSwitch]=\"col.field\">\r\n\r\n <ng-container *ngSwitchCase=\"'manually_logs'\" class=\"d-flex justify-content-start align-items-center pointer position-relative\">\r\n <ng-container *ngIf=\"d.manually_logs?.length > 0; else noManualLogsIcon\">\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/eye.svg'\"\r\n class=\"data-grid-svg-icon text-primary\"\r\n style=\"cursor: pointer; font-size: 16px;\"\r\n (mouseenter)=\"showManualLogsTooltip($event, row, d)\"\r\n (mouseleave)=\"hideManualLogsTooltip()\">\r\n </span>\r\n </ng-container>\r\n <ng-template #noManualLogsIcon>\u2013</ng-template>\r\n</ng-container>\r\n <!-- Breaks -->\r\n <ng-container *ngSwitchCase=\"'breaks'\">\r\n <ng-container *ngIf=\"d[col.field]?.length; else noBreaksLeft\">\r\n <app-badge-overflow\r\n [badges]=\"getBreakBadges(d[col.field])\"\r\n [maxWidth]=\"col.width || 200\"\r\n (badgeMouseEnter)=\"showBreakTooltip($event.event, $event.badge.data)\"\r\n (badgeMouseLeave)=\"hideBreakTooltip()\"\r\n (overflowCountClick)=\"onDetailBadgeOverflowCountClick(col, d)\">\r\n</app-badge-overflow>\r\n </ng-container>\r\n <ng-template #noBreaksLeft>\r\n <div >\r\n -\r\n </div>\r\n </ng-template>\r\n </ng-container>\r\n\r\n <!-- Short Breaks -->\r\n <ng-container *ngSwitchCase=\"'short_breaks'\">\r\n <ng-container *ngIf=\"d[col.field]?.duration; else noShortBreakLeft\">\r\n <div class=\"circle-value\"\r\n [ngClass]=\"(d[col.field].type || '').toLowerCase() === 'paid' ? 'break-color-paid' : (d[col.field].type || '').toLowerCase() === 'unpaid' ? 'break-color-unpaid' : (d[col.field].type || '').toLowerCase() === 'lunch' ? 'break-color-lunch' : 'break-color-default'\"\r\n (mouseenter)=\"showShortBreakTooltip($event, d[col.field], 'single_break'); preventCustomTooltipHide()\"\r\n (mouseleave)=\"hideShortBreakTooltip()\"\r\n (dblclick)=\"onShortBreakClick.emit(d)\">\r\n {{ d[col.field].duration }}m\r\n </div>\r\n </ng-container>\r\n <ng-template #noShortBreakLeft>\r\n <div >-</div>\r\n </ng-template>\r\n </ng-container>\r\n\r\n <!-- Short Leave -->\r\n <!-- Short Leave -->\r\n<ng-container *ngSwitchCase=\"'short_leave'\">\r\n <ng-container *ngIf=\"row.short_leave && row.short_leave.length > 0; else noShortLeaveMain\">\r\n <div class=\"w-100 d-flex main-progress-bar justify-content-center align-items-center\" \r\n style=\"background-color: rgb(111, 97, 207); height: 20px; border-radius: 4px; position: relative;\"\r\n (mouseenter)=\"showShortLeaveTooltip($event, row)\"\r\n (mouseleave)=\"hideShortLeaveTooltip()\">\r\n <span class=\"d-block\" [style.min-width.%]=\"row.short_leave[0].short_leave_time_percentage\" \r\n style=\"background-color: rgb(238, 99, 82); height: 100%; border-radius: 4px;\"></span>\r\n <span style=\"position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); color: white; font-size: 12px; font-weight: bold;\">\r\n {{ row.short_leave[0].short_leave_time_percentage }}%\r\n </span>\r\n </div>\r\n </ng-container>\r\n <ng-template #noShortLeaveMain>-</ng-template>\r\n</ng-container>\r\n\r\n<div *ngSwitchCase=\"'is_un_restricted'\" class=\"d-flex justify-content-start flex-column pointer position-relative\" (mouseenter)=\"showRestrictionTooltip($event, row, d); preventRestrictionTooltipHide()\" (mouseleave)=\"hideRestrictionTooltip()\">\r\n <span class=\"\" [class.restriction-indicator]=\"row.attendance_log_detail?.length > 0\">\r\n {{ d.is_un_restricted ? 'Yes' : 'No' }}\r\n </span>\r\n </div>\r\n\r\n <div *ngSwitchCase=\"'is_payroll_processed'\" class=\"d-flex justify-content-start flex-column pointer position-relative\" >\r\n <span class=\"\" >\r\n {{ d.is_payroll_processed ? 'Yes' : 'No' }}\r\n </span>\r\n </div>\r\n\r\n\r\n <!-- Status -->\r\n <ng-container *ngSwitchCase=\"'status'\">\r\n <ng-container *ngIf=\"getNestedValue(d, col.field); else noStatus\">\r\n <span class=\"badge\" [class]=\"getStatusBadgeClass(getNestedValue(d, col.field))\">\r\n {{ transformStatus(getNestedValue(d, col.field)) }}\r\n </span>\r\n </ng-container>\r\n <ng-template #noStatus>-</ng-template>\r\n</ng-container>\r\n\r\n<!-- Attendance Status -->\r\n<ng-container *ngSwitchCase=\"'attendanceStatus'\">\r\n <ng-container *ngIf=\"getNestedValue(d, col.field); else noAttendanceStatus\">\r\n <span class=\"badge\" [class]=\"getAttendanceStatusBadgeClass(getNestedValue(d, col.field))\">\r\n {{ transformStatus(getNestedValue(d, col.field)) }}\r\n </span>\r\n </ng-container>\r\n <ng-template #noAttendanceStatus>-</ng-template>\r\n</ng-container>\r\n\r\n <!-- Default fallback -->\r\n <ng-container *ngSwitchDefault>\r\n {{\r\n col.type === 'date'\r\n ? (getNestedValue(d, col.field) ? (getNestedValue(d, col.field) | timezoneFormat:prefs:'date') : '-')\r\n : col.type === 'time'\r\n ? ((getTimeValue(getNestedValue(d, col.field)) | timezoneFormat:prefs:'time'))\r\n : (getNestedValue(d, col.field)?.value || getNestedValue(d, col.field)?.name || getNestedValue(d, col.field) || '-')\r\n }}\r\n </ng-container>\r\n </ng-container>\r\n </td>\r\n </ng-container>\r\n </tr>\r\n</tbody>\r\n </table>\r\n </div>\r\n\r\n <!-- CENTER SECTION OF ACCORDION (WITH VIRTUAL SCROLL) -->\r\n\r\n<div class=\"accordion-center-section data-grid-accordion-section\" style=\"flex: 1; min-width: 0; display: flex; flex-direction: column; overflow: hidden;\">\r\n <!-- Header Section -->\r\n <div class=\"header-container\" style=\"overflow-x: auto; scrollbar-width: none; -ms-overflow-style: none;\" #headerContainer (scroll)=\"syncScroll($event)\">\r\n <table class=\"nested-table table-sm mb-0 data-grid-accordion-table\" [class.show-borders]=\"showVerticalBorder\" [class.show-shadow]=\"rowShadingEnabled\" style=\"table-layout: fixed; width: 100%;\">\r\n <thead>\r\n <tr\r\n [style.height.px]=\"nestedTableHeaderRowHeight\"\r\n cdkDropList\r\n [cdkDropListData]=\"row?.details.columns\"\r\n cdkDropListOrientation=\"horizontal\"\r\n (cdkDropListDropped)=\"dropColumn($event, row)\">\r\n <ng-container *ngFor=\"let col of row.details.columns; let i = index\">\r\n <th\r\n *ngIf=\"col.is_visible !== false && !col.pinned\"\r\n class=\"px-4\"\r\n cdkDrag\r\n [attr.field]=\"col.field\"\r\n [class.filter-applied]=\"isAccordionColumnFiltered(row, col)\"\r\n [style.width.px]=\"col.width || 150\"\r\n [style.min-width.px]=\"col.width || 150\"\r\n [style.backgroundColor]=\"headerBackgroundColor\"\r\n [style.color]=\"headerTextColor\"\r\n [style.fontSize.px]=\"headerTextFontsSize\"\r\n [style.fontWeight]=\"headerFontWeight\"\r\n style=\"cursor: move; position: relative;\">\r\n <div class=\"d-flex justify-content-between align-items-center\" style=\"width: 100%;\">\r\n <span class=\"d-flex align-items-center gap-1\">\r\n <span *ngIf=\"col.pinned\" [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/pin-blue.svg'\" class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"></span>\r\n {{ col.header }}\r\n <span *ngIf=\"isAccordionColumnFiltered(row, col)\"\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\"\r\n class=\"data-grid-svg-icon text-primary ms-1\"\r\n style=\"font-size: 12px;\"></span>\r\n </span>\r\n <span\r\n class=\"three-dots p-1\"\r\n (click)=\"openDetailThreeDotsMenus($event, col, row); activeDetailCol = col; activeDetailRow = row\"\r\n style=\"cursor: pointer;\">\r\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/three-dots-vertical.svg'\" class=\"data-grid-svg-icon\"></span>\r\n </span>\r\n </div>\r\n <!-- <div class=\"resize-handles\" (mousedown)=\"onResizeDetailColumn($event, row, col)\">\r\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/resize-handle.svg'\" class=\"data-grid-svg-icon text-primary\"></span>\r\n </div> -->\r\n <ng-container *ngIf=\"activeDetailCol?.field == col.field && activeDetailRow === row\">\r\n <div class=\"position-absolute detail-column-menu-wrapper\" [style.top.px]=\"nestedTableHeaderRowHeight\" [style.left.px]=\"0\">\r\n <ng-container *ngTemplateOutlet=\"detailColumnMenu; context: { col: col, row: row }\"></ng-container>\r\n </div>\r\n </ng-container>\r\n </th>\r\n </ng-container>\r\n </tr>\r\n </thead>\r\n </table>\r\n </div>\r\n\r\n <!-- Group Badges (if any) -->\r\n <div *ngIf=\"row.details?.groupedColumns?.length\" class=\"detail-group-badges\">\r\n <span *ngFor=\"let g of row.details.groupedColumns; trackBy: trackByField\" class=\"badge bg-light text-dark me-1\">\r\n {{ g.header }}\r\n <span class=\"ms-1 cursor-pointer\" (click)=\"ungroupDetailColumn(g, row)\" [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/x.svg'\"></span>\r\n </span>\r\n </div>\r\n\r\n <!-- No Data Message when filtered results are empty -->\r\n <div *ngIf=\"row.details.data.length === 0\" class=\"d-flex justify-content-center align-items-center\" style=\"flex: 1; min-height: 200px;\">\r\n <div class=\"text-center text-muted\">\r\n <div class=\"mb-2\">\r\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\" class=\"data-grid-svg-icon text-muted\" style=\"font-size: 24px;\"></span>\r\n </div>\r\n <div class=\"fw-bold\">No records found for this filter.</div>\r\n </div>\r\n </div>\r\n\r\n <!-- Data Table Section with Virtual Scroll -->\r\n <cdk-virtual-scroll-viewport\r\n *ngIf=\"row.details.data.length > 0\"\r\n itemSize=\"{{ nestedTablerowHeight }}\"\r\n minBufferPx=\"200\"\r\n maxBufferPx=\"400\"\r\n class=\"detail-virtual-scroll\"\r\n [attr.data-detail-row-id]=\"row._id || row.id\"\r\n style=\"flex: 1; overflow: auto;\"\r\n #dataContainer\r\n (scroll)=\"syncVerticalScroll($event)\"\r\n (scroll)=\"syncScroll($event)\">\r\n <table class=\"nested-table table-sm mb-0 data-grid-accordion-table\" [class.show-borders]=\"showVerticalBorder\" [class.show-shadow]=\"rowShadingEnabled\" style=\"table-layout: fixed; width: 100%;\">\r\n <tbody>\r\n <tr\r\n class=\"cursor-pointer data-grid-accordion-row\"\r\n *cdkVirtualFor=\"let d of row.details.data; trackBy: trackById; let j = index\"\r\n (contextmenu)=\"onRightClick($event, d, 'accordion-child')\"\r\n [style.height.px]=\"nestedTablerowHeight\">\r\n <ng-container *ngFor=\"let col of row.details.columns; let k = index\">\r\n <td\r\n *ngIf=\"col.is_visible !== false && !col.pinned\"\r\n class=\"px-4\"\r\n (mousedown)=\"startDetailSelection(row, j, k, col.field, $event, 'center')\"\r\n (mouseenter)=\"extendDetailSelection(row, j, k, col.field, $event, 'center')\"\r\n [class.selected-cell]=\"isDetailCellSelected(row, j, k, col.field, 'center')\"\r\n [attr.field]=\"col.field\"\r\n [style.width.px]=\"col.width || 150\"\r\n [style.min-width.px]=\"col.width || 150\"\r\n [style.fontSize.px]=\"bodyTextFontsSize\"\r\n [class.active-cell-detail]=\"isActiveDetailCell(row, d, col)\"\r\n style=\"cursor: pointer; position: relative; overflow: visible; cursor: cell; \">\r\n <div class=\"time-sheet-container\" style=\"overflow: visible; display: flex; gap: 4px; align-items: center; height: 100%; justify-content: center;\">\r\n <ng-container *ngIf=\"col.field === 'breaks' || col.field === 'short_breaks'; else defaultDetailCell\">\r\n <ng-container *ngIf=\"col.field === 'breaks'\">\r\n <ng-container *ngIf=\"d[col.field]?.length; else noBreaks\">\r\n <span *ngFor=\"let breakItem of d[col.field]; let breakIndex = index\"\r\n class=\"circle-value badge-outline break-on text-center\"\r\n [ngClass]=\"(breakItem.break_type?.data_value_name?.toLowerCase() || breakItem.breakType?.toLowerCase()) === 'paid' ? 'break-color-paid' : (breakItem.break_type?.data_value_name?.toLowerCase() || breakItem.breakType?.toLowerCase()) === 'unpaid' ? 'break-color-unpaid' : (breakItem.break_type?.data_value_name?.toLowerCase() || breakItem.breakType?.toLowerCase()) === 'lunch' ? 'break-color-lunch' : 'break-color-default'\"\r\n (mouseenter)=\"showBreakTooltip($event, breakItem)\"\r\n (mouseleave)=\"hideBreakTooltip()\">\r\n {{ breakItem.break_duration }}m\r\n</span>\r\n </ng-container>\r\n <ng-template #noBreaks>\r\n <div\r\n \r\n >\r\n -\r\n</div>\r\n</ng-template>\r\n</ng-container>\r\n <ng-container *ngIf=\"col.field === 'short_breaks' && !isDetailEditing(row, d, col)\">\r\n <div *ngIf=\"d[col.field]?.duration; else noShortBreak\"\r\n class=\"circle-value\"\r\n [ngClass]=\"(d[col.field].type || '').toLowerCase() === 'paid' ? 'break-color-paid' : (d[col.field].type || '').toLowerCase() === 'unpaid' ? 'break-color-unpaid' : (d[col.field].type || '').toLowerCase() === 'lunch' ? 'break-color-lunch' : 'break-color-default'\"\r\n (mouseenter)=\"showShortBreakTooltip($event, d[col.field], 'single_break'); preventCustomTooltipHide()\"\r\n (mouseleave)=\"hideShortBreakTooltip()\"\r\n (dblclick)=\"onShortBreakClick.emit(d)\">\r\n {{ d[col.field].duration }}m\r\n </div>\r\n <ng-template #noShortBreak>\r\n <div >-</div>\r\n </ng-template>\r\n</ng-container>\r\n <ng-container *ngIf=\"isDetailEditing(row, d, col)\">\r\n <input #detailInput type=\"text\" [ngModel]=\"getNestedValue(d, col.field)\" (blur)=\"disableDetailEdits(row, d, col)\" (keydown.enter)=\"disableDetailEdits(row, d, col)\" (keydown.escape)=\"disableDetailEdits(row, d, col)\" [attr.data-edit-key]=\"row._id + '-' + j + '-' + col.field\" class=\"form-control form-control-sm\" style=\"width: 100%; height: auto; position: absolute; top: 0; left: 0; z-index: 10;\" />\r\n </ng-container>\r\n </ng-container>\r\n <ng-template #defaultDetailCell>\r\n <span class=\"d-flex align-items-center h-100\">\r\n <ng-container *ngIf=\"!isDetailEditing(row, d, col)\">\r\n <ng-container [ngSwitch]=\"col.field\">\r\n <!-- \u2705 SHORT LEAVE: Progress bar in detail rows -->\r\n <div *ngSwitchCase=\"'short_leave'\" class=\"position-relative\" style=\"min-width: 100px; width: 150px;\">\r\n <ng-container *ngIf=\"d.short_leave && d.short_leave.length > 0; else noShortLeaveDetail\">\r\n <div\r\n class=\"w-100 d-flex main-progress-bar\"\r\n style=\"background-color: rgb(111, 97, 207); height: 20px; border-radius: 4px; position: relative;\"\r\n (mouseenter)=\"showShortLeaveTooltip($event, d)\"\r\n (mouseleave)=\"hideShortLeaveTooltip()\"\r\n >\r\n <span\r\n class=\"d-block\"\r\n [style.min-width.%]=\"d.short_leave[0].short_leave_time_percentage\"\r\n style=\"background-color: rgb(238, 99, 82); height: 100%; border-radius: 4px;\"\r\n ></span>\r\n <span style=\"position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); color: white; font-size: 12px; font-weight: bold;\">{{ d.short_leave[0].short_leave_time_percentage }}%</span>\r\n </div>\r\n </ng-container>\r\n <ng-template #noShortLeaveDetail>\r\n <div >-</div>\r\n </ng-template>\r\n </div>\r\n\r\n <!-- Status -->\r\n<ng-container *ngSwitchCase=\"'status'\">\r\n <ng-container *ngIf=\"getNestedValue(d, col.field); else noStatus\">\r\n <span class=\"badge\" [class]=\"getStatusBadgeClass(getNestedValue(d, col.field))\">\r\n {{ transformStatus(getNestedValue(d, col.field)) }}\r\n </span>\r\n </ng-container>\r\n <ng-template #noStatus>-</ng-template>\r\n</ng-container>\r\n\r\n<!-- Attendance Status -->\r\n<ng-container *ngSwitchCase=\"'attendanceStatus'\">\r\n <ng-container *ngIf=\"getNestedValue(d, col.field); else noAttendanceStatus\">\r\n <span class=\"badge\" [class]=\"getAttendanceStatusBadgeClass(getNestedValue(d, col.field))\">\r\n {{ transformStatus(getNestedValue(d, col.field)) }}\r\n </span>\r\n </ng-container>\r\n <ng-template #noAttendanceStatus>-</ng-template>\r\n</ng-container>\r\n\r\n <!-- Existing cases -->\r\n <div *ngSwitchCase=\"'is_un_restricted'\" class=\"d-flex justify-content-start flex-column pointer position-relative\" (mouseenter)=\"showRestrictionTooltip($event, row, d); preventRestrictionTooltipHide()\" (mouseleave)=\"hideRestrictionTooltip()\">\r\n <span class=\"popover__wrapper\" [class.restriction-indicator]=\"row.attendance_log_detail?.length > 0\">\r\n {{ d.is_un_restricted ? 'Yes' : 'No' }}\r\n </span>\r\n </div>\r\n\r\n <div *ngSwitchCase=\"'is_payroll_processed'\" class=\"d-flex justify-content-start flex-column pointer position-relative\" >\r\n <span class=\"\" >\r\n {{ d.is_payroll_processed ? 'Yes' : 'No' }}\r\n </span>\r\n </div>\r\n <div *ngSwitchCase=\"'manually_logs'\" class=\"d-flex justify-content-start align-items-center pointer position-relative\">\r\n <ng-container *ngIf=\"d.manually_logs?.length > 0; else noManualLogsIcon\">\r\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/eye.svg'\" class=\"data-grid-svg-icon text-primary\" style=\"cursor: pointer; font-size: 16px;\" (mouseenter)=\"showManualLogsTooltip($event, row, d)\" (mouseleave)=\"hideManualLogsTooltip()\"></span>\r\n </ng-container>\r\n <ng-template #noManualLogsIcon>\r\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/eye-cross.svg'\" class=\"data-grid-svg-icon text-muted\" style=\"font-size: 16px; cursor: not-allowed;\"></span>\r\n </ng-template>\r\n </div>\r\n\r\n <!-- Default fallback -->\r\n <span *ngSwitchDefault>\r\n {{\r\n col.type === 'date'\r\n ? (getNestedValue(d, col.field) ? (getNestedValue(d, col.field) | timezoneFormat:prefs:'date') : '-')\r\n : col.type === 'time'\r\n ? ((getTimeValue(getNestedValue(d, col.field)) | timezoneFormat:prefs:'time'))\r\n : (getNestedValue(d, col.field)?.value || getNestedValue(d, col.field)?.name || getNestedValue(d, col.field) || '-')\r\n }}\r\n </span>\r\n</ng-container>\r\n </ng-container>\r\n <ng-container *ngIf=\"isDetailEditing(row, d, col)\">\r\n <ng-container [ngSwitch]=\"col.type\">\r\n <input *ngSwitchCase=\"'string'\" #detailInput type=\"text\" [ngModel]=\"getNestedValue(d, col.field)\" (blur)=\"disableDetailEdits(row, d, col)\" (keydown.enter)=\"disableDetailEdits(row, d, col)\" (keydown.escape)=\"disableDetailEdits(row, d, col)\" class=\"form-control form-control-sm\" style=\"width: 100%; height: auto;\" />\r\n <input *ngSwitchCase=\"'number'\" #detailInput type=\"number\" [ngModel]=\"getNestedValue(d, col.field)\" (blur)=\"disableDetailEdits(row, d, col)\" (keydown.enter)=\"disableDetailEdits(row, d, col)\" (keydown.escape)=\"disableDetailEdits(row, d, col)\" class=\"form-control form-control-sm\" style=\"width: 100%; height: auto;\" />\r\n <input *ngSwitchCase=\"'date'\" #detailInput type=\"date\" [ngModel]=\"getNestedValue(d, col.field)\" (blur)=\"disableDetailEdits(row, d, col)\" (keydown.enter)=\"disableDetailEdits(row, d, col)\" (keydown.escape)=\"disableDetailEdits(row, d, col)\" class=\"form-control form-control-sm\" style=\"width: 100%; height: auto;\" />\r\n <input *ngSwitchCase=\"'time'\" #detailInput type=\"time\" [ngModel]=\"getNestedValue(d, col.field)\" (blur)=\"disableDetailEdits(row, d, col)\" (keydown.enter)=\"disableDetailEdits(row, d, col)\" (keydown.escape)=\"disableDetailEdits(row, d, col)\" class=\"form-control form-control-sm\" style=\"width: 100%; height: auto;\" />\r\n <input *ngSwitchCase=\"'currency'\" #detailInput type=\"number\" step=\"0.01\" [ngModel]=\"getNestedValue(d, col.field)\" (blur)=\"disableDetailEdits(row, d, col)\" (keydown.enter)=\"disableDetailEdits(row, d, col)\" (keydown.escape)=\"disableDetailEdits(row, d, col)\" class=\"form-control form-control-sm text-end\" style=\"width: 100%; height: auto;\" />\r\n <select *ngSwitchCase=\"'dropdown'\" #detailInput [ngModel]=\"getNestedValue(d, col.field)\" (blur)=\"disableDetailEdits(row, d, col)\" (keydown.enter)=\"disableDetailEdits(row, d, col)\" (keydown.escape)=\"disableDetailEdits(row, d, col)\" class=\"form-control form-control-sm\" style=\"width: 100%; height: auto;\">\r\n <option *ngFor=\"let option of col.column_dropdown_value\" [ngValue]=\"option?.value || option\">\r\n {{ option?.label || option?.name || option }}\r\n </option>\r\n </select>\r\n <input *ngSwitchDefault #detailInput type=\"text\" [ngModel]=\"getNestedValue(d, col.field)\" (blur)=\"disableDetailEdits(row, d, col)\" (keydown.enter)=\"disableDetailEdits(row, d, col)\" (keydown.escape)=\"disableDetailEdits(row, d, col)\" class=\"form-control form-control-sm\" style=\"width: 100%; height: auto;\" />\r\n </ng-container>\r\n </ng-container>\r\n </span>\r\n </ng-template>\r\n </div>\r\n </td>\r\n </ng-container>\r\n </tr>\r\n </tbody>\r\n </table>\r\n </cdk-virtual-scroll-viewport>\r\n</div>\r\n\r\n <!-- RIGHT SECTION OF ACCORDION -->\r\n <div #rightContainer class=\"accordion-right-section data-pin-body-wrapper \" [attr.data-detail-row-id]=\"row._id || row.id\" (scroll)=\"onDetailRightScroll($event, row)\" style=\"flex-shrink: 0; overflow-y: auto; overflow-x: hidden;\">\r\n <table class=\"nested-table table-sm mb-0 data-grid-accordion-table\" [class.show-shadow]=\"rowShadingEnabled\" style=\"table-layout: fixed; width: auto;\">\r\n <thead>\r\n <tr [style.height.px]=\"nestedTableHeaderRowHeight\" [style.backgroundColor]=\"headerBackgroundColor\" [style.color]=\"headerTextColor\" [style.fontSize.px]=\"headerTextFontsSize\" [style.fontWeight]=\"headerFontWeight\">\r\n <ng-container *ngFor=\"let col of row.details.columns | pinnedColumns:'right'; trackBy: trackByField\">\r\n <th *ngIf=\"col.is_visible !== false\"\r\n class=\"px-4\"\r\n [class.filter-applied]=\"isAccordionColumnFiltered(row, col)\"\r\n [style.width.px]=\"col.width || 150\"\r\n [style.min-width.px]=\"col.width || 150\"\r\n [attr.field]=\"col.field\"\r\n [attr.pinned]=\"col.pinned\">\r\n <div class=\"d-flex justify-content-between align-items-center\" style=\"width: 100%;\">\r\n <span class=\"d-flex align-items-center gap-1\">\r\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/pin-blue.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"></span>\r\n {{ col.header }}\r\n <span *ngIf=\"isAccordionColumnFiltered(row, col)\"\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\"\r\n class=\"data-grid-svg-icon text-primary ms-1\"\r\n style=\"font-size: 12px;\"></span>\r\n </span>\r\n <span class=\"three-dots p-1\"\r\n (click)=\"openDetailThreeDotsMenus($event, col, row); activeDetailCol = col; activeDetailRow = row\"\r\n style=\"cursor: pointer;\">\r\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/three-dots-vertical.svg'\" class=\"data-grid-svg-icon\"></span>\r\n </span>\r\n</div>\r\n\r\n <!-- <div class=\"resize-handles\" (mousedown)=\"onResizeDetailColumn($event, row, col)\">\r\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/resize-handle.svg'\" class=\"data-grid-svg-icon text-primary\"></span>\r\n </div> -->\r\n <ng-container *ngIf=\"activeDetailCol?.field == col.field && activeDetailRow === row\">\r\n <div class=\"position-absolute detail-column-menu-wrapper\"\r\n [style.top.px]=\"nestedTableHeaderRowHeight\"\r\n [style.left.px]=\"0\">\r\n <ng-container *ngTemplateOutlet=\"detailColumnMenu; context: { col: col, row: row }\"></ng-container>\r\n </div>\r\n </ng-container>\r\n </th>\r\n </ng-container>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <tr [style.height.px]=\"nestedTablerowHeight\" *ngFor=\"let d of row.details.data; let j = index; trackBy: trackById\">\r\n <ng-container *ngFor=\"let col of row.details.columns | pinnedColumns:'right'; let localK = index; trackBy: trackByField\">\r\n <td *ngIf=\"col.is_visible !== false\"\r\n class=\"px-4\"\r\n [attr.field]=\"col.field\"\r\n [attr.pinned]=\"col.pinned\"\r\n (mousedown)=\"startDetailSelection(row, j, localK, col.field, $event, 'right')\"\r\n (mouseenter)=\"extendDetailSelection(row, j, localK, col.field, $event, 'right')\"\r\n [class.selected-cell]=\"isDetailCellSelected(row, j, localK, col.field, 'right')\"\r\n [style.fontSize.px]=\"bodyTextFontsSize\"\r\n [class.active-cell-detail]=\"isActiveDetailCell(row, d, col)\">\r\n <ng-container [ngSwitch]=\"col.field\">\r\n\r\n <ng-container *ngSwitchCase=\"'manually_logs'\" class=\"d-flex justify-content-start align-items-center pointer position-relative\">\r\n <ng-container *ngIf=\"d.manually_logs?.length > 0; else noManualLogsIcon\">\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/eye.svg'\"\r\n class=\"data-grid-svg-icon text-primary\"\r\n style=\"cursor: pointer; font-size: 16px;\"\r\n (mouseenter)=\"showManualLogsTooltip($event, row, d)\"\r\n (mouseleave)=\"hideManualLogsTooltip()\">\r\n </span>\r\n </ng-container>\r\n <ng-template #noManualLogsIcon>\u2013</ng-template>\r\n</ng-container>\r\n <!-- Breaks -->\r\n <ng-container *ngSwitchCase=\"'breaks'\">\r\n <ng-container *ngIf=\"d[col.field]?.length; else noBreaksLeft\">\r\n <app-badge-overflow\r\n [badges]=\"getBreakBadges(d[col.field])\"\r\n [maxWidth]=\"col.width || 200\"\r\n (badgeMouseEnter)=\"showBreakTooltip($event.event, $event.badge.data)\"\r\n (badgeMouseLeave)=\"hideBreakTooltip()\"\r\n (overflowCountClick)=\"onDetailBadgeOverflowCountClick(col, d)\">\r\n</app-badge-overflow>\r\n </ng-container>\r\n <ng-template #noBreaksLeft>\r\n <div>\r\n -\r\n </div>\r\n </ng-template>\r\n </ng-container>\r\n\r\n <div *ngSwitchCase=\"'is_un_restricted'\" class=\"d-flex justify-content-start flex-column pointer position-relative\" (mouseenter)=\"showRestrictionTooltip($event, row, d); preventRestrictionTooltipHide()\" (mouseleave)=\"hideRestrictionTooltip()\">\r\n <span class=\"\" [class.restriction-indicator]=\"row.attendance_log_detail?.length > 0\">\r\n {{ d.is_un_restricted ? 'Yes' : 'No' }}\r\n </span>\r\n </div>\r\n\r\n <div *ngSwitchCase=\"'is_payroll_processed'\" class=\"d-flex justify-content-start flex-column pointer position-relative\" >\r\n <span class=\"\" >\r\n {{ d.is_payroll_processed ? 'Yes' : 'No' }}\r\n </span>\r\n </div>\r\n\r\n <!-- Short Breaks -->\r\n <ng-container *ngSwitchCase=\"'short_breaks'\">\r\n <ng-container *ngIf=\"d[col.field]?.duration; else noShortBreakLeft\">\r\n <div class=\"circle-value\"\r\n [ngClass]=\"(d[col.field].type || '').toLowerCase() === 'paid' ? 'break-color-paid' : (d[col.field].type || '').toLowerCase() === 'unpaid' ? 'break-color-unpaid' : (d[col.field].type || '').toLowerCase() === 'lunch' ? 'break-color-lunch' : 'break-color-default'\"\r\n (mouseenter)=\"showShortBreakTooltip($event, d[col.field], 'single_break'); preventCustomTooltipHide()\"\r\n (mouseleave)=\"hideShortBreakTooltip()\"\r\n (dblclick)=\"onShortBreakClick.emit(d)\">\r\n {{ d[col.field].duration }}m\r\n </div>\r\n </ng-container>\r\n <ng-template #noShortBreakLeft>\r\n <div >-</div>\r\n </ng-template>\r\n </ng-container>\r\n\r\n <!-- Short Leave -->\r\n <!-- Short Leave -->\r\n<ng-container *ngSwitchCase=\"'short_leave'\">\r\n <ng-container *ngIf=\"row.short_leave && row.short_leave.length > 0; else noShortLeaveMain\">\r\n <div class=\"w-100 d-flex main-progress-bar justify-content-center align-items-center\" \r\n style=\"background-color: rgb(111, 97, 207); height: 20px; border-radius: 4px; position: relative;\"\r\n (mouseenter)=\"showShortLeaveTooltip($event, row)\"\r\n (mouseleave)=\"hideShortLeaveTooltip()\">\r\n <span class=\"d-block\" [style.min-width.%]=\"row.short_leave[0].short_leave_time_percentage\" \r\n style=\"background-color: rgb(238, 99, 82); height: 100%; border-radius: 4px;\"></span>\r\n <span style=\"position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); color: white; font-size: 12px; font-weight: bold;\">\r\n {{ row.short_leave[0].short_leave_time_percentage }}%\r\n </span>\r\n </div>\r\n </ng-container>\r\n <ng-template #noShortLeaveMain>-</ng-template>\r\n</ng-container>\r\n\r\n<ng-container *ngSwitchCase=\"'status'\">\r\n <ng-container *ngIf=\"getNestedValue(d, col.field); else noStatus\">\r\n <span class=\"badge\" [class]=\"getStatusBadgeClass(getNestedValue(d, col.field))\">\r\n {{ transformStatus(getNestedValue(d, col.field)) }}\r\n </span>\r\n </ng-container>\r\n <ng-template #noStatus>-</ng-template>\r\n</ng-container>\r\n\r\n<!-- Attendance Status -->\r\n<ng-container *ngSwitchCase=\"'attendanceStatus'\">\r\n <ng-container *ngIf=\"getNestedValue(d, col.field); else noAttendanceStatus\">\r\n <span class=\"badge\" [class]=\"getAttendanceStatusBadgeClass(getNestedValue(d, col.field))\">\r\n {{ transformStatus(getNestedValue(d, col.field)) }}\r\n </span>\r\n </ng-container>\r\n <ng-template #noAttendanceStatus>-</ng-template>\r\n</ng-container>\r\n\r\n <!-- Default -->\r\n <ng-container *ngSwitchDefault>\r\n {{\r\n col.type === 'date'\r\n ? (getNestedValue(d, col.field) ? (getNestedValue(d, col.field) | timezoneFormat:prefs:'date') : '-')\r\n : col.type === 'time'\r\n ? ((getTimeValue(getNestedValue(d, col.field)) | timezoneFormat:prefs:'time'))\r\n : (getNestedValue(d, col.field)?.value || getNestedValue(d, col.field)?.name || getNestedValue(d, col.field) || '-')\r\n }}\r\n </ng-container>\r\n</ng-container>\r\n </td>\r\n </ng-container>\r\n </tr>\r\n</tbody>\r\n </table>\r\n\r\n </div>\r\n\r\n <!-- DETAIL SIDE MENU (Sticky on right end) -->\r\n <div class=\"detail-side-menu-wrapper\" >\r\n <div style=\"width: 30px\" class=\"d-flex flex-column align-items-center \">\r\n <div (click)=\"toggleDetailSideMenu(row, 'cols')\" [class.bg-white]=\"row.details.sideMenu?.currentTab === 'cols'\" class=\"columns-button d-flex flex-column align-items-center border-below\">\r\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/ui-checks-grid.svg'\" class=\"data-grid-svg-icon\"></span>\r\n <div class=\"side-menue-text\">Columns</div>\r\n </div>\r\n <!-- <div (click)=\"toggleDetailSideMenu(row, 'filtrs')\" [class.bg-white]=\"row.details.sideMenu?.currentTab === 'filtrs'\" class=\"columns-button d-flex flex-column align-items-center\">\r\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\" class=\"data-grid-svg-icon\"></span>\r\n <div class=\"side-menue-text\">Filter</div>\r\n </div> -->\r\n </div>\r\n\r\n <div *ngIf=\"row.details.sideMenu?.currentTab\" class=\"detail-side-menu-content\" [style.backgroundColor]=\"sidemenuBackgroundColor\" style=\"width: 250px; box-shadow: -2px 0 5px rgba(0,0,0,0.1);\">\r\n <!-- COLUMNS TAB -->\r\n <ng-container *ngIf=\"row.details.sideMenu.currentTab === 'cols'\">\r\n <div class=\"px-3 py-2 border-bottom d-flex align-items-center\">\r\n <strong class=\"me-auto\">Columns</strong>\r\n <input type=\"text\" class=\"form-control form-control-sm\" placeholder=\"Search...\" [(ngModel)]=\"row.details.sideMenu.columnSearch\" style=\"width: 120px; font-size: 12px;\" />\r\n </div>\r\n <div class=\"side-menu-scrollable\">\r\n <div *ngFor=\"let col of row.details.columns | filter: row.details.sideMenu.columnSearch:'header'; trackBy: trackByField\" class=\"d-flex align-items-center mb-2\">\r\n <input type=\"checkbox\" class=\"form-check-input me-2\" [(ngModel)]=\"col.is_visible\" (change)=\"onDetailColumnVisibilityChange(row)\" />\r\n <span>{{ col.header }}</span>\r\n </div>\r\n </div>\r\n </ng-container>\r\n\r\n <!-- FILTERS TAB -->\r\n <ng-container *ngIf=\"row.details.sideMenu.currentTab === 'filtrs'\">\r\n <div class=\"px-3 py-2 border-bottom d-flex align-items-center\">\r\n <strong class=\"me-auto\">Filters</strong>\r\n <input type=\"text\" class=\"form-control form-control-sm\" placeholder=\"Search...\" [(ngModel)]=\"row.details.sideMenu.columnSearch\" style=\"width: 120px; font-size: 12px;\" />\r\n </div>\r\n <div class=\"side-menu-scrollable\">\r\n <div *ngFor=\"let col of row.details.columns | filter: row.details.sideMenu.columnSearch:'header'; trackBy: trackByField\" class=\"mb-3\">\r\n <div class=\"d-flex justify-content-between align-items-center cursor-pointer\" (click)=\"col.expandedFilter = !col.expandedFilter\">\r\n <label class=\"mb-0 small\">{{ col.header }}</label>\r\n <span class=\"toggle-icon data-grid-svg-icon\" [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\" [class.rotate]=\"col.expandedFilter\"></span>\r\n </div>\r\n <div *ngIf=\"col.expandedFilter\" class=\"mt-2 filter-input-container ps-3 pe-3\">\r\n <ng-container *ngIf=\"col.type === 'dropdown'; else textFilter\">\r\n <div class=\"p-1\">\r\n <!-- Search -->\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm mb-2\"\r\n placeholder=\"Search...\"\r\n [(ngModel)]=\"col.searchValue\"\r\n />\r\n\r\n <!-- Select All -->\r\n <div class=\"form-check mb-1 ms-1\">\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n [checked]=\"\r\n row.details.filters[col.field]?._ids?.length == col.column_dropdown_value?.length\r\n \"\r\n (change)=\"toggleSelectAllDetailFilters(col, row, $event)\"\r\n id=\"detail_selectAll_{{ col.field }}\"\r\n />\r\n <label class=\"form-check-label\" for=\"detail_selectAll_{{ col.field }}\">\r\n Select All\r\n </label>\r\n </div>\r\n\r\n <!-- Options -->\r\n <div class=\"dropdown-options\">\r\n <div\r\n class=\"form-check mb-1 ms-1\"\r\n *ngFor=\"\r\n let option of col?.column_dropdown_value\r\n | filter : col.searchValue : 'value';\r\n trackBy: trackById\r\n \"\r\n >\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n [value]=\"option\"\r\n [checked]=\"\r\n row.details.filters[col.field]?._ids?.includes(option?._id || option?.id || option)\r\n \"\r\n (change)=\"onDetailOptionToggle(col, option, row)\"\r\n id=\"detail_option_{{ col.field }}_{{\r\n option?.id || option?._id || option\r\n }}\"\r\n />\r\n <label\r\n class=\"form-check-label\"\r\n [for]=\"\r\n 'detail_option_' +\r\n col.field +\r\n '_' +\r\n (option?.id || option?._id || option)\r\n \"\r\n >\r\n {{ option.value || option }}\r\n </label>\r\n </div>\r\n </div>\r\n </div>\r\n </ng-container>\r\n\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)]=\"row.details.filters[col.field].first_condition\"\r\n (ngModelChange)=\"applyDetailRowFilter(row)\"\r\n >\r\n <option value=\"contain\">Contains</option>\r\n <option value=\"equal\">Equals</option>\r\n <option value=\"before\">Begins With</option>\r\n <option value=\"after\">Ends With</option>\r\n </select>\r\n </div>\r\n\r\n <input\r\n [type]=\"col.type == 'date' ? 'date' : 'text'\"\r\n class=\"form-control form-control-sm mb-3\"\r\n placeholder=\"Value\"\r\n [(ngModel)]=\"row.details.filters[col.field].first_value\"\r\n (ngModelChange)=\"applyDetailRowFilter(row)\"\r\n />\r\n\r\n <ng-container *ngIf=\"row.details.filters[col.field]?.first_value\">\r\n <div class=\"form-group mb-2\">\r\n <div class=\"form-check form-check-inline\">\r\n <input\r\n class=\"form-check-input filter-radio-inputs\"\r\n type=\"radio\"\r\n name=\"detail_condition_{{ col.field }}\"\r\n [(ngModel)]=\"row.details.filters[col.field].condition\"\r\n (ngModelChange)=\"applyDetailRowFilter(row)\"\r\n value=\"and\"\r\n id=\"detail_and_{{ col.field }}\"\r\n />\r\n <label class=\"form-check-label\" for=\"detail_and_{{ col.field }}\"\r\n >AND</label\r\n >\r\n </div>\r\n <div class=\"form-check form-check-inline\">\r\n <input\r\n class=\"form-check-input filter-radio-inputs\"\r\n type=\"radio\"\r\n name=\"detail_condition_{{ col.field }}\"\r\n [(ngModel)]=\"row.details.filters[col.field].condition\"\r\n (ngModelChange)=\"applyDetailRowFilter(row)\"\r\n value=\"or\"\r\n id=\"detail_or_{{ col.field }}\"\r\n />\r\n <label class=\"form-check-label\" for=\"detail_or_{{ col.field }}\"\r\n >OR</label\r\n >\r\n </div>\r\n <div class=\"form-check form-check-inline\">\r\n <input\r\n class=\"form-check-input filter-radio-inputs\"\r\n type=\"radio\"\r\n name=\"detail_condition_{{ col.field }}\"\r\n [(ngModel)]=\"row.details.filters[col.field].condition\"\r\n (ngModelChange)=\"applyDetailRowFilter(row)\"\r\n value=\"none\"\r\n id=\"detail_none_{{ col.field }}\"\r\n />\r\n <label class=\"form-check-label\" for=\"detail_none_{{ col.field }}\"\r\n >None</label\r\n >\r\n </div>\r\n </div>\r\n\r\n <ng-container *ngIf=\"row.details.filters[col.field].condition !== 'none'\">\r\n <div class=\"form-group mb-2\">\r\n <select\r\n class=\"form-select form-select-sm\"\r\n [(ngModel)]=\"row.details.filters[col.field].second_condition\"\r\n (ngModelChange)=\"applyDetailRowFilter(row)\"\r\n >\r\n <option value=\"contain\">Contains</option>\r\n <option value=\"equal\">Equals</option>\r\n <option value=\"before\">Begins With</option>\r\n <option value=\"after\">Ends With</option>\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-2\"\r\n placeholder=\"Second Value\"\r\n [(ngModel)]=\"row.details.filters[col.field].second_value\"\r\n (ngModelChange)=\"applyDetailRowFilter(row)\"\r\n />\r\n </ng-container>\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 </div>\r\n </div>\r\n</div>\r\n\r\n<!-- Detail Side Menu -->\r\n\r\n\r\n\r\n<!-- Popover for Restriction Logs (is_un_restricted) -->\r\n<div\r\n *ngIf=\"restrictionTooltipVisible\"\r\n class=\"popover__content m-l-10 popoverRestriction position-absolute border rounded bg-white p-3\"\r\n [style.left.px]=\"restrictionTooltipPosition.x\"\r\n [style.top.px]=\"restrictionTooltipPosition.y\"\r\n (mouseenter)=\"preventRestrictionTooltipHide()\"\r\n (mouseleave)=\"hideRestrictionTooltip()\"\r\n style=\"z-index: 1000; min-width: 300px; font-size: 12px;\"\r\n>\r\n <div class=\"modal-area px-0 py-0\">\r\n <div class=\"table-responsive\">\r\n <table class=\"table table-row-primary-100 gs-0 gy-2 mb-0\">\r\n <thead>\r\n <tr class=\"fw-bolder text-muted bg-light\">\r\n <th class=\"center ps-2\">Clock in</th>\r\n <th class=\"center\">Clock out</th>\r\n <th class=\"center\">Log Hr</th>\r\n <th class=\"center\">Log Min</th>\r\n <th class=\"center pe-2\">Status</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <tr *ngFor=\"let item of currentRestrictionLogs\">\r\n <td class=\"center ps-2\">\r\n <span class=\"text-primary\"> {{ item?.clock_in_time | date:'shortTime'}}</span>\r\n </td>\r\n <td class=\"center\">\r\n <span class=\"text-primary\">{{ item?.clock_out_time | date:'shortTime'}}</span>\r\n </td>\r\n <td class=\"center\">\r\n <span class=\"text-primary\">{{ item?.logged_hours }}</span>\r\n </td>\r\n <td class=\"center\">\r\n <span class=\"text-primary\">{{ item?.logged_minutes }}</span>\r\n </td>\r\n <td class=\"center\">\r\n <span class=\"badge bg-light text-dark border\">\r\n {{ item?.status ? (item.status | titlecase) : 'N/A' }}\r\n </span>\r\n </td>\r\n </tr>\r\n </tbody>\r\n </table>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<!-- Popover for Manual Logs -->\r\n<div\r\n *ngIf=\"manualLogsTooltipVisible\"\r\n class=\"popover__content position-absolute border rounded bg-white p-3\"\r\n [style.left.px]=\"manualLogsTooltipPosition.x\"\r\n [style.top.px]=\"manualLogsTooltipPosition.y\"\r\n (mouseenter)=\"preventManualLogsTooltipHide()\"\r\n (mouseleave)=\"hideManualLogsTooltip()\"\r\n style=\"z-index: 1000; min-width: 500px; font-size: 12px;\"\r\n>\r\n <div class=\"modal-area px-0 py-0\">\r\n <ng-container *ngIf=\"currentManualLogs.length > 0; else noManualLogs\">\r\n <div class=\"table-responsive\">\r\n <table class=\"table table-row-primary-100 gs-0 gy-2 mb-0\">\r\n <thead>\r\n <tr class=\"fw-bolder text-muted bg-light\">\r\n <th class=\"center ps-2\" style=\"width: 18%;\">Name</th>\r\n <th class=\"center\">Date/Time</th>\r\n <th class=\"center\">Previous Time</th>\r\n <th class=\"center\">Updated Time</th>\r\n <th class=\"center\">Status</th>\r\n <th class=\"center pe-2\">Remarks</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <tr *ngFor=\"let log of currentManualLogs\">\r\n <td class=\"center ps-2\">\r\n <span class=\"text-primary\">{{ log.name }}</span>\r\n </td>\r\n <td class=\"center\">\r\n <span class=\"text-primary\">{{ log.date_time }}</span>\r\n </td>\r\n <td class=\"center\">\r\n <span class=\"text-primary\">{{ log.previous_time }}</span>\r\n </td>\r\n <td class=\"center\">\r\n <span class=\"text-primary\">{{ log.updated_time }}</span>\r\n </td>\r\n <td class=\"center\">\r\n <span class=\"badge bg-light text-dark border\">\r\n {{ log.log_status ? (log.log_status | titlecase) : 'N/A' }}\r\n </span>\r\n </td>\r\n <td class=\"center pe-2\">\r\n <span class=\"text-primary\">{{ log.remarks }}</span>\r\n </td>\r\n </tr>\r\n </tbody>\r\n </table>\r\n </div>\r\n </ng-container>\r\n </div>\r\n\r\n <ng-template #noManualLogs>\r\n <div class=\"text-center p-3\">\r\n <p class=\"text-muted mb-0\">No manual logs available for this record.</p>\r\n </div>\r\n </ng-template>\r\n</div>\r\n\r\n\r\n\r\n\r\n<!-- Existing Custom Tooltip for Breaks -->\r\n\r\n\r\n\r\n\r\n\r\n <!-- RIGHT PINNED: Empty table to keep alignment -->\r\n <div *ngIf=\"section === 'right' && row.isDetailsExpand && !isSingleDay\" class=\"accordion-details data-grid-accordion-section\" style=\"max-height: 350px; min-height: 350px; overflow: hidden;\">\r\n <table class=\"nested-table table table-sm w-100 mb-0 data-grid-accordion-table\" [class.show-shadow]=\"rowShadingEnabled\">\r\n <thead>\r\n <tr [style.height.px]=\"nestedTableHeaderRowHeight\" [style.backgroundColor]=\"headerBackgroundColor\">\r\n <th *ngFor=\"let _ of [1, 2, 3, 4, 5]\">&nbsp;</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <tr [style.height.px]=\"nestedTablerowHeight\" *ngFor=\"let _ of row.details.data\" [style.backgroundColor]=\"headerBackgroundColor\">\r\n <td *ngFor=\"let __ of [1, 2, 3, 4, 5]\">&nbsp;</td>\r\n </tr>\r\n </tbody>\r\n </table>\r\n </div>\r\n\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>\r\n <div\r\n (click)=\"disableEdit(row, col); setActiveCell(row, col)\"\r\n [style.fontWeight]=\"bodyFontWeight\"\r\n [class.border-right]=\"showVerticalBorder\"\r\n class=\"cell overflow-visible position-relative\"\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 [class.active-cell]=\"\r\n isActiveCell(row, col) && !isEditing(row, col) && selectedKeys.size == 1\r\n \"\r\n (dblclick)=\"$event.preventDefault(); enableEdit(row, col)\"\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=\"0\"\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 class=\"table-cell\" [class.active-for-editing]=\"isEditing(row, col) && getNestedValue(row, col.field)?.length <= 50\">\r\n <div\r\n (click)=\"$event.stopPropagation()\"\r\n *ngIf=\"isEditing(row, col) && getNestedValue(row, col.field)?.length <= 50; else viewMode\"\r\n >\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 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)\"\r\n autofocus\r\n (keydown.enter)=\"numberRef.blur()\"\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)\"\r\n autofocus\r\n class=\"form-control form-control-sm\"\r\n #dateInput=\"ngModel\"\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\">\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 />\r\n </div>\r\n\r\n <!-- Options -->\r\n <div\r\n class=\"cell-editin-dropdown\"\r\n style=\"max-height: 200px; overflow: auto\"\r\n >\r\n <div\r\n (click)=\"\r\n setNestedValue(row, col, option, true);\r\n disableEdit(row, col)\r\n \"\r\n class=\"px-2 py-1 d-flex align-items-center item\"\r\n *ngFor=\"\r\n let option of col.column_dropdown_value\r\n | filter : editinDropdownSearch : 'value'\r\n \"\r\n >\r\n <label\r\n class=\"form-check-label d-flex align-items-center mb-0\"\r\n [for]=\"col.field + '-' + option.value || option\"\r\n >\r\n {{ option.value || option }}\r\n </label>\r\n </div>\r\n </div>\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)=\"\r\n emailModel.control.markAsTouched(); emailInput.blur()\r\n \"\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 [(ngModel)]=\"row[col.field]\"\r\n name=\"{{ col.field }}\"\r\n required\r\n (blur)=\"disableEdit(row, col, textModel)\"\r\n (keydown.enter)=\"\r\n textModel.control.markAsTouched(); textInput.blur()\r\n \"\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 </div>\r\n\r\n <!-- Display mode -->\r\n <ng-template #viewMode>\r\n <div\r\n class=\"d-flex justify-between items-center w-100\"\r\n [ngClass]=\"getCellClasses(col, getNestedValue(row, col.field))\"\r\n >\r\n <!-- Text cell -->\r\n <div class=\"d-flex align-items-center w-100\">\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(row, col.field) | date : dateFormat)\r\n : getNestedValue(row, col.field)\r\n \"\r\n >\r\n <ng-container *ngIf=\"col.type !== 'image'\">\r\n <ng-container [ngSwitch]=\"col.field\">\r\n <!-- Breaks -->\r\n <ng-container *ngSwitchCase=\"'breaks'\">\r\n <ng-container *ngIf=\"getNestedValue(row, 'breaks')?.length; else noBreaksMain\">\r\n <app-badge-overflow\r\n [badges]=\"getBreakBadges(getNestedValue(row, 'breaks'))\"\r\n [maxWidth]=\"col.width || 200\"\r\n (badgeMouseEnter)=\"showBreakTooltip($event.event, $event.badge.data)\"\r\n (badgeMouseLeave)=\"hideBreakTooltip()\"\r\n (overflowCountClick)=\"onBadgeOverflowCountClick(col)\">\r\n </app-badge-overflow>\r\n </ng-container>\r\n <ng-template #noBreaksMain>\r\n <div >\r\n -\r\n </div>\r\n </ng-template>\r\n </ng-container>\r\n\r\n <!-- Short Breaks -->\r\n <ng-container *ngSwitchCase=\"'short_breaks'\">\r\n <ng-container *ngIf=\"row.short_breaks?.duration && row.short_breaks.duration > 0; else noShortBreak\">\r\n <span class=\"popover__wrapper d-flex justify-content-center align-items-center\" style=\"cursor: pointer;\" (dblclick)=\"onShortBreakClick.emit(row)\" (mouseenter)=\"showShortBreakTooltip($event, row.short_breaks)\" (mouseleave)=\"hideShortBreakTooltip()\">\r\n <span class=\"circle-value badge-outline text-center\" [ngClass]=\"(row.short_breaks.type || '').toLowerCase() === 'paid' ? 'break-color-paid' : (row.short_breaks.type || '').toLowerCase() === 'unpaid' ? 'break-color-unpaid' : (row.short_breaks.type || '').toLowerCase() === 'lunch' ? 'break-color-lunch' : 'break-color-default'\">\r\n {{ row.short_breaks.duration }}m\r\n </span>\r\n </span>\r\n </ng-container>\r\n <ng-template #noShortBreak>\r\n <div >-</div>\r\n </ng-template>\r\n </ng-container>\r\n\r\n <!-- Short Leave -->\r\n <!-- Short Leave -->\r\n<ng-container *ngSwitchCase=\"'short_leave'\">\r\n <ng-container *ngIf=\"row.short_leave && row.short_leave.length > 0; else noShortLeaveMain\">\r\n <div class=\"w-100 d-flex main-progress-bar justify-content-center align-items-center\" \r\n style=\"background-color: rgb(111, 97, 207); height: 20px; border-radius: 4px; position: relative;\"\r\n (mouseenter)=\"showShortLeaveTooltip($event, row)\"\r\n (mouseleave)=\"hideShortLeaveTooltip()\">\r\n <span class=\"d-block\" [style.min-width.%]=\"row.short_leave[0].short_leave_time_percentage\" \r\n style=\"background-color: rgb(238, 99, 82); height: 100%; border-radius: 4px;\"></span>\r\n <span style=\"position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); color: white; font-size: 12px; font-weight: bold;\">\r\n {{ row.short_leave[0].short_leave_time_percentage }}%\r\n </span>\r\n </div>\r\n </ng-container>\r\n <ng-template #noShortLeaveMain>-</ng-template>\r\n</ng-container>\r\n\r\n <!-- Status -->\r\n <ng-container *ngSwitchCase=\"'status'\">\r\n <span class=\"badge\" [class]=\"getStatusBadgeClass(getNestedValue(row, col.field))\">\r\n {{ transformStatus(getNestedValue(row, col.field)) || '-' }}\r\n </span>\r\n </ng-container>\r\n\r\n <!-- Attendance Status -->\r\n <ng-container *ngSwitchCase=\"'attendanceStatus'\">\r\n <span class=\"badge\" [class]=\"getAttendanceStatusBadgeClass(getNestedValue(row, col.field))\">\r\n {{ transformStatus(getNestedValue(row, col.field)) || '-' }}\r\n </span>\r\n </ng-container>\r\n\r\n <!-- Payroll Processed -->\r\n <ng-container *ngSwitchCase=\"'is_payroll_processed'\">\r\n <span class=\"badge\" [class]=\"getNestedValue(row, col.field) ? 'badge-success' : 'badge-secondary'\">\r\n {{ getNestedValue(row, col.field) ? 'Yes' : 'No' }}\r\n </span>\r\n </ng-container>\r\n\r\n <!-- Restriction -->\r\n <ng-container *ngSwitchCase=\"'is_un_restricted'\">\r\n <span class=\"badge\" [class]=\"getNestedValue(row, col.field) ? 'badge-success' : 'badge-secondary'\">\r\n {{ getNestedValue(row, col.field) ? 'Yes' : 'No' }}\r\n </span>\r\n </ng-container>\r\n\r\n <!-- Default -->\r\n <ng-container *ngSwitchDefault>\r\n {{\r\n !isNestedValueArray(row, col.field)\r\n ? col.type === 'date'\r\n ? (isDate(getNestedValue(row, col.field))\r\n ? ((getNestedValue(row, col.field)) | timezoneFormat:prefs:'date' )\r\n : (getNestedValue(row, col.field)?.value ||\r\n getNestedValue(row, col.field)?.name ||\r\n getNestedValue(row, col.field) ||\r\n '-'))\r\n : col.type === 'time'\r\n ? ((getTimeValue(getNestedValue(row, col.field)) | timezoneFormat:prefs:'time'))\r\n : (getNestedValue(row, col.field)?.value ||\r\n getNestedValue(row, col.field)?.name ||\r\n getNestedValue(row, col.field) ||\r\n '-')\r\n : (getNestedValue(row, col.field)?.[0]?.department_name ||\r\n getNestedValue(row, col.field)?.[0]?.roleName ||\r\n '-')\r\n }}\r\n </ng-container>\r\n </ng-container>\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: row,\r\n col: col,\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </div>\r\n\r\n <!-- Active dot and eye icon for employee name -->\r\n <span *ngIf=\"col.field === 'User' && hasManualLogs(row) && !row.isDetailsExpand\" class=\"badge badge-dot badge-success ms-1\" (mouseenter)=\"showManualLogsTooltip($event, row, row)\"></span>\r\n <i *ngIf=\"col.field === 'User' && hasManualLogs(row)\" class=\"bi bi-eye ms-1\" (mouseenter)=\"showManualLogsTooltip($event, row, row)\"></i>\r\n </div>\r\n\r\n <!-- Expand / Collapse icon for multiple data showing in one coll-->\r\n\r\n <!-- <span\r\n *ngIf=\"\r\n (isOverflowing(cellText) &&\r\n showCellDetailsBox &&\r\n getNestedValue(row, col.field)?.length > 50) ||\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 </div>\r\n\r\n <!-- Expanded text -->\r\n <div\r\n class=\"position-absolute w-100\"\r\n *ngIf=\"isExpanded(row, col)\"\r\n [style.zIndex]=\"getZIndex(row, col)\"\r\n style=\"top: 100%; left: 0\"\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\r\n\r\n \r\n\r\n\r\n\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<div\r\n *ngIf=\"currentBreakTooltip\"\r\n class=\"custom-break-tooltip\"\r\n [style.--tooltip-x.px]=\"tooltipPosition.x\"\r\n [style.--tooltip-y.px]=\"tooltipPosition.y\"\r\n>\r\n <div class=\"break-tooltip-header\">\r\n <strong>{{ currentBreakTooltip.break_type?.data_value_name || 'Break' }}</strong>\r\n <span class=\"text-muted ms-2\">\r\n {{ currentBreakTooltip.breakInstatus === 'breakOut' ? 'Taken' : 'On Break' }}\r\n </span>\r\n </div>\r\n\r\n <div class=\"break-tooltip-body\">\r\n <div>\r\n <i class=\"bi bi-play-circle\"></i>\r\n In: {{ getTimeValue(currentBreakTooltip.break_in_time) | timezoneFormat:prefs:'time' }}\r\n </div>\r\n\r\n <div>\r\n <i class=\"bi bi-stop-circle\"></i>\r\n Out: {{ getTimeValue(currentBreakTooltip.break_out_time) | timezoneFormat:prefs:'time' }}\r\n </div>\r\n\r\n <div>\r\n <i class=\"bi bi-clock\"></i>\r\n Duration: {{ currentBreakTooltip.break_duration }} min\r\n </div>\r\n </div>\r\n</div>\r\n\r\n\r\n\r\n\r\n\r\n<!-- Short Break Tooltip -->\r\n<div\r\n *ngIf=\"currentShortBreakTooltip\"\r\n class=\"custom-break-tooltip\"\r\n [style.--tooltip-x.px]=\"tooltipPosition.x\"\r\n [style.--tooltip-y.px]=\"tooltipPosition.y\"\r\n>\r\n <div class=\"break-tooltip-header\">\r\n <strong>{{ currentShortBreakTooltip.short_break_name || 'Short Break' }}</strong>\r\n </div>\r\n\r\n <div class=\"break-tooltip-body\">\r\n <div>\r\n <i class=\"bi bi-play-circle\"></i>\r\n Start: {{ getTimeValue(currentShortBreakTooltip.start_time) | timezoneFormat:prefs:'time' }}\r\n </div>\r\n\r\n <div>\r\n <i class=\"bi bi-stop-circle\"></i>\r\n End: {{ getTimeValue(currentShortBreakTooltip.end_time) | timezoneFormat:prefs:'time' }}\r\n </div>\r\n\r\n <div>\r\n <i class=\"bi bi-clock\"></i>\r\n Duration: {{ currentShortBreakTooltip.short_break_duration }} min\r\n </div>\r\n </div>\r\n</div>\r\n\r\n\r\n\r\n\r\n<!-- Headers Action List On clicking three dots -->\r\n\r\n<ng-template #columnMenu let-col=\"col\">\r\n <div\r\n class=\"column-menu three-dots-col-menu\"\r\n [class.visually-hidden]=\"isMenueHidden\"\r\n *ngIf=\"activeCol && !isThreeDotsFilterOpen && !loading\"\r\n [style.backgroundColor]=\"dropdownsBackgroundColor\"\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\">\r\n <div\r\n *ngIf=\"columnThreedotsMunuConfig?.showFilter && !(col.is_search_able === false )\"\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)=\"updateColumnPinInSourceByField(activeCol, 'left')\"\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)=\"updateColumnPinInSourceByField(activeCol, 'right')\"\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)=\"updateColumnPinInSourceByField(activeCol, null)\"\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 && !(col.is_groupable === false)\"\r\n class=\"column-menu-item\"\r\n (click)=\"groupBy(activeCol)\"\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 *ngIf=\"isThreeDotsFilterOpen\" class=\"three-dots-col-menu position-relative\" [style.left.px]=\"-140\" >\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\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'; else textFilter\">\r\n <div class=\"filter-dropdown-section p-1\">\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm mb-2\"\r\n placeholder=\"Search...\"\r\n [(ngModel)]=\"addFilterDropdownSearch\"\r\n #filterMenueSearchInput\r\n />\r\n\r\n <div class=\"form-check mb-1\">\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n [checked]=\"isAllSideFilterOptionsSelected(col)\"\r\n (change)=\"toggleSelectAllSideFilters(col, $event)\"\r\n id=\"selectAll_{{ col.field }}\"\r\n />\r\n <label class=\"form-check-label\" for=\"selectAll_{{ col.field }}\">\r\n Select All\r\n </label>\r\n </div>\r\n\r\n <div class=\"dropdown-options\">\r\n <div\r\n class=\"form-check mb-1\"\r\n *ngFor=\"\r\n let option of col?.column_dropdown_value\r\n | filter : addFilterDropdownSearch : 'value';\r\n trackBy: trackById\r\n \"\r\n >\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n [checked]=\"\r\n col.query?._ids?.includes(option?._id || option?.id || option)\r\n \"\r\n [value]=\"option\"\r\n id=\"option_{{ col.field }}_{{\r\n option?.id || option?._id || option\r\n }}\"\r\n (change)=\"onOptionToggle(col, option)\"\r\n />\r\n <label\r\n class=\"form-check-label\"\r\n [for]=\"\r\n 'option_' +\r\n col.field +\r\n '_' +\r\n (option?.id || option?._id || option)\r\n \"\r\n >\r\n {{ option?.value || option }}\r\n </label>\r\n </div>\r\n </div>\r\n </div>\r\n </ng-container>\r\n\r\n <!-- Text Filter Section -->\r\n <ng-template #textFilter>\r\n <div class=\"filter-text-section\">\r\n <div class=\"form-group mb-2\">\r\n <select\r\n class=\"form-select form-select-sm\"\r\n [ngModel]=\"col.query.first_condition || (col.type === 'date' || col.type === 'time' ? 'equal' : 'contain')\"\r\n (ngModelChange)=\"col.query.first_condition = $event\"\r\n >\r\n <ng-container *ngIf=\"col.type === 'date' || col.type === 'time'; else textOptions\">\r\n <option value=\"equal\">Equal 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-template #textOptions>\r\n <option value=\"contain\">Contains</option>\r\n <option value=\"equal\">Equals</option>\r\n <option value=\"before\">Begins With</option>\r\n <option value=\"after\">Ends With</option>\r\n </ng-template>\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)]=\"col.query.first_value\"\r\n [min]=\"col.type == 'number' ? 0 : null\"\r\n (input)=\"col.type == 'number' && $any($event.target).value < 0 ? $any($event.target).value = 0 : null\"\r\n (keydown)=\"col.type == 'number' && $event.key === '-' ? $event.preventDefault() : null\"\r\n [class.number-input]=\"col.type == 'number'\"\r\n #filterMenueTextchInput\r\n />\r\n\r\n <ng-container >\r\n <div class=\"form-group mb-2\">\r\n <div class=\"form-check form-check-inline\">\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 />\r\n <label class=\"form-check-label\" for=\"and_{{ col.field }}\"\r\n >AND</label\r\n >\r\n </div>\r\n <div class=\"form-check form-check-inline\">\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 />\r\n <label class=\"form-check-label\" for=\"or_{{ col.field }}\"\r\n >OR</label\r\n >\r\n </div>\r\n <div class=\"form-check form-check-inline\">\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 />\r\n <label class=\"form-check-label\" for=\"none_{{ col.field }}\"\r\n >None</label\r\n >\r\n </div>\r\n </div>\r\n\r\n <ng-container *ngIf=\"col.query?.first_value && condition !== 'none'\">\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 || (col.type === 'date' || col.type === 'time' ? 'equal' : 'contain')\"\r\n (ngModelChange)=\"col.query.second_condition = $event\"\r\n >\r\n <ng-container *ngIf=\"col.type === 'date' || col.type === 'time'; else textOptionsSecond\">\r\n <option value=\"equal\">Equal 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-template #textOptionsSecond>\r\n <option value=\"contain\">Contains</option>\r\n <option value=\"equal\">Equals</option>\r\n <option value=\"before\">Begins With</option>\r\n <option value=\"after\">Ends With</option>\r\n </ng-template>\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-2\"\r\n placeholder=\"Second Value\"\r\n [(ngModel)]=\"col.query.second_value\"\r\n [min]=\"col.type == 'number' ? 0 : null\"\r\n (input)=\"col.type == 'number' && $any($event.target).value < 0 ? $any($event.target).value = 0 : null\"\r\n (keydown)=\"col.type == 'number' && $event.key === '-' ? $event.preventDefault() : null\"\r\n [class.number-input]=\"col.type == 'number'\"\r\n />\r\n </ng-container>\r\n </ng-container>\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: 22px\"\r\n (click)=\"applyFilterFromFilterRow(col)\"\r\n >\r\n Apply\r\n </div>\r\n <div\r\n class=\"btn btn-sm btn-secondary d-flex justify-content-center align-items-center w-100\"\r\n style=\"height: 22px\"\r\n (click)=\"resetSideFilter(col)\"\r\n >\r\n Reset\r\n </div>\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<!-- Side Menue -->\r\n\r\n<!-- Add this new template for accordion detail column menu -->\r\n<ng-template #detailColumnMenu let-col=\"col\" let-row=\"row\">\r\n <div\r\n class=\"column-menu three-dots-col-menu detail-column-menu\"\r\n [class.visually-hidden]=\"isDetailMenueHidden\"\r\n *ngIf=\"activeDetailCol\"\r\n [style.backgroundColor]=\"dropdownsBackgroundColor\"\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=\"columnThreedotsMunuConfig?.showAscending\"\r\n class=\"column-menu-item\"\r\n (click)=\"sortDetailAsc(activeDetailCol, row)\"\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=\"columnThreedotsMunuConfig?.showDescending\"\r\n class=\"column-menu-item\"\r\n (click)=\"sortDetailDesc(activeDetailCol, row)\"\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=\"col?.sortOrder\"\r\n class=\"column-menu-item\"\r\n (click)=\"resetDetailSort(activeDetailCol, row)\"\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\r\n <div class=\"py-2 border-below\" *ngIf=\"isColumnFilterable(col)\">\r\n <span class=\"muted-text fs-7\" style=\"margin-left: 12px\">Filter</span>\r\n <div\r\n *ngIf=\"columnThreedotsMunuConfig?.showFilter\"\r\n class=\"column-menu-item\"\r\n (click)=\"openDetailFilterMenu($event, col, row)\"\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)=\"updateDetailColumnPin(activeDetailCol, row, 'left')\"\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)=\"updateDetailColumnPin(activeDetailCol, row, 'right')\"\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)=\"updateDetailColumnPin(activeDetailCol, row, null)\"\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)=\"autosizeDetailColumn(activeDetailCol, row)\"\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)=\"autosizeAllDetailColumns(row)\"\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\r\n <!-- Choose Columns -->\r\n <div\r\n *ngIf=\"columnThreedotsMunuConfig?.showChoseColumns\"\r\n class=\"column-menu-item\"\r\n (click)=\"openDetailChooseColumns(row)\"\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)=\"resetDetailColumns(row)\"\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</ng-template>\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\"\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\">\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<!-- 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\">\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\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% - 120px); 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 <!-- Apply and Reset Buttons -->\r\n <!-- <div class=\"d-flex gap-2 mt-3 px-2\">\r\n <button\r\n class=\"btn btn-sm btn-primary d-flex justify-content-center align-items-center flex-fill\"\r\n style=\"height: 32px;\"\r\n (click)=\"applySideMenuFilters()\"\r\n >\r\n Apply\r\n </button>\r\n <button\r\n class=\"btn btn-sm btn-secondary d-flex justify-content-center align-items-center flex-fill\"\r\n style=\"height: 32px;\"\r\n (click)=\"resetSideMenuFilters()\"\r\n >\r\n Reset\r\n </button>\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 class=\"column-group d-flex align-items-center mb-2\">\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\">\r\n <span\r\n class=\"me-2 filter-icon-wrapper me-2\"\r\n (click)=\"col.expandedFilter = !col.expandedFilter\"\r\n >\r\n <span\r\n class=\"toggle-icon data-grid-svg-icon\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\r\n \"\r\n [class.rotate]=\"col.expandedFilter\"\r\n ></span>\r\n </span>\r\n\r\n <label\r\n class=\"d-flex align-items-center mb-0 w-100\"\r\n style=\"cursor: pointer\"\r\n (click)=\"col.expandedFilter = !col.expandedFilter\"\r\n >\r\n <span class=\"text-truncate fw-bold\">{{ col.header }}</span>\r\n </label>\r\n </div>\r\n\r\n <!-- Show filter when expanded -->\r\n <div *ngIf=\"col.expandedFilter\" class=\"ps-4 pe-3\">\r\n <ng-container\r\n *ngTemplateOutlet=\"sideNestedFilter; context: { col: col }\"\r\n ></ng-container>\r\n </div>\r\n </ng-container>\r\n</ng-template>\r\n\r\n<!-- Side Nested Filters -->\r\n<ng-template #sideNestedFilter let-col=\"col\">\r\n <div class=\"\">\r\n <!-- Dropdown Type -->\r\n <ng-container *ngIf=\"col.type === 'dropdown'; else textFilter\">\r\n <div class=\"p-1\">\r\n <!-- Search -->\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm mb-2\"\r\n placeholder=\"Search...\"\r\n [(ngModel)]=\"col.searchValue\"\r\n />\r\n\r\n <!-- Select All -->\r\n <div class=\"form-check mb-1 ms-1\">\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n [checked]=\"\r\n col.query?._ids?.length == col?.column_dropdown_value?.length\r\n \"\r\n (change)=\"toggleSelectAllSideFilters(col, $event)\"\r\n id=\"selectAll_{{ col.field }}\"\r\n />\r\n <label class=\"form-check-label\" for=\"selectAll_{{ col.field }}\">\r\n Select All\r\n </label>\r\n </div>\r\n\r\n <!-- Options -->\r\n <div class=\"dropdown-options\">\r\n <div\r\n class=\"form-check mb-1 ms-1\"\r\n *ngFor=\"\r\n let option of col?.column_dropdown_value\r\n | filter : addFilterDropdownSearch : 'header'\r\n \"\r\n >\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n [value]=\"option\"\r\n [checked]=\"\r\n col.query?._ids?.includes(option?._id || option?.id || option)\r\n \"\r\n (change)=\"onOptionToggle(col, option)\"\r\n id=\"option_{{ col.field }}_{{\r\n option?.id || option?._id || option\r\n }}\"\r\n />\r\n <label\r\n class=\"form-check-label\"\r\n [for]=\"\r\n 'option_' +\r\n col.field +\r\n '_' +\r\n (option?.id || option?._id || option)\r\n \"\r\n >\r\n {{ option.value || option }}\r\n </label>\r\n </div>\r\n </div>\r\n\r\n <!-- Actions -->\r\n <!-- <div class=\"d-flex gap-2 mt-2\">\r\n <div\r\n class=\"btn btn-sm btn-primary d-flex justify-content-center align-items-center\"\r\n style=\"height: 22px;\"\r\n (click)=\"applySideMenuFilters()\"\r\n >\r\n Apply\r\n </div>\r\n <div\r\n class=\"btn btn-sm btn-secondary d-flex justify-content-center align-items-center\"\r\n style=\"height: 22px;\"\r\n (click)=\"resetSideMenuFilters()\"\r\n >\r\n Reset\r\n </div>\r\n </div> -->\r\n </div>\r\n </ng-container>\r\n\r\n <!-- Text Filter Section -->\r\n <ng-template #textFilter>\r\n <div class=\"filter-text-section\">\r\n <div class=\"form-group mb-2\">\r\n <select\r\n class=\"form-select form-select-sm\"\r\n [ngModel]=\"col!.query!.first_condition || (col.type === 'date' || col.type === 'time' ? 'equal' : 'contain')\"\r\n (ngModelChange)=\"col!.query!.first_condition = $event\"\r\n >\r\n <ng-container *ngIf=\"col.type === 'date' || col.type === 'time'; else textOptions\">\r\n <option value=\"equal\">Equal 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-template #textOptions>\r\n <option value=\"contain\">Contains</option>\r\n <option value=\"equal\">Equals</option>\r\n <option value=\"before\">Begins With</option>\r\n <option value=\"after\">Ends With</option>\r\n </ng-template>\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 [min]=\"col.type == 'number' ? 0 : null\"\r\n (input)=\"col.type == 'number' && $any($event.target).value < 0 ? $any($event.target).value = 0 : null\"\r\n (keydown)=\"col.type == 'number' && $event.key === '-' ? $event.preventDefault() : null\"\r\n [class.number-input]=\"col.type == 'number'\"\r\n />\r\n\r\n <ng-container *ngIf=\"col?.query?.first_value && col?.query?.condition !== 'none'\">\r\n <div class=\"form-group mb-2\">\r\n <div class=\"form-check form-check-inline\">\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\" for=\"and_{{ col.field }}\"\r\n >AND</label\r\n >\r\n </div>\r\n <div class=\"form-check form-check-inline\">\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\" for=\"or_{{ col.field }}\"\r\n >OR</label\r\n >\r\n </div>\r\n <div class=\"form-check form-check-inline\">\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 class=\"form-check-label\" for=\"none_{{ col.field }}\"\r\n >None</label\r\n >\r\n </div>\r\n </div>\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 || (col.type === 'date' || col.type === 'time' ? 'equal' : 'contain')\"\r\n (ngModelChange)=\"col!.query.second_condition = $event\"\r\n >\r\n <ng-container *ngIf=\"col.type === 'date' || col.type === 'time'; else textOptionsSecond\">\r\n <option value=\"equal\">Equal 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-template #textOptionsSecond>\r\n <option value=\"contain\">Contains</option>\r\n <option value=\"equal\">Equals</option>\r\n <option value=\"before\">Begins With</option>\r\n <option value=\"after\">Ends With</option>\r\n </ng-template>\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-2\"\r\n placeholder=\"Second Value\"\r\n [(ngModel)]=\"col!.query.second_value\"\r\n [min]=\"col.type == 'number' ? 0 : null\"\r\n (input)=\"col.type == 'number' && $any($event.target).value < 0 ? $any($event.target).value = 0 : null\"\r\n (keydown)=\"col.type == 'number' && $event.key === '-' ? $event.preventDefault() : null\"\r\n [class.number-input]=\"col.type == 'number'\"\r\n />\r\n </ng-container>\r\n\r\n <!-- Apply and Reset Buttons -->\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: 22px\"\r\n (click)=\"applyFilterFromFilterRow(col)\"\r\n >\r\n Apply\r\n </div>\r\n <div\r\n class=\"btn btn-sm btn-secondary d-flex justify-content-center align-items-center w-100\"\r\n style=\"height: 22px\"\r\n (click)=\"resetSideFilter(col)\"\r\n >\r\n Reset\r\n </div>\r\n </div>\r\n </div>\r\n </ng-template>\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\" (click)=\"closeModalColumnPanel()\">\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\">\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 [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 [class.border-right]=\"showVerticalBorder\"\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 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 />\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 rounded-3 bg-white 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>\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 rounded-3 bg-white 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 btn btn-link\"\r\n type=\"button\"\r\n id=\"savePresetDropdown\"\r\n (click)=\"$event.stopPropagation(); toggleSubActions('save-preset')\"\r\n >\r\n Save 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 class=\"\" (click)=\"selectDefault()\">\r\n <div class=\"fw-semibold\">Default View\r\n <span\r\n *ngIf=\"tableFilterViewId === 'default'\"\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/check-blue.svg'\"\r\n class=\"me-2\"\r\n ></span>\r\n </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 === 'default'\"\r\n class=\"badge bg-light text-primary ms-2\"\r\n >Default</span\r\n >\r\n <div\r\n class=\"dropdown d-flex justify-content-end\"\r\n *ngIf=\"tableFilterViewId\"\r\n >\r\n <a\r\n href=\"javascript:void(0)\"\r\n class=\"muted-text\"\r\n data-bs-toggle=\"dropdown\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/horizontal-dots.svg'\r\n \"\r\n class=\"me-2\"\r\n ></span>\r\n </a>\r\n <ul class=\"dropdown-menu dropdown-menu-end\">\r\n <a\r\n (click)=\"actionPreset({ id: 'default' }, 'setPreset')\"\r\n class=\"dropdown-item d-flex align-items-center\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/star.svg'\"\r\n class=\"me-2\"\r\n ></span>\r\n Set as default\r\n </a>\r\n </ul>\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=\"let table of filteredList; trackBy: trackByTable\"\r\n >\r\n <!-- Item -->\r\n <div\r\n class=\"list-group-item px-0 d-flex justify-content-between align-items-center\"\r\n >\r\n <div (click)=\"selectFilter(table)\">\r\n <div class=\"fw-semibold\" style=\"cursor: pointer;\">\r\n {{ table?.name }}\r\n <!-- {{table?.is_temp}} -->\r\n <span\r\n *ngIf=\"table?.is_temp\"\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_deafult\"\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\"\r\n >Created {{ table?.createdAt | timezoneFormat:prefs:'date' }}</small\r\n >\r\n </div>\r\n\r\n <div class=\"d-flex align-items-center\">\r\n <span\r\n *ngIf=\"table?.is_deafult\"\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_deafult\">\r\n <a\r\n href=\"javascript:void(0)\"\r\n class=\"muted-text\"\r\n data-bs-toggle=\"dropdown\"\r\n id=\"dropdownMenuButton2\" data-toggle=\"dropdown\" aria-haspopup=\"true\" aria-expanded=\"false\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/horizontal-dots.svg'\r\n \"\r\n class=\"me-2\"\r\n ></span>\r\n </a>\r\n <ul class=\"dropdown-menu dropdown-menu-end set-default-preset\" aria-labelledby=\"dropdownMenuButton2\">\r\n <a\r\n [class.d-none]=\"confirmDelete\"\r\n (click)=\"actionPreset(table, 'setPreset')\"\r\n class=\"dropdown-item d-flex align-items-center\"\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 </a>\r\n\r\n <!-- Delete with confirmation -->\r\n <ng-container *ngIf=\"!confirmDelete; else confirmBlock\">\r\n <a\r\n (click)=\"confirmDelete = true\"\r\n class=\"dropdown-item d-flex align-items-center text-danger\"\r\n >\r\n <span\r\n style=\"margin-top: -4px\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/trash-red.svg'\r\n \"\r\n class=\"me-2\"\r\n ></span>\r\n Delete\r\n </a>\r\n </ng-container>\r\n\r\n <!-- Confirmation block -->\r\n </ul>\r\n <ng-template #confirmBlock>\r\n <div class=\"dropdown-item\"><b>Delete preset</b></div>\r\n <div class=\"dropdown-item text-center\">\r\n <div class=\"mb-2\">\r\n Are you sure you want to delete the <br />\r\n <b>\u201C{{ table?.name }}\u201D</b> preset?\r\n </div>\r\n <button\r\n class=\"btn btn-sm btn-light me-2\"\r\n (click)=\"confirmDelete = false\"\r\n >\r\n Cancel\r\n </button>\r\n <button\r\n class=\"btn btn-sm btn-danger delete-preset\"\r\n (click)=\"actionPreset(table, 'deletePreset')\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/trash-red.svg'\r\n \"\r\n class=\"confirm-preset-delete\"\r\n ></span>\r\n Delete\r\n </button>\r\n </div>\r\n </ng-template>\r\n </div>\r\n </div>\r\n </div>\r\n <!-- Item End Here -->\r\n </div>\r\n\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\">Save preset</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\">\r\n <ng-container *ngIf=\"!closeDropdown.preset.loading && (!tableFilterViewId || tableFilterViewId === 'default')\"\r\n >Save</ng-container\r\n >\r\n <ng-container *ngIf=\"!closeDropdown.preset.loading && tableFilterViewId && tableFilterViewId !== 'default'\"\r\n >Update</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 </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 rounded-3 bg-white 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\"\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=\"\r\n max-height: calc(100vh - 300px);\r\n overflow: auto;\r\n scrollbar-width: thin;\r\n \"\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 type=\"checkbox\"\r\n id=\"show_hide_all\"\r\n class=\"form-check-input\"\r\n [checked]=\"areAllNonMandatoryVisible()\"\r\n (change)=\"toggleAllVisibleColumns()\"\r\n />\r\n <label for=\"show_hide_all\" class=\"form-check-label fw-semibold\">Show/Hide All</label>\r\n </div>\r\n </div>\r\n <!-- <div class=\"d-flex align-items-center mb-2\" *ngIf=\"hasAnyVisibleColumn\">\r\n <input\r\n type=\"checkbox\"\r\n class=\"form-check-input me-2\"\r\n [checked]=\"areAllNonMandatoryVisible()\"\r\n (change)=\"toggleAllVisibleColumns()\"\r\n />\r\n <label class=\"form-check-label fw-semibold\">Show All</label>\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 && !isMandatory(col)\"\r\n class=\"d-flex align-items-center cursor-pointer\"\r\n (click)=\"toggleColumnVisibility(col, false)\"\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 && isMandatory(col)) || (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\"\r\n *ngIf=\"hasAnyInVisibleColumn\"\r\n >\r\n Hide in table\r\n </div>\r\n <div class=\"d-flex align-items-center mb-2\" *ngIf=\"hasAnyInVisibleColumn\">\r\n <input\r\n type=\"checkbox\"\r\n id=\"hide_show_all\"\r\n class=\"form-check-input me-2\"\r\n [checked]=\"areAllNonMandatoryHidden()\"\r\n (change)=\"toggleAllInvisibleColumns()\"\r\n />\r\n <label class=\"form-check-label fw-semibold\">Hide All</label>\r\n </div> -->\r\n\r\n \r\n\r\n\r\n\r\n <div class=\"muted-text show-hide-table-label d-flex justify-content-between\" *ngIf=\"hasAnyInVisibleColumn\">\r\n Hide in table\r\n <div class=\"form-check\">\r\n <input\r\n type=\"checkbox\"\r\n id=\"hide_show_all\"\r\n class=\"form-check-input\"\r\n [checked]=\"areAllNonMandatoryHidden()\"\r\n (change)=\"toggleAllInvisibleColumns()\"\r\n />\r\n <label for=\"hide_show_all\" class=\"form-check-label fw-semibold\">Hide/Show All</label>\r\n </div>\r\n </div>\r\n <div class=\"list-group list-group-flush\">\r\n <ng-container *ngFor=\"let col of columns; trackBy: trackByField\">\r\n <div\r\n *ngIf=\"!col.is_visible\"\r\n class=\"list-group-item border-0 px-0 d-flex justify-content-between align-items-center\"\r\n >\r\n <div class=\"d-flex gap-1\">\r\n <div>\r\n <span\r\n *ngIf=\"!col?.pinned\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/grip-vertical.svg'\r\n \"\r\n class=\"data-grid-svg-icon cursor-grap\"\r\n (mousedown)=\"$event.preventDefault()\"\r\n ></span>\r\n <span\r\n *ngIf=\"col?.pinned\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/pin-blue.svg'\r\n \"\r\n class=\"data-grid-svg-icon cursor-grap\"\r\n (mousedown)=\"$event.preventDefault()\"\r\n ></span>\r\n </div>\r\n <div class=\"fw-semibold\">\r\n {{ col.header }}\r\n </div>\r\n </div>\r\n <div\r\n class=\"d-flex align-items-center cursor-pointer\"\r\n (click)=\"toggleColumnVisibility(col, true)\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/eye-cross.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n </div>\r\n </div>\r\n </ng-container>\r\n </div>\r\n\r\n <!-- Item End Here -->\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template #filterColumns let-col=\"column\">\r\n <div\r\n @slideToggle\r\n *ngIf=\"!isFilterOpen && activeTopButton == 'filter-columns'\"\r\n (click)=\"$event.stopPropagation()\"\r\n class=\"shadow rounded-3 bg-white actions-dropdown mt-1 show shadow custom-menu table-layout filter-columns\"\r\n style=\"width: 280px; right: unset; max-width: 230px\"\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\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'\"\r\n (click)=\"$event.stopPropagation()\"\r\n class=\"shadow rounded-3 bg-white actions-dropdown mt-1 show shadow custom-menu table-layout filter-columns\"\r\n style=\"width: 280px; right: unset; max-width: 230px\"\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\"\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 (ngModelChange)=\"selectedFilterOptions.length === 0 ? condition = 'none' : null\"\r\n />\r\n </div>\r\n </div>\r\n <div\r\n class=\"list-group list-group-flush\"\r\n style=\"max-height: calc(100vh - 600px); overflow: auto\"\r\n >\r\n <ng-container\r\n *ngFor=\"\r\n let col of selectedColumnForFilter.column_dropdown_value\r\n | filter : searchTextForFilterDropDown : 'value';\r\n let i = index\r\n \"\r\n >\r\n <div\r\n class=\"list-group-item border-0 px-2 d-flex justify-content-between align-items-center dropdown-item cursor-pointer\"\r\n >\r\n <div class=\"form-check\">\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n [id]=\"i\"\r\n [checked]=\"currentFilterSelectedIds.has(col.id || col._id || col)\"\r\n (change)=\"toggleSelectionInFilter(col)\"\r\n />\r\n <label class=\"form-check-label fw-semibold\" [for]=\"i\">\r\n {{ col?.value || col?.name || col }}\r\n </label>\r\n </div>\r\n </div>\r\n </ng-container>\r\n </div>\r\n <div\r\n class=\"d-flex justify-content-center gap-2 px-2 border-top\"\r\n style=\"height: 38px\"\r\n >\r\n <button\r\n type=\"button\"\r\n style=\"height: 32px\"\r\n class=\"btn btn-outline-secondary btn-light border w-100 d-flex align-items-center justify-content-center mt-1 btn-light\"\r\n (click)=\"$event.stopPropagation(); resetFilterChanges()\"\r\n >\r\n <span>Cancel</span>\r\n </button>\r\n <button\r\n type=\"button\"\r\n style=\"height: 32px\"\r\n class=\"btn btn-primary w-100 d-flex align-items-center justify-content-center mt-1\"\r\n (click)=\"applyDropdownFilter()\"\r\n >\r\n <span style=\"margin-top: -2px\">Save</span>\r\n </button>\r\n </div>\r\n </div>\r\n\r\n <!-- For Text fields and number fields-->\r\n\r\n <div\r\n @slideToggle\r\n *ngIf=\"\r\n isFilterOpen &&\r\n (selectedColumnForFilter.type == 'string' ||\r\n selectedColumnForFilter.type == 'number' ||\r\n selectedColumnForFilter.type == 'date')\r\n \"\r\n (click)=\"$event.stopPropagation()\"\r\n class=\"shadow rounded-3 bg-white actions-dropdown mt-1 show shadow custom-menu table-layout filter-columns\"\r\n style=\"width: 280px; right: unset; max-width: 230px\"\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\"\r\n [(ngModel)]=\"firstCondition\"\r\n >\r\n <ng-container *ngIf=\"selectedColumnForFilter.type === 'date' || selectedColumnForFilter.type === 'time'; else textOptions\">\r\n <option value=\"equal\">Equal 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-template #textOptions>\r\n <option value=\"equal\">Equals</option>\r\n <!-- <option value=\"not_equal\">Not Equals</option> -->\r\n <option value=\"contain\">Contains</option>\r\n <option value=\"before\">Begins With</option>\r\n <option value=\"after\">Ends With</option>\r\n </ng-template>\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]=\"\r\n selectedColumnForFilter.type == 'string'\r\n ? 'text'\r\n : selectedColumnForFilter.type\r\n \"\r\n [(ngModel)]=\"firstValue\"\r\n [min]=\"selectedColumnForFilter.type == 'number' ? 0 : null\"\r\n [class.number-input]=\"selectedColumnForFilter.type == 'number'\"\r\n (input)=\"selectedColumnForFilter.type == 'number' && $any($event.target).value < 0 ? $any($event.target).value = 0 : null\"\r\n (ngModelChange)=\"!firstValue ? condition = 'none' : null\"\r\n (keydown)=\"selectedColumnForFilter.type == 'number' && $event.key === '-' ? $event.preventDefault() : null\"\r\n />\r\n </div>\r\n <div class=\"d-flex my-3\">\r\n <div class=\"form-check form-check-inline\">\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\" for=\"logicalAnd\">AND</label>\r\n </div>\r\n\r\n <div class=\"form-check form-check-inline\">\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\" for=\"logicalOr\">OR</label>\r\n </div>\r\n\r\n <div class=\"form-check form-check-inline\">\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\" for=\"logicalNone\">None</label>\r\n </div>\r\n </div>\r\n\r\n <div *ngIf=\"firstValue && condition !== 'none'\">\r\n <div class=\"my-3\">\r\n <!-- Second condition select -->\r\n <select\r\n class=\"form-select form-select-sm\"\r\n [(ngModel)]=\"secondCondition\"\r\n >\r\n <ng-container *ngIf=\"selectedColumnForFilter.type === 'date' || selectedColumnForFilter.type === 'time'; else textOptionsSecond\">\r\n <option value=\"equal\">Equal 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-template #textOptionsSecond>\r\n <option value=\"equal\">Equals</option>\r\n <!-- <option value=\"not_equal\">Not Equals</option> -->\r\n <option value=\"contain\">Contains</option>\r\n <option value=\"before\">Begins With</option>\r\n <option value=\"after\">Ends With</option>\r\n </ng-template>\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 [(ngModel)]=\"secondValue\"\r\n [min]=\"selectedColumnForFilter.type == 'number' ? 0 : null\"\r\n [class.number-input]=\"selectedColumnForFilter.type == 'number'\"\r\n (input)=\"selectedColumnForFilter.type == 'number' && $any($event.target).value < 0 ? $any($event.target).value = 0 : null\"\r\n (keydown)=\"selectedColumnForFilter.type == 'number' && $event.key === '-' ? $event.preventDefault() : null\"\r\n />\r\n </div>\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 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 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</ng-template>\r\n\r\n<!-- Detail Filter Menu -->\r\n <div\r\n *ngIf=\"activeAccordionFilterMenu && detailFilterMenuPosition\"\r\n class=\"position-absolute shadow rounded-3 bg-white detail-filter-menu\"\r\n [style.left.px]=\"detailFilterMenuPosition.x\"\r\n [style.top.px]=\"detailFilterMenuPosition.y\"\r\n (click)=\"$event.stopPropagation()\"\r\n >\r\n <div class=\"px-3 border-below py-1 pb-2 d-flex ps-1\">\r\n <span\r\n (click)=\"closeDetailFilterMenu()\"\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>{{ activeDetailFilterCol?.header }}</b>\r\n </div>\r\n\r\n <!-- Text Filter -->\r\n <div *ngIf=\"detailFilterType === 'string'\" 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\"\r\n [(ngModel)]=\"detailFilterCondition\"\r\n >\r\n <option value=\"contain\">Contains</option>\r\n <option value=\"equal\">Equals</option>\r\n <option value=\"before\">Begins With</option>\r\n <option value=\"after\">Ends With</option>\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 value\"\r\n [(ngModel)]=\"detailFilterValue\"\r\n (keydown.enter)=\"applyDetailFilter()\"\r\n />\r\n </div>\r\n </div>\r\n\r\n <!-- Date Filter -->\r\n <div *ngIf=\"detailFilterType === 'date'\" 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\"\r\n [(ngModel)]=\"detailFilterCondition\"\r\n >\r\n <option value=\"equal\">Equal to</option>\r\n <option value=\"before\">Before</option>\r\n <option value=\"after\">After</option>\r\n </select>\r\n </div>\r\n <div class=\"mb-2\">\r\n <input\r\n type=\"date\"\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Select date\"\r\n [(ngModel)]=\"detailFilterDateValue\"\r\n (keydown.enter)=\"applyDetailFilter()\"\r\n />\r\n </div>\r\n </div>\r\n\r\n <!-- Time Filter -->\r\n <div *ngIf=\"detailFilterType === 'time'\" 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\"\r\n [(ngModel)]=\"detailFilterCondition\"\r\n >\r\n <option value=\"equal\">Equal to</option>\r\n <option value=\"before\">Before</option>\r\n <option value=\"after\">After</option>\r\n </select>\r\n </div>\r\n <div class=\"mb-2\">\r\n <input\r\n type=\"time\"\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Select time\"\r\n [(ngModel)]=\"detailFilterTimeValue\"\r\n (keydown.enter)=\"applyDetailFilter()\"\r\n />\r\n </div>\r\n </div>\r\n\r\n <!-- Dropdown Filter -->\r\n <div *ngIf=\"detailFilterType === 'dropdown'\" class=\"col-12 position-relative p-2 text-filter\">\r\n <div class=\"mb-2\">\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Search options...\"\r\n [(ngModel)]=\"detailFilterSearch\"\r\n (input)=\"filterDetailDropdownOptions()\"\r\n />\r\n </div>\r\n <div class=\"dropdown-options\" style=\"max-height: 150px; overflow-y: auto;\">\r\n <div\r\n *ngFor=\"let option of filteredDetailDropdownOptions; let i = index\"\r\n class=\"form-check mb-1 ms-1\"\r\n >\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n [id]=\"'detail-filter-option-' + i\"\r\n [checked]=\"detailSelectedFilterOptions.includes(option._id || option.id || option.value)\"\r\n (change)=\"toggleDetailFilterOption(option)\"\r\n />\r\n <label\r\n class=\"form-check-label\"\r\n [for]=\"'detail-filter-option-' + i\"\r\n >\r\n {{ option.value || option.name || option }}\r\n </label>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- <div class=\"d-flex gap-2\">\r\n <button\r\n type=\"button\"\r\n class=\"btn btn-primary w-100 d-flex align-items-center justify-content-center mt-1\"\r\n (click)=\"applyDetailFilter()\"\r\n >\r\n <span>Apply</span>\r\n </button>\r\n <button\r\n type=\"button\"\r\n class=\"btn btn-danger w-100 d-flex align-items-center justify-content-center mt-1\"\r\n (click)=\"resetDetailFilter()\"\r\n >\r\n <span>Reset</span>\r\n </button>\r\n \r\n</div> -->\r\n\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: 22px\"\r\n (click)=\"applyDetailFilter()\"\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: 22px\"\r\n (click)=\"resetDetailFilter()\"\r\n >\r\n Reset\r\n </div>\r\n </div>\r\n</div>\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 >\r\n <ng-container *ngIf=\"!isEditing(row, col)\">\r\n <div\r\n *ngIf=\"!isArray\"\r\n class=\"full-text-content\"\r\n (dblclick)=\"$event.stopPropagation(); $event.preventDefault(); enableEdit(row, col)\"\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 {{ item?.department_name || item?.roleName || \"-\" }}\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 #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\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 align-items-center w-100 cell-content image-placeholder cursor-pointer position-relative\"\r\n [title]=\"getEmployeeNameTitle(row)\"\r\n (click)=\"onEmployeeClick(row)\"\r\n >\r\n <!-- Blue dot for manual logs -->\r\n <span\r\n *ngIf=\"row?.manually_logs && row.manually_logs.length > 0\"\r\n class=\"manual-logs-indicator\"\r\n (mouseenter)=\"openManualLogsModal($event, row)\"\r\n (mouseleave)=\"closeManualLogsModal()\"\r\n ></span>\r\n <ng-container\r\n *ngIf=\"\r\n row?.User?.logo || row?.User?.profile_pictures?.length || row?.logo || row?.profile_pictures?.length || row?.assetImage || row?.invoice?.invoice_image;\r\n else placeholder\r\n \"\r\n >\r\n <span class=\"pic\">\r\n <img\r\n [width]=\"rowHeight - 12\"\r\n [height]=\"rowHeight - 12\"\r\n [src]=\"row?.User?.profile_pictures?.[4]?.path || row?.User?.logo || row?.profile_pictures?.[4]?.path || row?.logo || row?.assetImage || row?.invoice?.invoice_image\"\r\n alt=\"icon\"\r\n />\r\n </span>\r\n </ng-container>\r\n\r\n <ng-template #placeholder>\r\n <span\r\n [ngClass]=\"getDynamicClass(row?.User?.full_name || 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 >\r\n {{ getInitials(row?.User?.full_name || row?.full_name) }}\r\n </span>\r\n </ng-template>\r\n </span>\r\n</ng-template>\r\n\r\n<!-- Cell Content Template for Card View -->\r\n<ng-template #cellContent let-row=\"row\" let-parentRow=\"parentRow\" let-col=\"col\">\r\n <ng-container [ngSwitch]=\"col.type\">\r\n <!-- String/Text -->\r\n <ng-container *ngSwitchCase=\"'string'\">\r\n {{ getNestedValue(row, col.field) || getNestedValue(parentRow, col.field) || '-' }}\r\n </ng-container>\r\n\r\n <!-- Number -->\r\n <ng-container *ngSwitchCase=\"'number'\">\r\n {{ getNestedValue(row, col.field) || getNestedValue(parentRow, col.field) || '-' }}\r\n </ng-container>\r\n\r\n <!-- Date -->\r\n <ng-container *ngSwitchCase=\"'date'\">\r\n {{ getNestedValue(row, col.field) || getNestedValue(parentRow, col.field) ? (getNestedValue(row, col.field) || getNestedValue(parentRow, col.field) | timezoneFormat:prefs:'date') : '-' }}\r\n </ng-container>\r\n\r\n <!-- Time -->\r\n <ng-container *ngSwitchCase=\"'time'\">\r\n {{ (getNestedValue(row, col.field) || getNestedValue(parentRow, col.field)) !== null && (getNestedValue(row, col.field) || getNestedValue(parentRow, col.field)) !== undefined ? ((getTimeValue(getNestedValue(row, col.field) || getNestedValue(parentRow, col.field)) | timezoneFormat:prefs:'time')) : '-' }}\r\n </ng-container>\r\n\r\n <!-- Boolean -->\r\n <ng-container *ngSwitchCase=\"'boolean'\">\r\n <span class=\"badge\" [class]=\"(getNestedValue(row, col.field) || getNestedValue(parentRow, col.field) === true || getNestedValue(row, col.field) || getNestedValue(parentRow, col.field) === 'true') ? 'badge-success' : 'badge-secondary'\">\r\n {{ (getNestedValue(row, col.field) || getNestedValue(parentRow, col.field) === true || getNestedValue(row, col.field) || getNestedValue(parentRow, col.field) === 'true') ? 'Yes' : 'No' }}\r\n </span>\r\n </ng-container>\r\n\r\n <!-- <div *ngSwitchCase=\"'is_payroll_processed'\" class=\"d-flex justify-content-start flex-column pointer position-relative\" >\r\n <span class=\"popover__wrapper\" >none\r\n {{ row.is_payroll_processed ? 'Yes' : 'No' }}\r\n </span>\r\n </div> -->\r\n\r\n <!-- Status -->\r\n <ng-container *ngSwitchCase=\"'status'\">\r\n <span class=\"badge\" [class]=\"getStatusBadgeClass(getNestedValue(row, col.field) || getNestedValue(parentRow, col.field))\">\r\n {{ transformStatus(getNestedValue(row, col.field) || getNestedValue(parentRow, col.field)) || '-' }}\r\n </span>\r\n </ng-container>\r\n\r\n <!-- Array -->\r\n <ng-container *ngSwitchCase=\"'array'\">\r\n <ng-container *ngIf=\"isArray(getNestedValue(row, col.field) || getNestedValue(parentRow, col.field))\">\r\n <ng-container *ngIf=\"col.field === 'breaks' || col.header?.toLowerCase().includes('break')\">\r\n <app-badge-overflow\r\n [badges]=\"getBreakBadges(getNestedValue(row, col.field) || getNestedValue(parentRow, col.field) || [])\"\r\n [maxWidth]=\"col.width || 200\"\r\n (badgeMouseEnter)=\"showBreakTooltip($event.event, $event.badge.data)\"\r\n (badgeMouseLeave)=\"hideBreakTooltip()\"\r\n (overflowCountClick)=\"onBadgeOverflowCountClick(col)\">\r\n </app-badge-overflow>\r\n </ng-container>\r\n <ng-container *ngIf=\"!(col.field === 'breaks' || col.header?.toLowerCase().includes('break'))\">\r\n {{ (getNestedValue(row, col.field) || getNestedValue(parentRow, col.field) || []).length }} items\r\n </ng-container>\r\n </ng-container>\r\n <ng-container *ngIf=\"!isArray(getNestedValue(row, col.field) || getNestedValue(parentRow, col.field))\">\r\n {{ getNestedValue(row, col.field) || getNestedValue(parentRow, col.field) || '-' }}\r\n </ng-container>\r\n </ng-container>\r\n\r\n <!-- Default -->\r\n <ng-container *ngSwitchDefault>\r\n {{ getNestedValue(row, col.field) || getNestedValue(parentRow, col.field) || '-' }}\r\n </ng-container>\r\n \r\n </ng-container>\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 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<div\r\n [style.bottom.px]=\"footerRowHeight + 50\"\r\n *ngIf=\"selectedRows.size > 0 && showTaskbar\"\r\n class=\"taskbar\"\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 {{ config?.paginationParams?.totalItems }} Total\r\n </span>\r\n <div class=\"action-buttons\">\r\n <ng-container *ngFor=\"let action of taskbarActions; let i = index\">\r\n <span\r\n class=\"action-btn verified btn {{ action }}\"\r\n (click)=\"action === 'Export' ? onExportClick() : action === 'Delete' ? onDeleteClick() : onVerifyClick(action)\"\r\n >{{ action }}</span\r\n >\r\n <span\r\n *ngIf=\"taskbarActions.length > 1 && i !== taskbarActions.length - 1\"\r\n class=\"separator\"\r\n >|</span\r\n >\r\n </ng-container>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<!-- Detail Row Choose Columns Modal -->\r\n<div *ngIf=\"showDetailColumnPanel\" 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=\"detailModalColumnPannel\"></ng-container>\r\n </div>\r\n</div>\r\n\r\n<!-- Short Leave Tooltip Modal -->\r\n<div *ngIf=\"showShortLeaveTooltipModal\" \r\n class=\"custom-break-tooltips\" \r\n [style.--tooltip-x.px]=\"shortLeaveTooltipPosition.x\" \r\n [style.--tooltip-y.px]=\"shortLeaveTooltipPosition.y\"\r\n (mouseenter)=\"preventShortLeaveTooltipHide()\" \r\n (mouseleave)=\"hideShortLeaveTooltip()\">\r\n <div class=\"modal-body\">\r\n <div class=\"table-responsive\">\r\n <table class=\"table table-striped text-dark\">\r\n <thead>\r\n <tr>\r\n <th>Leave Type</th>\r\n <th>Start Time</th>\r\n <th>End Time</th>\r\n <th>Duration (min)</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <tr *ngFor=\"let item of currentShortLeaveData\">\r\n <td>{{ item.leave_type || 'N/A' }}</td>\r\n <td>{{ item.star_time || 'N/A' }}</td>\r\n <td>{{ item.end_time || 'N/A' }}</td>\r\n <td>{{ item.minutes || 'N/A' }}</td>\r\n </tr>\r\n </tbody>\r\n </table>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<!-- Tooltip for accordion manual logs -->\r\n<!-- Tooltip for accordion manual logs -->\r\n<div *ngIf=\"showManualLogsTooltipModal\" class=\"custom-break-tooltips\"\r\n [style.--tooltip-x.px]=\"manualLogsTooltipPosition.x\"\r\n [style.--tooltip-y.px]=\"manualLogsTooltipPosition.y\"\r\n (mouseenter)=\"preventManualLogsTooltipHide()\"\r\n (mouseleave)=\"hideManualLogsTooltip()\">\r\n\r\n <div class=\"modal-body\">\r\n <div class=\"table-responsive\">\r\n <table class=\"table table-striped text-dark\">\r\n <thead>\r\n <tr>\r\n <th>Name</th>\r\n <th>Date/Time</th>\r\n <th>Previous</th>\r\n <th>Updated</th>\r\n <th>Status</th>\r\n <th>Remarks</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <ng-container *ngFor=\"let item of selectedManualLogs; let i = index\">\r\n <tr>\r\n <td>{{ item?.updated_by?.full_name || selectedManualLogsRow?.User?.full_name }}</td>\r\n <td>{{ item?.log_date && item.log_date !== '--' ? (item.log_date | timezoneFormat:prefs:'date') : (selectedManualLogsRow?.attendanceDate && selectedManualLogsRow?.attendanceDate !== '--' ? (selectedManualLogsRow?.attendanceDate | timezoneFormat:prefs:'date') : '-') }}</td>\r\n <td>{{ formatLogState(item?.log_details?.previous_state) }}</td>\r\n <td>{{ formatLogState(item?.log_details?.updated_state) }}</td>\r\n <td>{{ item?.log_details?.status ? transformStatus(item.log_details.status) : (item.log_details?.status || '-') }}</td>\r\n <td>{{ item?.log_details?.remarks || item?.remarks || selectedManualLogsRow?.message || '-' }}</td>\r\n </tr>\r\n </ng-container>\r\n\r\n <!-- Fallback for empty manual logs -->\r\n <tr *ngIf=\"!selectedManualLogs || selectedManualLogs.length === 0\">\r\n <td colspan=\"6\" class=\"text-center\">No manual logs available</td>\r\n </tr>\r\n </tbody>\r\n </table>\r\n </div>\r\n </div>\r\n </div>\r\n<!-- </div> -->\r\n\r\n<ng-template #detailModalColumnPannel>\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 Detail Columns\r\n <span class=\"filter-icon-wrapper\" (click)=\"closeDetailColumnPanel()\">\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 <input\r\n type=\"checkbox\"\r\n class=\"form-check-input me-2\"\r\n [checked]=\"allDetailColumnsSelected()\"\r\n (change)=\"toggleAllDetailColumnsVisibility()\"\r\n />\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Search detail columns...\"\r\n [(ngModel)]=\"choseColumnsSearch\"\r\n />\r\n </div>\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 (currentDetailRowForColumnSelection?.details?.columns || [])\r\n | filter : choseColumnsSearch : 'header';\r\n trackBy: trackByField\r\n \"\r\n >\r\n <div class=\"d-flex align-items-center mb-2\">\r\n <input\r\n type=\"checkbox\"\r\n class=\"form-check-input me-2\"\r\n [checked]=\"col.is_visible !== false\"\r\n (change)=\"toggleDetailColumnVisibility(col, !col.is_visible)\"\r\n [id]=\"'detail_col_' + col.field\"\r\n />\r\n <label\r\n class=\"d-flex align-items-center mb-0 w-100\"\r\n [for]=\"'detail_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 </div>\r\n </div>\r\n <!-- <div class=\"px-3 py-2 border-top d-flex justify-content-end\">\r\n <button class=\"btn btn-sm btn-link\" (click)=\"resetDetailColumnsInModal()\">Reset</button>\r\n </div> -->\r\n </div>\r\n</ng-template>\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n", styles: ["@charset \"UTF-8\";@keyframes fadeInUp{0%{opacity:0;transform:translateY(8px)}to{opacity:1;transform:translateY(0)}}@keyframes fadeInScale{0%{opacity:0;transform:scale(.95)}to{opacity:1;transform:scale(1)}}@keyframes slideInRight{0%{opacity:0;transform:translate(16px)}to{opacity:1;transform:translate(0)}}@keyframes pulse{0%{transform:scale(1)}50%{transform:scale(1.02)}to{transform:scale(1)}}@keyframes shimmer{0%{background-position:-200px 0}to{background-position:calc(200px + 100%) 0}}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.loading-overlay{animation:fadeInScale .25s cubic-bezier(.4,0,.2,1);transform:translateZ(0)}.loading-overlay .spinner-border{animation:spin 1s linear infinite}.data-grid-table-wrapper{height:100%;width:100%;border:1px solid #d9d9db;border-radius:12px;box-shadow:none!important;position:relative;animation:fadeInScale .35s cubic-bezier(.4,0,.2,1);transform:translateZ(0)}.data-grid-table-wrapper[data-theme=white]{border-color:#d9d9db;background-color:#f6f8ff;color:#000}.data-grid-table-wrapper[data-theme=white] *,.data-grid-table-wrapper[data-theme=white] *:before,.data-grid-table-wrapper[data-theme=white] *:after{color:#000!important}.data-grid-table-wrapper[data-theme=white] ::selection{background-color:#007bff!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=white] ::-moz-selection{background-color:#007bff!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=white] .data-grid-header-wrapper{background-color:#f8f9fa;color:#000!important}.data-grid-table-wrapper[data-theme=white] .data-grid-body-wrapper{background-color:#f6f8ff;box-shadow:none!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .data-grid-row{border-bottom-color:#d9d9db;box-shadow:none!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .data-grid-row:nth-child(2n){background-color:#f8f9fa!important}.data-grid-table-wrapper[data-theme=white] .data-grid-row:nth-child(odd){background-color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=white] .data-grid-row:hover{background-color:#007bff1a!important}.data-grid-table-wrapper[data-theme=white] .selected-cell,.data-grid-table-wrapper[data-theme=white] .row-selected{background-color:#e3f2fd!important}.data-grid-table-wrapper[data-theme=white] .cell,.data-grid-table-wrapper[data-theme=white] .header-cell,.data-grid-table-wrapper[data-theme=white] .data-grid-row,.data-grid-table-wrapper[data-theme=white] .data-grid-header,.data-grid-table-wrapper[data-theme=white] .cell-content,.data-grid-table-wrapper[data-theme=white] .full-text-content,.data-grid-table-wrapper[data-theme=white] .circle-value,.data-grid-table-wrapper[data-theme=white] .pic,.data-grid-table-wrapper[data-theme=white] .image-placeholder,.data-grid-table-wrapper[data-theme=white] .s-no,.data-grid-table-wrapper[data-theme=white] .fw-500{color:#000!important}.data-grid-table-wrapper[data-theme=white] span,.data-grid-table-wrapper[data-theme=white] div,.data-grid-table-wrapper[data-theme=white] p,.data-grid-table-wrapper[data-theme=white] td,.data-grid-table-wrapper[data-theme=white] th,.data-grid-table-wrapper[data-theme=white] label,.data-grid-table-wrapper[data-theme=white] a:not(.text-primary){color:#000!important}.data-grid-table-wrapper[data-theme=white] svg,.data-grid-table-wrapper[data-theme=white] svg path,.data-grid-table-wrapper[data-theme=white] svg circle,.data-grid-table-wrapper[data-theme=white] svg rect,.data-grid-table-wrapper[data-theme=white] svg polygon{color:#000!important;fill:#000!important;stroke:#000!important}.data-grid-table-wrapper[data-theme=white] .data-grid-svg-icon{color:#000!important}.data-grid-table-wrapper[data-theme=white] .data-grid-svg-icon path{stroke:#000!important;fill:#000!important}.data-grid-table-wrapper[data-theme=white] .badge.badge-danger{background-color:#ea5353!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=white] .badge.badge-success{background-color:#84ca81!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=white] .badge.badge-warning{background-color:#fff3dc!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .badge.badge-info{background-color:#e8fbfd!important;color:#00bad1!important}.data-grid-table-wrapper[data-theme=white] .context-menu{background:#f6f8ff;border-color:#d9d9db;color:#000!important}.data-grid-table-wrapper[data-theme=white] .context-menu li{color:#000!important}.data-grid-table-wrapper[data-theme=white] .context-menu li:hover{background-color:#007bff1a!important}.data-grid-table-wrapper[data-theme=white] .custom-tooltip,.data-grid-table-wrapper[data-theme=white] .popover__content,.data-grid-table-wrapper[data-theme=white] .custom-break-tooltip{background:#f6f8ff!important;border-color:#d9d9db!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .actions-dropdown,.data-grid-table-wrapper[data-theme=white] .custom-menu{background-color:#f6f8ff!important;border-color:#d9d9db!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .actions-dropdown .dropdown-item,.data-grid-table-wrapper[data-theme=white] .custom-menu .dropdown-item{color:#000!important}.data-grid-table-wrapper[data-theme=white] .actions-dropdown .dropdown-item:hover,.data-grid-table-wrapper[data-theme=white] .custom-menu .dropdown-item:hover{background-color:#007bff1a!important}.data-grid-table-wrapper[data-theme=white] .taskbar .selected-rows-action-bar{background-color:#343a40!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=white] .taskbar .selected-rows-action-bar .action-btn{color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=white] .manual-logs-modal .modal-header{background:linear-gradient(135deg,#343a40,#495057)!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=white] .manual-logs-modal .modal-header .modal-title{color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=white] .manual-logs-modal .modal-body{background-color:#f6f8ff!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .manual-logs-modal .modal-body .table{color:#000!important}.data-grid-table-wrapper[data-theme=white] .manual-logs-modal .modal-body .table thead th{background:linear-gradient(135deg,#f8f9fa,#e9ecef)!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .manual-logs-modal .modal-body .table tbody tr{color:#000!important}.data-grid-table-wrapper[data-theme=white] .manual-logs-modal .modal-body .table tbody tr:nth-child(2n){background-color:#f8f9fa!important}.data-grid-table-wrapper[data-theme=white] .manual-logs-modal .modal-body .table tbody tr:hover{background-color:#007bff1a!important}.data-grid-table-wrapper[data-theme=white] .manual-logs-modal .modal-body .table tbody tr td{color:#000!important;border-color:#d9d9db!important}.data-grid-table-wrapper[data-theme=white] .form-control,.data-grid-table-wrapper[data-theme=white] .form-select{background-color:#f6f8ff!important;border-color:#d9d9db!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .form-control::placeholder,.data-grid-table-wrapper[data-theme=white] .form-select::placeholder{color:#6c757d!important}.data-grid-table-wrapper[data-theme=white] .form-control option,.data-grid-table-wrapper[data-theme=white] .form-select option{background-color:#f6f8ff!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .filter-serach-inpt{background-color:#f6f8ff!important;border-color:#d9d9db!important}.data-grid-table-wrapper[data-theme=white] .filter-serach-inpt input{background-color:#f6f8ff!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .active-filters{background-color:#f8f9fa!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .custom-modal-overlay .custom-modal-content{background-color:#f6f8ff!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .circle-value{background-color:#f8f9fa!important;border-color:#d9d9db!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .pagination-container,.data-grid-table-wrapper[data-theme=white] .page-size,.data-grid-table-wrapper[data-theme=white] .page-info,.data-grid-table-wrapper[data-theme=white] .page-buttons{color:#000!important}.data-grid-table-wrapper[data-theme=white] .pagination-container select,.data-grid-table-wrapper[data-theme=white] .pagination-container button,.data-grid-table-wrapper[data-theme=white] .pagination-container span,.data-grid-table-wrapper[data-theme=white] .page-size select,.data-grid-table-wrapper[data-theme=white] .page-size button,.data-grid-table-wrapper[data-theme=white] .page-size span,.data-grid-table-wrapper[data-theme=white] .page-info select,.data-grid-table-wrapper[data-theme=white] .page-info button,.data-grid-table-wrapper[data-theme=white] .page-info span,.data-grid-table-wrapper[data-theme=white] .page-buttons select,.data-grid-table-wrapper[data-theme=white] .page-buttons button,.data-grid-table-wrapper[data-theme=white] .page-buttons span{background-color:#f6f8ff!important;border-color:#d9d9db!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .pagination-container button.active,.data-grid-table-wrapper[data-theme=white] .page-size button.active,.data-grid-table-wrapper[data-theme=white] .page-info button.active,.data-grid-table-wrapper[data-theme=white] .page-buttons button.active{background-color:#e3f2fd!important}.data-grid-table-wrapper[data-theme=white] .footer-row{background-color:#f8f9fa!important;border-top-color:#d9d9db!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] ::-webkit-scrollbar{background-color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=white] ::-webkit-scrollbar-thumb{background-color:#d9d9db!important}.data-grid-table-wrapper[data-theme=white] ::-webkit-scrollbar-thumb:hover{background-color:#adb5bd!important}.data-grid-table-wrapper[data-theme=white] ::-webkit-scrollbar-track{background-color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker{background-color:#f6f8ff!important;color:#000!important;border-color:#d9d9db!important}.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker .bs-datepicker-head{background:linear-gradient(135deg,#343a40,#495057)!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker .bs-datepicker-body{background-color:#f6f8ff!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker table td,.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker table th{color:#000!important}.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker table td.is-other-month,.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker table th.is-other-month{color:#6c757d!important}.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker table td.active,.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker table th.active{background-color:#e3f2fd!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker table td span.in-range,.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker table th span.in-range{background-color:#e3f2fd!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker table td:hover:not(.active),.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker table th:hover:not(.active){background-color:#007bff1a!important}.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker .bs-datepicker-buttons{background-color:#f8f9fa!important;border-top-color:#d9d9db!important}.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker .bs-datepicker-buttons .btn-primary{background:linear-gradient(135deg,#007bff,#0056b3)!important;color:#f6f8ff!important;border-color:#007bff!important}.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker .bs-datepicker-buttons .btn-secondary{background-color:#f6f8ff!important;color:#000!important;border-color:#d9d9db!important}.data-grid-table-wrapper[data-theme=white] button,.data-grid-table-wrapper[data-theme=white] .btn,.data-grid-table-wrapper[data-theme=white] .button{background-color:#f6f8ff!important;border-color:#d9d9db!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] button:hover,.data-grid-table-wrapper[data-theme=white] .btn:hover,.data-grid-table-wrapper[data-theme=white] .button:hover{background-color:#007bff1a!important}.data-grid-table-wrapper[data-theme=white] button.btn-primary,.data-grid-table-wrapper[data-theme=white] .btn.btn-primary,.data-grid-table-wrapper[data-theme=white] .button.btn-primary{background-color:#007bff!important;border-color:#007bff!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=white] button.btn-outline-primary,.data-grid-table-wrapper[data-theme=white] .btn.btn-outline-primary,.data-grid-table-wrapper[data-theme=white] .button.btn-outline-primary{border-color:#007bff!important;color:#007bff!important;background-color:transparent!important}.data-grid-table-wrapper[data-theme=white] a:not(.text-primary){color:#007bff!important}.data-grid-table-wrapper[data-theme=white] a:not(.text-primary):hover{color:#0056b3!important}.data-grid-table-wrapper[data-theme=white] .text-primary{color:#007bff!important}.data-grid-table-wrapper[data-theme=white] .text-danger{color:#dc3545!important}.data-grid-table-wrapper[data-theme=white] .text-success{color:#28a745!important}.data-grid-table-wrapper[data-theme=white] .text-warning{color:#ffc107!important}.data-grid-table-wrapper[data-theme=white] .text-info{color:#17a2b8!important}.data-grid-table-wrapper[data-theme=white] .text-muted,.data-grid-table-wrapper[data-theme=white] .muted-text{color:#6c757d!important}.data-grid-table-wrapper[data-theme=white] .border,.data-grid-table-wrapper[data-theme=white] .border-top,.data-grid-table-wrapper[data-theme=white] .border-bottom,.data-grid-table-wrapper[data-theme=white] .border-left,.data-grid-table-wrapper[data-theme=white] .border-right,.data-grid-table-wrapper[data-theme=white] .border-below,.data-grid-table-wrapper[data-theme=white] .border-start,.data-grid-table-wrapper[data-theme=white] .border-end{border-color:#d9d9db!important}.data-grid-table-wrapper[data-theme=white] .accordion-details,.data-grid-table-wrapper[data-theme=white] .nested-table,.data-grid-table-wrapper[data-theme=white] .detail-virtual-scroll{background-color:#f6f8ff!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .accordion-details td,.data-grid-table-wrapper[data-theme=white] .accordion-details th,.data-grid-table-wrapper[data-theme=white] .nested-table td,.data-grid-table-wrapper[data-theme=white] .nested-table th,.data-grid-table-wrapper[data-theme=white] .detail-virtual-scroll td,.data-grid-table-wrapper[data-theme=white] .detail-virtual-scroll th{color:#000!important;border-color:#d9d9db!important}.data-grid-table-wrapper[data-theme=blue]{border-color:#b3d9ff;background-color:#f0f8ff;color:#1e3a5f}.data-grid-table-wrapper[data-theme=blue] *,.data-grid-table-wrapper[data-theme=blue] *:before,.data-grid-table-wrapper[data-theme=blue] *:after{color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] ::selection{background-color:#007cf5!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=blue] ::-moz-selection{background-color:#007cf5!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=blue] .data-grid-header-wrapper{background-color:#e6f3ff;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .data-grid-body-wrapper{background-color:#f0f8ff;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .data-grid-row{border-bottom-color:#b3d9ff;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .data-grid-row:nth-child(2n){background-color:#f0f8ff!important}.data-grid-table-wrapper[data-theme=blue] .data-grid-row:nth-child(odd){background-color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=blue] .data-grid-row:hover{background-color:#1e3a5f1a!important}.data-grid-table-wrapper[data-theme=blue] .selected-cell,.data-grid-table-wrapper[data-theme=blue] .row-selected{background-color:#cce5ff!important}.data-grid-table-wrapper[data-theme=blue] .cell,.data-grid-table-wrapper[data-theme=blue] .header-cell,.data-grid-table-wrapper[data-theme=blue] .data-grid-row,.data-grid-table-wrapper[data-theme=blue] .data-grid-header,.data-grid-table-wrapper[data-theme=blue] .cell-content,.data-grid-table-wrapper[data-theme=blue] .full-text-content,.data-grid-table-wrapper[data-theme=blue] .circle-value,.data-grid-table-wrapper[data-theme=blue] .pic,.data-grid-table-wrapper[data-theme=blue] .image-placeholder,.data-grid-table-wrapper[data-theme=blue] .s-no,.data-grid-table-wrapper[data-theme=blue] .fw-500{color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] span,.data-grid-table-wrapper[data-theme=blue] div,.data-grid-table-wrapper[data-theme=blue] p,.data-grid-table-wrapper[data-theme=blue] td,.data-grid-table-wrapper[data-theme=blue] th,.data-grid-table-wrapper[data-theme=blue] label,.data-grid-table-wrapper[data-theme=blue] a:not(.text-primary){color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] svg,.data-grid-table-wrapper[data-theme=blue] svg path,.data-grid-table-wrapper[data-theme=blue] svg circle,.data-grid-table-wrapper[data-theme=blue] svg rect,.data-grid-table-wrapper[data-theme=blue] svg polygon{color:#1e3a5f!important;fill:#1e3a5f!important;stroke:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .data-grid-svg-icon{color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .data-grid-svg-icon path{stroke:#1e3a5f!important;fill:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .badge.badge-danger{background-color:#ff8787!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=blue] .badge.badge-success{background-color:#69db7c!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=blue] .badge.badge-warning{background-color:#ffd43b!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .badge.badge-info{background-color:#74c0fc!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=blue] .context-menu{background:#e6f3ff;border-color:#b3d9ff;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .context-menu li{color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .context-menu li:hover{background-color:#1e3a5f1a!important}.data-grid-table-wrapper[data-theme=blue] .custom-tooltip,.data-grid-table-wrapper[data-theme=blue] .popover__content,.data-grid-table-wrapper[data-theme=blue] .custom-break-tooltip{background:#e6f3ff!important;border-color:#b3d9ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .actions-dropdown,.data-grid-table-wrapper[data-theme=blue] .custom-menu{background-color:#e6f3ff!important;border-color:#b3d9ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .actions-dropdown .dropdown-item,.data-grid-table-wrapper[data-theme=blue] .custom-menu .dropdown-item{color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .actions-dropdown .dropdown-item:hover,.data-grid-table-wrapper[data-theme=blue] .custom-menu .dropdown-item:hover{background-color:#1e3a5f1a!important}.data-grid-table-wrapper[data-theme=blue] .taskbar .selected-rows-action-bar{background-color:#1e3a5f!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=blue] .taskbar .selected-rows-action-bar .action-btn{color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=blue] .manual-logs-modal .modal-header{background:linear-gradient(135deg,#1e3a5f,#2d4a6b)!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=blue] .manual-logs-modal .modal-header .modal-title{color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=blue] .manual-logs-modal .modal-body{background-color:#f0f8ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .manual-logs-modal .modal-body .table{color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .manual-logs-modal .modal-body .table thead th{background:linear-gradient(135deg,#e6f3ff,#cce5ff)!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .manual-logs-modal .modal-body .table tbody tr{color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .manual-logs-modal .modal-body .table tbody tr:nth-child(2n){background-color:#f0f8ff!important}.data-grid-table-wrapper[data-theme=blue] .manual-logs-modal .modal-body .table tbody tr:hover{background-color:#1e3a5f1a!important}.data-grid-table-wrapper[data-theme=blue] .manual-logs-modal .modal-body .table tbody tr td{color:#1e3a5f!important;border-color:#b3d9ff!important}.data-grid-table-wrapper[data-theme=blue] .form-control,.data-grid-table-wrapper[data-theme=blue] .form-select{background-color:#f6f8ff!important;border-color:#b3d9ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .form-control::placeholder,.data-grid-table-wrapper[data-theme=blue] .form-select::placeholder{color:#888!important}.data-grid-table-wrapper[data-theme=blue] .form-control option,.data-grid-table-wrapper[data-theme=blue] .form-select option{background-color:#f6f8ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .filter-serach-inpt{background-color:#f6f8ff!important;border-color:#b3d9ff!important}.data-grid-table-wrapper[data-theme=blue] .filter-serach-inpt input{background-color:#f6f8ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .active-filters,.data-grid-table-wrapper[data-theme=blue] .custom-modal-overlay .custom-modal-content{background-color:#e6f3ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .circle-value{background-color:#f6f8ff!important;border-color:#b3d9ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .pagination-container,.data-grid-table-wrapper[data-theme=blue] .page-size,.data-grid-table-wrapper[data-theme=blue] .page-info,.data-grid-table-wrapper[data-theme=blue] .page-buttons{color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .pagination-container select,.data-grid-table-wrapper[data-theme=blue] .pagination-container button,.data-grid-table-wrapper[data-theme=blue] .pagination-container span,.data-grid-table-wrapper[data-theme=blue] .page-size select,.data-grid-table-wrapper[data-theme=blue] .page-size button,.data-grid-table-wrapper[data-theme=blue] .page-size span,.data-grid-table-wrapper[data-theme=blue] .page-info select,.data-grid-table-wrapper[data-theme=blue] .page-info button,.data-grid-table-wrapper[data-theme=blue] .page-info span,.data-grid-table-wrapper[data-theme=blue] .page-buttons select,.data-grid-table-wrapper[data-theme=blue] .page-buttons button,.data-grid-table-wrapper[data-theme=blue] .page-buttons span{background-color:#f6f8ff!important;border-color:#b3d9ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .pagination-container button.active,.data-grid-table-wrapper[data-theme=blue] .page-size button.active,.data-grid-table-wrapper[data-theme=blue] .page-info button.active,.data-grid-table-wrapper[data-theme=blue] .page-buttons button.active{background-color:#cce5ff!important}.data-grid-table-wrapper[data-theme=blue] .footer-row{background-color:#e6f3ff!important;border-top-color:#b3d9ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] ::-webkit-scrollbar{background-color:#f0f8ff!important}.data-grid-table-wrapper[data-theme=blue] ::-webkit-scrollbar-thumb{background-color:#b3d9ff!important}.data-grid-table-wrapper[data-theme=blue] ::-webkit-scrollbar-thumb:hover{background-color:#74c0fc!important}.data-grid-table-wrapper[data-theme=blue] ::-webkit-scrollbar-track{background-color:#f0f8ff!important}.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker{background-color:#e6f3ff!important;color:#1e3a5f!important;border-color:#b3d9ff!important}.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker .bs-datepicker-head{background:linear-gradient(135deg,#1e3a5f,#2d4a6b)!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker .bs-datepicker-body{background-color:#f0f8ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker table td,.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker table th{color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker table td.is-other-month,.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker table th.is-other-month{color:#888!important}.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker table td.active,.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker table th.active{background-color:#cce5ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker table td span.in-range,.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker table th span.in-range{background-color:#cce5ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker table td:hover:not(.active),.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker table th:hover:not(.active){background-color:#1e3a5f1a!important}.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker .bs-datepicker-buttons{background-color:#f6f8ff!important;border-top-color:#b3d9ff!important}.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker .bs-datepicker-buttons .btn-primary{background:linear-gradient(135deg,#1e3a5f,#2d4a6b)!important;color:#f6f8ff!important;border-color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker .bs-datepicker-buttons .btn-secondary{background-color:#f0f8ff!important;color:#1e3a5f!important;border-color:#b3d9ff!important}.data-grid-table-wrapper[data-theme=blue] button,.data-grid-table-wrapper[data-theme=blue] .btn,.data-grid-table-wrapper[data-theme=blue] .button{background-color:#f6f8ff!important;border-color:#b3d9ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] button:hover,.data-grid-table-wrapper[data-theme=blue] .btn:hover,.data-grid-table-wrapper[data-theme=blue] .button:hover{background-color:#1e3a5f1a!important}.data-grid-table-wrapper[data-theme=blue] button.btn-primary,.data-grid-table-wrapper[data-theme=blue] .btn.btn-primary,.data-grid-table-wrapper[data-theme=blue] .button.btn-primary{background-color:#007cf5!important;border-color:#007cf5!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=blue] button.btn-outline-primary,.data-grid-table-wrapper[data-theme=blue] .btn.btn-outline-primary,.data-grid-table-wrapper[data-theme=blue] .button.btn-outline-primary{border-color:#007cf5!important;color:#007cf5!important;background-color:transparent!important}.data-grid-table-wrapper[data-theme=blue] a:not(.text-primary){color:#007cf5!important}.data-grid-table-wrapper[data-theme=blue] a:not(.text-primary):hover{color:#0056b3!important}.data-grid-table-wrapper[data-theme=blue] .text-primary{color:#007cf5!important}.data-grid-table-wrapper[data-theme=blue] .text-danger{color:#dc3545!important}.data-grid-table-wrapper[data-theme=blue] .text-success{color:#28a745!important}.data-grid-table-wrapper[data-theme=blue] .text-warning{color:#ffc107!important}.data-grid-table-wrapper[data-theme=blue] .text-info{color:#17a2b8!important}.data-grid-table-wrapper[data-theme=blue] .text-muted,.data-grid-table-wrapper[data-theme=blue] .muted-text{color:#6c757d!important}.data-grid-table-wrapper[data-theme=blue] .border,.data-grid-table-wrapper[data-theme=blue] .border-top,.data-grid-table-wrapper[data-theme=blue] .border-bottom,.data-grid-table-wrapper[data-theme=blue] .border-left,.data-grid-table-wrapper[data-theme=blue] .border-right,.data-grid-table-wrapper[data-theme=blue] .border-below,.data-grid-table-wrapper[data-theme=blue] .border-start,.data-grid-table-wrapper[data-theme=blue] .border-end{border-color:#b3d9ff!important}.data-grid-table-wrapper[data-theme=blue] .accordion-details,.data-grid-table-wrapper[data-theme=blue] .nested-table,.data-grid-table-wrapper[data-theme=blue] .detail-virtual-scroll{background-color:#f0f8ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .accordion-details td,.data-grid-table-wrapper[data-theme=blue] .accordion-details th,.data-grid-table-wrapper[data-theme=blue] .nested-table td,.data-grid-table-wrapper[data-theme=blue] .nested-table th,.data-grid-table-wrapper[data-theme=blue] .detail-virtual-scroll td,.data-grid-table-wrapper[data-theme=blue] .detail-virtual-scroll th{color:#1e3a5f!important;border-color:#b3d9ff!important}.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:30px}.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;position:relative}.resize-handle.resizing{z-index:9999!important;opacity:1!important;background-color:#007bff1a;border-right:2px solid #007bff;box-shadow:0 0 8px #007bff4d;position:relative!important;pointer-events:none!important}.group-header .resize-handle{top:25%}.h-100{height:100%}.data-grid-body{position:relative;overflow-y:auto;overflow-x:hidden;box-shadow:none!important}.cell{padding:8px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;height:100%;display:flex;align-items:center}.data-grid-row{display:flex;min-width:max-content;align-items:center;border-bottom:1px solid #d9d9db;transition:all .25s cubic-bezier(.4,0,.2,1);transform:translateZ(0);will-change:transform,box-shadow;backface-visibility:hidden}.data-grid-row:hover{transform:translate(2px);box-shadow:2px 0 8px #007bff1a}.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;background:#f6f8ff}.right-pinned-header{position:absolute;right:0;border-left:1px solid #d9d9db;z-index:unset}.left-pinned{left:0;border-right:1px solid #d9d9db}.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{display:flex}.data-grid-body-wrapper{scrollbar-width:none;-ms-overflow-style:none}.data-grid-body-wrapper::-webkit-scrollbar{display:none}.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:#f6f8ff;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:-15px;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:16px}.border-below{border-bottom:1px solid #d9d9db!important}.three-dots{width:22px;height:22px;display:flex;justify-content:center;align-items:center;border-radius:6px;margin-right:8px;cursor:pointer;transition:all .25s cubic-bezier(.4,0,.2,1);transform:translateZ(0);position:relative}.three-dots:before{content:\"\";position:absolute;top:50%;left:50%;width:0;height:0;background:#007bff1a;border-radius:50%;transform:translate(-50%,-50%);transition:width .25s,height .25s}.three-dots:hover{background-color:#007bff1a;transform:rotate(90deg)}.three-dots:hover:before{width:28px;height:28px}.three-dots:active{transform:rotate(90deg) scale(.95);transition-duration:.15s}.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:6px;cursor:pointer;transition:all .25s cubic-bezier(.4,0,.2,1);transform:translateZ(0);position:relative}.filter-icon-wrapper:before{content:\"\";position:absolute;top:50%;left:50%;width:0;height:0;background:#007bff1a;border-radius:50%;transform:translate(-50%,-50%);transition:width .25s,height .25s}.filter-icon-wrapper:hover{background-color:#007bff1a;transform:scale(1.05)}.filter-icon-wrapper:hover:before{width:32px;height:32px}.filter-icon-wrapper:active{transform:scale(.95);transition-duration:.15s}.column-panel-item{font-size:.875rem;color:#333;transition:all .25s cubic-bezier(.4,0,.2,1);transform:translateZ(0)}.column-panel-item:hover{background-color:#007bff0d;color:#007bff;transform:translate(2px)}.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:all .25s cubic-bezier(.4,0,.2,1);transform:translateZ(0);border-radius:4px;padding:2px}.toggle-icon:hover{background-color:#007bff1a;transform:scale(1.1)}.toggle-icon:active{transform:scale(.95)}.grab-icon{cursor:grab;color:#6c757d;transition:all .25s cubic-bezier(.4,0,.2,1);transform:translateZ(0)}.grab-icon:hover{color:#007bff;transform:scale(1.1)}.grab-icon:active{cursor:grabbing;transform:scale(.95)}.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:6px;display:flex;justify-content:center;align-items:center;transition:all .25s cubic-bezier(.4,0,.2,1);margin-right:8px;transform:translateZ(0);position:relative}.chevron-wrapper:before{content:\"\";position:absolute;top:50%;left:50%;width:0;height:0;background:#007bff1a;border-radius:50%;transform:translate(-50%,-50%);transition:width .25s,height .25s}.chevron-wrapper:hover{background-color:#007bff1a;transform:scale(1.1)}.chevron-wrapper:hover:before{width:36px;height:36px}.chevron-wrapper:hover i{transform:scale(1.2);transition:transform .25s cubic-bezier(.4,0,.2,1)}.chevron-wrapper:active{transform:scale(.95);transition-duration:.15s}.chevron-wrapper i{font-size:14px;transition:transform .25s cubic-bezier(.4,0,.2,1)}.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;transition:all .25s cubic-bezier(.4,0,.2,1);transform:translateZ(0);border-radius:6px}.columns-button:hover{background-color:#007bff1a;transform:scale(1.05)}.columns-button:active{transform:scale(.95)}.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:fixed;right:200px;z-index:1050;background-color:#fff;cursor:default;animation:slideInRight .25s cubic-bezier(.4,0,.2,1);transform:translateZ(0);border-radius:8px;box-shadow:0 8px 32px #0000001f;backdrop-filter:blur(8px)}.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;transition:all .25s cubic-bezier(.4,0,.2,1);transform:translateZ(0)}.action-button:hover{transform:translateY(-1px);box-shadow:0 4px 12px #007cf54d}.action-button:active{transform:translateY(0);transition-duration:.15s}.global-search{max-width:380px!important}.global-search span{margin-top:2px}.global-search input{padding-left:28px;border-radius:8px!important;transition:all .25s cubic-bezier(.4,0,.2,1);transform:translateZ(0)}.global-search input:focus{outline:none!important;box-shadow:0 0 0 3px #007bff1a!important;border-color:#007bff!important;transform:scale(1.02)}.active .top-icon ::ng-deep svg path{stroke:#007cf5!important}.custom-menu{width:220px;border-radius:8px;padding:4px 0}.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}.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;transition:all .25s cubic-bezier(.4,0,.2,1);transform:translateZ(0)}.page-buttons button:hover:not(:disabled){background-color:#007bff1a;border-color:#007bff;transform:translateY(-1px)}.page-buttons button:active:not(:disabled){transform:translateY(0) scale(.98)}.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!important}.text-filter select option{font-size:14px;font-weight:500}.text-filter select:focus{border:0!important}.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;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-width:600px;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{letter-spacing:.5px}.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;bottom:0;left:45%;display:flex;justify-content:center;z-index:1000;padding:36px}.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{font-size:14px;padding:6px 12px;border-radius:6px;text-align:center;height:auto;min-height:28px;display:inline-flex;align-items:center;justify-content:center;font-weight:500;line-height:1.5;white-space:nowrap;transition:all .2s cubic-bezier(.4,0,.2,1);will-change:transform,opacity;backface-visibility:hidden;transform:translateZ(0)}.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}.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;animation:pulse .25s cubic-bezier(.4,0,.2,1);transform:translateZ(0);position:relative}.selected-cell:before,.row-selected:before{content:\"\";position:absolute;inset:0;background:linear-gradient(45deg,transparent,rgba(255,255,255,.1),transparent);animation:shimmer 1.5s ease-in-out infinite}.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}.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.dragging th,.accordion-details.dragging td{pointer-events:none}.accordion-details.dragging th{z-index:2}.drag-handle{cursor:move;opacity:.5;transition:opacity .2s}.drag-handle:hover{opacity:1}.detail-edit-input{z-index:100;position:relative}.detail-filter-menu{position:absolute;background:#fff;border:1px solid #ddd;border-radius:4px;padding:10px;z-index:1000;box-shadow:0 2px 8px #00000026}.detail-filter-menu-positioned{width:280px;right:unset;max-width:230px;z-index:99;left:375px;top:225px}.resize-handle{cursor:col-resize;opacity:.5;width:8px;display:flex;align-items:center;justify-content:center}.resize-handle:hover{opacity:1;background-color:#f0f0f0}.detail-header-row{transition:all .3s ease}.detail-header-row.dragging{opacity:.7;transform:translate(5px)}.detail-cell{transition:background-color .2s ease,transform .3s ease}.detail-cell.active-drag{background-color:#f0f0f0;transform:scale(1.02)}.break-color-paid{background-color:#4caf50!important}.break-color-unpaid{background-color:#f44336!important}.break-color-lunch{background-color:#2196f3!important}.break-color-default{background-color:#f44336!important}.circle-value{display:flex;align-items:center;justify-content:center;width:32px;height:32px;border-radius:50%;background-color:#f8f9fa;border:2px solid #d9d9db;font-size:12px;font-weight:600;color:#000;text-align:center;line-height:1;vertical-align:middle;box-sizing:border-box;white-space:nowrap;overflow:hidden;cursor:pointer;transition:all .3s cubic-bezier(.4,0,.2,1);transform:translateZ(0);will-change:transform,box-shadow,background-color;backface-visibility:hidden}.circle-value:hover{background-color:#e9ecef;box-shadow:0 6px 16px #007bff40;transform:scale(1.15) translateY(-2px);border-color:#007bff}.circle-value:active{transform:scale(1.08) translateY(-1px);transition-duration:.15s}.break-tooltip-wrapper{position:relative;display:inline-block}.break-tooltip-wrapper:hover .custom-break-tooltip{opacity:1;visibility:visible}.circle-value[title]{position:relative}.circle-value[title]:after{content:attr(title);position:absolute;bottom:100%;left:50%;transform:translate(-50%);background-color:#333;color:#fff;padding:4px 8px;border-radius:4px;font-size:12px;white-space:nowrap;opacity:0;transition:opacity .2s ease;pointer-events:none}.circle-value[title]:hover:after{opacity:1}.custom-tooltip{position:fixed;background:#fff;border:1px solid #dcdcdc;border-radius:8px;padding:12px 16px;max-width:300px;z-index:9999;font-size:13px;animation:fadeIn .2s ease-in-out}.tooltip-title{font-size:14px;font-weight:600;margin-bottom:8px;color:#333}.tooltip-list{margin:0;padding-left:16px;list-style-type:disc}.tooltip-list li{margin-bottom:4px;line-height:1.4;color:#444}.tooltip-total{font-weight:700;margin-top:8px;color:#222}@keyframes fadeIn{0%{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:translateY(0)}}.restriction-indicator{position:absolute;display:inline-block;padding-right:10px}.restriction-indicator:after{content:\"\";position:absolute;top:0;right:0;width:8px;height:8px;background-color:#0d6efd;border-radius:50%}.manual-logs-indicator{position:absolute;top:2px;right:2px;width:8px;height:8px;background-color:#0d6efd;border-radius:50%;border:1px solid #fff;box-shadow:0 0 2px #0d6efd80;cursor:pointer;z-index:10;transition:all .2s ease}.manual-logs-indicator:hover{transform:scale(1.2);box-shadow:0 0 4px #0d6efdcc}.manual-logs-table-tooltip{background:#fff!important;border:1px solid #dcdcdc!important;border-radius:8px!important;box-shadow:0 4px 12px #00000026!important;font-size:13px!important;animation:fadeIn .2s ease-in-out!important;display:block!important;visibility:visible!important;opacity:1!important}.manual-logs-table-tooltip .popover__content,.manual-logs-table-tooltip .modal-area{padding:0!important;display:block!important;visibility:visible!important}.manual-logs-table-tooltip .table-responsive{max-height:300px;overflow-y:auto;display:block!important;visibility:visible!important}.manual-logs-table-tooltip table{margin:0!important;border-collapse:collapse!important;display:table!important;visibility:visible!important}.manual-logs-table-tooltip table th,.manual-logs-table-tooltip table td{padding:6px 8px!important;border:1px solid #f1f1f1!important;text-align:center!important;vertical-align:middle!important;display:table-cell!important;visibility:visible!important}.manual-logs-table-tooltip table th{background-color:#f8f9fa!important;font-weight:600!important;color:#495057!important;position:sticky!important;top:0!important;z-index:1!important}.manual-logs-table-tooltip table tbody tr:nth-child(2n){background-color:#f8f9fa!important}.manual-logs-table-tooltip table tbody tr:hover{background-color:#e3f2fd!important}.manual-logs-table-tooltip table .text-primary{color:#0d6efd!important;text-decoration:none!important}.manual-logs-table-tooltip table .capitalize{text-transform:capitalize!important}@keyframes fadeIn{0%{opacity:0;transform:translate(-50%) translateY(-110%)}to{opacity:1;transform:translate(-50%) translateY(-100%)}}.detail-column-menu{max-height:250px;overflow-y:auto;overflow-x:auto;white-space:nowrap;padding:8px 0;border-radius:6px;scrollbar-width:thin}.detail-column-menu-wrapper{z-index:1001;position:absolute}.accordion-details{position:relative;z-index:999}.detail-column-menu .column-menu-item{padding:8px 12px;cursor:pointer;display:flex;align-items:center;transition:all .25s cubic-bezier(.4,0,.2,1);font-size:14px;transform:translateZ(0);border-radius:4px}.detail-column-menu .column-menu-item:hover{background-color:#007bff1a;transform:translate(2px);color:#007bff}.detail-column-menu .column-menu-item:active{transform:translate(0) scale(.98)}.detail-column-menu .column-menu-item:hover{background-color:#deebf7}.nested-table th[pinned=left],.nested-table td[pinned=left]{border-right:2px solid #ccc;border-left:none;border-bottom:2px solid #ccc}.nested-table th[pinned=right],.nested-table td[pinned=right]{border-left:2px solid #ccc;border-right:none;border-bottom:2px solid #ccc}.data-grid-accordion-table.show-borders{border:1px solid #d9d9db;border-collapse:collapse}.data-grid-accordion-table.show-borders th,.data-grid-accordion-table.show-borders td{border:1px solid #d9d9db}.data-grid-accordion-table.show-shadow tbody tr:hover{box-shadow:0 4px 8px #0000001a;transition:box-shadow .3s ease}.data-grid-accordion-table tbody tr:hover{background-color:#deebf7;transition:background-color .3s ease}.data-grid-pin-icon{display:inline-block;vertical-align:middle;margin-left:4px}.accordion-details.center-section{position:relative;display:flex}.detail-side-menu-wrapper{display:flex;flex-shrink:0;position:sticky;right:0;top:0;height:100%;max-height:275px}.detail-side-menu-content{width:250px;box-shadow:-2px 0 5px #0000001a;display:flex;flex-direction:column}.side-menu-scrollable{flex:1;overflow-y:auto;padding:0 12px 12px;max-height:calc(100% - 40px)}.filter-input-container{padding:8px;background:#f9f9f9;border-radius:4px}.toggle-icon.rotate{transform:rotate(90deg)}.resize-handle{top:0;right:3px;bottom:0;width:8px;cursor:col-resize;z-index:10;display:flex;align-items:center;justify-content:center;opacity:1.4;transition:all .25s cubic-bezier(.4,0,.2,1);background:transparent;transform:translateZ(0)}.resize-handle:hover{opacity:1;background:#007bff1a}.resize-handle:active{opacity:1;background:#007bff33;transform:scaleX(1.2)}th:hover .resize-handle{opacity:40}.resize-handles{top:0;right:3px;bottom:0;width:8px;cursor:col-resize;z-index:10;display:flex;align-items:center;justify-content:center;position:absolute;opacity:1.4;transition:all .25s cubic-bezier(.4,0,.2,1);background:transparent;transform:translateZ(0)}.resize-handles:hover{opacity:1;background:#007bff1a}.resize-handles:active{opacity:1;background:#007bff33;transform:scaleX(1.2)}.resize-handles.resizing{z-index:9999!important;opacity:1!important;background-color:#007bff1a;border-right:2px solid #007bff;box-shadow:0 0 8px #007bff4d;pointer-events:none!important}th:hover .resize-handles{opacity:40}.resizing-highlight{background-color:#007bff1a!important}.accordion-details-wrapper{display:flex;width:100%;max-height:350px;overflow:hidden}.accordion-details.show-borders,.accordion-details-wrapper.show-borders{border:1px solid #d9d9db;border-radius:4px}.accordion-left-section,.accordion-right-section,.detail-side-menu-wrapper{flex-shrink:0;max-height:350px;overflow:hidden;height:fit-content}.accordion-center-section{flex:1;min-width:0;overflow:auto;max-height:350px}.detail-virtual-scroll{display:block;width:100%;height:250px;overflow:auto}.detail-virtual-scroll table{table-layout:fixed;width:100%}.detail-virtual-scroll td,.detail-virtual-scroll th{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.detail-header-scroll-container{scrollbar-width:none}.detail-header-scroll-container::-webkit-scrollbar{display:none}.accordion-left-section thead th,.accordion-right-section thead th{position:sticky;top:0;z-index:2}.data-pin-body-wrapper{-webkit-user-select:none;user-select:none;display:flex}.data-pin-body-wrapper{scrollbar-width:none;-ms-overflow-style:none}.data-pin-body-wrapper::-webkit-scrollbar{display:none}.detail-virtual-scroll .selected-cell,.accordion-left-section .selected-cell,.accordion-right-section .selected-cell{background-color:#cce5ff!important}.custom-datepicker-buttons button{height:28px;padding:0 10px;font-size:12px}.manual-logs-modal{max-width:800px;max-height:80vh;overflow:hidden;border-radius:12px;box-shadow:0 10px 40px #0003}.manual-logs-modal .modal-header{background:linear-gradient(135deg,#4361ee,#3a0ca3);color:#fff;padding:16px 20px;border-bottom:none;border-radius:12px 12px 0 0}.manual-logs-modal .modal-header .modal-title{font-weight:600;font-size:18px;margin:0}.manual-logs-modal .modal-header .btn-close{background:#fff3;border:none;border-radius:50%;width:32px;height:32px;display:flex;align-items:center;justify-content:center;color:#fff;opacity:.8;transition:all .25s cubic-bezier(.4,0,.2,1);transform:translateZ(0)}.manual-logs-modal .modal-header .btn-close:hover{background:#ffffff4d;opacity:1;transform:scale(1.1) rotate(90deg)}.manual-logs-modal .modal-header .btn-close:active{transform:scale(.95) rotate(90deg)}.manual-logs-modal .modal-body{padding:20px;max-height:calc(80vh - 80px);overflow-y:auto}.manual-logs-modal .modal-body .table-responsive{border-radius:8px;overflow:hidden;box-shadow:0 2px 8px #0000001a}.manual-logs-modal .modal-body .table-responsive .table{margin-bottom:0;font-size:14px}.manual-logs-modal .modal-body .table-responsive .table thead th{background:linear-gradient(135deg,#f8f9fa,#e9ecef);border-bottom:2px solid #dee2e6;font-weight:600;color:#495057;padding:12px 16px;position:sticky;top:0;z-index:10}.manual-logs-modal .modal-body .table-responsive .table tbody tr{transition:background-color .2s ease}.manual-logs-modal .modal-body .table-responsive .table tbody tr:hover{background-color:#f8f9fa}.manual-logs-modal .modal-body .table-responsive .table tbody tr:nth-child(2n){background-color:#f8f9fa}.manual-logs-modal .modal-body .table-responsive .table tbody tr td{padding:10px 16px;vertical-align:middle;border-color:#e9ecef}.manual-logs-modal .modal-body .table-responsive .table tbody tr td .text-primary{color:#0d6efd!important;font-weight:500;text-decoration:none}.manual-logs-modal .modal-body .table-responsive .table tbody tr td .text-primary:hover{text-decoration:underline}.manual-logs-modal .modal-body .table-responsive .table tbody tr td .capitalize{text-transform:capitalize}::ng-deep bs-daterangepicker-container .bs-datepicker{border-radius:4px!important;box-shadow:0 2px 8px #0000001a!important;font-size:14px!important;display:flex!important;align-items:flex-start!important;left:142px!important}::ng-deep .bs-datepicker-head{background:#f8f9fa!important;color:#495057!important;border-bottom:1px solid #dee2e6!important;padding:8px 12px!important;border-radius:4px 4px 0 0!important}::ng-deep .bs-datepicker-head .current{font-weight:600!important;color:#495057!important;font-size:13px!important}::ng-deep .bs-datepicker-head .previous,::ng-deep .bs-datepicker-head .next{background:#fff!important;color:#495057!important;border:1px solid #dee2e6!important;width:24px!important;border-radius:4px!important;font-size:12px!important}::ng-deep .bs-datepicker-head .previous:hover,::ng-deep .bs-datepicker-head .next:hover{background:#e9ecef!important}::ng-deep .bs-datepicker .bs-datepicker-buttons{padding:8px!important;background:#f8f9fa!important;border-top:1px solid #dee2e6!important;border-radius:0 0 4px 4px!important}::ng-deep .bs-datepicker .bs-datepicker-buttons .btn-primary{background:#007bff!important;color:#fff!important;border:1px solid #007bff!important;font-weight:500!important;padding:4px 8px!important;border-radius:4px!important;font-size:12px!important}::ng-deep .bs-datepicker .bs-datepicker-buttons .btn-primary:hover{background:#0056b3!important;border-color:#0056b3!important}::ng-deep .bs-datepicker .bs-datepicker-buttons .btn-secondary{background:#fff!important;color:#495057!important;border:1px solid #dee2e6!important;font-weight:500!important;padding:4px 8px!important;border-radius:4px!important;font-size:12px!important}::ng-deep .bs-datepicker .bs-datepicker-buttons .btn-secondary:hover{background:#e9ecef!important}::ng-deep .bs-datepicker-body{background:#fff!important;padding:6px!important}::ng-deep .bs-datepicker-body table{background:#fff!important;border-collapse:separate!important;border-spacing:1px!important}::ng-deep .bs-datepicker-body table th,::ng-deep .bs-datepicker-body table td{border:1px solid #dee2e6!important;border-radius:4px!important;text-align:center!important;font-weight:500!important;color:#495057!important;cursor:pointer!important;transition:all .2s ease!important;font-size:12px!important;width:32px!important;height:32px!important;line-height:24px!important}::ng-deep .bs-datepicker-body table th{background:#f8f9fa!important;font-weight:600!important;font-size:11px!important;padding:2px!important;height:24px!important;line-height:20px!important}::ng-deep .bs-datepicker-body table td:hover:not(.disabled){background:#e9ecef!important}::ng-deep .bs-datepicker-body table td.active{background:#007bff!important;color:#fff!important;border-color:#007bff!important}::ng-deep .bs-datepicker-body table td.is-other-month{color:#6c757d!important;background:#f8f9fa!important}::ng-deep .bs-datepicker-body table td.disabled{color:#adb5bd!important;background:#e9ecef!important;cursor:not-allowed!important}::ng-deep .bs-datepicker-custom-range{background:transparent!important;border-right:1px solid #dee2e6!important;padding:6px!important;width:130px!important;margin-right:8px!important;align-self:flex-start!important}::ng-deep .bs-datepicker-predefined-btns{display:flex!important;flex-direction:column!important;gap:2px!important}::ng-deep .bs-datepicker-predefined-btns button{background:transparent!important;color:#495057!important;border:1px solid #dee2e6!important;border-radius:4px!important;padding:4px 6px!important;font-size:11px!important;font-weight:500!important;text-align:left!important;cursor:pointer!important;transition:all .2s ease!important;width:100%!important;margin:0!important}::ng-deep .bs-datepicker-predefined-btns button:hover{background:#e9ecef!important;border-color:#adb5bd!important}::ng-deep .bs-datepicker-predefined-btns button:active,::ng-deep .bs-datepicker-predefined-btns button:focus{outline:none!important;box-shadow:0 0 0 2px #007bff40!important;background:#007bff!important;color:#fff!important;border-color:#007bff!important}.manual-logs-modal-overlay{position:fixed;top:0;left:0;width:100%;height:100%;background-color:#00000080;display:flex;justify-content:center;align-items:center;z-index:9999}.manual-logs-modal-content{background:#fff;border-radius:8px;max-width:800px;max-height:80vh;overflow:auto;box-shadow:0 4px 8px #0000001a}.popover__wrapper{position:relative;display:inline-block}.popover__content{position:absolute;bottom:100%;left:50%;transform:translate(-50%);background:#fff;border:1px solid #ccc;border-radius:8px;padding:12px;box-shadow:0 4px 12px #00000026;z-index:1000;opacity:0;visibility:hidden;transition:opacity .3s ease,visibility .3s ease;min-width:250px;max-width:400px;font-size:14px}.popover__wrapper:hover .popover__content{opacity:1;visibility:visible}.popover__content .modal-area{padding:0}.popover__content h4{margin:0 0 8px;font-size:16px;font-weight:600;color:#333}.popover__content .break-status{font-size:12px;color:#666;margin-bottom:8px}.popover__content .d-flex{gap:12px}.popover__content p{margin:0 0 4px;font-size:12px;color:#666}.popover__content h5{margin:0;font-size:14px;font-weight:500;color:#333}.popover__content .break-footer{border-top:1px solid #eee;margin-top:8px;padding-top:8px}.popover__content .break-footer p{font-size:12px;color:#666;margin:0}.custom-break-tooltip{position:fixed;z-index:1000;background:#fff;border:1px solid #ddd;border-radius:8px;box-shadow:0 4px 12px #00000026;padding:12px;font-size:13px;max-width:220px;pointer-events:none;top:0;left:0;transform:translate(var(--tooltip-x, 0px),var(--tooltip-y, 0px))}.custom-break-tooltips{position:fixed;z-index:1000;background:#fff;border:1px solid #ddd;border-radius:8px;box-shadow:0 4px 12px #00000026;padding:8px;font-size:12px;max-width:500px;max-height:300px;top:0;left:0;transform:translate(var(--tooltip-x, 0px),var(--tooltip-y, 0px))}.custom-break-tooltips .modal-body{max-height:250px!important;overflow-y:auto;padding:0}.custom-break-tooltips .table-responsive{max-height:250px}.custom-break-tooltips thead th{position:sticky;top:0;background:#f8f9fa;z-index:10;border-bottom:2px solid #dee2e6;font-size:11px;padding:4px 8px;font-weight:600}.custom-break-tooltips table{font-size:11px;margin-bottom:0}.custom-break-tooltips table td{padding:4px 8px;white-space:nowrap}.custom-break-tooltips .table-striped tbody tr:nth-of-type(odd){background-color:#00000005}.popver_content_progress_bar{visibility:hidden}.badge-overflow-container{display:flex;flex-wrap:nowrap;gap:4px;align-items:center;min-width:0;overflow:hidden;width:100%}.badge-overflow-container .badge{flex-shrink:0;white-space:nowrap;font-size:12px;padding:4px 8px;border-radius:50%;display:inline-flex;align-items:center;justify-content:center;font-weight:600;line-height:1;text-transform:uppercase;letter-spacing:.5px;transition:all .3s cubic-bezier(.4,0,.2,1);border:2px solid transparent;width:32px;height:32px;box-sizing:border-box;cursor:pointer;transform:translateZ(0);will-change:transform,box-shadow,background-color;backface-visibility:hidden}.badge-overflow-container .badge:hover{transform:scale(1.15) translateY(-2px);box-shadow:0 6px 16px #007bff40}.badge-overflow-container .badge:active{transform:scale(1.08) translateY(-1px);transition-duration:.15s}.badge-overflow-container .badge-overflow-count{background-color:#6c757d!important;color:#fff!important;cursor:pointer;border:2px solid #6c757d!important;flex-shrink:0;border-radius:50%;width:32px;height:32px;display:inline-flex;align-items:center;justify-content:center;font-weight:600;transition:all .3s cubic-bezier(.4,0,.2,1);transform:translateZ(0);will-change:transform,box-shadow,background-color;backface-visibility:hidden}.badge-overflow-container .badge-overflow-count:hover{background-color:#5a6268!important;border-color:#5a6268!important;transform:scale(1.15) translateY(-2px);box-shadow:0 6px 16px #007bff40}.badge-overflow-container .badge-overflow-count:active{transform:scale(1.08) translateY(-1px);transition-duration:.15s}.timeline-view-container{padding:1rem;background-color:#f8f9fa}.timeline-view-container .timeline-header{margin-bottom:2rem}.timeline-view-container .timeline-header h5{color:#495057;font-weight:600;margin-bottom:1rem}.timeline-view-container .timeline-header .timeline-hours{display:flex;justify-content:space-between;padding:.5rem 0;border-bottom:1px solid #dee2e6;margin-bottom:1rem;background:#fff;border-radius:8px;padding:1rem}.timeline-view-container .timeline-header .timeline-hours .timeline-hour{font-size:.8rem;color:#6c757d;font-weight:500;min-width:40px;text-align:center;padding:.5rem;border-radius:4px;background:#f8f9fa}.timeline-view-container .timeline-body .timeline-row{background:#fff;border:1px solid #dee2e6;border-radius:8px;margin-bottom:1rem;padding:1rem;box-shadow:0 2px 4px #0000001a;transition:box-shadow .2s ease}.timeline-view-container .timeline-body .timeline-row:hover{box-shadow:0 4px 8px #00000026}.timeline-view-container .timeline-body .timeline-row .timeline-employee{margin-bottom:1rem}.timeline-view-container .timeline-body .timeline-row .timeline-employee .employee-name{font-weight:600;color:#495057;font-size:1.1rem}.timeline-view-container .timeline-body .timeline-row .timeline-track{position:relative;height:40px;background:#f8f9fa;border-radius:4px;border:1px solid #e9ecef}.timeline-view-container .timeline-body .timeline-row .timeline-track .work-duration-bar{position:absolute;height:100%;background:linear-gradient(135deg,#28a745,#20c997);border-radius:4px;box-shadow:0 2px 4px #28a7454d;transition:opacity .2s ease}.timeline-view-container .timeline-body .timeline-row .timeline-track .work-duration-bar:hover{opacity:.8}.timeline-view-container .timeline-body .timeline-row .timeline-track .break-bar{position:absolute;height:100%;border-radius:4px;box-shadow:0 2px 4px #0003;border:1px solid rgba(255,255,255,.5);transition:opacity .2s ease}.timeline-view-container .timeline-body .timeline-row .timeline-track .break-bar:hover{opacity:.8}.calendar-view-container .calendar-header{margin-bottom:2rem}.calendar-view-container .calendar-header h5{color:#495057;font-weight:600}.calendar-view-container .calendar-header .calendar-nav button{border:1px solid #dee2e6;background:#fff;color:#495057;padding:.375rem .75rem;border-radius:.375rem;transition:all .2s ease}.calendar-view-container .calendar-header .calendar-nav button:hover{background-color:#f8f9fa;border-color:#adb5bd}.calendar-view-container .calendar-header .calendar-nav button:first-child{border-top-right-radius:0;border-bottom-right-radius:0;border-right:none}.calendar-view-container .calendar-header .calendar-nav button:last-child{border-top-left-radius:0;border-bottom-left-radius:0}.calendar-view-container .calendar-grid .calendar-week-header{display:flex;background-color:#f8f9fa;border:1px solid #dee2e6;border-bottom:none}.calendar-view-container .calendar-grid .calendar-week-header .calendar-day-header{flex:1;padding:.75rem;text-align:center;font-weight:600;color:#495057;border-right:1px solid #dee2e6}.calendar-view-container .calendar-grid .calendar-week-header .calendar-day-header:last-child{border-right:none}.calendar-view-container .calendar-grid .calendar-weeks{border:1px solid #dee2e6;border-top:none}.calendar-view-container .calendar-grid .calendar-weeks .calendar-week{display:flex;border-bottom:1px solid #dee2e6}.calendar-view-container .calendar-grid .calendar-weeks .calendar-week:last-child{border-bottom:none}.calendar-view-container .calendar-grid .calendar-weeks .calendar-week .calendar-day{flex:1;min-height:100px;padding:.5rem;border-right:1px solid #dee2e6;background:#fff}.calendar-view-container .calendar-grid .calendar-weeks .calendar-week .calendar-day:last-child{border-right:none}.calendar-view-container .calendar-grid .calendar-weeks .calendar-week .calendar-day.current-month{background:#fff}.calendar-view-container .calendar-grid .calendar-weeks .calendar-week .calendar-day.today{background-color:#fff3cd;border:2px solid #ffc107}.calendar-view-container .calendar-grid .calendar-weeks .calendar-week .calendar-day .day-number{font-weight:600;color:#495057;margin-bottom:.25rem}.calendar-view-container .calendar-grid .calendar-weeks .calendar-week .calendar-day .day-entries .entry-dot{width:8px;height:8px;border-radius:50%;display:inline-block;margin-right:2px;margin-bottom:2px}.heatmap-view-container .heatmap-header{margin-bottom:2rem}.heatmap-view-container .heatmap-header h5{color:#495057;font-weight:600}.heatmap-view-container .heatmap-header .heatmap-legend .legend-colors{display:flex;margin:0 1rem}.heatmap-view-container .heatmap-header .heatmap-legend .legend-colors .legend-color{width:12px;height:12px;margin-right:2px;border-radius:2px}.heatmap-view-container .heatmap-header .heatmap-legend span{font-size:.875rem;color:#6c757d}.heatmap-view-container .heatmap-grid .heatmap-months{display:flex;margin-bottom:.5rem}.heatmap-view-container .heatmap-grid .heatmap-months .month-label{flex:1;text-align:center;font-size:.8rem;font-weight:600;color:#495057}.heatmap-view-container .heatmap-grid .heatmap-weeks .heatmap-week{display:flex;margin-bottom:2px}.heatmap-view-container .heatmap-grid .heatmap-weeks .heatmap-week .heatmap-day{flex:1;aspect-ratio:1;border-radius:2px;margin-right:2px;transition:opacity .2s ease}.heatmap-view-container .heatmap-grid .heatmap-weeks .heatmap-week .heatmap-day:hover{opacity:.8}.heatmap-view-container .heatmap-grid .heatmap-weeks .heatmap-week .heatmap-day:last-child{margin-right:0}.card-view-container{padding:1rem;height:100%;overflow-y:auto;overflow-x:hidden}.card-view-container[data-theme=white]{background-color:#f6f8ff;color:#000}.card-view-container[data-theme=white] .attendance-card{background-color:#f6f8ff;border-color:#d9d9db;color:#000}.card-view-container[data-theme=white] .attendance-card:hover{background-color:#007bff1a}.card-view-container[data-theme=white] .attendance-card .card-header{background-color:#f8f9fa;color:#000;border-bottom-color:#d9d9db}.card-view-container[data-theme=white] .attendance-card .card-body{background-color:#f6f8ff;color:#000}.card-view-container[data-theme=white] .attendance-card .badge.bg-success{background-color:#84ca81;color:#f6f8ff}.card-view-container[data-theme=white] .attendance-card .badge.bg-danger{background-color:#ea5353;color:#f6f8ff}.card-view-container[data-theme=white] .attendance-card .badge.bg-warning{background-color:#fff3dc;color:#000}.card-view-container[data-theme=white] .attendance-card .badge.bg-info{background-color:#e8fbfd;color:#00bad1}.card-view-container[data-theme=blue]{background-color:#f0f8ff;color:#1e3a5f}.card-view-container[data-theme=blue] .attendance-card{background-color:#f6f8ff;border-color:#b3d9ff;color:#1e3a5f}.card-view-container[data-theme=blue] .attendance-card:hover{background-color:#1e3a5f1a}.card-view-container[data-theme=blue] .attendance-card .card-header{background-color:#e6f3ff;color:#1e3a5f;border-bottom-color:#b3d9ff}.card-view-container[data-theme=blue] .attendance-card .card-body{background-color:#f6f8ff;color:#1e3a5f}.card-view-container[data-theme=blue] .attendance-card .badge.bg-success{background-color:#69db7c;color:#f6f8ff}.card-view-container[data-theme=blue] .attendance-card .badge.bg-danger{background-color:#ff8787;color:#f6f8ff}.card-view-container[data-theme=blue] .attendance-card .badge.bg-warning{background-color:#ffd43b;color:#1e3a5f}.card-view-container[data-theme=blue] .attendance-card .badge.bg-info{background-color:#74c0fc;color:#f6f8ff}.card-view-container .row{margin:0}.card-view-container .row .col-xl-4,.card-view-container .row .col-lg-6,.card-view-container .row .col-md-6,.card-view-container .row .col-sm-12{padding:.5rem}.card-view-container .attendance-card{transition:background-color .2s ease;border:1px solid #d9d9db;border-radius:4px;overflow:hidden;height:100%;display:flex;flex-direction:column;font-family:sans-serif;font-size:16px}.card-view-container .attendance-card:hover{box-shadow:0 2px 4px #0000001a}.card-view-container .attendance-card.expanded .card-body{max-height:none}.card-view-container .attendance-card .card-header{padding:8px;border-bottom:1px solid #d9d9db;flex-shrink:0;font-weight:500}.card-view-container .attendance-card .card-header .employee-avatar{margin-right:.75rem;flex-shrink:0}.card-view-container .attendance-card .card-header .employee-avatar img,.card-view-container .attendance-card .card-header .employee-avatar .avatar-placeholder{border:1px solid #d9d9db;width:40px;height:40px;border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:16px;font-weight:400}.card-view-container .attendance-card .card-header .flex-grow-1{min-width:0}.card-view-container .attendance-card .card-header h6{margin:0;font-weight:500;font-size:16px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.card-view-container .attendance-card .card-header small{opacity:.9;font-weight:400;font-size:16px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.card-view-container .attendance-card .card-header .card-actions{flex-shrink:0}.card-view-container .attendance-card .card-header .card-actions .btn{background-color:transparent;border:1px solid #d9d9db;color:inherit;padding:.25rem .5rem}.card-view-container .attendance-card .card-header .card-actions .btn:hover{background-color:#007bff1a}.card-view-container .attendance-card .card-header .card-actions .btn i{font-size:.8rem}.card-view-container .attendance-card .card-body{padding:8px;flex:1;display:flex;flex-direction:column}.card-view-container .attendance-card .card-body .info-item{text-align:center;margin-bottom:.5rem}.card-view-container .attendance-card .card-body .info-item small{display:block;font-weight:400;color:#6c757d;text-transform:uppercase;font-size:12px;letter-spacing:.5px;margin-bottom:.25rem}.card-view-container .attendance-card .card-body .info-item span{font-size:16px;font-weight:400;color:inherit}.card-view-container .attendance-card .card-body .badge{font-size:12px;padding:.25rem .5rem;border-radius:4px;font-weight:400;text-transform:uppercase;letter-spacing:.5px;border:none}.card-view-container .attendance-card .card-body .badge.bg-success,.card-view-container .attendance-card .card-body .badge.bg-danger{color:#f6f8ff}.card-view-container .attendance-card .card-body .badge.bg-warning{color:#000}.card-view-container .attendance-card .card-body .badge.bg-secondary{color:#f6f8ff}.card-view-container .attendance-card .card-body .card-details{margin-top:1rem}.card-view-container .attendance-card .card-body .card-details .section-title{font-size:14px;font-weight:500;color:inherit;margin-bottom:.75rem;display:flex;align-items:center}.card-view-container .attendance-card .card-body .card-details .section-title i{margin-right:.5rem;opacity:.8}.card-view-container .attendance-card .card-body .card-details .breaks-list .break-item,.card-view-container .attendance-card .card-body .card-details .breaks-list .leave-item,.card-view-container .attendance-card .card-body .card-details .short-leave-list .break-item,.card-view-container .attendance-card .card-body .card-details .short-leave-list .leave-item{background-color:inherit;border:1px solid #d9d9db;border-radius:4px;padding:8px;margin-bottom:.5rem;cursor:pointer;transition:all .25s cubic-bezier(.4,0,.2,1);transform:translateZ(0)}.card-view-container .attendance-card .card-body .card-details .breaks-list .break-item .d-flex,.card-view-container .attendance-card .card-body .card-details .breaks-list .leave-item .d-flex,.card-view-container .attendance-card .card-body .card-details .short-leave-list .break-item .d-flex,.card-view-container .attendance-card .card-body .card-details .short-leave-list .leave-item .d-flex{gap:.75rem;align-items:center}.card-view-container .attendance-card .card-body .card-details .breaks-list .break-item .d-flex small,.card-view-container .attendance-card .card-body .card-details .breaks-list .leave-item .d-flex small,.card-view-container .attendance-card .card-body .card-details .short-leave-list .break-item .d-flex small,.card-view-container .attendance-card .card-body .card-details .short-leave-list .leave-item .d-flex small{font-weight:500;color:inherit;margin-bottom:.25rem}.card-view-container .attendance-card .card-body .card-details .breaks-list .break-item .d-flex .text-muted,.card-view-container .attendance-card .card-body .card-details .breaks-list .leave-item .d-flex .text-muted,.card-view-container .attendance-card .card-body .card-details .short-leave-list .break-item .d-flex .text-muted,.card-view-container .attendance-card .card-body .card-details .short-leave-list .leave-item .d-flex .text-muted{font-size:12px;color:#6c757d}.card-view-container .attendance-card .card-body .card-details .breaks-list .break-item .d-flex .badge,.card-view-container .attendance-card .card-body .card-details .breaks-list .leave-item .d-flex .badge,.card-view-container .attendance-card .card-body .card-details .short-leave-list .break-item .d-flex .badge,.card-view-container .attendance-card .card-body .card-details .short-leave-list .leave-item .d-flex .badge{font-size:10px;padding:.2rem .4rem}.card-view-container .attendance-card .card-body .card-details .additional-details .row .col-6{margin-bottom:.5rem}.card-view-container .attendance-card .card-body .card-details .additional-details .row .col-6 small{font-weight:400;color:#6c757d;text-transform:uppercase;font-size:12px;letter-spacing:.5px;margin-bottom:.25rem}.card-view-container .attendance-card .card-body .card-details .additional-details .row .col-6 span{font-weight:400;color:inherit;font-size:14px}@media (max-width: 1200px){.card-view-container .row .col-xl-4{flex:0 0 50%;max-width:50%}}@media (max-width: 768px){.card-view-container .row .col-xl-4,.card-view-container .col-lg-6,.card-view-container .col-md-6{flex:0 0 100%;max-width:100%}.card-view-container .attendance-card .card-body{padding:8px}.card-view-container .attendance-card .card-body .info-item small{font-size:10px}.card-view-container .attendance-card .card-body .info-item span{font-size:14px}}@media (max-width: 576px){.card-view-container{padding:.5rem}.card-view-container .row .col-sm-12{padding:.25rem}.card-view-container .attendance-card .card-header{padding:8px}.card-view-container .attendance-card .card-header h6,.card-view-container .attendance-card .card-header small{font-size:14px}.card-view-container .attendance-card .card-body{padding:8px}}.btn-xs{padding:.125rem .3rem!important;font-size:.9rem!important;border-radius:.2rem!important;line-height:1.5!important}.form-select.form-select-sm:invalid{border-color:#d9d9db!important}.form-select.form-select-sm:valid{border-color:#d9d9db!important}.date-range-container{gap:8px;flex-wrap:nowrap;align-items:center}.date-range-btn{padding:6px 12px;font-size:14px;font-weight:500;border-radius:6px;transition:all .25s cubic-bezier(.4,0,.2,1);white-space:nowrap;display:inline-flex;align-items:center;justify-content:center;min-height:36px;transform:translateZ(0);position:relative;overflow:hidden}.date-range-btn:before{content:\"\";position:absolute;top:50%;left:50%;width:0;height:0;background:#fff3;border-radius:50%;transform:translate(-50%,-50%);transition:width .25s,height .25s}.date-range-btn:active:before{width:300px;height:300px}.calendar-btn{border-color:#0d6efd;color:#0d6efd;background-color:transparent}.calendar-btn:hover{background-color:#0d6efd;color:#fff;transform:translateY(-1px);box-shadow:0 4px 12px #0d6efd4d}.clear-btn{border-color:#dc3545;color:#dc3545;background-color:transparent}.clear-btn:hover{background-color:#dc3545;color:#fff;transform:translateY(-1px);box-shadow:0 4px 12px #dc35454d}.date-range-label{font-size:14px;font-weight:500;padding:4px 8px;min-width:180px;text-align:center;white-space:nowrap;cursor:pointer}.date-range-btn .bi{font-size:14px;transition:transform .2s ease}.date-range-btn:hover .bi{transform:scale(1.1)}@media (max-width: 768px){.date-range-container{flex-wrap:wrap;justify-content:flex-start}.date-range-label{min-width:100%;margin-top:8px;order:3}}.date-range-btn:focus{outline:none;box-shadow:0 0 0 3px #0d6efd40}.clear-btn:focus{box-shadow:0 0 0 3px #dc354540}.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}.badge-overflow-wrapper{width:100%;min-width:0;display:flex;align-items:center}\n"] }]
8845
- }], ctorParameters: () => [{ type: i0.Injector }, { type: i0.ViewContainerRef }, { type: CommonService }], propDecorators: { onShortBreakClick: [{
9228
+ ], template: "<div class=\"position-relative h-100\">\r\n <!-- <h1>abu </h1> -->\r\n <div\r\n class=\"d-flex justify-content-between mb-3 align-items-center position-relative\"\r\n >\r\n <div class=\"col-4 global-search position-relative\">\r\n\r\n <span\r\n\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 style=\"height: 36px\"\r\n class=\"form-control\"\r\n placeholder=\"Search all columns and press Enter\"\r\n [(ngModel)]=\"tableSearch\"\r\n (keydown.enter)=\"onGlobalSearch()\"\r\n\r\n />\r\n <span\r\n *ngIf=\"tableSearch\"\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/x.svg'\"\r\n class=\"data-grid-svg-icon position-absolute end-0 top-50 translate-middle-y me-2 cursor-pointer\"\r\n (click)=\"onSearchReset()\"\r\n title=\"Clear search\"\r\n ></span>\r\n\r\n </div>\r\n\r\n <!-- Date Picker Buttons -->\r\n <!-- Date Picker Section - Improved Version -->\r\n<div class=\"position-relative d-flex justify-content-center align-items-center ms-2 date-range-container\">\r\n\r\n <!-- Hidden Date Picker Input -->\r\n <input\r\n type=\"text\"\r\n class=\"form-control\"\r\n bsDaterangepicker\r\n #picker=\"bsDaterangepicker\"\r\n [(ngModel)]=\"bsRangeValue\"\r\n [bsConfig]=\"bsConfig\"\r\n (bsValueChange)=\"onRangeSelected($event, picker)\"\r\n style=\"opacity: 0; width: 0; height: 0; position: absolute;\"\r\n />\r\n\r\n <!-- Left Arrow Button -->\r\n <span\r\n class=\"text-primary cursor-pointer me-2 date-range-btn arrow-btn\"\r\n (click)=\"navigateDate('left')\"\r\n title=\"Previous Date Range\"\r\n *ngIf=\"bsRangeValue && bsRangeValue.length > 0\"\r\n >\r\n <span class=\"bi bi-chevron-left\"></span>\r\n </span>\r\n\r\n <!-- Date Range Label -->\r\n <span\r\n *ngIf=\"bsRangeValue && bsRangeValue.length > 0\"\r\n class=\"text-primary date-range-label cursor-pointer\"\r\n (click)=\"togglePicker(picker)\"\r\n title=\"Click to open calendar\"\r\n >\r\n {{ bsRangeValue[0] | timezoneFormat:prefs:'date' }} - {{ bsRangeValue[1] | timezoneFormat:prefs:'date' }}\r\n </span>\r\n\r\n <!-- Right Arrow Button -->\r\n <span\r\n class=\"text-primary cursor-pointer ms-2 date-range-btn arrow-btn\"\r\n (click)=\"navigateDate('right')\"\r\n title=\"Next Date Range\"\r\n *ngIf=\"bsRangeValue && bsRangeValue.length > 0\"\r\n >\r\n <span class=\"bi bi-chevron-right\"></span>\r\n </span>\r\n\r\n\r\n\r\n</div>\r\n\r\n <div class=\"d-flex gap-2 align-items-center table-right-top-actions\">\r\n\r\n <!-- Pivot Mode Button -->\r\n <!-- <a\r\n href=\"JavaScript:void(0)\"\r\n class=\"button button-small btn btn-active-primary border border-primary me-2 header-icon\"\r\n (click)=\"togglePivotMode()\"\r\n [class.active]=\"pivotMode\"\r\n title=\"Toggle Pivot Mode\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/pivot.svg'\"\r\n class=\"svg-icon svg-icon-2\"\r\n ></span>\r\n </a> -->\r\n\r\n <div class=\"action-buttons-row d-flex gap-2 align-items-center\">\r\n <a\r\n href=\"JavaScript:void(0)\"\r\n class=\"button button-small btn btn-active-primary border border-primary p-0 d-flex align-items-center justify-content-center px-3\"\r\n (click)=\"togglePicker(picker)\"\r\n title=\"Select Date Range\"\r\n >\r\n <span class=\"bi bi-calendar3 text-primary\"></span>\r\n <span class=\"label-hidden text-white\">Calendar</span>\r\n </a>\r\n <button\r\n *ngIf=\"bsRangeValue && bsRangeValue.length > 0 && !isDefaultDateRange\"\r\n type=\"button\"\r\n class=\"button button-small btn btn-active-danger border border-danger p-0 d-flex align-items-center justify-content-center px-3\"\r\n (click)=\"clearDateRange()\"\r\n title=\"Clear Date Range\"\r\n >\r\n <span class=\"bi bi-x-circle text-danger\"></span>\r\n <span class=\"label-hidden text-white\">Clear</span>\r\n </button>\r\n</div>\r\n<ng-container *ngFor=\"let button of buttons\">\r\n <div\r\n class=\"action-buttons-row d-flex align-items-center\"\r\n *ngIf=\"getButtonPermission(button) && (!button.condition || (button.condition === '!isSingleDay' && !isSingleDay) || (button.condition === 'isSingleDay' && isSingleDay))\"\r\n >\r\n <a\r\n href=\"JavaScript:void(0)\"\r\n (click)=\"onActionButtonClick(button.name)\"\r\n class=\"button\"\r\n [title]=\"button.name\"\r\n >\r\n <span\r\n *ngIf=\"button.is_showIcon\"\r\n [inlineSVG]=\"button.iconPath\"\r\n class=\"svg-icon\"\r\n ></span>\r\n <span\r\n class=\"label-hidden\"\r\n >{{ button.name }}</span\r\n >\r\n </a>\r\n </div>\r\n</ng-container>\r\n\r\n<!-- Calendar Button -->\r\n\r\n\r\n<!-- Existing filter, settings, etc. -->\r\n <div\r\n *ngIf=\"!showFilterRow\"\r\n class=\"cursor-pointer position-relative action-buttons-row d-flex align-items-center\"\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 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 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\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 <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 *ngIf=\"activeFilteredColumns?.length\">\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 >\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 class=\"d-flex gap-2 align-items-center me-5\">\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 <ng-container\r\n *ngFor=\"\r\n let child of groupedColumns;\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 groupedColumns.length > 1 && i != groupedColumns.length - 1\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </div>\r\n\r\n\r\n\r\n\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 class=\"data-grid-header left-pinned\" #leftPinnedHeader>\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]=\"65\"\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</div>\r\n <div\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 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 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: 0.2px\"\r\n [style.background-color]=\"headerBackgroundColor\"\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 [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)=\"onCenterHeaderScroll($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)=\"openThreeDotsMenu($event, 'group')\"\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)=\"onResizeGroupBox($event)\"\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 === 'TimeSheet' && !areDatesSelectedAndEqual\"\r\n >\r\n </span> -->\r\n <div\r\n class=\"dragable-header\"\r\n (cdkDragStarted)=\"\r\n checkColumnGroupingStatus(col); dragStartOnGroup(col)\r\n \"\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 [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: 'centerColumns'\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 *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 *ngIf=\"!areDatesSelectedAndEqual\" class=\"header-cell border-below\" [style.width.px]=\"30\" [style.height.px]=\"headerRowHeight\" [style.backgroundColor]=\"headerBackgroundColor\"></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 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: 'previewRightPinnedColumns'\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 [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: 'centerColumns'\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\"\r\n >\r\n No Record Found\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\"\r\n style=\"\r\n z-index: 999;\r\n background: rgba(255, 255, 255, 0.8);\r\n backdrop-filter: blur(1px);\r\n \"\r\n >\r\n <div class=\"text-center p-2\">\r\n <div class=\"spinner-border text-primary\" role=\"status\"></div> Loading...\r\n</div>\r\n </div>\r\n\r\n <!-- Card View -->\r\n \r\n\r\n <!-- Table View -->\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 *ngIf=\"dataSet.length\"\r\n >\r\n <!-- LEFT PINNED -->\r\n <div [style.height.px]=\"!groupedColumns.length ? originalDataSet.length * rowHeight: 0\"></div>\r\n <div [class.h-100]=\"originalDataSet.length <= 10\">\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 *ngIf=\"!loading && !dataSetLoading\"\r\n [@rowDynamic]=\"rowAnimation\"\r\n [style.transform]=\"\r\n 'translateY(' + startIndex * rowHeight + 'px)'\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 }\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=\"\"\r\n [style.width.px]=\"centerPinnedHeader.clientWidth\"\r\n >\r\n <div\r\n class=\"data-grid-body center-scrollable\"\r\n [@rowDynamic]=\"rowAnimation\" *ngIf=\"!loading && !dataSetLoading\"\r\n style=\"overflow-y: hidden; overflow-x: auto\"\r\n [style.transform]=\"\r\n 'translateY(' + startIndex * rowHeight + 'px)'\r\n \"\r\n [style.backgroundColor]=\"bodyBackgroundColor\"\r\n #centerScrollableBody\r\n (scroll)=\"onCenterBodyScroll($event)\"\r\n [style.boxShadow]=\"leftPinnedBoxshadow\"\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: previewCenterColumns,\r\n isEven: (startIndex + i) % 2 === 0,\r\n isOdd: (startIndex + i) % 2 !== 0,\r\n section: 'center'\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 <= 10\"\r\n [style.max-width.px]=\"isScrollbarVisible ? rightPinnedHeader.offsetWidth - 15: rightPinnedHeader.offsetWidth\"\r\n >\r\n <div\r\n class=\"data-grid-body right-pinned-body w-100\"\r\n style=\"overflow-y: hidden\"\r\n [style.transform]=\"\r\n 'translateY(' + startIndex * rowHeight + 'px)'\r\n \"\r\n [style.boxShadow]=\"rightPinnedBoxshadow\"\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 }\r\n \"\r\n ></ng-container>\r\n </ng-container>\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 * (paginationConfig.totalResults || flattenedData.length)\"></div>\r\n </div>\r\n </div>\r\n\r\n <!-- Horizintal Fake Scrollbars -->\r\n <div class=\"d-flex justify-content-between\" *ngIf=\"dataSet.length\">\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)=\"onHorizintalFakeScroll($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\"></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 && !hasOpenAccordion\"\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-white]=\"\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-white]=\"\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 [style.height.px]=\"footerRowHeight\" class=\"border-top\">\r\n <!-- Rows: <span class=\"fw-500 ms-1\">{{ dataSet.length }}</span> -->\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.selectedPageSize\"\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=\"\"> per page </span>\r\n </div>\r\n\r\n <div class=\"page-info\">\r\n Results: {{ paginationConfig.page }}-{{\r\n paginationConfig.page * paginationConfig.limit\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-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)=\"onResizeGroup($event, col, pinnedRight)\"\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 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)=\"openThreeDotsMenu($event, child); openFilteronThreeDotsClick(child)\"\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)=\"openThreeDotsMenu($event, child)\"\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 >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n columnMenu;\r\n context: { col: child }\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)=\"onResizeColumn($event, child)\"\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)]=\"col.filterValue\"\r\n (ngModelChange)=\"onFilterChange(col)\"\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 ><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 class=\"group-column-wrapper\">\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\"\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)=\"openThreeDotsMenu($event, col); openFilteronThreeDotsClick(col)\"\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 <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath +\r\n (sortingConfig?.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 mt-1\"\r\n ></span>\r\n </div>\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\"\r\n [style.left.px]=\"\r\n -(!col?.pinned ? centerPinnedHeader.scrollLeft : 0)\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"columnMenu; context: { col: col }\"\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)=\"onResizeColumn($event, col)\"\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 />\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 ><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>\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 border-below d-flex align-items-center\"\r\n [style.height.px]=\"rowHeight\"\r\n [style.width]=\"\r\n section == 'center'\r\n ? centerScrollableBody?.nativeElement?.scrollWidth + '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]=\"65\"\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 >\r\n {{ row.__virtualIndex }}\r\n </div>\r\n <div\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 >\r\n <input style=\"width: 16px; height: 16px\" type=\"checkbox\" />\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 class=\"d-flex align-items-center ps-2 h-100\"\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 * 16 : 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\"\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\">\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 }\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 class=\"d-flex\" [style.height.px]=\"rowHeight\">\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=\"section == 'center' && gridType === 'TimeSheet' && detailsIconPosition === 'start' && !areDatesSelectedAndEqual\"\r\n [ngStyle]=\"{\r\n 'background-color':\r\n hoveredRowId === (row._id || row.id)\r\n ? rowHoverColor\r\n : isRowSelected(row)\r\n ? checkedRowBackgroundColor\r\n : isEven\r\n ? evenRowsBackgroundColor\r\n : oddRowsBackgroundColor\r\n }\"\r\n (click)=\"row.isDetailsExpand = !row.isDetailsExpand\"\r\n >\r\n <span\r\n class=\"data-grid-svg-icon\"\r\n [inlineSVG]=\"\r\n row.isDetailsExpand\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, row?.details?.data?.length ? 'accordion-parent' : 'main')\"\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':\r\n hoveredRowId === (row._id || row.id)\r\n ? rowHoverColor\r\n : isRowSelected(row)\r\n ? checkedRowBackgroundColor\r\n : isEven\r\n ? evenRowsBackgroundColor\r\n : oddRowsBackgroundColor\r\n }\"\r\n ></div>\r\n <div\r\n (contextmenu)=\"onRightClick($event, row, row?.details?.data?.length ? 'accordion-parent' : 'main')\"\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':\r\n hoveredRowId === (row._id || row.id)\r\n ? rowHoverColor\r\n : isRowSelected(row)\r\n ? checkedRowBackgroundColor\r\n : isEven\r\n ? evenRowsBackgroundColor\r\n : oddRowsBackgroundColor\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]=\"65\"\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 >\r\n {{ row.__virtualIndex }}\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\"\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 >\r\n <input\r\n *ngIf=\"hasAnyVisibleColumn\"\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 }\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\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 }\r\n \"\r\n ></ng-container>\r\n </ng-template>\r\n </ng-container>\r\n </div>\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=\"section == 'center' && gridType === 'TimeSheet' && detailsIconPosition === 'end' && !areDatesSelectedAndEqual\"\r\n [ngStyle]=\"{\r\n 'background-color':\r\n hoveredRowId === (row._id || row.id)\r\n ? rowHoverColor\r\n : isRowSelected(row)\r\n ? checkedRowBackgroundColor\r\n : isEven\r\n ? evenRowsBackgroundColor\r\n : oddRowsBackgroundColor\r\n }\"\r\n (click)=\"row.isDetailsExpand = !row.isDetailsExpand\"\r\n >\r\n <span\r\n class=\"data-grid-svg-icon\"\r\n [inlineSVG]=\"\r\n row.isDetailsExpand\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 <!-- LEFT PINNED: Empty table to keep alignment -->\r\n <div *ngIf=\"section === 'left' && row.isDetailsExpand && !isSingleDay\" class=\"accordion-details data-grid-accordion-section\" [style.color]=\"headerTextColor\" style=\"max-height: 350px; min-height: 150px ; overflow: hidden;\">\r\n <table class=\"nested-table table table-sm w-100 mb-0 data-grid-accordion-table\" [class.show-shadow]=\"rowShadingEnabled\">\r\n <thead>\r\n <tr [style.height.px]=\"nestedTableHeaderRowHeight\" [style.backgroundColor]=\"headerBackgroundColor\" [style.color]=\"headerTextColor\" [style.fontSize.px]=\"headerTextFontsSize\" [style.fontWeight]=\"headerFontWeight\">\r\n <th *ngFor=\"let _ of [1, 2, 3, 4, 5]\"></th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <tr [style.height.px]=\"nestedTablerowHeight\" *ngFor=\"let _ of row.details.data\" [style.backgroundColor]=\"headerBackgroundColor\">\r\n <td *ngFor=\"let __ of [1, 2, 3, 4, 5]\"></td>\r\n </tr>\r\n </tbody>\r\n </table>\r\n </div>\r\n\r\n<!-- CENTER SECTION: Actual details table -->\r\n\r\n<div *ngIf=\"section === 'center' && row.isDetailsExpand && !isSingleDay\" class=\"accordion-details-wrapper data-grid-accordion\" [style.fontFamily]=\"fontFaimly\" [style.fontSize.px]=\"bodyTextFontsSize\" style=\"display: flex; width: 100%; max-height: 350px; min-height: 150px ; overflow: hidden ; \">\r\n <!-- LEFT SECTION OF ACCORDION -->\r\n <div #leftContainer class=\"accordion-left-section data-pin-body-wrapper data-grid-accordion-section\" [attr.data-detail-row-id]=\"row._id || row.id\" (scroll)=\"onDetailLeftScroll($event, row)\" style=\"flex-shrink: 0; overflow-y: auto; overflow-x: hidden;\">\r\n <table class=\"nested-table table-sm mb-0 data-grid-accordion-table\" [class.show-borders]=\"showVerticalBorder\" [class.show-shadow]=\"rowShadingEnabled\" style=\"table-layout: fixed; width: auto;\">\r\n <thead>\r\n <tr [style.height.px]=\"nestedTableHeaderRowHeight\" [style.backgroundColor]=\"headerBackgroundColor\" [style.color]=\"headerTextColor\" [style.fontSize.px]=\"headerTextFontsSize\" [style.fontWeight]=\"headerFontWeight\">\r\n <ng-container *ngFor=\"let col of row.details.columns | pinnedColumns:'left'; trackBy: trackByField\">\r\n <th *ngIf=\"col.is_visible !== false\"\r\n class=\"px-4\"\r\n [class.filter-applied]=\"isAccordionColumnFiltered(row, col)\"\r\n [attr.field]=\"col.field\"\r\n [attr.pinned]=\"col.pinned\"\r\n [style.width.px]=\"col.width || 150\"\r\n [style.min-width.px]=\"col.width || 150\">\r\n <div class=\"d-flex justify-content-between align-items-center\" style=\"width: 100%;\">\r\n <span class=\"d-flex align-items-center gap-1\">\r\n <span *ngIf=\"col.pinned\" [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/pin-blue.svg'\" class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"></span>\r\n {{ col.header }}\r\n <span *ngIf=\"isAccordionColumnFiltered(row, col)\"\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\"\r\n class=\"data-grid-svg-icon text-primary ms-1\"\r\n style=\"font-size: 12px;\"></span>\r\n </span>\r\n <span class=\"three-dots p-1\"\r\n (click)=\"openDetailThreeDotsMenus($event, col, row)\"\r\n style=\"cursor: pointer;\">\r\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/three-dots-vertical.svg'\" class=\"data-grid-svg-icon\"></span>\r\n </span>\r\n </div>\r\n <!-- <div class=\"resize-handles\" (mousedown)=\"onResizeDetailColumn($event, row, col)\">\r\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/resize-handle.svg'\" class=\"data-grid-svg-icon text-primary\"></span>\r\n </div> -->\r\n <ng-container *ngIf=\"activeDetailCol?.field == col.field && activeDetailRow === row\">\r\n <div class=\"position-absolute detail-column-menu-wrapper\"\r\n [style.top.px]=\"nestedTableHeaderRowHeight\"\r\n [style.left.px]=\"0\">\r\n <ng-container *ngTemplateOutlet=\"detailColumnMenu; context: { col: col, row: row }\"></ng-container>\r\n </div>\r\n </ng-container>\r\n </th>\r\n </ng-container>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <tr [style.height.px]=\"nestedTablerowHeight\" *ngFor=\"let d of row.details.data; let j = index; trackBy: trackById\">\r\n <ng-container *ngFor=\"let col of row.details.columns | pinnedColumns:'left'; let localK = index; trackBy: trackByField\">\r\n <td *ngIf=\"col.is_visible !== false\"\r\n class=\"px-4\"\r\n (mousedown)=\"startDetailSelection(row, j, localK, col.field, $event, 'left')\"\r\n (mouseenter)=\"extendDetailSelection(row, j, localK, col.field, $event, 'left')\"\r\n [class.selected-cell]=\"isDetailCellSelected(row, j, localK, col.field, 'left')\"\r\n [attr.field]=\"col.field\"\r\n [attr.pinned]=\"col.pinned\"\r\n [style.fontSize.px]=\"nestedTablerowFontsize\"\r\n (dblclick)=\"enableDetailEdits(row, d, col)\"\r\n [class.active-cell-detail]=\"isActiveDetailCell(row, d, col)\">\r\n <!-- Use the same rendering logic as center section -->\r\n <ng-container [ngSwitch]=\"col.field\">\r\n\r\n <ng-container *ngSwitchCase=\"'manually_logs'\" class=\"d-flex justify-content-start align-items-center pointer position-relative\">\r\n <ng-container *ngIf=\"d.manually_logs?.length > 0; else noManualLogsIcon\">\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/eye.svg'\"\r\n class=\"data-grid-svg-icon text-primary\"\r\n style=\"cursor: pointer; font-size: 16px;\"\r\n (mouseenter)=\"showManualLogsTooltip($event, row, d)\"\r\n (mouseleave)=\"hideManualLogsTooltip()\">\r\n </span>\r\n </ng-container>\r\n <ng-template #noManualLogsIcon>\u2013</ng-template>\r\n</ng-container>\r\n <!-- Breaks -->\r\n <ng-container *ngSwitchCase=\"'breaks'\">\r\n <ng-container *ngIf=\"d[col.field]?.length; else noBreaksLeft\">\r\n <app-badge-overflow\r\n [badges]=\"getBreakBadges(d[col.field])\"\r\n [maxWidth]=\"col.width || 200\"\r\n (badgeMouseEnter)=\"showBreakTooltip($event.event, $event.badge.data)\"\r\n (badgeMouseLeave)=\"hideBreakTooltip()\"\r\n (overflowCountClick)=\"onDetailBadgeOverflowCountClick(col, d)\">\r\n</app-badge-overflow>\r\n </ng-container>\r\n <ng-template #noBreaksLeft>\r\n <div >\r\n -\r\n </div>\r\n </ng-template>\r\n </ng-container>\r\n\r\n <!-- Short Breaks -->\r\n <ng-container *ngSwitchCase=\"'short_breaks'\">\r\n <ng-container *ngIf=\"d[col.field]?.short_break_duration; else noShortBreakLeft\">\r\n <div (dblclick)=\"onShortBreakClick.emit(d)\">\r\n <app-badge-overflow\r\n [badges]=\"getShortBreakBadges(d[col.field])\"\r\n [maxWidth]=\"col.width || 200\"\r\n (badgeMouseEnter)=\"showShortBreakTooltip($event.event, $event.badge.data)\"\r\n (badgeMouseLeave)=\"hideShortBreakTooltip()\"\r\n (badgeClick)=\"handleShortBreakClick(d, $event)\"\r\n (overflowCountClick)=\"onDetailBadgeOverflowCountClick(col, d)\">\r\n </app-badge-overflow>\r\n </div>\r\n </ng-container>\r\n <ng-template #noShortBreakLeft>\r\n <div >-</div>\r\n </ng-template>\r\n </ng-container>\r\n\r\n <!-- Short Leave -->\r\n <!-- Short Leave -->\r\n<ng-container *ngSwitchCase=\"'short_leave'\">\r\n <ng-container *ngIf=\"row.short_leave && row.short_leave.length > 0; else noShortLeaveMain\">\r\n <div class=\"w-100 d-flex main-progress-bar justify-content-center align-items-center\" \r\n style=\"background-color: rgb(111, 97, 207); height: 20px; border-radius: 4px; position: relative;\"\r\n (mouseenter)=\"showShortLeaveTooltip($event, row)\"\r\n (mouseleave)=\"hideShortLeaveTooltip()\">\r\n <span class=\"d-block\" [style.min-width.%]=\"row.short_leave[0].short_leave_time_percentage\" \r\n style=\"background-color: rgb(238, 99, 82); height: 100%; border-radius: 4px;\"></span>\r\n <span style=\"position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); color: white; font-size: 12px; font-weight: bold;\">\r\n {{ row.short_leave[0].short_leave_time_percentage }}%\r\n </span>\r\n </div>\r\n </ng-container>\r\n <ng-template #noShortLeaveMain>-</ng-template>\r\n</ng-container>\r\n\r\n<div *ngSwitchCase=\"'is_un_restricted'\" class=\"d-flex justify-content-start flex-column pointer position-relative\" (mouseenter)=\"showRestrictionTooltip($event, row, d); preventRestrictionTooltipHide()\" (mouseleave)=\"hideRestrictionTooltip()\">\r\n <span class=\"\" [class.restriction-indicator]=\"row.attendance_log_detail?.length > 0\">\r\n {{ d.is_un_restricted ? 'Yes' : 'No' }}\r\n </span>\r\n </div>\r\n\r\n <div *ngSwitchCase=\"'is_payroll_processed'\" class=\"d-flex justify-content-start flex-column pointer position-relative\" >\r\n <span class=\"\" >\r\n {{ d.is_payroll_processed ? 'Yes' : 'No' }}\r\n </span>\r\n </div>\r\n\r\n\r\n <!-- Status -->\r\n <ng-container *ngSwitchCase=\"'status'\">\r\n <ng-container *ngIf=\"getNestedValue(d, col.field); else noStatus\">\r\n <span class=\"badge\" [class]=\"getStatusBadgeClass(getNestedValue(d, col.field))\">\r\n {{ transformStatus(getNestedValue(d, col.field)) }}\r\n </span>\r\n </ng-container>\r\n <ng-template #noStatus>-</ng-template>\r\n</ng-container>\r\n\r\n<!-- Attendance Status -->\r\n<ng-container *ngSwitchCase=\"'attendanceStatus'\">\r\n <ng-container *ngIf=\"getNestedValue(d, col.field); else noAttendanceStatus\">\r\n <span class=\"badge\" [class]=\"getAttendanceStatusBadgeClass(getNestedValue(d, col.field))\">\r\n {{ transformStatus(getNestedValue(d, col.field)) }}\r\n </span>\r\n </ng-container>\r\n <ng-template #noAttendanceStatus>-</ng-template>\r\n</ng-container>\r\n\r\n <!-- Default fallback -->\r\n <ng-container *ngSwitchDefault>\r\n {{\r\n col.type === 'date'\r\n ? (getNestedValue(d, col.field) ? (getNestedValue(d, col.field) | timezoneFormat:prefs:'date') : '-')\r\n : col.type === 'time'\r\n ? ((getTimeValue(getNestedValue(d, col.field)) | timezoneFormat:prefs:'time'))\r\n : (getNestedValue(d, col.field)?.value || getNestedValue(d, col.field)?.name || getNestedValue(d, col.field) || '-')\r\n }}\r\n </ng-container>\r\n </ng-container>\r\n </td>\r\n </ng-container>\r\n </tr>\r\n</tbody>\r\n </table>\r\n </div>\r\n\r\n <!-- CENTER SECTION OF ACCORDION (WITH VIRTUAL SCROLL) -->\r\n\r\n<div class=\"accordion-center-section data-grid-accordion-section\" style=\"flex: 1; min-width: 0; display: flex; flex-direction: column; overflow: hidden;\">\r\n <!-- Header Section -->\r\n <div class=\"header-container\" style=\"overflow-x: auto; scrollbar-width: none; -ms-overflow-style: none;\" #headerContainer (scroll)=\"syncScroll($event)\">\r\n <table class=\"nested-table table-sm mb-0 data-grid-accordion-table\" [class.show-borders]=\"showVerticalBorder\" [class.show-shadow]=\"rowShadingEnabled\" style=\"table-layout: fixed; width: 100%;\">\r\n <thead>\r\n <tr\r\n [style.height.px]=\"nestedTableHeaderRowHeight\"\r\n cdkDropList\r\n [cdkDropListData]=\"row?.details.columns\"\r\n cdkDropListOrientation=\"horizontal\"\r\n (cdkDropListDropped)=\"dropColumn($event, row)\">\r\n <ng-container *ngFor=\"let col of row.details.columns; let i = index\">\r\n <th\r\n *ngIf=\"col.is_visible !== false && !col.pinned\"\r\n class=\"px-4\"\r\n cdkDrag\r\n [attr.field]=\"col.field\"\r\n [class.filter-applied]=\"isAccordionColumnFiltered(row, col)\"\r\n [style.width.px]=\"col.width || 150\"\r\n [style.min-width.px]=\"col.width || 150\"\r\n [style.backgroundColor]=\"headerBackgroundColor\"\r\n [style.color]=\"headerTextColor\"\r\n [style.fontSize.px]=\"headerTextFontsSize\"\r\n [style.fontWeight]=\"headerFontWeight\"\r\n style=\"cursor: move; position: relative;\">\r\n <div class=\"d-flex justify-content-between align-items-center\" style=\"width: 100%;\">\r\n <span class=\"d-flex align-items-center gap-1\">\r\n <span *ngIf=\"col.pinned\" [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/pin-blue.svg'\" class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"></span>\r\n {{ col.header }}\r\n <span *ngIf=\"isAccordionColumnFiltered(row, col)\"\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\"\r\n class=\"data-grid-svg-icon text-primary ms-1\"\r\n style=\"font-size: 12px;\"></span>\r\n </span>\r\n <span\r\n class=\"three-dots p-1\"\r\n (click)=\"openDetailThreeDotsMenus($event, col, row); activeDetailCol = col; activeDetailRow = row\"\r\n style=\"cursor: pointer;\">\r\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/three-dots-vertical.svg'\" class=\"data-grid-svg-icon\"></span>\r\n </span>\r\n </div>\r\n <!-- <div class=\"resize-handles\" (mousedown)=\"onResizeDetailColumn($event, row, col)\">\r\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/resize-handle.svg'\" class=\"data-grid-svg-icon text-primary\"></span>\r\n </div> -->\r\n <ng-container *ngIf=\"activeDetailCol?.field == col.field && activeDetailRow === row\">\r\n <div class=\"position-absolute detail-column-menu-wrapper\" [style.top.px]=\"nestedTableHeaderRowHeight\" [style.left.px]=\"0\">\r\n <ng-container *ngTemplateOutlet=\"detailColumnMenu; context: { col: col, row: row }\"></ng-container>\r\n </div>\r\n </ng-container>\r\n </th>\r\n </ng-container>\r\n </tr>\r\n </thead>\r\n </table>\r\n </div>\r\n\r\n <!-- Group Badges (if any) -->\r\n <div *ngIf=\"row.details?.groupedColumns?.length\" class=\"detail-group-badges\">\r\n <span *ngFor=\"let g of row.details.groupedColumns; trackBy: trackByField\" class=\"badge bg-light text-dark me-1\">\r\n {{ g.header }}\r\n <span class=\"ms-1 cursor-pointer\" (click)=\"ungroupDetailColumn(g, row)\" [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/x.svg'\"></span>\r\n </span>\r\n </div>\r\n\r\n <!-- No Data Message when filtered results are empty -->\r\n <div *ngIf=\"row.details.data.length === 0\" class=\"d-flex justify-content-center align-items-center\" style=\"flex: 1; min-height: 104px ;\">\r\n <div class=\"text-center text-muted\">\r\n <div class=\"mb-2\">\r\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\" class=\"data-grid-svg-icon text-muted\" style=\"font-size: 24px;\"></span>\r\n </div>\r\n <div class=\"fw-bold\">No records found for this filter.</div>\r\n </div>\r\n </div>\r\n\r\n <!-- Data Table Section with Virtual Scroll -->\r\n <cdk-virtual-scroll-viewport\r\n *ngIf=\"row.details.data.length > 0\"\r\n itemSize=\"{{ nestedTablerowHeight }}\"\r\n minBufferPx=\"200\"\r\n maxBufferPx=\"400\"\r\n class=\"detail-virtual-scroll\"\r\n [attr.data-detail-row-id]=\"row._id || row.id\"\r\n style=\"flex: 1; overflow: auto;\"\r\n #dataContainer\r\n (scroll)=\"syncVerticalScroll($event)\"\r\n (scroll)=\"syncScroll($event)\">\r\n <table class=\"nested-table table-sm mb-0 data-grid-accordion-table\" [class.show-borders]=\"showVerticalBorder\" [class.show-shadow]=\"rowShadingEnabled\" style=\"table-layout: fixed; width: 100%;\">\r\n <tbody>\r\n <tr\r\n class=\"cursor-pointer data-grid-accordion-row\"\r\n *cdkVirtualFor=\"let d of row.details.data; trackBy: trackById; let j = index\"\r\n (contextmenu)=\"onRightClick($event, d, 'accordion-child')\"\r\n [style.height.px]=\"nestedTablerowHeight\">\r\n <ng-container *ngFor=\"let col of row.details.columns; let k = index\">\r\n <td\r\n *ngIf=\"col.is_visible !== false && !col.pinned\"\r\n class=\"px-4\"\r\n (mousedown)=\"startDetailSelection(row, j, k, col.field, $event, 'center')\"\r\n (mouseenter)=\"extendDetailSelection(row, j, k, col.field, $event, 'center')\"\r\n [class.selected-cell]=\"isDetailCellSelected(row, j, k, col.field, 'center')\"\r\n [attr.field]=\"col.field\"\r\n [style.width.px]=\"col.width || 150\"\r\n [style.min-width.px]=\"col.width || 150\"\r\n [style.fontSize.px]=\"bodyTextFontsSize\"\r\n [class.active-cell-detail]=\"isActiveDetailCell(row, d, col)\"\r\n style=\"cursor: pointer; position: relative; overflow: visible; cursor: cell; \">\r\n <div class=\"time-sheet-container\" style=\"overflow: visible; display: flex; gap: 4px; align-items: center; height: 100%; justify-content: center;\">\r\n <ng-container *ngIf=\"col.field === 'breaks' || col.field === 'short_breaks'; else defaultDetailCell\">\r\n <ng-container *ngIf=\"col.field === 'breaks'\">\r\n <ng-container *ngIf=\"d[col.field]?.length; else noBreaks\">\r\n <span *ngFor=\"let breakItem of d[col.field]; let breakIndex = index\"\r\n class=\"circle-value badge-outline break-on text-center\"\r\n [ngClass]=\"(breakItem.break_type?.data_value_name?.toLowerCase() || breakItem.breakType?.toLowerCase()) === 'paid' ? 'break-color-paid' : (breakItem.break_type?.data_value_name?.toLowerCase() || breakItem.breakType?.toLowerCase()) === 'unpaid' ? 'break-color-unpaid' : (breakItem.break_type?.data_value_name?.toLowerCase() || breakItem.breakType?.toLowerCase()) === 'lunch' ? 'break-color-lunch' : 'break-color-default'\"\r\n (mouseenter)=\"showBreakTooltip($event, breakItem)\"\r\n (mouseleave)=\"hideBreakTooltip()\">\r\n {{ breakItem.break_duration }}m\r\n</span>\r\n </ng-container>\r\n <ng-template #noBreaks>\r\n <div\r\n \r\n >\r\n -\r\n</div>\r\n</ng-template>\r\n</ng-container>\r\n <ng-container *ngIf=\"col.field === 'short_breaks' && !isDetailEditing(row, d, col)\">\r\n <ng-container *ngIf=\"d[col.field]?.short_break_duration; else noShortBreak\">\r\n <div (dblclick)=\"onShortBreakClick.emit(d)\">\r\n <app-badge-overflow\r\n [badges]=\"getShortBreakBadges(d[col.field])\"\r\n [maxWidth]=\"col.width || 200\"\r\n (badgeMouseEnter)=\"showShortBreakTooltip($event.event, $event.badge.data)\"\r\n (badgeMouseLeave)=\"hideShortBreakTooltip()\"\r\n (badgeClick)=\"handleShortBreakClick(d, $event)\"\r\n (overflowCountClick)=\"onDetailBadgeOverflowCountClick(col, d)\">\r\n </app-badge-overflow>\r\n </div>\r\n </ng-container>\r\n <ng-template #noShortBreak>\r\n <div >-</div>\r\n </ng-template>\r\n</ng-container>\r\n <ng-container *ngIf=\"isDetailEditing(row, d, col)\">\r\n <input #detailInput type=\"text\" [ngModel]=\"getNestedValue(d, col.field)\" (blur)=\"disableDetailEdits(row, d, col)\" (keydown.enter)=\"disableDetailEdits(row, d, col)\" (keydown.escape)=\"disableDetailEdits(row, d, col)\" [attr.data-edit-key]=\"row._id + '-' + j + '-' + col.field\" class=\"form-control form-control-sm\" style=\"width: 100%; height: auto; position: absolute; top: 0; left: 0; z-index: 10;\" />\r\n </ng-container>\r\n </ng-container>\r\n <ng-template #defaultDetailCell>\r\n <span class=\"d-flex align-items-center h-100\">\r\n <ng-container *ngIf=\"!isDetailEditing(row, d, col)\">\r\n <ng-container [ngSwitch]=\"col.field\">\r\n <!-- \u2705 SHORT LEAVE: Progress bar in detail rows -->\r\n <div *ngSwitchCase=\"'short_leave'\" class=\"position-relative\" style=\"min-width: 100px; width: 150px;\">\r\n <ng-container *ngIf=\"d.short_leave && d.short_leave.length > 0; else noShortLeaveDetail\">\r\n <div\r\n class=\"w-100 d-flex main-progress-bar\"\r\n style=\"background-color: rgb(111, 97, 207); height: 20px; border-radius: 4px; position: relative;\"\r\n (mouseenter)=\"showShortLeaveTooltip($event, d)\"\r\n (mouseleave)=\"hideShortLeaveTooltip()\"\r\n >\r\n <span\r\n class=\"d-block\"\r\n [style.min-width.%]=\"d.short_leave[0].short_leave_time_percentage\"\r\n style=\"background-color: rgb(238, 99, 82); height: 100%; border-radius: 4px;\"\r\n ></span>\r\n <span style=\"position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); color: white; font-size: 12px; font-weight: bold;\">{{ d.short_leave[0].short_leave_time_percentage }}%</span>\r\n </div>\r\n </ng-container>\r\n <ng-template #noShortLeaveDetail>\r\n <div >-</div>\r\n </ng-template>\r\n </div>\r\n\r\n <!-- Status -->\r\n<ng-container *ngSwitchCase=\"'status'\">\r\n <ng-container *ngIf=\"getNestedValue(d, col.field); else noStatus\">\r\n <span class=\"badge\" [class]=\"getStatusBadgeClass(getNestedValue(d, col.field))\">\r\n {{ transformStatus(getNestedValue(d, col.field)) }}\r\n </span>\r\n </ng-container>\r\n <ng-template #noStatus>-</ng-template>\r\n</ng-container>\r\n\r\n<!-- Attendance Status -->\r\n<ng-container *ngSwitchCase=\"'attendanceStatus'\">\r\n <ng-container *ngIf=\"getNestedValue(d, col.field); else noAttendanceStatus\">\r\n <span class=\"badge\" [class]=\"getAttendanceStatusBadgeClass(getNestedValue(d, col.field))\">\r\n {{ transformStatus(getNestedValue(d, col.field)) }}\r\n </span>\r\n </ng-container>\r\n <ng-template #noAttendanceStatus>-</ng-template>\r\n</ng-container>\r\n\r\n <!-- Existing cases -->\r\n <div *ngSwitchCase=\"'is_un_restricted'\" class=\"d-flex justify-content-start flex-column pointer position-relative\" (mouseenter)=\"showRestrictionTooltip($event, row, d); preventRestrictionTooltipHide()\" (mouseleave)=\"hideRestrictionTooltip()\">\r\n <span class=\"popover__wrapper\" [class.restriction-indicator]=\"row.attendance_log_detail?.length > 0\">\r\n {{ d.is_un_restricted ? 'Yes' : 'No' }}\r\n </span>\r\n </div>\r\n\r\n <div *ngSwitchCase=\"'is_payroll_processed'\" class=\"d-flex justify-content-start flex-column pointer position-relative\" >\r\n <span class=\"\" >\r\n {{ d.is_payroll_processed ? 'Yes' : 'No' }}\r\n </span>\r\n </div>\r\n <div *ngSwitchCase=\"'manually_logs'\" class=\"d-flex justify-content-start align-items-center pointer position-relative\">\r\n <ng-container *ngIf=\"d.manually_logs?.length > 0; else noManualLogsIcon\">\r\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/eye.svg'\" class=\"data-grid-svg-icon text-primary\" style=\"cursor: pointer; font-size: 16px;\" (mouseenter)=\"showManualLogsTooltip($event, row, d)\" (mouseleave)=\"hideManualLogsTooltip()\"></span>\r\n </ng-container>\r\n <ng-template #noManualLogsIcon>\r\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/eye-cross.svg'\" class=\"data-grid-svg-icon text-muted\" style=\"font-size: 16px; cursor: not-allowed;\"></span>\r\n </ng-template>\r\n </div>\r\n\r\n <!-- Default fallback -->\r\n <span *ngSwitchDefault>\r\n {{\r\n col.type === 'date'\r\n ? (getNestedValue(d, col.field) ? (getNestedValue(d, col.field) | timezoneFormat:prefs:'date') : '-')\r\n : col.type === 'time'\r\n ? ((getTimeValue(getNestedValue(d, col.field)) | timezoneFormat:prefs:'time'))\r\n : (getNestedValue(d, col.field)?.value || getNestedValue(d, col.field)?.name || getNestedValue(d, col.field) || '-')\r\n }}\r\n </span>\r\n</ng-container>\r\n </ng-container>\r\n <ng-container *ngIf=\"isDetailEditing(row, d, col)\">\r\n <ng-container [ngSwitch]=\"col.type\">\r\n <input *ngSwitchCase=\"'string'\" #detailInput type=\"text\" [ngModel]=\"getNestedValue(d, col.field)\" (blur)=\"disableDetailEdits(row, d, col)\" (keydown.enter)=\"disableDetailEdits(row, d, col)\" (keydown.escape)=\"disableDetailEdits(row, d, col)\" class=\"form-control form-control-sm\" style=\"width: 100%; height: auto;\" />\r\n <input *ngSwitchCase=\"'number'\" #detailInput type=\"number\" [ngModel]=\"getNestedValue(d, col.field)\" (blur)=\"disableDetailEdits(row, d, col)\" (keydown.enter)=\"disableDetailEdits(row, d, col)\" (keydown.escape)=\"disableDetailEdits(row, d, col)\" class=\"form-control form-control-sm\" style=\"width: 100%; height: auto;\" />\r\n <input *ngSwitchCase=\"'date'\" #detailInput type=\"date\" [ngModel]=\"getNestedValue(d, col.field)\" (blur)=\"disableDetailEdits(row, d, col)\" (keydown.enter)=\"disableDetailEdits(row, d, col)\" (keydown.escape)=\"disableDetailEdits(row, d, col)\" class=\"form-control form-control-sm\" style=\"width: 100%; height: auto;\" />\r\n <input *ngSwitchCase=\"'time'\" #detailInput type=\"time\" [ngModel]=\"getNestedValue(d, col.field)\" (blur)=\"disableDetailEdits(row, d, col)\" (keydown.enter)=\"disableDetailEdits(row, d, col)\" (keydown.escape)=\"disableDetailEdits(row, d, col)\" class=\"form-control form-control-sm\" style=\"width: 100%; height: auto;\" />\r\n <input *ngSwitchCase=\"'currency'\" #detailInput type=\"number\" step=\"0.01\" [ngModel]=\"getNestedValue(d, col.field)\" (blur)=\"disableDetailEdits(row, d, col)\" (keydown.enter)=\"disableDetailEdits(row, d, col)\" (keydown.escape)=\"disableDetailEdits(row, d, col)\" class=\"form-control form-control-sm text-end\" style=\"width: 100%; height: auto;\" />\r\n <select *ngSwitchCase=\"'dropdown'\" #detailInput [ngModel]=\"getNestedValue(d, col.field)\" (blur)=\"disableDetailEdits(row, d, col)\" (keydown.enter)=\"disableDetailEdits(row, d, col)\" (keydown.escape)=\"disableDetailEdits(row, d, col)\" class=\"form-control form-control-sm\" style=\"width: 100%; height: auto;\">\r\n <option *ngFor=\"let option of col.column_dropdown_value\" [ngValue]=\"option?.value || option\">\r\n {{ option?.label || option?.name || option }}\r\n </option>\r\n </select>\r\n <input *ngSwitchDefault #detailInput type=\"text\" [ngModel]=\"getNestedValue(d, col.field)\" (blur)=\"disableDetailEdits(row, d, col)\" (keydown.enter)=\"disableDetailEdits(row, d, col)\" (keydown.escape)=\"disableDetailEdits(row, d, col)\" class=\"form-control form-control-sm\" style=\"width: 100%; height: auto;\" />\r\n </ng-container>\r\n </ng-container>\r\n </span>\r\n </ng-template>\r\n </div>\r\n </td>\r\n </ng-container>\r\n </tr>\r\n </tbody>\r\n </table>\r\n </cdk-virtual-scroll-viewport>\r\n</div>\r\n\r\n <!-- RIGHT SECTION OF ACCORDION -->\r\n <div #rightContainer class=\"accordion-right-section data-pin-body-wrapper \" [attr.data-detail-row-id]=\"row._id || row.id\" (scroll)=\"onDetailRightScroll($event, row)\" style=\"flex-shrink: 0; overflow-y: auto; overflow-x: hidden;\">\r\n <table class=\"nested-table table-sm mb-0 data-grid-accordion-table\" [class.show-shadow]=\"rowShadingEnabled\" style=\"table-layout: fixed; width: auto;\">\r\n <thead>\r\n <tr [style.height.px]=\"nestedTableHeaderRowHeight\" [style.backgroundColor]=\"headerBackgroundColor\" [style.color]=\"headerTextColor\" [style.fontSize.px]=\"headerTextFontsSize\" [style.fontWeight]=\"headerFontWeight\">\r\n <ng-container *ngFor=\"let col of row.details.columns | pinnedColumns:'right'; trackBy: trackByField\">\r\n <th *ngIf=\"col.is_visible !== false\"\r\n class=\"px-4\"\r\n [class.filter-applied]=\"isAccordionColumnFiltered(row, col)\"\r\n [style.width.px]=\"col.width || 150\"\r\n [style.min-width.px]=\"col.width || 150\"\r\n [attr.field]=\"col.field\"\r\n [attr.pinned]=\"col.pinned\">\r\n <div class=\"d-flex justify-content-between align-items-center\" style=\"width: 100%;\">\r\n <span class=\"d-flex align-items-center gap-1\">\r\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/pin-blue.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"></span>\r\n {{ col.header }}\r\n <span *ngIf=\"isAccordionColumnFiltered(row, col)\"\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\"\r\n class=\"data-grid-svg-icon text-primary ms-1\"\r\n style=\"font-size: 12px;\"></span>\r\n </span>\r\n <span class=\"three-dots p-1\"\r\n (click)=\"openDetailThreeDotsMenus($event, col, row); activeDetailCol = col; activeDetailRow = row\"\r\n style=\"cursor: pointer;\">\r\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/three-dots-vertical.svg'\" class=\"data-grid-svg-icon\"></span>\r\n </span>\r\n</div>\r\n\r\n <!-- <div class=\"resize-handles\" (mousedown)=\"onResizeDetailColumn($event, row, col)\">\r\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/resize-handle.svg'\" class=\"data-grid-svg-icon text-primary\"></span>\r\n </div> -->\r\n <ng-container *ngIf=\"activeDetailCol?.field == col.field && activeDetailRow === row\">\r\n <div class=\"position-absolute detail-column-menu-wrapper\"\r\n [style.top.px]=\"nestedTableHeaderRowHeight\"\r\n [style.left.px]=\"0\">\r\n <ng-container *ngTemplateOutlet=\"detailColumnMenu; context: { col: col, row: row }\"></ng-container>\r\n </div>\r\n </ng-container>\r\n </th>\r\n </ng-container>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <tr [style.height.px]=\"nestedTablerowHeight\" *ngFor=\"let d of row.details.data; let j = index; trackBy: trackById\">\r\n <ng-container *ngFor=\"let col of row.details.columns | pinnedColumns:'right'; let localK = index; trackBy: trackByField\">\r\n <td *ngIf=\"col.is_visible !== false\"\r\n class=\"px-4\"\r\n [attr.field]=\"col.field\"\r\n [attr.pinned]=\"col.pinned\"\r\n (mousedown)=\"startDetailSelection(row, j, localK, col.field, $event, 'right')\"\r\n (mouseenter)=\"extendDetailSelection(row, j, localK, col.field, $event, 'right')\"\r\n [class.selected-cell]=\"isDetailCellSelected(row, j, localK, col.field, 'right')\"\r\n [style.fontSize.px]=\"bodyTextFontsSize\"\r\n [class.active-cell-detail]=\"isActiveDetailCell(row, d, col)\">\r\n <ng-container [ngSwitch]=\"col.field\">\r\n\r\n <ng-container *ngSwitchCase=\"'manually_logs'\" class=\"d-flex justify-content-start align-items-center pointer position-relative\">\r\n <ng-container *ngIf=\"d.manually_logs?.length > 0; else noManualLogsIcon\">\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/eye.svg'\"\r\n class=\"data-grid-svg-icon text-primary\"\r\n style=\"cursor: pointer; font-size: 16px;\"\r\n (mouseenter)=\"showManualLogsTooltip($event, row, d)\"\r\n (mouseleave)=\"hideManualLogsTooltip()\">\r\n </span>\r\n </ng-container>\r\n <ng-template #noManualLogsIcon>\u2013</ng-template>\r\n</ng-container>\r\n <!-- Breaks -->\r\n <ng-container *ngSwitchCase=\"'breaks'\">\r\n <ng-container *ngIf=\"d[col.field]?.length; else noBreaksLeft\">\r\n <app-badge-overflow\r\n [badges]=\"getBreakBadges(d[col.field])\"\r\n [maxWidth]=\"col.width || 200\"\r\n (badgeMouseEnter)=\"showBreakTooltip($event.event, $event.badge.data)\"\r\n (badgeMouseLeave)=\"hideBreakTooltip()\"\r\n (overflowCountClick)=\"onDetailBadgeOverflowCountClick(col, d)\">\r\n</app-badge-overflow>\r\n </ng-container>\r\n <ng-template #noBreaksLeft>\r\n <div>\r\n -\r\n </div>\r\n </ng-template>\r\n </ng-container>\r\n\r\n <div *ngSwitchCase=\"'is_un_restricted'\" class=\"d-flex justify-content-start flex-column pointer position-relative\" (mouseenter)=\"showRestrictionTooltip($event, row, d); preventRestrictionTooltipHide()\" (mouseleave)=\"hideRestrictionTooltip()\">\r\n <span class=\"\" [class.restriction-indicator]=\"row.attendance_log_detail?.length > 0\">\r\n {{ d.is_un_restricted ? 'Yes' : 'No' }}\r\n </span>\r\n </div>\r\n\r\n <div *ngSwitchCase=\"'is_payroll_processed'\" class=\"d-flex justify-content-start flex-column pointer position-relative\" >\r\n <span class=\"\" >\r\n {{ d.is_payroll_processed ? 'Yes' : 'No' }}\r\n </span>\r\n </div>\r\n\r\n <!-- Short Breaks -->\r\n <ng-container *ngSwitchCase=\"'short_breaks'\">\r\n <ng-container *ngIf=\"d[col.field]?.short_break_duration; else noShortBreakLeft\">\r\n <div (dblclick)=\"onShortBreakClick.emit(d)\">\r\n <app-badge-overflow\r\n [badges]=\"getShortBreakBadges(d[col.field])\"\r\n [maxWidth]=\"col.width || 200\"\r\n (badgeMouseEnter)=\"showShortBreakTooltip($event.event, $event.badge.data)\"\r\n (badgeMouseLeave)=\"hideShortBreakTooltip()\"\r\n (badgeClick)=\"handleShortBreakClick(d, $event)\"\r\n (overflowCountClick)=\"onDetailBadgeOverflowCountClick(col, d)\">\r\n </app-badge-overflow>\r\n </div>\r\n </ng-container>\r\n <ng-template #noShortBreakLeft>\r\n <div >-</div>\r\n </ng-template>\r\n </ng-container>\r\n\r\n <!-- Short Leave -->\r\n <!-- Short Leave -->\r\n<ng-container *ngSwitchCase=\"'short_leave'\">\r\n <ng-container *ngIf=\"row.short_leave && row.short_leave.length > 0; else noShortLeaveMain\">\r\n <div class=\"w-100 d-flex main-progress-bar justify-content-center align-items-center\" \r\n style=\"background-color: rgb(111, 97, 207); height: 20px; border-radius: 4px; position: relative;\"\r\n (mouseenter)=\"showShortLeaveTooltip($event, row)\"\r\n (mouseleave)=\"hideShortLeaveTooltip()\">\r\n <span class=\"d-block\" [style.min-width.%]=\"row.short_leave[0].short_leave_time_percentage\" \r\n style=\"background-color: rgb(238, 99, 82); height: 100%; border-radius: 4px;\"></span>\r\n <span style=\"position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); color: white; font-size: 12px; font-weight: bold;\">\r\n {{ row.short_leave[0].short_leave_time_percentage }}%\r\n </span>\r\n </div>\r\n </ng-container>\r\n <ng-template #noShortLeaveMain>-</ng-template>\r\n</ng-container>\r\n\r\n<ng-container *ngSwitchCase=\"'status'\">\r\n <ng-container *ngIf=\"getNestedValue(d, col.field); else noStatus\">\r\n <span class=\"badge\" [class]=\"getStatusBadgeClass(getNestedValue(d, col.field))\">\r\n {{ transformStatus(getNestedValue(d, col.field)) }}\r\n </span>\r\n </ng-container>\r\n <ng-template #noStatus>-</ng-template>\r\n</ng-container>\r\n\r\n<!-- Attendance Status -->\r\n<ng-container *ngSwitchCase=\"'attendanceStatus'\">\r\n <ng-container *ngIf=\"getNestedValue(d, col.field); else noAttendanceStatus\">\r\n <span class=\"badge\" [class]=\"getAttendanceStatusBadgeClass(getNestedValue(d, col.field))\">\r\n {{ transformStatus(getNestedValue(d, col.field)) }}\r\n </span>\r\n </ng-container>\r\n <ng-template #noAttendanceStatus>-</ng-template>\r\n</ng-container>\r\n\r\n <!-- Default -->\r\n <ng-container *ngSwitchDefault>\r\n {{\r\n col.type === 'date'\r\n ? (getNestedValue(d, col.field) ? (getNestedValue(d, col.field) | timezoneFormat:prefs:'date') : '-')\r\n : col.type === 'time'\r\n ? ((getTimeValue(getNestedValue(d, col.field)) | timezoneFormat:prefs:'time'))\r\n : (getNestedValue(d, col.field)?.value || getNestedValue(d, col.field)?.name || getNestedValue(d, col.field) || '-')\r\n }}\r\n </ng-container>\r\n</ng-container>\r\n </td>\r\n </ng-container>\r\n </tr>\r\n</tbody>\r\n </table>\r\n\r\n </div>\r\n\r\n <!-- DETAIL SIDE MENU (Sticky on right end) -->\r\n <!-- <div class=\"detail-side-menu-wrapper\" >\r\n <div style=\"width: 30px\" class=\"d-flex flex-column align-items-center \">\r\n <div (click)=\"toggleDetailSideMenu(row, 'cols')\" [class.bg-white]=\"row.details.sideMenu?.currentTab === 'cols'\" class=\"columns-button d-flex flex-column align-items-center border-below\">\r\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/ui-checks-grid.svg'\" class=\"data-grid-svg-icon\"></span>\r\n <div class=\"side-menue-text\">Columns</div>\r\n </div>\r\n \r\n </div>\r\n\r\n <div *ngIf=\"row.details.sideMenu?.currentTab\" class=\"detail-side-menu-content\" [style.backgroundColor]=\"sidemenuBackgroundColor\" style=\"width: 250px; box-shadow: -2px 0 5px rgba(0,0,0,0.1);\">\r\n <ng-container *ngIf=\"row.details.sideMenu.currentTab === 'cols'\">\r\n <div class=\"px-3 py-2 border-bottom d-flex align-items-center\">\r\n <strong class=\"me-auto\">Columns</strong>\r\n <input type=\"text\" class=\"form-control form-control-sm\" placeholder=\"Search...\" [(ngModel)]=\"row.details.sideMenu.columnSearch\" style=\"width: 120px; font-size: 12px;\" />\r\n </div>\r\n <div class=\"side-menu-scrollable\">\r\n <div *ngFor=\"let col of row.details.columns | filter: row.details.sideMenu.columnSearch:'header'; trackBy: trackByField\" class=\"d-flex align-items-center mb-2\">\r\n <input type=\"checkbox\" class=\"form-check-input me-2\" [(ngModel)]=\"col.is_visible\" (change)=\"onDetailColumnVisibilityChange(row)\" />\r\n <span>{{ col.header }}</span>\r\n </div>\r\n </div>\r\n </ng-container>\r\n\r\n <ng-container *ngIf=\"row.details.sideMenu.currentTab === 'filtrs'\">\r\n <div class=\"px-3 py-2 border-bottom d-flex align-items-center\">\r\n <strong class=\"me-auto\">Filters</strong>\r\n <input type=\"text\" class=\"form-control form-control-sm\" placeholder=\"Search...\" [(ngModel)]=\"row.details.sideMenu.columnSearch\" style=\"width: 120px; font-size: 12px;\" />\r\n </div>\r\n <div class=\"side-menu-scrollable\">\r\n <div *ngFor=\"let col of row.details.columns | filter: row.details.sideMenu.columnSearch:'header'; trackBy: trackByField\" class=\"mb-3\">\r\n <div class=\"d-flex justify-content-between align-items-center cursor-pointer\" (click)=\"col.expandedFilter = !col.expandedFilter\">\r\n <label class=\"mb-0 small\">{{ col.header }}</label>\r\n <span class=\"toggle-icon data-grid-svg-icon\" [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\" [class.rotate]=\"col.expandedFilter\"></span>\r\n </div>\r\n <div *ngIf=\"col.expandedFilter\" class=\"mt-2 filter-input-container ps-3 pe-3\">\r\n <ng-container *ngIf=\"col.type === 'dropdown'; else textFilter\">\r\n <div class=\"p-1\">\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm mb-2\"\r\n placeholder=\"Search...\"\r\n [(ngModel)]=\"col.searchValue\"\r\n />\r\n\r\n <div class=\"form-check mb-1 ms-1\">\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n [checked]=\"\r\n row.details.filters[col.field]?._ids?.length == col.column_dropdown_value?.length\r\n \"\r\n (change)=\"toggleSelectAllDetailFilters(col, row, $event)\"\r\n id=\"detail_selectAll_{{ col.field }}\"\r\n />\r\n <label class=\"form-check-label\" for=\"detail_selectAll_{{ col.field }}\">\r\n Select All\r\n </label>\r\n </div>\r\n\r\n <div class=\"dropdown-options\">\r\n <div\r\n class=\"form-check mb-1 ms-1\"\r\n *ngFor=\"\r\n let option of col?.column_dropdown_value\r\n | filter : col.searchValue : 'value';\r\n trackBy: trackById\r\n \"\r\n >\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n [value]=\"option\"\r\n [checked]=\"\r\n row.details.filters[col.field]?._ids?.includes(option?._id || option?.id || option)\r\n \"\r\n (change)=\"onDetailOptionToggle(col, option, row)\"\r\n id=\"detail_option_{{ col.field }}_{{\r\n option?.id || option?._id || option\r\n }}\"\r\n />\r\n <label\r\n class=\"form-check-label\"\r\n [for]=\"\r\n 'detail_option_' +\r\n col.field +\r\n '_' +\r\n (option?.id || option?._id || option)\r\n \"\r\n >\r\n {{ option.value || option }}\r\n </label>\r\n </div>\r\n </div>\r\n </div>\r\n </ng-container>\r\n\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)]=\"row.details.filters[col.field].first_condition\"\r\n (ngModelChange)=\"applyDetailRowFilter(row)\"\r\n >\r\n <option value=\"contain\">Contains</option>\r\n <option value=\"equal\">Equals</option>\r\n <option value=\"before\">Begins With</option>\r\n <option value=\"after\">Ends With</option>\r\n </select>\r\n </div>\r\n\r\n <input\r\n [type]=\"col.type == 'date' ? 'date' : 'text'\"\r\n class=\"form-control form-control-sm mb-3\"\r\n placeholder=\"Value\"\r\n [(ngModel)]=\"row.details.filters[col.field].first_value\"\r\n (ngModelChange)=\"applyDetailRowFilter(row)\"\r\n />\r\n\r\n <ng-container *ngIf=\"row.details.filters[col.field]?.first_value\">\r\n <div class=\"form-group mb-2\">\r\n <div class=\"form-check form-check-inline\">\r\n <input\r\n class=\"form-check-input filter-radio-inputs\"\r\n type=\"radio\"\r\n name=\"detail_condition_{{ col.field }}\"\r\n [(ngModel)]=\"row.details.filters[col.field].condition\"\r\n (ngModelChange)=\"applyDetailRowFilter(row)\"\r\n value=\"and\"\r\n id=\"detail_and_{{ col.field }}\"\r\n />\r\n <label class=\"form-check-label\" for=\"detail_and_{{ col.field }}\"\r\n >AND</label\r\n >\r\n </div>\r\n <div class=\"form-check form-check-inline\">\r\n <input\r\n class=\"form-check-input filter-radio-inputs\"\r\n type=\"radio\"\r\n name=\"detail_condition_{{ col.field }}\"\r\n [(ngModel)]=\"row.details.filters[col.field].condition\"\r\n (ngModelChange)=\"applyDetailRowFilter(row)\"\r\n value=\"or\"\r\n id=\"detail_or_{{ col.field }}\"\r\n />\r\n <label class=\"form-check-label\" for=\"detail_or_{{ col.field }}\"\r\n >OR</label\r\n >\r\n </div>\r\n <div class=\"form-check form-check-inline\">\r\n <input\r\n class=\"form-check-input filter-radio-inputs\"\r\n type=\"radio\"\r\n name=\"detail_condition_{{ col.field }}\"\r\n [(ngModel)]=\"row.details.filters[col.field].condition\"\r\n (ngModelChange)=\"applyDetailRowFilter(row)\"\r\n value=\"none\"\r\n id=\"detail_none_{{ col.field }}\"\r\n />\r\n <label class=\"form-check-label\" for=\"detail_none_{{ col.field }}\"\r\n >None</label\r\n >\r\n </div>\r\n </div>\r\n\r\n <ng-container *ngIf=\"row.details.filters[col.field].condition !== 'none'\">\r\n <div class=\"form-group mb-2\">\r\n <select\r\n class=\"form-select form-select-sm\"\r\n [(ngModel)]=\"row.details.filters[col.field].second_condition\"\r\n (ngModelChange)=\"applyDetailRowFilter(row)\"\r\n >\r\n <option value=\"contain\">Contains</option>\r\n <option value=\"equal\">Equals</option>\r\n <option value=\"before\">Begins With</option>\r\n <option value=\"after\">Ends With</option>\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-2\"\r\n placeholder=\"Second Value\"\r\n [(ngModel)]=\"row.details.filters[col.field].second_value\"\r\n (ngModelChange)=\"applyDetailRowFilter(row)\"\r\n />\r\n </ng-container>\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 </div>\r\n </div> -->\r\n</div>\r\n\r\n<!-- Detail Side Menu -->\r\n\r\n\r\n\r\n<!-- Popover for Restriction Logs (is_un_restricted) -->\r\n<div\r\n *ngIf=\"restrictionTooltipVisible\"\r\n class=\"popover__content m-l-10 popoverRestriction position-absolute border rounded bg-white p-3\"\r\n [style.left.px]=\"restrictionTooltipPosition.x\"\r\n [style.top.px]=\"restrictionTooltipPosition.y\"\r\n (mouseenter)=\"preventRestrictionTooltipHide()\"\r\n (mouseleave)=\"hideRestrictionTooltip()\"\r\n style=\"z-index: 1000; min-width: 300px; font-size: 12px;\"\r\n>\r\n <div class=\"modal-area px-0 py-0\">\r\n <div class=\"table-responsive\">\r\n <table class=\"table table-row-primary-100 gs-0 gy-2 mb-0\">\r\n <thead>\r\n <tr class=\"fw-bolder text-muted bg-light\">\r\n <th class=\"center ps-2\">Clock in</th>\r\n <th class=\"center\">Clock out</th>\r\n <th class=\"center\">Log Hr</th>\r\n <th class=\"center\">Log Min</th>\r\n <th class=\"center pe-2\">Status</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <tr *ngFor=\"let item of currentRestrictionLogs\">\r\n <td class=\"center ps-2\">\r\n <span class=\"text-primary\"> {{ item?.clock_in_time | date:'shortTime'}}</span>\r\n </td>\r\n <td class=\"center\">\r\n <span class=\"text-primary\">{{ item?.clock_out_time | date:'shortTime'}}</span>\r\n </td>\r\n <td class=\"center\">\r\n <span class=\"text-primary\">{{ item?.logged_hours }}</span>\r\n </td>\r\n <td class=\"center\">\r\n <span class=\"text-primary\">{{ item?.logged_minutes }}</span>\r\n </td>\r\n <td class=\"center\">\r\n <span class=\"badge bg-light text-dark border\">\r\n {{ item?.status ? (item.status | titlecase) : 'N/A' }}\r\n </span>\r\n </td>\r\n </tr>\r\n </tbody>\r\n </table>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<!-- Popover for Manual Logs -->\r\n<div\r\n *ngIf=\"manualLogsTooltipVisible\"\r\n class=\"popover__content position-absolute border rounded bg-white p-3\"\r\n [style.left.px]=\"manualLogsTooltipPosition.x\"\r\n [style.top.px]=\"manualLogsTooltipPosition.y\"\r\n (mouseenter)=\"preventManualLogsTooltipHide()\"\r\n (mouseleave)=\"hideManualLogsTooltip()\"\r\n style=\"z-index: 1000; min-width: 500px; font-size: 12px;\"\r\n>\r\n <div class=\"modal-area px-0 py-0\">\r\n <ng-container *ngIf=\"currentManualLogs.length > 0; else noManualLogs\">\r\n <div class=\"table-responsive\">\r\n <table class=\"table table-row-primary-100 gs-0 gy-2 mb-0\">\r\n <thead>\r\n <tr class=\"fw-bolder text-muted bg-light\">\r\n <th class=\"center ps-2\" style=\"width: 18%;\">Name</th>\r\n <th class=\"center\">Date/Time</th>\r\n <th class=\"center\">Previous Time</th>\r\n <th class=\"center\">Updated Time</th>\r\n <th class=\"center\">Status</th>\r\n <th class=\"center pe-2\">Remarks</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <tr *ngFor=\"let log of currentManualLogs\">\r\n <td class=\"center ps-2\">\r\n <span class=\"text-primary\">{{ log.name }}</span>\r\n </td>\r\n <td class=\"center\">\r\n <span class=\"text-primary\">{{ log.date_time }}</span>\r\n </td>\r\n <td class=\"center\">\r\n <span class=\"text-primary\">{{ log.previous_time }}</span>\r\n </td>\r\n <td class=\"center\">\r\n <span class=\"text-primary\">{{ log.updated_time }}</span>\r\n </td>\r\n <td class=\"center\">\r\n <span class=\"badge bg-light text-dark border\">\r\n {{ log.log_status ? (log.log_status | titlecase) : 'N/A' }}\r\n </span>\r\n </td>\r\n <td class=\"center pe-2\">\r\n <span class=\"text-primary\">{{ log.remarks }}</span>\r\n </td>\r\n </tr>\r\n </tbody>\r\n </table>\r\n </div>\r\n </ng-container>\r\n </div>\r\n\r\n <ng-template #noManualLogs>\r\n <div class=\"text-center p-3\">\r\n <p class=\"text-muted mb-0\">No manual logs available for this record.</p>\r\n </div>\r\n </ng-template>\r\n</div>\r\n\r\n\r\n\r\n\r\n<!-- Existing Custom Tooltip for Breaks -->\r\n\r\n\r\n\r\n\r\n\r\n <!-- RIGHT PINNED: Empty table to keep alignment -->\r\n <div *ngIf=\"section === 'right' && row.isDetailsExpand && !isSingleDay\" class=\"accordion-details data-grid-accordion-section\" style=\"max-height: 350px; min-height: 150px ; overflow: hidden;\">\r\n <table class=\"nested-table table table-sm w-100 mb-0 data-grid-accordion-table\" [class.show-shadow]=\"rowShadingEnabled\">\r\n <thead>\r\n <tr [style.height.px]=\"nestedTableHeaderRowHeight\" [style.backgroundColor]=\"headerBackgroundColor\">\r\n <th *ngFor=\"let _ of [1, 2, 3, 4, 5]\">&nbsp;</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <tr [style.height.px]=\"nestedTablerowHeight\" *ngFor=\"let _ of row.details.data\" [style.backgroundColor]=\"headerBackgroundColor\">\r\n <td *ngFor=\"let __ of [1, 2, 3, 4, 5]\">&nbsp;</td>\r\n </tr>\r\n </tbody>\r\n </table>\r\n </div>\r\n\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>\r\n <div\r\n (click)=\"disableEdit(row, col); setActiveCell(row, col)\"\r\n [style.fontWeight]=\"bodyFontWeight\"\r\n [class.border-right]=\"showVerticalBorder\"\r\n class=\"cell overflow-visible position-relative\"\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 [class.active-cell]=\"\r\n isActiveCell(row, col) && !isEditing(row, col) && selectedKeys.size == 1\r\n \"\r\n (dblclick)=\"$event.preventDefault(); enableEdit(row, col)\"\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=\"0\"\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 class=\"table-cell\" [class.active-for-editing]=\"isEditing(row, col) && getNestedValue(row, col.field)?.length <= 50\">\r\n <div\r\n (click)=\"$event.stopPropagation()\"\r\n *ngIf=\"isEditing(row, col) && getNestedValue(row, col.field)?.length <= 50; else viewMode\"\r\n >\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 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)\"\r\n autofocus\r\n (keydown.enter)=\"numberRef.blur()\"\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)\"\r\n autofocus\r\n class=\"form-control form-control-sm\"\r\n #dateInput=\"ngModel\"\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\">\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 />\r\n </div>\r\n\r\n <!-- Options -->\r\n <div\r\n class=\"cell-editin-dropdown\"\r\n style=\"max-height: 200px; overflow: auto\"\r\n >\r\n <div\r\n (click)=\"\r\n setNestedValue(row, col, option, true);\r\n disableEdit(row, col)\r\n \"\r\n class=\"px-2 py-1 d-flex align-items-center item\"\r\n *ngFor=\"\r\n let option of col.column_dropdown_value\r\n | filter : editinDropdownSearch : 'value'\r\n \"\r\n >\r\n <label\r\n class=\"form-check-label d-flex align-items-center mb-0\"\r\n [for]=\"col.field + '-' + option.value || option\"\r\n >\r\n {{ option.value || option }}\r\n </label>\r\n </div>\r\n </div>\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)=\"\r\n emailModel.control.markAsTouched(); emailInput.blur()\r\n \"\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 [(ngModel)]=\"row[col.field]\"\r\n name=\"{{ col.field }}\"\r\n required\r\n (blur)=\"disableEdit(row, col, textModel)\"\r\n (keydown.enter)=\"\r\n textModel.control.markAsTouched(); textInput.blur()\r\n \"\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 </div>\r\n\r\n <!-- Display mode -->\r\n <ng-template #viewMode>\r\n <div\r\n class=\"d-flex justify-between items-center w-100\"\r\n [ngClass]=\"getCellClasses(col, getNestedValue(row, col.field))\"\r\n >\r\n <!-- Text cell -->\r\n <div class=\"d-flex align-items-center w-100\">\r\n <div\r\n #cellText\r\n class=\"text-ellipsis flex-grow-1\"\r\n \r\n >\r\n <ng-container *ngIf=\"col.type !== 'image'\">\r\n <ng-container [ngSwitch]=\"col.field\">\r\n <!-- Breaks -->\r\n <ng-container *ngSwitchCase=\"'breaks'\">\r\n <ng-container *ngIf=\"getNestedValue(row, 'breaks')?.length; else noBreaksMain\">\r\n <app-badge-overflow\r\n [badges]=\"getBreakBadges(getNestedValue(row, 'breaks'))\"\r\n [maxWidth]=\"col.width || 200\"\r\n (badgeMouseEnter)=\"showBreakTooltip($event.event, $event.badge.data)\"\r\n (badgeMouseLeave)=\"hideBreakTooltip()\"\r\n (overflowCountClick)=\"onBadgeOverflowCountClick(col)\">\r\n </app-badge-overflow>\r\n </ng-container>\r\n <ng-template #noBreaksMain>\r\n <div >\r\n -\r\n </div>\r\n </ng-template>\r\n </ng-container>\r\n\r\n <!-- Short Breaks -->\r\n <ng-container *ngSwitchCase=\"'short_breaks'\">\r\n <ng-container *ngIf=\"row.short_breaks?.short_break_duration && row.short_breaks.short_break_duration > 0; else noShortBreak\">\r\n <div (dblclick)=\"onShortBreakClick.emit(row)\"> <app-badge-overflow\r\n [badges]=\"getShortBreakBadges(row.short_breaks)\"\r\n [maxWidth]=\"col.width || 200\"\r\n (badgeMouseEnter)=\"showShortBreakTooltip($event.event, $event.badge.data)\"\r\n (badgeMouseLeave)=\"hideShortBreakTooltip()\"\r\n (badgeClick)=\"handleShortBreakClick(row, $event)\"\r\n (overflowCountClick)=\"onShortBreakOverflowCountClick(col)\">\r\n </app-badge-overflow> </div>\r\n \r\n \r\n </ng-container>\r\n <ng-template #noShortBreak>\r\n <div >-</div>\r\n </ng-template>\r\n </ng-container>\r\n\r\n <!-- Short Leave -->\r\n <!-- Short Leave -->\r\n<ng-container *ngSwitchCase=\"'short_leave'\">\r\n <ng-container *ngIf=\"row.short_leave && row.short_leave.length > 0; else noShortLeaveMain\">\r\n <div class=\"w-100 d-flex main-progress-bar justify-content-center align-items-center\" \r\n style=\"background-color: rgb(111, 97, 207); height: 20px; border-radius: 4px; position: relative;\"\r\n (mouseenter)=\"showShortLeaveTooltip($event, row)\"\r\n (mouseleave)=\"hideShortLeaveTooltip()\">\r\n <span class=\"d-block\" [style.min-width.%]=\"row.short_leave[0].short_leave_time_percentage\" \r\n style=\"background-color: rgb(238, 99, 82); height: 100%; border-radius: 4px;\"></span>\r\n <span style=\"position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); color: white; font-size: 12px; font-weight: bold;\">\r\n {{ row.short_leave[0].short_leave_time_percentage }}%\r\n </span>\r\n </div>\r\n </ng-container>\r\n <ng-template #noShortLeaveMain>-</ng-template>\r\n</ng-container>\r\n\r\n <!-- Status -->\r\n <ng-container *ngSwitchCase=\"'status'\">\r\n <span class=\"badge\" [class]=\"getStatusBadgeClass(getNestedValue(row, col.field))\">\r\n {{ transformStatus(getNestedValue(row, col.field)) || '-' }}\r\n </span>\r\n </ng-container>\r\n\r\n <!-- Attendance Status -->\r\n <ng-container *ngSwitchCase=\"'attendanceStatus'\">\r\n <span class=\"badge\" [class]=\"getAttendanceStatusBadgeClass(getNestedValue(row, col.field))\">\r\n {{ transformStatus(getNestedValue(row, col.field)) || '-' }}\r\n </span>\r\n </ng-container>\r\n\r\n <!-- Payroll Processed -->\r\n <ng-container *ngSwitchCase=\"'is_payroll_processed'\">\r\n <span class=\"badge\" [class]=\"getNestedValue(row, col.field) ? 'badge-success' : 'badge-secondary'\">\r\n {{ getNestedValue(row, col.field) ? 'Yes' : 'No' }}\r\n </span>\r\n </ng-container>\r\n\r\n <!-- Restriction -->\r\n <ng-container *ngSwitchCase=\"'is_un_restricted'\">\r\n <span class=\"badge\" [class]=\"getNestedValue(row, col.field) ? 'badge-success' : 'badge-secondary'\">\r\n {{ getNestedValue(row, col.field) ? 'Yes' : 'No' }}\r\n </span>\r\n </ng-container>\r\n\r\n <!-- Default -->\r\n <ng-container *ngSwitchDefault>\r\n {{\r\n !isNestedValueArray(row, col.field)\r\n ? col.type === 'date'\r\n ? (isDate(getNestedValue(row, col.field))\r\n ? ((getNestedValue(row, col.field)) | timezoneFormat:prefs:'date' )\r\n : (getNestedValue(row, col.field)?.value ||\r\n getNestedValue(row, col.field)?.name ||\r\n getNestedValue(row, col.field) ||\r\n '-'))\r\n : col.type === 'time'\r\n ? ((getTimeValue(getNestedValue(row, col.field)) | timezoneFormat:prefs:'time'))\r\n : (getNestedValue(row, col.field)?.value ||\r\n getNestedValue(row, col.field)?.name ||\r\n getNestedValue(row, col.field) ||\r\n '-')\r\n : (getNestedValue(row, col.field)?.[0]?.department_name ||\r\n getNestedValue(row, col.field)?.[0]?.roleName ||\r\n '-')\r\n }}\r\n </ng-container>\r\n </ng-container>\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: row,\r\n col: col,\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </div>\r\n\r\n <!-- Active dot and eye icon for employee name -->\r\n <span *ngIf=\"col.field === 'User' && hasManualLogs(row) && !row.isDetailsExpand\" class=\"badge badge-dot badge-success ms-1\" (mouseenter)=\"showManualLogsTooltip($event, row, row)\"></span>\r\n <i *ngIf=\"col.field === 'User' && hasManualLogs(row)\" class=\"bi bi-eye ms-1\" (mouseenter)=\"showManualLogsTooltip($event, row, row)\"></i>\r\n </div>\r\n\r\n <!-- Expand / Collapse icon for multiple data showing in one coll-->\r\n\r\n <!-- <span\r\n *ngIf=\"\r\n (isOverflowing(cellText) &&\r\n showCellDetailsBox &&\r\n getNestedValue(row, col.field)?.length > 50) ||\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 </div>\r\n\r\n <!-- Expanded text -->\r\n <div\r\n class=\"position-absolute w-100\"\r\n *ngIf=\"isExpanded(row, col)\"\r\n [style.zIndex]=\"getZIndex(row, col)\"\r\n style=\"top: 100%; left: 0\"\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\r\n\r\n \r\n\r\n\r\n\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<div\r\n *ngIf=\"currentBreakTooltip\"\r\n class=\"custom-break-tooltip\"\r\n [style.--tooltip-x.px]=\"tooltipPosition.x\"\r\n [style.--tooltip-y.px]=\"tooltipPosition.y\"\r\n>\r\n <div class=\"break-tooltip-header\">\r\n <strong>{{ currentBreakTooltip.break_type?.data_value_name || 'Break' }}</strong>\r\n <span class=\"text-muted ms-2\">\r\n {{ currentBreakTooltip.breakInstatus === 'breakOut' ? 'Taken' : 'On Break' }}\r\n </span>\r\n </div>\r\n\r\n <div class=\"break-tooltip-body\">\r\n <div>\r\n <i class=\"bi bi-play-circle\"></i>\r\n In: {{ getTimeValue(currentBreakTooltip.break_in_time) | timezoneFormat:prefs:'time' }}\r\n </div>\r\n\r\n <div>\r\n <i class=\"bi bi-stop-circle\"></i>\r\n Out: {{ getTimeValue(currentBreakTooltip.break_out_time) | timezoneFormat:prefs:'time' }}\r\n </div>\r\n\r\n <div>\r\n <i class=\"bi bi-clock\"></i>\r\n Duration: {{ currentBreakTooltip.break_duration }} min\r\n </div>\r\n </div>\r\n</div>\r\n\r\n\r\n\r\n\r\n\r\n<!-- Short Break Tooltip -->\r\n<div\r\n *ngIf=\"currentShortBreakTooltip\"\r\n class=\"custom-break-tooltip\"\r\n [style.--tooltip-x.px]=\"tooltipPosition.x\"\r\n [style.--tooltip-y.px]=\"tooltipPosition.y\"\r\n>\r\n <div class=\"break-tooltip-header\">\r\n <strong>{{ currentShortBreakTooltip.short_break_name || 'Short Break' }}</strong>\r\n </div>\r\n\r\n <div class=\"break-tooltip-body\">\r\n <div>\r\n <i class=\"bi bi-play-circle\"></i>\r\n Start: {{ getTimeValue(currentShortBreakTooltip.start_time) | timezoneFormat:prefs:'time' }}\r\n </div>\r\n\r\n <div>\r\n <i class=\"bi bi-stop-circle\"></i>\r\n End: {{ getTimeValue(currentShortBreakTooltip.end_time) | timezoneFormat:prefs:'time' }}\r\n </div>\r\n\r\n <div>\r\n <i class=\"bi bi-clock\"></i>\r\n Duration: {{ currentShortBreakTooltip.short_break_duration }} min\r\n </div>\r\n </div>\r\n</div>\r\n\r\n\r\n\r\n\r\n<!-- Headers Action List On clicking three dots -->\r\n\r\n<ng-template #columnMenu let-col=\"col\">\r\n <div\r\n class=\"column-menu three-dots-col-menu\"\r\n [class.visually-hidden]=\"isMenueHidden\"\r\n *ngIf=\"activeCol && !isThreeDotsFilterOpen && !loading\"\r\n [style.backgroundColor]=\"dropdownsBackgroundColor\"\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\">\r\n <div\r\n *ngIf=\"columnThreedotsMunuConfig?.showFilter && !(col.is_search_able === false )\"\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)=\"updateColumnPinInSourceByField(activeCol, 'left')\"\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)=\"updateColumnPinInSourceByField(activeCol, 'right')\"\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)=\"updateColumnPinInSourceByField(activeCol, null)\"\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 && !(col.is_groupable === false)\"\r\n class=\"column-menu-item\"\r\n (click)=\"groupBy(activeCol)\"\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 *ngIf=\"isThreeDotsFilterOpen\" class=\"three-dots-col-menu position-relative\" [style.left.px]=\"-140\" >\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\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'; else textFilter\">\r\n <div class=\"filter-dropdown-section p-1\">\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm mb-2\"\r\n placeholder=\"Search...\"\r\n [(ngModel)]=\"addFilterDropdownSearch\"\r\n #filterMenueSearchInput\r\n />\r\n\r\n <div class=\"form-check mb-1\">\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n [checked]=\"isAllSideFilterOptionsSelected(col)\"\r\n (change)=\"toggleSelectAllSideFilters(col, $event)\"\r\n id=\"selectAll_{{ col.field }}\"\r\n />\r\n <label class=\"form-check-label\" for=\"selectAll_{{ col.field }}\">\r\n Select All\r\n </label>\r\n </div>\r\n\r\n <div class=\"dropdown-options\">\r\n <div\r\n class=\"form-check mb-1\"\r\n *ngFor=\"\r\n let option of col?.column_dropdown_value\r\n | filter : addFilterDropdownSearch : 'value';\r\n trackBy: trackById\r\n \"\r\n >\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n [checked]=\"\r\n col.query?._ids?.includes(option?._id || option?.id || option)\r\n \"\r\n [value]=\"option\"\r\n id=\"option_{{ col.field }}_{{\r\n option?.id || option?._id || option\r\n }}\"\r\n (change)=\"onOptionToggle(col, option)\"\r\n />\r\n <label\r\n class=\"form-check-label\"\r\n [for]=\"\r\n 'option_' +\r\n col.field +\r\n '_' +\r\n (option?.id || option?._id || option)\r\n \"\r\n >\r\n {{ option?.value || option }}\r\n </label>\r\n </div>\r\n </div>\r\n </div>\r\n </ng-container>\r\n\r\n <!-- Text Filter Section -->\r\n <ng-template #textFilter>\r\n <div class=\"filter-text-section\">\r\n <div class=\"form-group mb-2\">\r\n <select\r\n class=\"form-select form-select-sm\"\r\n [ngModel]=\"col.query.first_condition || (col.type === 'date' || col.type === 'time' ? 'equal' : 'contain')\"\r\n (ngModelChange)=\"col.query.first_condition = $event\"\r\n >\r\n <ng-container *ngIf=\"col.type === 'date' || col.type === 'time'; else textOptions\">\r\n <option value=\"equal\">Equal 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-template #textOptions>\r\n <option value=\"contain\">Contains</option>\r\n <option value=\"equal\">Equals</option>\r\n <option value=\"before\">Begins With</option>\r\n <option value=\"after\">Ends With</option>\r\n </ng-template>\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)]=\"col.query.first_value\"\r\n [min]=\"col.type == 'number' ? 0 : null\"\r\n (input)=\"col.type == 'number' && $any($event.target).value < 0 ? $any($event.target).value = 0 : null\"\r\n (keydown)=\"col.type == 'number' && $event.key === '-' ? $event.preventDefault() : null\"\r\n [class.number-input]=\"col.type == 'number'\"\r\n #filterMenueTextchInput\r\n />\r\n\r\n <ng-container >\r\n <div class=\"form-group mb-2\">\r\n <div class=\"form-check form-check-inline\">\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 />\r\n <label class=\"form-check-label\" for=\"and_{{ col.field }}\"\r\n >AND</label\r\n >\r\n </div>\r\n <div class=\"form-check form-check-inline\">\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 />\r\n <label class=\"form-check-label\" for=\"or_{{ col.field }}\"\r\n >OR</label\r\n >\r\n </div>\r\n <div class=\"form-check form-check-inline\">\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 />\r\n <label class=\"form-check-label\" for=\"none_{{ col.field }}\"\r\n >None</label\r\n >\r\n </div>\r\n </div>\r\n\r\n <ng-container *ngIf=\"col.query?.first_value && condition !== 'none'\">\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 || (col.type === 'date' || col.type === 'time' ? 'equal' : 'contain')\"\r\n (ngModelChange)=\"col.query.second_condition = $event\"\r\n >\r\n <ng-container *ngIf=\"col.type === 'date' || col.type === 'time'; else textOptionsSecond\">\r\n <option value=\"equal\">Equal 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-template #textOptionsSecond>\r\n <option value=\"contain\">Contains</option>\r\n <option value=\"equal\">Equals</option>\r\n <option value=\"before\">Begins With</option>\r\n <option value=\"after\">Ends With</option>\r\n </ng-template>\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-2\"\r\n placeholder=\"Second Value\"\r\n [(ngModel)]=\"col.query.second_value\"\r\n [min]=\"col.type == 'number' ? 0 : null\"\r\n (input)=\"col.type == 'number' && $any($event.target).value < 0 ? $any($event.target).value = 0 : null\"\r\n (keydown)=\"col.type == 'number' && $event.key === '-' ? $event.preventDefault() : null\"\r\n [class.number-input]=\"col.type == 'number'\"\r\n />\r\n </ng-container>\r\n </ng-container>\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: 22px\"\r\n (click)=\"applyFilterFromFilterRow(col)\"\r\n >\r\n Apply\r\n </div>\r\n <div\r\n class=\"btn btn-sm btn-secondary d-flex justify-content-center align-items-center w-100\"\r\n style=\"height: 22px\"\r\n (click)=\"resetSideFilter(col)\"\r\n >\r\n Reset\r\n </div>\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<!-- Side Menue -->\r\n\r\n<!-- Add this new template for accordion detail column menu -->\r\n<ng-template #detailColumnMenu let-col=\"col\" let-row=\"row\">\r\n <div\r\n class=\"column-menu three-dots-col-menu detail-column-menu\"\r\n [class.visually-hidden]=\"isDetailMenueHidden\"\r\n *ngIf=\"activeDetailCol\"\r\n [style.backgroundColor]=\"dropdownsBackgroundColor\"\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=\"columnThreedotsMunuConfig?.showAscending\"\r\n class=\"column-menu-item\"\r\n (click)=\"sortDetailAsc(activeDetailCol, row)\"\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=\"columnThreedotsMunuConfig?.showDescending\"\r\n class=\"column-menu-item\"\r\n (click)=\"sortDetailDesc(activeDetailCol, row)\"\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=\"col?.sortOrder\"\r\n class=\"column-menu-item\"\r\n (click)=\"resetDetailSort(activeDetailCol, row)\"\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\r\n <div class=\"py-2 border-below\" *ngIf=\"isColumnFilterable(col)\">\r\n <span class=\"muted-text fs-7\" style=\"margin-left: 12px\">Filter</span>\r\n <div\r\n *ngIf=\"columnThreedotsMunuConfig?.showFilter\"\r\n class=\"column-menu-item\"\r\n (click)=\"openDetailFilterMenu($event, col, row)\"\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)=\"updateDetailColumnPin(activeDetailCol, row, 'left')\"\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)=\"updateDetailColumnPin(activeDetailCol, row, 'right')\"\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)=\"updateDetailColumnPin(activeDetailCol, row, null)\"\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)=\"autosizeDetailColumn(activeDetailCol, row)\"\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)=\"autosizeAllDetailColumns(row)\"\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\r\n <!-- Choose Columns -->\r\n <div\r\n *ngIf=\"columnThreedotsMunuConfig?.showChoseColumns\"\r\n class=\"column-menu-item\"\r\n (click)=\"openDetailChooseColumns(row)\"\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)=\"resetDetailColumns(row)\"\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</ng-template>\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\"\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\">\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<!-- 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\">\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\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% - 120px); 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 <!-- Apply and Reset Buttons -->\r\n <!-- <div class=\"d-flex gap-2 mt-3 px-2\">\r\n <button\r\n class=\"btn btn-sm btn-primary d-flex justify-content-center align-items-center flex-fill\"\r\n style=\"height: 32px;\"\r\n (click)=\"applySideMenuFilters()\"\r\n >\r\n Apply\r\n </button>\r\n <button\r\n class=\"btn btn-sm btn-secondary d-flex justify-content-center align-items-center flex-fill\"\r\n style=\"height: 32px;\"\r\n (click)=\"resetSideMenuFilters()\"\r\n >\r\n Reset\r\n </button>\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 class=\"column-group d-flex align-items-center mb-2\">\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\">\r\n <span\r\n class=\"me-2 filter-icon-wrapper me-2\"\r\n (click)=\"col.expandedFilter = !col.expandedFilter\"\r\n >\r\n <span\r\n class=\"toggle-icon data-grid-svg-icon\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\r\n \"\r\n [class.rotate]=\"col.expandedFilter\"\r\n ></span>\r\n </span>\r\n\r\n <label\r\n class=\"d-flex align-items-center mb-0 w-100\"\r\n style=\"cursor: pointer\"\r\n (click)=\"col.expandedFilter = !col.expandedFilter\"\r\n >\r\n <span class=\"text-truncate fw-bold\">{{ col.header }}</span>\r\n </label>\r\n </div>\r\n\r\n <!-- Show filter when expanded -->\r\n <div *ngIf=\"col.expandedFilter\" class=\"ps-4 pe-3\">\r\n <ng-container\r\n *ngTemplateOutlet=\"sideNestedFilter; context: { col: col }\"\r\n ></ng-container>\r\n </div>\r\n </ng-container>\r\n</ng-template>\r\n\r\n<!-- Side Nested Filters -->\r\n<ng-template #sideNestedFilter let-col=\"col\">\r\n <div class=\"\">\r\n <!-- Dropdown Type -->\r\n <ng-container *ngIf=\"col.type === 'dropdown'; else textFilter\">\r\n <div class=\"p-1\">\r\n <!-- Search -->\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm mb-2\"\r\n placeholder=\"Search...\"\r\n [(ngModel)]=\"col.searchValue\"\r\n />\r\n\r\n <!-- Select All -->\r\n <div class=\"form-check mb-1 ms-1\">\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n [checked]=\"\r\n col.query?._ids?.length == col?.column_dropdown_value?.length\r\n \"\r\n (change)=\"toggleSelectAllSideFilters(col, $event)\"\r\n id=\"selectAll_{{ col.field }}\"\r\n />\r\n <label class=\"form-check-label\" for=\"selectAll_{{ col.field }}\">\r\n Select All\r\n </label>\r\n </div>\r\n\r\n <!-- Options -->\r\n <div class=\"dropdown-options\">\r\n <div\r\n class=\"form-check mb-1 ms-1\"\r\n *ngFor=\"\r\n let option of col?.column_dropdown_value\r\n | filter : addFilterDropdownSearch : 'header'\r\n \"\r\n >\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n [value]=\"option\"\r\n [checked]=\"\r\n col.query?._ids?.includes(option?._id || option?.id || option)\r\n \"\r\n (change)=\"onOptionToggle(col, option)\"\r\n id=\"option_{{ col.field }}_{{\r\n option?.id || option?._id || option\r\n }}\"\r\n />\r\n <label\r\n class=\"form-check-label\"\r\n [for]=\"\r\n 'option_' +\r\n col.field +\r\n '_' +\r\n (option?.id || option?._id || option)\r\n \"\r\n >\r\n {{ option.value || option }}\r\n </label>\r\n </div>\r\n </div>\r\n\r\n <!-- Actions -->\r\n <!-- <div class=\"d-flex gap-2 mt-2\">\r\n <div\r\n class=\"btn btn-sm btn-primary d-flex justify-content-center align-items-center\"\r\n style=\"height: 22px;\"\r\n (click)=\"applySideMenuFilters()\"\r\n >\r\n Apply\r\n </div>\r\n <div\r\n class=\"btn btn-sm btn-secondary d-flex justify-content-center align-items-center\"\r\n style=\"height: 22px;\"\r\n (click)=\"resetSideMenuFilters()\"\r\n >\r\n Reset\r\n </div>\r\n </div> -->\r\n </div>\r\n </ng-container>\r\n\r\n <!-- Text Filter Section -->\r\n <ng-template #textFilter>\r\n <div class=\"filter-text-section\">\r\n <div class=\"form-group mb-2\">\r\n <select\r\n class=\"form-select form-select-sm\"\r\n [ngModel]=\"col!.query!.first_condition || (col.type === 'date' || col.type === 'time' ? 'equal' : 'contain')\"\r\n (ngModelChange)=\"col!.query!.first_condition = $event\"\r\n >\r\n <ng-container *ngIf=\"col.type === 'date' || col.type === 'time'; else textOptions\">\r\n <option value=\"equal\">Equal 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-template #textOptions>\r\n <option value=\"contain\">Contains</option>\r\n <option value=\"equal\">Equals</option>\r\n <option value=\"before\">Begins With</option>\r\n <option value=\"after\">Ends With</option>\r\n </ng-template>\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 [min]=\"col.type == 'number' ? 0 : null\"\r\n (input)=\"col.type == 'number' && $any($event.target).value < 0 ? $any($event.target).value = 0 : null\"\r\n (keydown)=\"col.type == 'number' && $event.key === '-' ? $event.preventDefault() : null\"\r\n [class.number-input]=\"col.type == 'number'\"\r\n />\r\n\r\n <ng-container *ngIf=\"col?.query?.first_value && col?.query?.condition !== 'none'\">\r\n <div class=\"form-group mb-2\">\r\n <div class=\"form-check form-check-inline\">\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\" for=\"and_{{ col.field }}\"\r\n >AND</label\r\n >\r\n </div>\r\n <div class=\"form-check form-check-inline\">\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\" for=\"or_{{ col.field }}\"\r\n >OR</label\r\n >\r\n </div>\r\n <div class=\"form-check form-check-inline\">\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 class=\"form-check-label\" for=\"none_{{ col.field }}\"\r\n >None</label\r\n >\r\n </div>\r\n </div>\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 || (col.type === 'date' || col.type === 'time' ? 'equal' : 'contain')\"\r\n (ngModelChange)=\"col!.query.second_condition = $event\"\r\n >\r\n <ng-container *ngIf=\"col.type === 'date' || col.type === 'time'; else textOptionsSecond\">\r\n <option value=\"equal\">Equal 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-template #textOptionsSecond>\r\n <option value=\"contain\">Contains</option>\r\n <option value=\"equal\">Equals</option>\r\n <option value=\"before\">Begins With</option>\r\n <option value=\"after\">Ends With</option>\r\n </ng-template>\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-2\"\r\n placeholder=\"Second Value\"\r\n [(ngModel)]=\"col!.query.second_value\"\r\n [min]=\"col.type == 'number' ? 0 : null\"\r\n (input)=\"col.type == 'number' && $any($event.target).value < 0 ? $any($event.target).value = 0 : null\"\r\n (keydown)=\"col.type == 'number' && $event.key === '-' ? $event.preventDefault() : null\"\r\n [class.number-input]=\"col.type == 'number'\"\r\n />\r\n </ng-container>\r\n\r\n <!-- Apply and Reset Buttons -->\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: 22px\"\r\n (click)=\"applyFilterFromFilterRow(col)\"\r\n >\r\n Apply\r\n </div>\r\n <div\r\n class=\"btn btn-sm btn-secondary d-flex justify-content-center align-items-center w-100\"\r\n style=\"height: 22px\"\r\n (click)=\"resetSideFilter(col)\"\r\n >\r\n Reset\r\n </div>\r\n </div>\r\n </div>\r\n </ng-template>\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\" (click)=\"closeModalColumnPanel()\">\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\">\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 [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 [class.border-right]=\"showVerticalBorder\"\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 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 />\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 rounded-3 bg-white 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)=\"emitConfigUpdate()\"\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>\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 rounded-3 bg-white 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 btn btn-link\"\r\n type=\"button\"\r\n id=\"savePresetDropdown\"\r\n (click)=\"$event.stopPropagation(); toggleSubActions('save-preset')\"\r\n >\r\n Save 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 class=\"\" (click)=\"selectDefault()\">\r\n <div class=\"fw-semibold\">Default View\r\n <span\r\n *ngIf=\"tableFilterViewId === 'default'\"\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/check-blue.svg'\"\r\n class=\"me-2\"\r\n ></span>\r\n </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 === 'default'\"\r\n class=\"badge bg-light text-primary ms-2\"\r\n >Default</span\r\n >\r\n <div\r\n class=\"dropdown d-flex justify-content-end\"\r\n *ngIf=\"tableFilterViewId\"\r\n >\r\n <a\r\n href=\"javascript:void(0)\"\r\n class=\"muted-text\"\r\n data-bs-toggle=\"dropdown\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/horizontal-dots.svg'\r\n \"\r\n class=\"me-2\"\r\n ></span>\r\n </a>\r\n <ul class=\"dropdown-menu dropdown-menu-end\">\r\n <a\r\n (click)=\"actionPreset({ id: 'default' }, 'setPreset')\"\r\n class=\"dropdown-item d-flex align-items-center\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/star.svg'\"\r\n class=\"me-2\"\r\n ></span>\r\n Set as default\r\n </a>\r\n </ul>\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=\"let table of filteredList; trackBy: trackByTable\"\r\n >\r\n <!-- Item -->\r\n <div\r\n class=\"list-group-item px-0 d-flex justify-content-between align-items-center\"\r\n >\r\n <div (click)=\"selectFilter(table)\">\r\n <div class=\"fw-semibold\" style=\"cursor: pointer;\">\r\n {{ table?.name }}\r\n <!-- {{table?.is_temp}} -->\r\n <span\r\n *ngIf=\"table?.is_temp\"\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_deafult\"\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\"\r\n >Created {{ table?.createdAt | timezoneFormat:prefs:'date' }}</small\r\n >\r\n </div>\r\n\r\n <div class=\"d-flex align-items-center\">\r\n <span\r\n *ngIf=\"table?.is_deafult\"\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 position-relative\" *ngIf=\"!table?.is_deafult\">\r\n <a href=\"javascript:void(0)\" class=\"muted-text\" (click)=\"togglePresetDropdown(table.id)\">\r\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/horizontal-dots.svg'\" class=\"me-2\"></span>\r\n </a>\r\n\r\n <div\r\n *ngIf=\"activePresetDropdownId === table.id\"\r\n class=\"dropdown-menu dropdown-menu-end show position-absolute\"\r\n style=\"z-index: 1000; top: 100%; right: 0; min-width: 180px\"\r\n (click)=\"$event.stopPropagation()\"\r\n >\r\n <a\r\n [class.d-none]=\"confirmDeletePresetId === table.id\"\r\n (click)=\"actionPreset(table, 'setPreset'); activePresetDropdownId = null;\"\r\n class=\"dropdown-item d-flex align-items-center\"\r\n >\r\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/star.svg'\" class=\"me-2\"></span>\r\n Set as default\r\n </a>\r\n\r\n <ng-container *ngIf=\"confirmDeletePresetId !== table.id; else confirmBlock\">\r\n <a\r\n (click)=\"confirmDeletePresetId = table.id\"\r\n class=\"dropdown-item d-flex align-items-center text-danger\"\r\n >\r\n <span style=\"margin-top: -4px\" [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/trash-red.svg'\" class=\"me-2\"></span>\r\n Delete\r\n </a>\r\n </ng-container>\r\n\r\n <ng-template #confirmBlock>\r\n <div class=\"dropdown-item\"><b>Delete preset</b></div>\r\n <div class=\"dropdown-item text-center\">\r\n <div class=\"mb-2\">\r\n Are you sure you want to delete the <br />\r\n <b>\u201C{{ table?.name }}\u201D</b> preset?\r\n </div>\r\n <button\r\n class=\"btn btn-sm btn-light me-2\"\r\n (click)=\"confirmDeletePresetId = null\"\r\n >\r\n Cancel\r\n </button>\r\n <button\r\n class=\"btn btn-sm btn-danger delete-preset\"\r\n (click)=\"actionPreset(table, 'deletePreset'); confirmDeletePresetId = null; activePresetDropdownId = null;\"\r\n >\r\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/trash-red.svg'\" class=\"confirm-preset-delete\"></span>\r\n Delete\r\n </button>\r\n </div>\r\n </ng-template>\r\n </div>\r\n</div>\r\n </div>\r\n </div>\r\n <!-- Item End Here -->\r\n </div>\r\n\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\">Save preset</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\">\r\n <ng-container *ngIf=\"!closeDropdown.preset.loading && (!tableFilterViewId || tableFilterViewId === 'default')\"\r\n >Save</ng-container\r\n >\r\n <ng-container *ngIf=\"!closeDropdown.preset.loading && tableFilterViewId && tableFilterViewId !== 'default'\"\r\n >Update</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 </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 rounded-3 bg-white 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\"\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=\"\r\n max-height: calc(100vh - 300px);\r\n overflow: auto;\r\n scrollbar-width: thin;\r\n \"\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 type=\"checkbox\"\r\n id=\"show_hide_all\"\r\n class=\"form-check-input\"\r\n [checked]=\"areAllNonMandatoryVisible()\"\r\n (change)=\"toggleAllVisibleColumns()\"\r\n />\r\n <label for=\"show_hide_all\" class=\"form-check-label fw-semibold\">Show/Hide All</label>\r\n </div>\r\n </div>\r\n <!-- <div class=\"d-flex align-items-center mb-2\" *ngIf=\"hasAnyVisibleColumn\">\r\n <input\r\n type=\"checkbox\"\r\n class=\"form-check-input me-2\"\r\n [checked]=\"areAllNonMandatoryVisible()\"\r\n (change)=\"toggleAllVisibleColumns()\"\r\n />\r\n <label class=\"form-check-label fw-semibold\">Show All</label>\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 && !isMandatory(col)\"\r\n class=\"d-flex align-items-center cursor-pointer\"\r\n (click)=\"toggleColumnVisibility(col, false)\"\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 && isMandatory(col)) || (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\"\r\n *ngIf=\"hasAnyInVisibleColumn\"\r\n >\r\n Hide in table\r\n </div>\r\n <div class=\"d-flex align-items-center mb-2\" *ngIf=\"hasAnyInVisibleColumn\">\r\n <input\r\n type=\"checkbox\"\r\n id=\"hide_show_all\"\r\n class=\"form-check-input me-2\"\r\n [checked]=\"areAllNonMandatoryHidden()\"\r\n (change)=\"toggleAllInvisibleColumns()\"\r\n />\r\n <label class=\"form-check-label fw-semibold\">Hide All</label>\r\n </div> -->\r\n\r\n \r\n\r\n\r\n\r\n <div class=\"muted-text show-hide-table-label d-flex justify-content-between\" *ngIf=\"hasAnyInVisibleColumn\">\r\n Hide in table\r\n <div class=\"form-check\">\r\n <input\r\n type=\"checkbox\"\r\n id=\"hide_show_all\"\r\n class=\"form-check-input\"\r\n [checked]=\"areAllNonMandatoryHidden()\"\r\n (change)=\"toggleAllInvisibleColumns()\"\r\n />\r\n <label for=\"hide_show_all\" class=\"form-check-label fw-semibold\">Hide/Show All</label>\r\n </div>\r\n </div>\r\n <div class=\"list-group list-group-flush\">\r\n <ng-container *ngFor=\"let col of columns; trackBy: trackByField\">\r\n <div\r\n *ngIf=\"!col.is_visible\"\r\n class=\"list-group-item border-0 px-0 d-flex justify-content-between align-items-center\"\r\n >\r\n <div class=\"d-flex gap-1\">\r\n <div>\r\n <span\r\n *ngIf=\"!col?.pinned\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/grip-vertical.svg'\r\n \"\r\n class=\"data-grid-svg-icon cursor-grap\"\r\n (mousedown)=\"$event.preventDefault()\"\r\n ></span>\r\n <span\r\n *ngIf=\"col?.pinned\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/pin-blue.svg'\r\n \"\r\n class=\"data-grid-svg-icon cursor-grap\"\r\n (mousedown)=\"$event.preventDefault()\"\r\n ></span>\r\n </div>\r\n <div class=\"fw-semibold\">\r\n {{ col.header }}\r\n </div>\r\n </div>\r\n <div\r\n class=\"d-flex align-items-center cursor-pointer\"\r\n (click)=\"toggleColumnVisibility(col, true)\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/eye-cross.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n </div>\r\n </div>\r\n </ng-container>\r\n </div>\r\n\r\n <!-- Item End Here -->\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template #filterColumns let-col=\"column\">\r\n <div\r\n @slideToggle\r\n *ngIf=\"!isFilterOpen && activeTopButton == 'filter-columns'\"\r\n (click)=\"$event.stopPropagation()\"\r\n class=\"shadow rounded-3 bg-white actions-dropdown mt-1 show shadow custom-menu table-layout filter-columns\"\r\n style=\"width: 280px; right: unset; max-width: 230px\"\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\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'\"\r\n (click)=\"$event.stopPropagation()\"\r\n class=\"shadow rounded-3 bg-white actions-dropdown mt-1 show shadow custom-menu table-layout filter-columns\"\r\n style=\"width: 280px; right: unset; max-width: 230px\"\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\"\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 (ngModelChange)=\"selectedFilterOptions.length === 0 ? condition = 'none' : null\"\r\n />\r\n </div>\r\n </div>\r\n <div\r\n class=\"list-group list-group-flush\"\r\n style=\"max-height: calc(100vh - 600px); overflow: auto\"\r\n >\r\n <ng-container\r\n *ngFor=\"\r\n let col of selectedColumnForFilter.column_dropdown_value\r\n | filter : searchTextForFilterDropDown : 'value';\r\n let i = index\r\n \"\r\n >\r\n <div\r\n class=\"list-group-item border-0 px-2 d-flex justify-content-between align-items-center dropdown-item cursor-pointer\"\r\n >\r\n <div class=\"form-check\">\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n [id]=\"i\"\r\n [checked]=\"currentFilterSelectedIds.has(col.id || col._id || col)\"\r\n (change)=\"toggleSelectionInFilter(col)\"\r\n />\r\n <label class=\"form-check-label fw-semibold\" [for]=\"i\">\r\n {{ col?.value || col?.name || col }}\r\n </label>\r\n </div>\r\n </div>\r\n </ng-container>\r\n </div>\r\n <div\r\n class=\"d-flex justify-content-center gap-2 px-2 border-top\"\r\n style=\"height: 38px\"\r\n >\r\n <button\r\n type=\"button\"\r\n style=\"height: 32px\"\r\n class=\"btn btn-outline-secondary btn-light border w-100 d-flex align-items-center justify-content-center mt-1 btn-light\"\r\n (click)=\"$event.stopPropagation(); resetFilterChanges()\"\r\n >\r\n <span>Cancel</span>\r\n </button>\r\n <button\r\n type=\"button\"\r\n style=\"height: 32px\"\r\n class=\"btn btn-primary w-100 d-flex align-items-center justify-content-center mt-1\"\r\n (click)=\"applyDropdownFilter()\"\r\n >\r\n <span style=\"margin-top: -2px\">Save</span>\r\n </button>\r\n </div>\r\n </div>\r\n\r\n <!-- For Text fields and number fields-->\r\n\r\n <div\r\n @slideToggle\r\n *ngIf=\"\r\n isFilterOpen &&\r\n (selectedColumnForFilter.type == 'string' ||\r\n selectedColumnForFilter.type == 'number' ||\r\n selectedColumnForFilter.type == 'date')\r\n \"\r\n (click)=\"$event.stopPropagation()\"\r\n class=\"shadow rounded-3 bg-white actions-dropdown mt-1 show shadow custom-menu table-layout filter-columns\"\r\n style=\"width: 280px; right: unset; max-width: 230px\"\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\"\r\n [(ngModel)]=\"firstCondition\"\r\n >\r\n <ng-container *ngIf=\"selectedColumnForFilter.type === 'date' || selectedColumnForFilter.type === 'time'; else textOptions\">\r\n <option value=\"equal\">Equal 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-template #textOptions>\r\n <option value=\"equal\">Equals</option>\r\n <!-- <option value=\"not_equal\">Not Equals</option> -->\r\n <option value=\"contain\">Contains</option>\r\n <option value=\"before\">Begins With</option>\r\n <option value=\"after\">Ends With</option>\r\n </ng-template>\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]=\"\r\n selectedColumnForFilter.type == 'string'\r\n ? 'text'\r\n : selectedColumnForFilter.type\r\n \"\r\n [(ngModel)]=\"firstValue\"\r\n [min]=\"selectedColumnForFilter.type == 'number' ? 0 : null\"\r\n [class.number-input]=\"selectedColumnForFilter.type == 'number'\"\r\n (input)=\"selectedColumnForFilter.type == 'number' && $any($event.target).value < 0 ? $any($event.target).value = 0 : null\"\r\n (ngModelChange)=\"!firstValue ? condition = 'none' : null\"\r\n (keydown)=\"selectedColumnForFilter.type == 'number' && $event.key === '-' ? $event.preventDefault() : null\"\r\n />\r\n </div>\r\n <div class=\"d-flex my-3\">\r\n <div class=\"form-check form-check-inline\">\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\" for=\"logicalAnd\">AND</label>\r\n </div>\r\n\r\n <div class=\"form-check form-check-inline\">\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\" for=\"logicalOr\">OR</label>\r\n </div>\r\n\r\n <div class=\"form-check form-check-inline\">\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\" for=\"logicalNone\">None</label>\r\n </div>\r\n </div>\r\n\r\n <div *ngIf=\"firstValue && condition !== 'none'\">\r\n <div class=\"my-3\">\r\n <!-- Second condition select -->\r\n <select\r\n class=\"form-select form-select-sm\"\r\n [(ngModel)]=\"secondCondition\"\r\n >\r\n <ng-container *ngIf=\"selectedColumnForFilter.type === 'date' || selectedColumnForFilter.type === 'time'; else textOptionsSecond\">\r\n <option value=\"equal\">Equal 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-template #textOptionsSecond>\r\n <option value=\"equal\">Equals</option>\r\n <!-- <option value=\"not_equal\">Not Equals</option> -->\r\n <option value=\"contain\">Contains</option>\r\n <option value=\"before\">Begins With</option>\r\n <option value=\"after\">Ends With</option>\r\n </ng-template>\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 [(ngModel)]=\"secondValue\"\r\n [min]=\"selectedColumnForFilter.type == 'number' ? 0 : null\"\r\n [class.number-input]=\"selectedColumnForFilter.type == 'number'\"\r\n (input)=\"selectedColumnForFilter.type == 'number' && $any($event.target).value < 0 ? $any($event.target).value = 0 : null\"\r\n (keydown)=\"selectedColumnForFilter.type == 'number' && $event.key === '-' ? $event.preventDefault() : null\"\r\n />\r\n </div>\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 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 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</ng-template>\r\n\r\n<!-- Detail Filter Menu -->\r\n <div\r\n *ngIf=\"activeAccordionFilterMenu && detailFilterMenuPosition\"\r\n class=\"detail-filter-menu\"\r\n [style.backgroundColor]=\"dropdownsBackgroundColor\"\r\n [style.left.px]=\"detailFilterMenuPosition.x\"\r\n [style.top.px]=\"detailFilterMenuPosition.y\"\r\n (click)=\"$event.stopPropagation()\"\r\n >\r\n <div class=\"px-3 border-below py-1 pb-2 d-flex ps-1\">\r\n <span\r\n (click)=\"closeDetailFilterMenu()\"\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>{{ activeDetailFilterCol?.header }}</b>\r\n </div>\r\n\r\n <!-- Text Filter -->\r\n <div *ngIf=\"detailFilterType === 'string'\" 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\"\r\n [(ngModel)]=\"detailFilterCondition\"\r\n >\r\n <option value=\"contain\">Contains</option>\r\n <option value=\"equal\">Equals</option>\r\n <option value=\"before\">Begins With</option>\r\n <option value=\"after\">Ends With</option>\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 value\"\r\n [(ngModel)]=\"detailFilterValue\"\r\n (keydown.enter)=\"applyDetailFilter()\"\r\n />\r\n </div>\r\n </div>\r\n\r\n <!-- Date Filter -->\r\n <div *ngIf=\"detailFilterType === 'date'\" 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\"\r\n [(ngModel)]=\"detailFilterCondition\"\r\n >\r\n <option value=\"equal\">Equal to</option>\r\n <option value=\"before\">Before</option>\r\n <option value=\"after\">After</option>\r\n </select>\r\n </div>\r\n <div class=\"mb-2\">\r\n <input\r\n type=\"date\"\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Select date\"\r\n [(ngModel)]=\"detailFilterDateValue\"\r\n (keydown.enter)=\"applyDetailFilter()\"\r\n />\r\n <small class=\"text-muted d-block mt-1\">{{ detailFilterDateValue | timezoneFormat:prefs:'date' }}</small>\r\n </div>\r\n </div>\r\n\r\n <!-- Time Filter -->\r\n <div *ngIf=\"detailFilterType === 'time'\" 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\"\r\n [(ngModel)]=\"detailFilterCondition\"\r\n >\r\n <option value=\"equal\">Equal to</option>\r\n <option value=\"before\">Before</option>\r\n <option value=\"after\">After</option>\r\n </select>\r\n </div>\r\n <div class=\"mb-2\">\r\n <input\r\n type=\"time\"\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Select time\"\r\n [(ngModel)]=\"detailFilterTimeValue\"\r\n (keydown.enter)=\"applyDetailFilter()\"\r\n />\r\n </div>\r\n </div>\r\n\r\n <!-- Dropdown Filter -->\r\n <div *ngIf=\"detailFilterType === 'dropdown'\" class=\"col-12 position-relative p-2 text-filter\">\r\n <div class=\"mb-2\">\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Search options...\"\r\n [(ngModel)]=\"detailFilterSearch\"\r\n (input)=\"filterDetailDropdownOptions()\"\r\n />\r\n </div>\r\n <div class=\"dropdown-options\" style=\"max-height: 150px; overflow-y: auto;\">\r\n <div\r\n *ngFor=\"let option of filteredDetailDropdownOptions; let i = index\"\r\n class=\"form-check mb-1 ms-1\"\r\n >\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n [id]=\"'detail-filter-option-' + i\"\r\n [checked]=\"detailSelectedFilterOptions.includes(option._id || option.id || option.value)\"\r\n (change)=\"toggleDetailFilterOption(option)\"\r\n />\r\n <label\r\n class=\"form-check-label\"\r\n [for]=\"'detail-filter-option-' + i\"\r\n >\r\n {{ option.value || option.name || option }}\r\n </label>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- <div class=\"d-flex gap-2\">\r\n <button\r\n type=\"button\"\r\n class=\"btn btn-primary w-100 d-flex align-items-center justify-content-center mt-1\"\r\n (click)=\"applyDetailFilter()\"\r\n >\r\n <span>Apply</span>\r\n </button>\r\n <button\r\n type=\"button\"\r\n class=\"btn btn-danger w-100 d-flex align-items-center justify-content-center mt-1\"\r\n (click)=\"resetDetailFilter()\"\r\n >\r\n <span>Reset</span>\r\n </button>\r\n \r\n</div> -->\r\n\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: 22px\"\r\n (click)=\"applyDetailFilter()\"\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: 22px\"\r\n (click)=\"resetDetailFilter()\"\r\n >\r\n Reset\r\n </div>\r\n </div>\r\n</div>\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 >\r\n <ng-container *ngIf=\"!isEditing(row, col)\">\r\n <div\r\n *ngIf=\"!isArray\"\r\n class=\"full-text-content\"\r\n (dblclick)=\"$event.stopPropagation(); $event.preventDefault(); enableEdit(row, col)\"\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 {{ item?.department_name || item?.roleName || \"-\" }}\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 #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\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 align-items-center w-100 cell-content image-placeholder cursor-pointer position-relative\"\r\n \r\n (click)=\"onEmployeeClick(row)\"\r\n >\r\n <!-- Blue dot for manual logs -->\r\n <span\r\n *ngIf=\"row?.manually_logs && row.manually_logs.length > 0\"\r\n class=\"manual-logs-indicator\"\r\n (mouseenter)=\"openManualLogsModal($event, row)\"\r\n (mouseleave)=\"closeManualLogsModal()\"\r\n ></span>\r\n <ng-container\r\n *ngIf=\"\r\n row?.User?.logo || row?.User?.profile_pictures?.length || row?.logo || row?.profile_pictures?.length || row?.assetImage || row?.invoice?.invoice_image;\r\n else placeholder\r\n \"\r\n >\r\n <span class=\"pic\">\r\n <img\r\n [width]=\"rowHeight - 12\"\r\n [height]=\"rowHeight - 12\"\r\n [src]=\"row?.User?.profile_pictures?.[4]?.path || row?.User?.logo || row?.profile_pictures?.[4]?.path || row?.logo || row?.assetImage || row?.invoice?.invoice_image\"\r\n alt=\"icon\"\r\n />\r\n </span>\r\n </ng-container>\r\n\r\n <ng-template #placeholder>\r\n <span\r\n [ngClass]=\"getDynamicClass(row?.User?.full_name || 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 >\r\n {{ getInitials(row?.User?.full_name || row?.full_name) }}\r\n </span>\r\n </ng-template>\r\n </span>\r\n</ng-template>\r\n\r\n<!-- Cell Content Template for Card View -->\r\n<ng-template #cellContent let-row=\"row\" let-parentRow=\"parentRow\" let-col=\"col\">\r\n <ng-container [ngSwitch]=\"col.type\">\r\n <!-- String/Text -->\r\n <ng-container *ngSwitchCase=\"'string'\">\r\n {{ getNestedValue(row, col.field) || getNestedValue(parentRow, col.field) || '-' }}\r\n </ng-container>\r\n\r\n <!-- Number -->\r\n <ng-container *ngSwitchCase=\"'number'\">\r\n {{ getNestedValue(row, col.field) || getNestedValue(parentRow, col.field) || '-' }}\r\n </ng-container>\r\n\r\n <!-- Date -->\r\n <ng-container *ngSwitchCase=\"'date'\">\r\n {{ getNestedValue(row, col.field) || getNestedValue(parentRow, col.field) ? (getNestedValue(row, col.field) || getNestedValue(parentRow, col.field) | timezoneFormat:prefs:'date') : '-' }}\r\n </ng-container>\r\n\r\n <!-- Time -->\r\n <ng-container *ngSwitchCase=\"'time'\">\r\n {{ (getNestedValue(row, col.field) || getNestedValue(parentRow, col.field)) !== null && (getNestedValue(row, col.field) || getNestedValue(parentRow, col.field)) !== undefined ? ((getTimeValue(getNestedValue(row, col.field) || getNestedValue(parentRow, col.field)) | timezoneFormat:prefs:'time')) : '-' }}\r\n </ng-container>\r\n\r\n <!-- Boolean -->\r\n <ng-container *ngSwitchCase=\"'boolean'\">\r\n <span class=\"badge\" [class]=\"(getNestedValue(row, col.field) || getNestedValue(parentRow, col.field) === true || getNestedValue(row, col.field) || getNestedValue(parentRow, col.field) === 'true') ? 'badge-success' : 'badge-secondary'\">\r\n {{ (getNestedValue(row, col.field) || getNestedValue(parentRow, col.field) === true || getNestedValue(row, col.field) || getNestedValue(parentRow, col.field) === 'true') ? 'Yes' : 'No' }}\r\n </span>\r\n </ng-container>\r\n\r\n <!-- <div *ngSwitchCase=\"'is_payroll_processed'\" class=\"d-flex justify-content-start flex-column pointer position-relative\" >\r\n <span class=\"popover__wrapper\" >none\r\n {{ row.is_payroll_processed ? 'Yes' : 'No' }}\r\n </span>\r\n </div> -->\r\n\r\n <!-- Status -->\r\n <ng-container *ngSwitchCase=\"'status'\">\r\n <span class=\"badge\" [class]=\"getStatusBadgeClass(getNestedValue(row, col.field) || getNestedValue(parentRow, col.field))\">\r\n {{ transformStatus(getNestedValue(row, col.field) || getNestedValue(parentRow, col.field)) || '-' }}\r\n </span>\r\n </ng-container>\r\n\r\n <!-- Array -->\r\n <ng-container *ngSwitchCase=\"'array'\">\r\n <ng-container *ngIf=\"isArray(getNestedValue(row, col.field) || getNestedValue(parentRow, col.field))\">\r\n <ng-container *ngIf=\"col.field === 'breaks' || col.header?.toLowerCase().includes('break')\">\r\n <app-badge-overflow\r\n [badges]=\"getBreakBadges(getNestedValue(row, col.field) || getNestedValue(parentRow, col.field) || [])\"\r\n [maxWidth]=\"col.width || 200\"\r\n (badgeMouseEnter)=\"showBreakTooltip($event.event, $event.badge.data)\"\r\n (badgeMouseLeave)=\"hideBreakTooltip()\"\r\n (overflowCountClick)=\"onBadgeOverflowCountClick(col)\">\r\n </app-badge-overflow>\r\n </ng-container>\r\n <ng-container *ngIf=\"!(col.field === 'breaks' || col.header?.toLowerCase().includes('break'))\">\r\n {{ (getNestedValue(row, col.field) || getNestedValue(parentRow, col.field) || []).length }} items\r\n </ng-container>\r\n </ng-container>\r\n <ng-container *ngIf=\"!isArray(getNestedValue(row, col.field) || getNestedValue(parentRow, col.field))\">\r\n {{ getNestedValue(row, col.field) || getNestedValue(parentRow, col.field) || '-' }}\r\n </ng-container>\r\n </ng-container>\r\n\r\n <!-- Default -->\r\n <ng-container *ngSwitchDefault>\r\n {{ getNestedValue(row, col.field) || getNestedValue(parentRow, col.field) || '-' }}\r\n </ng-container>\r\n \r\n </ng-container>\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 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<div\r\n [style.bottom.px]=\"footerRowHeight + 50\"\r\n *ngIf=\"selectedRows.size > 0 && showTaskbar\"\r\n class=\"taskbar\"\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 {{ config?.paginationParams?.totalItems }} Total\r\n </span>\r\n <div class=\"action-buttons\">\r\n <ng-container *ngFor=\"let action of taskbarActions; let i = index\">\r\n <span\r\n class=\"action-btn verified btn {{ action }}\"\r\n (click)=\"action === 'Export' ? onExportClick() : action === 'Delete' ? onDeleteClick() : onVerifyClick(action)\"\r\n >{{ action }}</span\r\n >\r\n <span\r\n *ngIf=\"taskbarActions.length > 1 && i !== taskbarActions.length - 1\"\r\n class=\"separator\"\r\n >|</span\r\n >\r\n </ng-container>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<!-- Detail Row Choose Columns Modal -->\r\n<div *ngIf=\"showDetailColumnPanel\" 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=\"detailModalColumnPannel\"></ng-container>\r\n </div>\r\n</div>\r\n\r\n<!-- Paste Confirmation Modal -->\r\n<div *ngIf=\"showPasteConfirmationModal\" class=\"custom-modal-overlay\" (click)=\"cancelPaste()\">\r\n <div class=\"custom-modal-content\" [style.backgroundColor]=\"dropdownsBackgroundColor\" (click)=\"$event.stopPropagation()\">\r\n <div class=\"column-panel-header\">\r\n <div class=\"d-flex justify-content-between align-items-center px-2 ps-3 rounded-top-2 moda-header\" style=\"height: 48px;\">\r\n Confirm Paste Operation\r\n <span class=\"filter-icon-wrapper\" (click)=\"cancelPaste()\">\r\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/x.svg'\" class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"></span>\r\n </span>\r\n </div>\r\n <hr class=\"my-0\" />\r\n <div class=\"p-3\">\r\n <div class=\"mb-3\">\r\n <h6 class=\"mb-3\">You are about to paste the following data:</h6>\r\n <div class=\"border rounded p-3 bg-light\">\r\n <pre class=\"mb-0 text-dark small\">{{ pastePreviewData }}</pre>\r\n </div>\r\n </div>\r\n <div class=\"alert alert-warning\" role=\"alert\">\r\n <strong>Warning:</strong> This action will overwrite existing data in the selected cells. This cannot be undone.\r\n </div>\r\n <div class=\"d-flex justify-content-end gap-2 mt-4\">\r\n <button type=\"button\" class=\"btn btn-secondary\" (click)=\"cancelPaste()\">Cancel</button>\r\n <button type=\"button\" class=\"btn btn-primary\" (click)=\"confirmPaste()\">Confirm Paste</button>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<!-- Short Leave Tooltip Modal -->\r\n<div *ngIf=\"showShortLeaveTooltipModal\"\r\n class=\"custom-break-tooltips\"\r\n [style.--tooltip-x.px]=\"shortLeaveTooltipPosition.x\"\r\n [style.--tooltip-y.px]=\"shortLeaveTooltipPosition.y\"\r\n (mouseenter)=\"preventShortLeaveTooltipHide()\"\r\n (mouseleave)=\"hideShortLeaveTooltip()\">\r\n <div class=\"modal-body\">\r\n <div class=\"table-responsive\">\r\n <table class=\"table table-striped text-dark\">\r\n <thead>\r\n <tr>\r\n <th>Leave Type</th>\r\n <th>Start Time</th>\r\n <th>End Time</th>\r\n <th>Duration (min)</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <tr *ngFor=\"let item of currentShortLeaveData\">\r\n <td>{{ item.leave_type || 'N/A' }}</td>\r\n <td>{{ item.star_time || 'N/A' }}</td>\r\n <td>{{ item.end_time || 'N/A' }}</td>\r\n <td>{{ item.minutes || 'N/A' }}</td>\r\n </tr>\r\n </tbody>\r\n </table>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n<!-- Paste Confirmation Modal -->\r\n<div *ngIf=\"showPasteConfirmationModal\" class=\"custom-modal-overlay\" (click)=\"cancelPaste()\">\r\n <div class=\"custom-modal-content\" [style.backgroundColor]=\"dropdownsBackgroundColor\" (click)=\"$event.stopPropagation()\">\r\n <div class=\"column-panel-header\">\r\n <div class=\"d-flex justify-content-between align-items-center px-2 ps-3 rounded-top-2 moda-header\" style=\"height: 48px;\">\r\n <span class=\"fw-bold\">Confirm Paste</span>\r\n <span class=\"filter-icon-wrapper\" (click)=\"cancelPaste()\">\r\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/x.svg'\" class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"></span>\r\n </span>\r\n </div>\r\n <hr class=\"my-0\" />\r\n <div class=\"p-3\">\r\n <div class=\"mb-3\">\r\n <p class=\"mb-2\">Are you sure you want to paste the following data?</p>\r\n <div class=\"border rounded p-2 bg-light\">\r\n <small class=\"text-muted\">{{ pastePreviewData }}</small>\r\n </div>\r\n </div>\r\n <div class=\"d-flex gap-2 justify-content-end\">\r\n <button type=\"button\" class=\"btn btn-secondary\" (click)=\"cancelPaste()\">Cancel</button>\r\n <button type=\"button\" class=\"btn btn-primary\" (click)=\"confirmPaste()\">Confirm Paste</button>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<!-- Paste Confirmation Modal -->\r\n<div *ngIf=\"showPasteConfirmationModal\" class=\"custom-modal-overlay\" (click)=\"cancelPaste()\">\r\n <div class=\"custom-modal-content\" [style.backgroundColor]=\"dropdownsBackgroundColor\" (click)=\"$event.stopPropagation()\">\r\n <div class=\"modal-header d-flex justify-content-between align-items-center p-3\">\r\n <h5 class=\"modal-title mb-0\">Confirm Paste</h5>\r\n <button type=\"button\" class=\"btn-close\" (click)=\"cancelPaste()\"></button>\r\n </div>\r\n <div class=\"modal-body p-3\">\r\n <p class=\"mb-3\">Are you sure you want to paste the clipboard data into the selected cells?</p>\r\n <div class=\"alert alert-info\" *ngIf=\"pastePreviewData\">\r\n <strong>Paste Preview:</strong>\r\n <pre class=\"mt-2\">{{ pastePreviewData }}</pre>\r\n </div>\r\n </div>\r\n <div class=\"modal-footer p-3\">\r\n <button type=\"button\" class=\"btn btn-secondary\" (click)=\"cancelPaste()\">Cancel</button>\r\n <button type=\"button\" class=\"btn btn-primary\" (click)=\"confirmPaste()\">Paste</button>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<!-- Tooltip for accordion manual logs -->\r\n<!-- Tooltip for accordion manual logs -->\r\n<div *ngIf=\"showManualLogsTooltipModal\" class=\"custom-break-tooltips\"\r\n [style.--tooltip-x.px]=\"manualLogsTooltipPosition.x\"\r\n [style.--tooltip-y.px]=\"manualLogsTooltipPosition.y\"\r\n (mouseenter)=\"preventManualLogsTooltipHide()\"\r\n (mouseleave)=\"hideManualLogsTooltip()\">\r\n\r\n <div class=\"modal-body\">\r\n <div class=\"table-responsive\">\r\n <table class=\"table table-striped text-dark\">\r\n <thead>\r\n <tr>\r\n <th>Name</th>\r\n <th>Date/Time</th>\r\n <th>Previous</th>\r\n <th>Updated</th>\r\n <th>Status</th>\r\n <th>Remarks</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <ng-container *ngFor=\"let item of selectedManualLogs; let i = index\">\r\n <tr>\r\n <td>{{ item?.updated_by?.full_name || selectedManualLogsRow?.User?.full_name }}</td>\r\n <td>{{ item?.log_date && item.log_date !== '--' ? (item.log_date | timezoneFormat:prefs:'datetime') : (selectedManualLogsRow?.attendanceDate && selectedManualLogsRow?.attendanceDate !== '--' ? (selectedManualLogsRow?.attendanceDate | timezoneFormat:prefs:'datetime') : '-') }}</td>\r\n <td>{{ formatLogState(item?.log_details?.previous_state) }}</td>\r\n <td>{{ formatLogState(item?.log_details?.updated_state) }}</td>\r\n <td>{{ item?.log_details?.status ? transformStatus(item.log_details.status) : (item.log_details?.status || '-') }}</td>\r\n <td>{{ item?.log_details?.remarks || item?.remarks || selectedManualLogsRow?.message || '-' }}</td>\r\n </tr>\r\n </ng-container>\r\n\r\n <!-- Fallback for empty manual logs -->\r\n <tr *ngIf=\"!selectedManualLogs || selectedManualLogs.length === 0\">\r\n <td colspan=\"6\" class=\"text-center\">No manual logs available</td>\r\n </tr>\r\n </tbody>\r\n </table>\r\n </div>\r\n </div>\r\n </div>\r\n<!-- </div> -->\r\n\r\n<ng-template #detailModalColumnPannel>\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 Detail Columns\r\n <span class=\"filter-icon-wrapper\" (click)=\"closeDetailColumnPanel()\">\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 <input\r\n type=\"checkbox\"\r\n class=\"form-check-input me-2\"\r\n [checked]=\"allDetailColumnsSelected()\"\r\n (change)=\"toggleAllDetailColumnsVisibility()\"\r\n />\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Search detail columns...\"\r\n [(ngModel)]=\"choseColumnsSearch\"\r\n />\r\n </div>\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 (currentDetailRowForColumnSelection?.details?.columns || [])\r\n | filter : choseColumnsSearch : 'header';\r\n trackBy: trackByField\r\n \"\r\n >\r\n <div class=\"d-flex align-items-center mb-2\">\r\n <input\r\n type=\"checkbox\"\r\n class=\"form-check-input me-2\"\r\n [checked]=\"col.is_visible !== false\"\r\n (change)=\"toggleDetailColumnVisibility(col, !col.is_visible)\"\r\n [id]=\"'detail_col_' + col.field\"\r\n />\r\n <label\r\n class=\"d-flex align-items-center mb-0 w-100\"\r\n [for]=\"'detail_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 </div>\r\n </div>\r\n <!-- <div class=\"px-3 py-2 border-top d-flex justify-content-end\">\r\n <button class=\"btn btn-sm btn-link\" (click)=\"resetDetailColumnsInModal()\">Reset</button>\r\n </div> -->\r\n </div>\r\n</ng-template>\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n", styles: ["@charset \"UTF-8\";@keyframes fadeInUp{0%{opacity:0;transform:translateY(8px)}to{opacity:1;transform:translateY(0)}}@keyframes fadeInScale{0%{opacity:0;transform:scale(.95)}to{opacity:1;transform:scale(1)}}@keyframes slideInRight{0%{opacity:0;transform:translate(16px)}to{opacity:1;transform:translate(0)}}@keyframes pulse{0%{transform:scale(1)}50%{transform:scale(1.02)}to{transform:scale(1)}}@keyframes shimmer{0%{background-position:-200px 0}to{background-position:calc(200px + 100%) 0}}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.loading-overlay{animation:fadeInScale .25s cubic-bezier(.4,0,.2,1);transform:translateZ(0)}.loading-overlay .spinner-border{animation:spin 1s linear infinite}.data-grid-table-wrapper{height:100%;width:100%;border:1px solid #d9d9db;border-radius:12px;box-shadow:none!important;position:relative;animation:fadeInScale .35s cubic-bezier(.4,0,.2,1);transform:translateZ(0)}.data-grid-table-wrapper[data-theme=white]{border-color:#d9d9db;background-color:#f6f8ff;color:#000}.data-grid-table-wrapper[data-theme=white] *,.data-grid-table-wrapper[data-theme=white] *:before,.data-grid-table-wrapper[data-theme=white] *:after{color:#000!important}.data-grid-table-wrapper[data-theme=white] ::selection{background-color:#007bff!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=white] ::-moz-selection{background-color:#007bff!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=white] .data-grid-header-wrapper{background-color:#f8f9fa;color:#000!important}.data-grid-table-wrapper[data-theme=white] .data-grid-body-wrapper{background-color:#f6f8ff;box-shadow:none!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .data-grid-row{border-bottom-color:#d9d9db;box-shadow:none!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .data-grid-row:nth-child(2n){background-color:#f8f9fa!important}.data-grid-table-wrapper[data-theme=white] .data-grid-row:nth-child(odd){background-color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=white] .data-grid-row:hover{background-color:#007bff1a!important}.data-grid-table-wrapper[data-theme=white] .selected-cell,.data-grid-table-wrapper[data-theme=white] .row-selected{background-color:#e3f2fd!important}.data-grid-table-wrapper[data-theme=white] .cell,.data-grid-table-wrapper[data-theme=white] .header-cell,.data-grid-table-wrapper[data-theme=white] .data-grid-row,.data-grid-table-wrapper[data-theme=white] .data-grid-header,.data-grid-table-wrapper[data-theme=white] .cell-content,.data-grid-table-wrapper[data-theme=white] .full-text-content,.data-grid-table-wrapper[data-theme=white] .circle-value,.data-grid-table-wrapper[data-theme=white] .pic,.data-grid-table-wrapper[data-theme=white] .image-placeholder,.data-grid-table-wrapper[data-theme=white] .s-no,.data-grid-table-wrapper[data-theme=white] .fw-500{color:#000!important}.data-grid-table-wrapper[data-theme=white] span,.data-grid-table-wrapper[data-theme=white] div,.data-grid-table-wrapper[data-theme=white] p,.data-grid-table-wrapper[data-theme=white] td,.data-grid-table-wrapper[data-theme=white] th,.data-grid-table-wrapper[data-theme=white] label,.data-grid-table-wrapper[data-theme=white] a:not(.text-primary){color:#000!important}.data-grid-table-wrapper[data-theme=white] svg,.data-grid-table-wrapper[data-theme=white] svg path,.data-grid-table-wrapper[data-theme=white] svg circle,.data-grid-table-wrapper[data-theme=white] svg rect,.data-grid-table-wrapper[data-theme=white] svg polygon{color:#000!important;fill:#000!important;stroke:#000!important}.data-grid-table-wrapper[data-theme=white] .data-grid-svg-icon{color:#000!important}.data-grid-table-wrapper[data-theme=white] .data-grid-svg-icon path{stroke:#000!important;fill:#000!important}.data-grid-table-wrapper[data-theme=white] .badge.badge-danger{background-color:#ea5353!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=white] .badge.badge-success{background-color:#84ca81!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=white] .badge.badge-warning{background-color:#fff3dc!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .badge.badge-info{background-color:#e8fbfd!important;color:#00bad1!important}.data-grid-table-wrapper[data-theme=white] .context-menu{background:#f6f8ff;border-color:#d9d9db;color:#000!important}.data-grid-table-wrapper[data-theme=white] .context-menu li{color:#000!important}.data-grid-table-wrapper[data-theme=white] .context-menu li:hover{background-color:#007bff1a!important}.data-grid-table-wrapper[data-theme=white] .custom-tooltip,.data-grid-table-wrapper[data-theme=white] .popover__content,.data-grid-table-wrapper[data-theme=white] .custom-break-tooltip{background:#f6f8ff!important;border-color:#d9d9db!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .actions-dropdown,.data-grid-table-wrapper[data-theme=white] .custom-menu{background-color:#f6f8ff!important;border-color:#d9d9db!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .actions-dropdown .dropdown-item,.data-grid-table-wrapper[data-theme=white] .custom-menu .dropdown-item{color:#000!important}.data-grid-table-wrapper[data-theme=white] .actions-dropdown .dropdown-item:hover,.data-grid-table-wrapper[data-theme=white] .custom-menu .dropdown-item:hover{background-color:#007bff1a!important}.data-grid-table-wrapper[data-theme=white] .taskbar .selected-rows-action-bar{background-color:#343a40!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=white] .taskbar .selected-rows-action-bar .action-btn{color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=white] .manual-logs-modal .modal-header{background:linear-gradient(135deg,#343a40,#495057)!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=white] .manual-logs-modal .modal-header .modal-title{color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=white] .manual-logs-modal .modal-body{background-color:#f6f8ff!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .manual-logs-modal .modal-body .table{color:#000!important}.data-grid-table-wrapper[data-theme=white] .manual-logs-modal .modal-body .table thead th{background:linear-gradient(135deg,#f8f9fa,#e9ecef)!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .manual-logs-modal .modal-body .table tbody tr{color:#000!important}.data-grid-table-wrapper[data-theme=white] .manual-logs-modal .modal-body .table tbody tr:nth-child(2n){background-color:#f8f9fa!important}.data-grid-table-wrapper[data-theme=white] .manual-logs-modal .modal-body .table tbody tr:hover{background-color:#007bff1a!important}.data-grid-table-wrapper[data-theme=white] .manual-logs-modal .modal-body .table tbody tr td{color:#000!important;border-color:#d9d9db!important}.data-grid-table-wrapper[data-theme=white] .form-control,.data-grid-table-wrapper[data-theme=white] .form-select{background-color:#f6f8ff!important;border-color:#d9d9db!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .form-control::placeholder,.data-grid-table-wrapper[data-theme=white] .form-select::placeholder{color:#6c757d!important}.data-grid-table-wrapper[data-theme=white] .form-control option,.data-grid-table-wrapper[data-theme=white] .form-select option{background-color:#f6f8ff!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .filter-serach-inpt{background-color:#f6f8ff!important;border-color:#d9d9db!important}.data-grid-table-wrapper[data-theme=white] .filter-serach-inpt input{background-color:#f6f8ff!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .active-filters{background-color:#f8f9fa!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .custom-modal-overlay .custom-modal-content{background-color:#f6f8ff!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .circle-value{background-color:#f8f9fa!important;border-color:#d9d9db!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .pagination-container,.data-grid-table-wrapper[data-theme=white] .page-size,.data-grid-table-wrapper[data-theme=white] .page-info,.data-grid-table-wrapper[data-theme=white] .page-buttons{color:#000!important}.data-grid-table-wrapper[data-theme=white] .pagination-container select,.data-grid-table-wrapper[data-theme=white] .pagination-container button,.data-grid-table-wrapper[data-theme=white] .pagination-container span,.data-grid-table-wrapper[data-theme=white] .page-size select,.data-grid-table-wrapper[data-theme=white] .page-size button,.data-grid-table-wrapper[data-theme=white] .page-size span,.data-grid-table-wrapper[data-theme=white] .page-info select,.data-grid-table-wrapper[data-theme=white] .page-info button,.data-grid-table-wrapper[data-theme=white] .page-info span,.data-grid-table-wrapper[data-theme=white] .page-buttons select,.data-grid-table-wrapper[data-theme=white] .page-buttons button,.data-grid-table-wrapper[data-theme=white] .page-buttons span{background-color:#f6f8ff!important;border-color:#d9d9db!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .pagination-container button.active,.data-grid-table-wrapper[data-theme=white] .page-size button.active,.data-grid-table-wrapper[data-theme=white] .page-info button.active,.data-grid-table-wrapper[data-theme=white] .page-buttons button.active{background-color:#e3f2fd!important}.data-grid-table-wrapper[data-theme=white] .footer-row{background-color:#f8f9fa!important;border-top-color:#d9d9db!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] ::-webkit-scrollbar{background-color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=white] ::-webkit-scrollbar-thumb{background-color:#d9d9db!important}.data-grid-table-wrapper[data-theme=white] ::-webkit-scrollbar-thumb:hover{background-color:#adb5bd!important}.data-grid-table-wrapper[data-theme=white] ::-webkit-scrollbar-track{background-color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker{background-color:#f6f8ff!important;color:#000!important;border-color:#d9d9db!important}.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker .bs-datepicker-head{background:linear-gradient(135deg,#343a40,#495057)!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker .bs-datepicker-body{background-color:#f6f8ff!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker table td,.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker table th{color:#000!important}.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker table td.is-other-month,.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker table th.is-other-month{color:#6c757d!important}.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker table td.active,.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker table th.active{background-color:#e3f2fd!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker table td span.in-range,.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker table th span.in-range{background-color:#e3f2fd!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker table td:hover:not(.active),.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker table th:hover:not(.active){background-color:#007bff1a!important}.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker .bs-datepicker-buttons{background-color:#f8f9fa!important;border-top-color:#d9d9db!important}.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker .bs-datepicker-buttons .btn-primary{background:linear-gradient(135deg,#007bff,#0056b3)!important;color:#f6f8ff!important;border-color:#007bff!important}.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker .bs-datepicker-buttons .btn-secondary{background-color:#f6f8ff!important;color:#000!important;border-color:#d9d9db!important}.data-grid-table-wrapper[data-theme=white] button,.data-grid-table-wrapper[data-theme=white] .btn,.data-grid-table-wrapper[data-theme=white] .button{background-color:#f6f8ff!important;border-color:#d9d9db!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] button:hover,.data-grid-table-wrapper[data-theme=white] .btn:hover,.data-grid-table-wrapper[data-theme=white] .button:hover{background-color:#007bff1a!important}.data-grid-table-wrapper[data-theme=white] button.btn-primary,.data-grid-table-wrapper[data-theme=white] .btn.btn-primary,.data-grid-table-wrapper[data-theme=white] .button.btn-primary{background-color:#007bff!important;border-color:#007bff!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=white] button.btn-outline-primary,.data-grid-table-wrapper[data-theme=white] .btn.btn-outline-primary,.data-grid-table-wrapper[data-theme=white] .button.btn-outline-primary{border-color:#007bff!important;color:#007bff!important;background-color:transparent!important}.data-grid-table-wrapper[data-theme=white] a:not(.text-primary){color:#007bff!important}.data-grid-table-wrapper[data-theme=white] a:not(.text-primary):hover{color:#0056b3!important}.data-grid-table-wrapper[data-theme=white] .text-primary{color:#007bff!important}.data-grid-table-wrapper[data-theme=white] .text-danger{color:#dc3545!important}.data-grid-table-wrapper[data-theme=white] .text-success{color:#28a745!important}.data-grid-table-wrapper[data-theme=white] .text-warning{color:#ffc107!important}.data-grid-table-wrapper[data-theme=white] .text-info{color:#17a2b8!important}.data-grid-table-wrapper[data-theme=white] .text-muted,.data-grid-table-wrapper[data-theme=white] .muted-text{color:#6c757d!important}.data-grid-table-wrapper[data-theme=white] .border,.data-grid-table-wrapper[data-theme=white] .border-top,.data-grid-table-wrapper[data-theme=white] .border-bottom,.data-grid-table-wrapper[data-theme=white] .border-left,.data-grid-table-wrapper[data-theme=white] .border-right,.data-grid-table-wrapper[data-theme=white] .border-below,.data-grid-table-wrapper[data-theme=white] .border-start,.data-grid-table-wrapper[data-theme=white] .border-end{border-color:#d9d9db!important}.data-grid-table-wrapper[data-theme=white] .accordion-details,.data-grid-table-wrapper[data-theme=white] .nested-table,.data-grid-table-wrapper[data-theme=white] .detail-virtual-scroll{background-color:#f6f8ff!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .accordion-details td,.data-grid-table-wrapper[data-theme=white] .accordion-details th,.data-grid-table-wrapper[data-theme=white] .nested-table td,.data-grid-table-wrapper[data-theme=white] .nested-table th,.data-grid-table-wrapper[data-theme=white] .detail-virtual-scroll td,.data-grid-table-wrapper[data-theme=white] .detail-virtual-scroll th{color:#000!important;border-color:#d9d9db!important}.data-grid-table-wrapper[data-theme=blue]{border-color:#b3d9ff;background-color:#f0f8ff;color:#1e3a5f}.data-grid-table-wrapper[data-theme=blue] *,.data-grid-table-wrapper[data-theme=blue] *:before,.data-grid-table-wrapper[data-theme=blue] *:after{color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] ::selection{background-color:#007cf5!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=blue] ::-moz-selection{background-color:#007cf5!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=blue] .data-grid-header-wrapper{background-color:#e6f3ff;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .data-grid-body-wrapper{background-color:#f0f8ff;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .data-grid-row{border-bottom-color:#b3d9ff;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .data-grid-row:nth-child(2n){background-color:#f0f8ff!important}.data-grid-table-wrapper[data-theme=blue] .data-grid-row:nth-child(odd){background-color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=blue] .data-grid-row:hover{background-color:#1e3a5f1a!important}.data-grid-table-wrapper[data-theme=blue] .selected-cell,.data-grid-table-wrapper[data-theme=blue] .row-selected{background-color:#cce5ff!important}.data-grid-table-wrapper[data-theme=blue] .cell,.data-grid-table-wrapper[data-theme=blue] .header-cell,.data-grid-table-wrapper[data-theme=blue] .data-grid-row,.data-grid-table-wrapper[data-theme=blue] .data-grid-header,.data-grid-table-wrapper[data-theme=blue] .cell-content,.data-grid-table-wrapper[data-theme=blue] .full-text-content,.data-grid-table-wrapper[data-theme=blue] .circle-value,.data-grid-table-wrapper[data-theme=blue] .pic,.data-grid-table-wrapper[data-theme=blue] .image-placeholder,.data-grid-table-wrapper[data-theme=blue] .s-no,.data-grid-table-wrapper[data-theme=blue] .fw-500{color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] span,.data-grid-table-wrapper[data-theme=blue] div,.data-grid-table-wrapper[data-theme=blue] p,.data-grid-table-wrapper[data-theme=blue] td,.data-grid-table-wrapper[data-theme=blue] th,.data-grid-table-wrapper[data-theme=blue] label,.data-grid-table-wrapper[data-theme=blue] a:not(.text-primary){color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] svg,.data-grid-table-wrapper[data-theme=blue] svg path,.data-grid-table-wrapper[data-theme=blue] svg circle,.data-grid-table-wrapper[data-theme=blue] svg rect,.data-grid-table-wrapper[data-theme=blue] svg polygon{color:#1e3a5f!important;fill:#1e3a5f!important;stroke:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .data-grid-svg-icon{color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .data-grid-svg-icon path{stroke:#1e3a5f!important;fill:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .badge.badge-danger{background-color:#ff8787!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=blue] .badge.badge-success{background-color:#69db7c!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=blue] .badge.badge-warning{background-color:#ffd43b!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .badge.badge-info{background-color:#74c0fc!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=blue] .context-menu{background:#e6f3ff;border-color:#b3d9ff;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .context-menu li{color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .context-menu li:hover{background-color:#1e3a5f1a!important}.data-grid-table-wrapper[data-theme=blue] .custom-tooltip,.data-grid-table-wrapper[data-theme=blue] .popover__content,.data-grid-table-wrapper[data-theme=blue] .custom-break-tooltip{background:#e6f3ff!important;border-color:#b3d9ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .actions-dropdown,.data-grid-table-wrapper[data-theme=blue] .custom-menu{background-color:#e6f3ff!important;border-color:#b3d9ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .actions-dropdown .dropdown-item,.data-grid-table-wrapper[data-theme=blue] .custom-menu .dropdown-item{color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .actions-dropdown .dropdown-item:hover,.data-grid-table-wrapper[data-theme=blue] .custom-menu .dropdown-item:hover{background-color:#1e3a5f1a!important}.data-grid-table-wrapper[data-theme=blue] .taskbar .selected-rows-action-bar{background-color:#1e3a5f!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=blue] .taskbar .selected-rows-action-bar .action-btn{color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=blue] .manual-logs-modal .modal-header{background:linear-gradient(135deg,#1e3a5f,#2d4a6b)!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=blue] .manual-logs-modal .modal-header .modal-title{color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=blue] .manual-logs-modal .modal-body{background-color:#f0f8ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .manual-logs-modal .modal-body .table{color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .manual-logs-modal .modal-body .table thead th{background:linear-gradient(135deg,#e6f3ff,#cce5ff)!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .manual-logs-modal .modal-body .table tbody tr{color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .manual-logs-modal .modal-body .table tbody tr:nth-child(2n){background-color:#f0f8ff!important}.data-grid-table-wrapper[data-theme=blue] .manual-logs-modal .modal-body .table tbody tr:hover{background-color:#1e3a5f1a!important}.data-grid-table-wrapper[data-theme=blue] .manual-logs-modal .modal-body .table tbody tr td{color:#1e3a5f!important;border-color:#b3d9ff!important}.data-grid-table-wrapper[data-theme=blue] .form-control,.data-grid-table-wrapper[data-theme=blue] .form-select{background-color:#f6f8ff!important;border-color:#b3d9ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .form-control::placeholder,.data-grid-table-wrapper[data-theme=blue] .form-select::placeholder{color:#888!important}.data-grid-table-wrapper[data-theme=blue] .form-control option,.data-grid-table-wrapper[data-theme=blue] .form-select option{background-color:#f6f8ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .filter-serach-inpt{background-color:#f6f8ff!important;border-color:#b3d9ff!important}.data-grid-table-wrapper[data-theme=blue] .filter-serach-inpt input{background-color:#f6f8ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .active-filters,.data-grid-table-wrapper[data-theme=blue] .custom-modal-overlay .custom-modal-content{background-color:#e6f3ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .circle-value{background-color:#f6f8ff!important;border-color:#b3d9ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .pagination-container,.data-grid-table-wrapper[data-theme=blue] .page-size,.data-grid-table-wrapper[data-theme=blue] .page-info,.data-grid-table-wrapper[data-theme=blue] .page-buttons{color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .pagination-container select,.data-grid-table-wrapper[data-theme=blue] .pagination-container button,.data-grid-table-wrapper[data-theme=blue] .pagination-container span,.data-grid-table-wrapper[data-theme=blue] .page-size select,.data-grid-table-wrapper[data-theme=blue] .page-size button,.data-grid-table-wrapper[data-theme=blue] .page-size span,.data-grid-table-wrapper[data-theme=blue] .page-info select,.data-grid-table-wrapper[data-theme=blue] .page-info button,.data-grid-table-wrapper[data-theme=blue] .page-info span,.data-grid-table-wrapper[data-theme=blue] .page-buttons select,.data-grid-table-wrapper[data-theme=blue] .page-buttons button,.data-grid-table-wrapper[data-theme=blue] .page-buttons span{background-color:#f6f8ff!important;border-color:#b3d9ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .pagination-container button.active,.data-grid-table-wrapper[data-theme=blue] .page-size button.active,.data-grid-table-wrapper[data-theme=blue] .page-info button.active,.data-grid-table-wrapper[data-theme=blue] .page-buttons button.active{background-color:#cce5ff!important}.data-grid-table-wrapper[data-theme=blue] .footer-row{background-color:#e6f3ff!important;border-top-color:#b3d9ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] ::-webkit-scrollbar{background-color:#f0f8ff!important}.data-grid-table-wrapper[data-theme=blue] ::-webkit-scrollbar-thumb{background-color:#b3d9ff!important}.data-grid-table-wrapper[data-theme=blue] ::-webkit-scrollbar-thumb:hover{background-color:#74c0fc!important}.data-grid-table-wrapper[data-theme=blue] ::-webkit-scrollbar-track{background-color:#f0f8ff!important}.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker{background-color:#e6f3ff!important;color:#1e3a5f!important;border-color:#b3d9ff!important}.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker .bs-datepicker-head{background:linear-gradient(135deg,#1e3a5f,#2d4a6b)!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker .bs-datepicker-body{background-color:#f0f8ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker table td,.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker table th{color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker table td.is-other-month,.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker table th.is-other-month{color:#888!important}.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker table td.active,.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker table th.active{background-color:#cce5ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker table td span.in-range,.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker table th span.in-range{background-color:#cce5ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker table td:hover:not(.active),.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker table th:hover:not(.active){background-color:#1e3a5f1a!important}.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker .bs-datepicker-buttons{background-color:#f6f8ff!important;border-top-color:#b3d9ff!important}.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker .bs-datepicker-buttons .btn-primary{background:linear-gradient(135deg,#1e3a5f,#2d4a6b)!important;color:#f6f8ff!important;border-color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker .bs-datepicker-buttons .btn-secondary{background-color:#f0f8ff!important;color:#1e3a5f!important;border-color:#b3d9ff!important}.data-grid-table-wrapper[data-theme=blue] button,.data-grid-table-wrapper[data-theme=blue] .btn,.data-grid-table-wrapper[data-theme=blue] .button{background-color:#f6f8ff!important;border-color:#b3d9ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] button:hover,.data-grid-table-wrapper[data-theme=blue] .btn:hover,.data-grid-table-wrapper[data-theme=blue] .button:hover{background-color:#1e3a5f1a!important}.data-grid-table-wrapper[data-theme=blue] button.btn-primary,.data-grid-table-wrapper[data-theme=blue] .btn.btn-primary,.data-grid-table-wrapper[data-theme=blue] .button.btn-primary{background-color:#007cf5!important;border-color:#007cf5!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=blue] button.btn-outline-primary,.data-grid-table-wrapper[data-theme=blue] .btn.btn-outline-primary,.data-grid-table-wrapper[data-theme=blue] .button.btn-outline-primary{border-color:#007cf5!important;color:#007cf5!important;background-color:transparent!important}.data-grid-table-wrapper[data-theme=blue] a:not(.text-primary){color:#007cf5!important}.data-grid-table-wrapper[data-theme=blue] a:not(.text-primary):hover{color:#0056b3!important}.data-grid-table-wrapper[data-theme=blue] .text-primary{color:#007cf5!important}.data-grid-table-wrapper[data-theme=blue] .text-danger{color:#dc3545!important}.data-grid-table-wrapper[data-theme=blue] .text-success{color:#28a745!important}.data-grid-table-wrapper[data-theme=blue] .text-warning{color:#ffc107!important}.data-grid-table-wrapper[data-theme=blue] .text-info{color:#17a2b8!important}.data-grid-table-wrapper[data-theme=blue] .text-muted,.data-grid-table-wrapper[data-theme=blue] .muted-text{color:#6c757d!important}.data-grid-table-wrapper[data-theme=blue] .border,.data-grid-table-wrapper[data-theme=blue] .border-top,.data-grid-table-wrapper[data-theme=blue] .border-bottom,.data-grid-table-wrapper[data-theme=blue] .border-left,.data-grid-table-wrapper[data-theme=blue] .border-right,.data-grid-table-wrapper[data-theme=blue] .border-below,.data-grid-table-wrapper[data-theme=blue] .border-start,.data-grid-table-wrapper[data-theme=blue] .border-end{border-color:#b3d9ff!important}.data-grid-table-wrapper[data-theme=blue] .accordion-details,.data-grid-table-wrapper[data-theme=blue] .nested-table,.data-grid-table-wrapper[data-theme=blue] .detail-virtual-scroll{background-color:#f0f8ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .accordion-details td,.data-grid-table-wrapper[data-theme=blue] .accordion-details th,.data-grid-table-wrapper[data-theme=blue] .nested-table td,.data-grid-table-wrapper[data-theme=blue] .nested-table th,.data-grid-table-wrapper[data-theme=blue] .detail-virtual-scroll td,.data-grid-table-wrapper[data-theme=blue] .detail-virtual-scroll th{color:#1e3a5f!important;border-color:#b3d9ff!important}.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:30px}.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;position:relative}.resize-handle.resizing{z-index:9999!important;opacity:1!important;background-color:#007bff1a;border-right:2px solid #007bff;box-shadow:0 0 8px #007bff4d;position:relative!important;pointer-events:none!important}.group-header .resize-handle{top:25%}.h-100{height:100%}.data-grid-body{position:relative;overflow-y:auto;overflow-x:hidden;box-shadow:none!important}.cell{padding:8px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;height:100%;display:flex;align-items:center}.data-grid-row{display:flex;min-width:max-content;align-items:center;border-bottom:1px solid #d9d9db;transition:all .25s cubic-bezier(.4,0,.2,1);transform:translateZ(0);will-change:transform,box-shadow;backface-visibility:hidden}.data-grid-row:hover{transform:translate(2px);box-shadow:2px 0 8px #007bff1a}.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;background:#f6f8ff}.right-pinned-header{position:absolute;right:0;border-left:1px solid #d9d9db;z-index:unset}.left-pinned{left:0;border-right:1px solid #d9d9db}.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{display:flex}.data-grid-body-wrapper{scrollbar-width:none;-ms-overflow-style:none}.data-grid-body-wrapper::-webkit-scrollbar{display:none}.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:#f6f8ff;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:-15px;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:16px}.border-below{border-bottom:1px solid #d9d9db!important}.three-dots{width:22px;height:22px;display:flex;justify-content:center;align-items:center;border-radius:6px;margin-right:8px;cursor:pointer;transition:all .25s cubic-bezier(.4,0,.2,1);transform:translateZ(0);position:relative}.three-dots:before{content:\"\";position:absolute;top:50%;left:50%;width:0;height:0;background:#007bff1a;border-radius:50%;transform:translate(-50%,-50%);transition:width .25s,height .25s}.three-dots:hover{background-color:#007bff1a;transform:rotate(90deg)}.three-dots:hover:before{width:28px;height:28px}.three-dots:active{transform:rotate(90deg) scale(.95);transition-duration:.15s}.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:6px;cursor:pointer;transition:all .25s cubic-bezier(.4,0,.2,1);transform:translateZ(0);position:relative}.filter-icon-wrapper:before{content:\"\";position:absolute;top:50%;left:50%;width:0;height:0;background:#007bff1a;border-radius:50%;transform:translate(-50%,-50%);transition:width .25s,height .25s}.filter-icon-wrapper:hover{background-color:#007bff1a;transform:scale(1.05)}.filter-icon-wrapper:hover:before{width:32px;height:32px}.filter-icon-wrapper:active{transform:scale(.95);transition-duration:.15s}.column-panel-item{font-size:.875rem;color:#333;transition:all .25s cubic-bezier(.4,0,.2,1);transform:translateZ(0)}.column-panel-item:hover{background-color:#007bff0d;color:#007bff;transform:translate(2px)}.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:all .25s cubic-bezier(.4,0,.2,1);transform:translateZ(0);border-radius:4px;padding:2px}.toggle-icon:hover{background-color:#007bff1a;transform:scale(1.1)}.toggle-icon:active{transform:scale(.95)}.grab-icon{cursor:grab;color:#6c757d;transition:all .25s cubic-bezier(.4,0,.2,1);transform:translateZ(0)}.grab-icon:hover{color:#007bff;transform:scale(1.1)}.grab-icon:active{cursor:grabbing;transform:scale(.95)}.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:6px;display:flex;justify-content:center;align-items:center;transition:all .25s cubic-bezier(.4,0,.2,1);margin-right:8px;transform:translateZ(0);position:relative}.chevron-wrapper:before{content:\"\";position:absolute;top:50%;left:50%;width:0;height:0;background:#007bff1a;border-radius:50%;transform:translate(-50%,-50%);transition:width .25s,height .25s}.chevron-wrapper:hover{background-color:#007bff1a;transform:scale(1.1)}.chevron-wrapper:hover:before{width:36px;height:36px}.chevron-wrapper:hover i{transform:scale(1.2);transition:transform .25s cubic-bezier(.4,0,.2,1)}.chevron-wrapper:active{transform:scale(.95);transition-duration:.15s}.chevron-wrapper i{font-size:14px;transition:transform .25s cubic-bezier(.4,0,.2,1)}.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;transition:all .25s cubic-bezier(.4,0,.2,1);transform:translateZ(0);border-radius:6px}.columns-button:hover{background-color:#007bff1a;transform:scale(1.05)}.columns-button:active{transform:scale(.95)}.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:fixed;right:200px;z-index:1050;background-color:#fff;cursor:default;animation:slideInRight .25s cubic-bezier(.4,0,.2,1);transform:translateZ(0);border-radius:8px;box-shadow:0 8px 32px #0000001f;backdrop-filter:blur(8px)}.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;transition:all .25s cubic-bezier(.4,0,.2,1);transform:translateZ(0)}.action-button:hover{transform:translateY(-1px);box-shadow:0 4px 12px #007cf54d}.action-button:active{transform:translateY(0);transition-duration:.15s}.global-search{max-width:380px!important}.global-search span{margin-top:2px}.global-search input{padding-left:28px;border-radius:8px!important;transition:all .25s cubic-bezier(.4,0,.2,1);transform:translateZ(0)}.global-search input:focus{outline:none!important;box-shadow:0 0 0 3px #007bff1a!important;border-color:#007bff!important;transform:scale(1.02)}.active .top-icon ::ng-deep svg path{stroke:#007cf5!important}.custom-menu{width:220px;border-radius:8px;padding:4px 0}.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}.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;transition:all .25s cubic-bezier(.4,0,.2,1);transform:translateZ(0)}.page-buttons button:hover:not(:disabled){background-color:#007bff1a;border-color:#007bff;transform:translateY(-1px)}.page-buttons button:active:not(:disabled){transform:translateY(0) scale(.98)}.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!important}.text-filter select option{font-size:14px;font-weight:500}.text-filter select:focus{border:0!important}.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;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-width:600px;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{letter-spacing:.5px}.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;bottom:0;left:45%;display:flex;justify-content:center;z-index:1000;padding:36px}.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{font-size:14px;padding:6px 12px;border-radius:6px;text-align:center;height:auto;min-height:28px;display:inline-flex;align-items:center;justify-content:center;font-weight:500;line-height:1.5;white-space:nowrap;transition:all .2s cubic-bezier(.4,0,.2,1);will-change:transform,opacity;backface-visibility:hidden;transform:translateZ(0)}.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}.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;animation:pulse .25s cubic-bezier(.4,0,.2,1);transform:translateZ(0);position:relative}.selected-cell:before,.row-selected:before{content:\"\";position:absolute;inset:0;background:linear-gradient(45deg,transparent,rgba(255,255,255,.1),transparent);animation:shimmer 1.5s ease-in-out infinite}.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}.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.dragging th,.accordion-details.dragging td{pointer-events:none}.accordion-details.dragging th{z-index:2}.drag-handle{cursor:move;opacity:.5;transition:opacity .2s}.drag-handle:hover{opacity:1}.detail-edit-input{z-index:100;position:relative}.detail-filter-menu{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}.detail-filter-menu-positioned{width:280px;right:unset;max-width:230px;z-index:99;left:375px;top:225px}.resize-handle{cursor:col-resize;opacity:.5;width:8px;display:flex;align-items:center;justify-content:center}.resize-handle:hover{opacity:1;background-color:#f0f0f0}.detail-header-row{transition:all .3s ease}.detail-header-row.dragging{opacity:.7;transform:translate(5px)}.detail-cell{transition:background-color .2s ease,transform .3s ease}.detail-cell.active-drag{background-color:#f0f0f0;transform:scale(1.02)}.break-color-paid{background-color:#4caf50!important}.break-color-unpaid{background-color:#f44336!important}.break-color-lunch{background-color:#2196f3!important}.break-color-default{background-color:#f44336!important}.circle-value{display:flex;align-items:center;justify-content:center;width:32px;height:32px;border-radius:50%;background-color:#f8f9fa;border:2px solid #d9d9db;font-size:12px;font-weight:600;color:#000;text-align:center;line-height:1;vertical-align:middle;box-sizing:border-box;white-space:nowrap;overflow:hidden;cursor:pointer;transition:all .3s cubic-bezier(.4,0,.2,1);transform:translateZ(0);will-change:transform,box-shadow,background-color;backface-visibility:hidden}.circle-value:hover{background-color:#e9ecef;box-shadow:0 6px 16px #007bff40;transform:scale(1.15) translateY(-2px);border-color:#007bff}.circle-value:active{transform:scale(1.08) translateY(-1px);transition-duration:.15s}.break-tooltip-wrapper{position:relative;display:inline-block}.break-tooltip-wrapper:hover .custom-break-tooltip{opacity:1;visibility:visible}.circle-value[title]{position:relative}.circle-value[title]:after{content:attr(title);position:absolute;bottom:100%;left:50%;transform:translate(-50%);background-color:#333;color:#fff;padding:4px 8px;border-radius:4px;font-size:12px;white-space:nowrap;opacity:0;transition:opacity .2s ease;pointer-events:none}.circle-value[title]:hover:after{opacity:1}.custom-tooltip{position:fixed;background:#fff;border:1px solid #dcdcdc;border-radius:8px;padding:12px 16px;max-width:300px;z-index:9999;font-size:13px;animation:fadeIn .2s ease-in-out}.tooltip-title{font-size:14px;font-weight:600;margin-bottom:8px;color:#333}.tooltip-list{margin:0;padding-left:16px;list-style-type:disc}.tooltip-list li{margin-bottom:4px;line-height:1.4;color:#444}.tooltip-total{font-weight:700;margin-top:8px;color:#222}@keyframes fadeIn{0%{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:translateY(0)}}.restriction-indicator{position:absolute;display:inline-block;padding-right:10px}.restriction-indicator:after{content:\"\";position:absolute;top:0;right:0;width:8px;height:8px;background-color:#0d6efd;border-radius:50%}.manual-logs-indicator{position:absolute;top:2px;right:2px;width:8px;height:8px;background-color:#0d6efd;border-radius:50%;border:1px solid #fff;box-shadow:0 0 2px #0d6efd80;cursor:pointer;z-index:10;transition:all .2s ease}.manual-logs-indicator:hover{transform:scale(1.2);box-shadow:0 0 4px #0d6efdcc}.manual-logs-table-tooltip{background:#fff!important;border:1px solid #dcdcdc!important;border-radius:8px!important;box-shadow:0 4px 12px #00000026!important;font-size:13px!important;animation:fadeIn .2s ease-in-out!important;display:block!important;visibility:visible!important;opacity:1!important}.manual-logs-table-tooltip .popover__content,.manual-logs-table-tooltip .modal-area{padding:0!important;display:block!important;visibility:visible!important}.manual-logs-table-tooltip .table-responsive{max-height:300px;overflow-y:auto;display:block!important;visibility:visible!important}.manual-logs-table-tooltip table{margin:0!important;border-collapse:collapse!important;display:table!important;visibility:visible!important}.manual-logs-table-tooltip table th,.manual-logs-table-tooltip table td{padding:6px 8px!important;border:1px solid #f1f1f1!important;text-align:center!important;vertical-align:middle!important;display:table-cell!important;visibility:visible!important}.manual-logs-table-tooltip table th{background-color:#f8f9fa!important;font-weight:600!important;color:#495057!important;position:sticky!important;top:0!important;z-index:1!important}.manual-logs-table-tooltip table tbody tr:nth-child(2n){background-color:#f8f9fa!important}.manual-logs-table-tooltip table tbody tr:hover{background-color:#e3f2fd!important}.manual-logs-table-tooltip table .text-primary{color:#0d6efd!important;text-decoration:none!important}.manual-logs-table-tooltip table .capitalize{text-transform:capitalize!important}@keyframes fadeIn{0%{opacity:0;transform:translate(-50%) translateY(-110%)}to{opacity:1;transform:translate(-50%) translateY(-100%)}}.detail-column-menu{max-height:250px;overflow-y:auto;overflow-x:auto;white-space:nowrap;padding:8px 0;border-radius:6px;scrollbar-width:thin}.detail-column-menu-wrapper{z-index:1001;position:absolute}.accordion-details{position:relative;z-index:999}.detail-column-menu .column-menu-item{padding:8px 12px;cursor:pointer;display:flex;align-items:center;transition:all .25s cubic-bezier(.4,0,.2,1);font-size:14px;transform:translateZ(0);border-radius:4px}.detail-column-menu .column-menu-item:hover{background-color:#007bff1a;transform:translate(2px);color:#007bff}.detail-column-menu .column-menu-item:active{transform:translate(0) scale(.98)}.detail-column-menu .column-menu-item:hover{background-color:#deebf7}.nested-table th[pinned=left],.nested-table td[pinned=left]{border-right:2px solid #ccc;border-left:none;border-bottom:2px solid #ccc}.nested-table th[pinned=right],.nested-table td[pinned=right]{border-left:2px solid #ccc;border-right:none;border-bottom:2px solid #ccc}.data-grid-accordion-table.show-borders{border:1px solid #d9d9db;border-collapse:collapse}.data-grid-accordion-table.show-borders th,.data-grid-accordion-table.show-borders td{border:1px solid #d9d9db}.data-grid-accordion-table.show-shadow tbody tr:hover{box-shadow:0 4px 8px #0000001a;transition:box-shadow .3s ease}.data-grid-accordion-table tbody tr:hover{background-color:#deebf7;transition:background-color .3s ease}.data-grid-pin-icon{display:inline-block;vertical-align:middle;margin-left:4px}.accordion-details.center-section{position:relative;display:flex}.detail-side-menu-wrapper{display:flex;flex-shrink:0;position:sticky;right:0;top:0;height:100%;max-height:275px}.detail-side-menu-content{width:250px;box-shadow:-2px 0 5px #0000001a;display:flex;flex-direction:column}.side-menu-scrollable{flex:1;overflow-y:auto;padding:0 12px 12px;max-height:calc(100% - 40px)}.filter-input-container{padding:8px;background:#f9f9f9;border-radius:4px}.toggle-icon.rotate{transform:rotate(90deg)}.resize-handle{top:0;right:3px;bottom:0;width:8px;cursor:col-resize;z-index:10;display:flex;align-items:center;justify-content:center;opacity:1.4;transition:all .25s cubic-bezier(.4,0,.2,1);background:transparent;transform:translateZ(0)}.resize-handle:hover{opacity:1;background:#007bff1a}.resize-handle:active{opacity:1;background:#007bff33;transform:scaleX(1.2)}th:hover .resize-handle{opacity:40}.resize-handles{top:0;right:3px;bottom:0;width:8px;cursor:col-resize;z-index:10;display:flex;align-items:center;justify-content:center;position:absolute;opacity:1.4;transition:all .25s cubic-bezier(.4,0,.2,1);background:transparent;transform:translateZ(0)}.resize-handles:hover{opacity:1;background:#007bff1a}.resize-handles:active{opacity:1;background:#007bff33;transform:scaleX(1.2)}.resize-handles.resizing{z-index:9999!important;opacity:1!important;background-color:#007bff1a;border-right:2px solid #007bff;box-shadow:0 0 8px #007bff4d;pointer-events:none!important}th:hover .resize-handles{opacity:40}.resizing-highlight{background-color:#007bff1a!important}.accordion-details-wrapper{display:flex;width:100%;max-height:350px;overflow:hidden}.accordion-details.show-borders,.accordion-details-wrapper.show-borders{border:1px solid #d9d9db;border-radius:4px}.accordion-left-section,.accordion-right-section,.detail-side-menu-wrapper{flex-shrink:0;max-height:350px;overflow:hidden;height:fit-content}.accordion-center-section{flex:1;min-width:0;overflow:auto;max-height:350px}.detail-virtual-scroll{display:block;width:100%;height:250px;overflow:auto}.detail-virtual-scroll table{table-layout:fixed;width:100%}.detail-virtual-scroll td,.detail-virtual-scroll th{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.detail-header-scroll-container{scrollbar-width:none}.detail-header-scroll-container::-webkit-scrollbar{display:none}.accordion-left-section thead th,.accordion-right-section thead th{position:sticky;top:0;z-index:2}.data-pin-body-wrapper{-webkit-user-select:none;user-select:none;display:flex}.data-pin-body-wrapper{scrollbar-width:none;-ms-overflow-style:none}.data-pin-body-wrapper::-webkit-scrollbar{display:none}.detail-virtual-scroll .selected-cell,.accordion-left-section .selected-cell,.accordion-right-section .selected-cell{background-color:#cce5ff!important}.custom-datepicker-buttons button{height:28px;padding:0 10px;font-size:12px}.manual-logs-modal{max-width:800px;max-height:80vh;overflow:hidden;border-radius:12px;box-shadow:0 10px 40px #0003}.manual-logs-modal .modal-header{background:linear-gradient(135deg,#4361ee,#3a0ca3);color:#fff;padding:16px 20px;border-bottom:none;border-radius:12px 12px 0 0}.manual-logs-modal .modal-header .modal-title{font-weight:600;font-size:18px;margin:0}.manual-logs-modal .modal-header .btn-close{background:#fff3;border:none;border-radius:50%;width:32px;height:32px;display:flex;align-items:center;justify-content:center;color:#fff;opacity:.8;transition:all .25s cubic-bezier(.4,0,.2,1);transform:translateZ(0)}.manual-logs-modal .modal-header .btn-close:hover{background:#ffffff4d;opacity:1;transform:scale(1.1) rotate(90deg)}.manual-logs-modal .modal-header .btn-close:active{transform:scale(.95) rotate(90deg)}.manual-logs-modal .modal-body{padding:20px;max-height:calc(80vh - 80px);overflow-y:auto}.manual-logs-modal .modal-body .table-responsive{border-radius:8px;overflow:hidden;box-shadow:0 2px 8px #0000001a}.manual-logs-modal .modal-body .table-responsive .table{margin-bottom:0;font-size:14px}.manual-logs-modal .modal-body .table-responsive .table thead th{background:linear-gradient(135deg,#f8f9fa,#e9ecef);border-bottom:2px solid #dee2e6;font-weight:600;color:#495057;padding:12px 16px;position:sticky;top:0;z-index:10}.manual-logs-modal .modal-body .table-responsive .table tbody tr{transition:background-color .2s ease}.manual-logs-modal .modal-body .table-responsive .table tbody tr:hover{background-color:#f8f9fa}.manual-logs-modal .modal-body .table-responsive .table tbody tr:nth-child(2n){background-color:#f8f9fa}.manual-logs-modal .modal-body .table-responsive .table tbody tr td{padding:10px 16px;vertical-align:middle;border-color:#e9ecef}.manual-logs-modal .modal-body .table-responsive .table tbody tr td .text-primary{color:#0d6efd!important;font-weight:500;text-decoration:none}.manual-logs-modal .modal-body .table-responsive .table tbody tr td .text-primary:hover{text-decoration:underline}.manual-logs-modal .modal-body .table-responsive .table tbody tr td .capitalize{text-transform:capitalize}::ng-deep bs-daterangepicker-container .bs-datepicker{border-radius:4px!important;box-shadow:0 2px 8px #0000001a!important;font-size:14px!important;display:flex!important;align-items:flex-start!important;left:142px!important}::ng-deep .bs-datepicker-head{background:#f8f9fa!important;color:#495057!important;border-bottom:1px solid #dee2e6!important;padding:8px 12px!important;border-radius:4px 4px 0 0!important}::ng-deep .bs-datepicker-head .current{font-weight:600!important;color:#495057!important;font-size:13px!important}::ng-deep .bs-datepicker-head .previous,::ng-deep .bs-datepicker-head .next{background:#fff!important;color:#495057!important;border:1px solid #dee2e6!important;width:24px!important;border-radius:4px!important;font-size:12px!important}::ng-deep .bs-datepicker-head .previous:hover,::ng-deep .bs-datepicker-head .next:hover{background:#e9ecef!important}::ng-deep .bs-datepicker .bs-datepicker-buttons{padding:8px!important;background:#f8f9fa!important;border-top:1px solid #dee2e6!important;border-radius:0 0 4px 4px!important}::ng-deep .bs-datepicker .bs-datepicker-buttons .btn-primary{background:#007bff!important;color:#fff!important;border:1px solid #007bff!important;font-weight:500!important;padding:4px 8px!important;border-radius:4px!important;font-size:12px!important}::ng-deep .bs-datepicker .bs-datepicker-buttons .btn-primary:hover{background:#0056b3!important;border-color:#0056b3!important}::ng-deep .bs-datepicker .bs-datepicker-buttons .btn-secondary{background:#fff!important;color:#495057!important;border:1px solid #dee2e6!important;font-weight:500!important;padding:4px 8px!important;border-radius:4px!important;font-size:12px!important}::ng-deep .bs-datepicker .bs-datepicker-buttons .btn-secondary:hover{background:#e9ecef!important}::ng-deep .bs-datepicker-body{background:#fff!important;padding:6px!important}::ng-deep .bs-datepicker-body table{background:#fff!important;border-collapse:separate!important;border-spacing:1px!important}::ng-deep .bs-datepicker-body table th,::ng-deep .bs-datepicker-body table td{border:1px solid #dee2e6!important;border-radius:4px!important;text-align:center!important;font-weight:500!important;color:#495057!important;cursor:pointer!important;transition:all .2s ease!important;font-size:12px!important;width:32px!important;height:32px!important;line-height:24px!important}::ng-deep .bs-datepicker-body table th{background:#f8f9fa!important;font-weight:600!important;font-size:11px!important;padding:2px!important;height:24px!important;line-height:20px!important}::ng-deep .bs-datepicker-body table td:hover:not(.disabled){background:#e9ecef!important}::ng-deep .bs-datepicker-body table td.active{background:#007bff!important;color:#fff!important;border-color:#007bff!important}::ng-deep .bs-datepicker-body table td.is-other-month{color:#6c757d!important;background:#f8f9fa!important}::ng-deep .bs-datepicker-body table td.disabled{color:#adb5bd!important;background:#e9ecef!important;cursor:not-allowed!important}::ng-deep .bs-datepicker-custom-range{background:transparent!important;border-right:1px solid #dee2e6!important;padding:6px!important;width:130px!important;margin-right:8px!important;align-self:flex-start!important}::ng-deep .bs-datepicker-predefined-btns{display:flex!important;flex-direction:column!important;gap:2px!important}::ng-deep .bs-datepicker-predefined-btns button{background:transparent!important;color:#495057!important;border:1px solid #dee2e6!important;border-radius:4px!important;padding:4px 6px!important;font-size:11px!important;font-weight:500!important;text-align:left!important;cursor:pointer!important;transition:all .2s ease!important;width:100%!important;margin:0!important}::ng-deep .bs-datepicker-predefined-btns button:hover{background:#e9ecef!important;border-color:#adb5bd!important}::ng-deep .bs-datepicker-predefined-btns button:active,::ng-deep .bs-datepicker-predefined-btns button:focus{outline:none!important;box-shadow:0 0 0 2px #007bff40!important;background:#007bff!important;color:#fff!important;border-color:#007bff!important}.manual-logs-modal-overlay{position:fixed;top:0;left:0;width:100%;height:100%;background-color:#00000080;display:flex;justify-content:center;align-items:center;z-index:9999}.manual-logs-modal-content{background:#fff;border-radius:8px;max-width:800px;max-height:80vh;overflow:auto;box-shadow:0 4px 8px #0000001a}.popover__wrapper{position:relative;display:inline-block}.popover__content{position:absolute;bottom:100%;left:50%;transform:translate(-50%);background:#fff;border:1px solid #ccc;border-radius:8px;padding:12px;box-shadow:0 4px 12px #00000026;z-index:1000;opacity:0;visibility:hidden;transition:opacity .3s ease,visibility .3s ease;min-width:250px;max-width:400px;font-size:14px}.popover__wrapper:hover .popover__content{opacity:1;visibility:visible}.popover__content .modal-area{padding:0}.popover__content h4{margin:0 0 8px;font-size:16px;font-weight:600;color:#333}.popover__content .break-status{font-size:12px;color:#666;margin-bottom:8px}.popover__content .d-flex{gap:12px}.popover__content p{margin:0 0 4px;font-size:12px;color:#666}.popover__content h5{margin:0;font-size:14px;font-weight:500;color:#333}.popover__content .break-footer{border-top:1px solid #eee;margin-top:8px;padding-top:8px}.popover__content .break-footer p{font-size:12px;color:#666;margin:0}.custom-break-tooltip{position:fixed;z-index:1000;background:#fff;border:1px solid #ddd;border-radius:8px;box-shadow:0 4px 12px #00000026;padding:12px;font-size:13px;max-width:220px;pointer-events:none;top:0;left:0;transform:translate(var(--tooltip-x, 0px),var(--tooltip-y, 0px))}.custom-break-tooltips{position:fixed;z-index:1000;background:#fff;border:1px solid #ddd;border-radius:8px;box-shadow:0 4px 12px #00000026;padding:8px;font-size:12px;max-width:500px;max-height:300px;top:0;left:0;transform:translate(var(--tooltip-x, 0px),var(--tooltip-y, 0px))}.custom-break-tooltips .modal-body{max-height:250px!important;overflow-y:auto;padding:0}.custom-break-tooltips .table-responsive{max-height:250px}.custom-break-tooltips thead th{position:sticky;top:0;background:#f8f9fa;z-index:10;border-bottom:2px solid #dee2e6;font-size:11px;padding:4px 8px;font-weight:600}.custom-break-tooltips table{font-size:11px;margin-bottom:0}.custom-break-tooltips table td{padding:4px 8px;white-space:nowrap}.custom-break-tooltips .table-striped tbody tr:nth-of-type(odd){background-color:#00000005}.popver_content_progress_bar{visibility:hidden}.badge-overflow-container{display:flex;flex-wrap:nowrap;gap:4px;align-items:center;min-width:0;overflow:hidden;width:100%}.badge-overflow-container .badge{flex-shrink:0;white-space:nowrap;font-size:12px;padding:4px 8px;border-radius:50%;display:inline-flex;align-items:center;justify-content:center;font-weight:600;line-height:1;text-transform:uppercase;letter-spacing:.5px;transition:all .3s cubic-bezier(.4,0,.2,1);border:2px solid transparent;width:32px;height:32px;box-sizing:border-box;cursor:pointer;transform:translateZ(0);will-change:transform,box-shadow,background-color;backface-visibility:hidden}.badge-overflow-container .badge:hover{transform:scale(1.15) translateY(-2px);box-shadow:0 6px 16px #007bff40}.badge-overflow-container .badge:active{transform:scale(1.08) translateY(-1px);transition-duration:.15s}.badge-overflow-container .badge-overflow-count{background-color:#6c757d!important;color:#fff!important;cursor:pointer;border:2px solid #6c757d!important;flex-shrink:0;border-radius:50%;width:32px;height:32px;display:inline-flex;align-items:center;justify-content:center;font-weight:600;transition:all .3s cubic-bezier(.4,0,.2,1);transform:translateZ(0);will-change:transform,box-shadow,background-color;backface-visibility:hidden}.badge-overflow-container .badge-overflow-count:hover{background-color:#5a6268!important;border-color:#5a6268!important;transform:scale(1.15) translateY(-2px);box-shadow:0 6px 16px #007bff40}.badge-overflow-container .badge-overflow-count:active{transform:scale(1.08) translateY(-1px);transition-duration:.15s}.timeline-view-container{padding:1rem;background-color:#f8f9fa}.timeline-view-container .timeline-header{margin-bottom:2rem}.timeline-view-container .timeline-header h5{color:#495057;font-weight:600;margin-bottom:1rem}.timeline-view-container .timeline-header .timeline-hours{display:flex;justify-content:space-between;padding:.5rem 0;border-bottom:1px solid #dee2e6;margin-bottom:1rem;background:#fff;border-radius:8px;padding:1rem}.timeline-view-container .timeline-header .timeline-hours .timeline-hour{font-size:.8rem;color:#6c757d;font-weight:500;min-width:40px;text-align:center;padding:.5rem;border-radius:4px;background:#f8f9fa}.timeline-view-container .timeline-body .timeline-row{background:#fff;border:1px solid #dee2e6;border-radius:8px;margin-bottom:1rem;padding:1rem;box-shadow:0 2px 4px #0000001a;transition:box-shadow .2s ease}.timeline-view-container .timeline-body .timeline-row:hover{box-shadow:0 4px 8px #00000026}.timeline-view-container .timeline-body .timeline-row .timeline-employee{margin-bottom:1rem}.timeline-view-container .timeline-body .timeline-row .timeline-employee .employee-name{font-weight:600;color:#495057;font-size:1.1rem}.timeline-view-container .timeline-body .timeline-row .timeline-track{position:relative;height:40px;background:#f8f9fa;border-radius:4px;border:1px solid #e9ecef}.timeline-view-container .timeline-body .timeline-row .timeline-track .work-duration-bar{position:absolute;height:100%;background:linear-gradient(135deg,#28a745,#20c997);border-radius:4px;box-shadow:0 2px 4px #28a7454d;transition:opacity .2s ease}.timeline-view-container .timeline-body .timeline-row .timeline-track .work-duration-bar:hover{opacity:.8}.timeline-view-container .timeline-body .timeline-row .timeline-track .break-bar{position:absolute;height:100%;border-radius:4px;box-shadow:0 2px 4px #0003;border:1px solid rgba(255,255,255,.5);transition:opacity .2s ease}.timeline-view-container .timeline-body .timeline-row .timeline-track .break-bar:hover{opacity:.8}.calendar-view-container .calendar-header{margin-bottom:2rem}.calendar-view-container .calendar-header h5{color:#495057;font-weight:600}.calendar-view-container .calendar-header .calendar-nav button{border:1px solid #dee2e6;background:#fff;color:#495057;padding:.375rem .75rem;border-radius:.375rem;transition:all .2s ease}.calendar-view-container .calendar-header .calendar-nav button:hover{background-color:#f8f9fa;border-color:#adb5bd}.calendar-view-container .calendar-header .calendar-nav button:first-child{border-top-right-radius:0;border-bottom-right-radius:0;border-right:none}.calendar-view-container .calendar-header .calendar-nav button:last-child{border-top-left-radius:0;border-bottom-left-radius:0}.calendar-view-container .calendar-grid .calendar-week-header{display:flex;background-color:#f8f9fa;border:1px solid #dee2e6;border-bottom:none}.calendar-view-container .calendar-grid .calendar-week-header .calendar-day-header{flex:1;padding:.75rem;text-align:center;font-weight:600;color:#495057;border-right:1px solid #dee2e6}.calendar-view-container .calendar-grid .calendar-week-header .calendar-day-header:last-child{border-right:none}.calendar-view-container .calendar-grid .calendar-weeks{border:1px solid #dee2e6;border-top:none}.calendar-view-container .calendar-grid .calendar-weeks .calendar-week{display:flex;border-bottom:1px solid #dee2e6}.calendar-view-container .calendar-grid .calendar-weeks .calendar-week:last-child{border-bottom:none}.calendar-view-container .calendar-grid .calendar-weeks .calendar-week .calendar-day{flex:1;min-height:100px;padding:.5rem;border-right:1px solid #dee2e6;background:#fff}.calendar-view-container .calendar-grid .calendar-weeks .calendar-week .calendar-day:last-child{border-right:none}.calendar-view-container .calendar-grid .calendar-weeks .calendar-week .calendar-day.current-month{background:#fff}.calendar-view-container .calendar-grid .calendar-weeks .calendar-week .calendar-day.today{background-color:#fff3cd;border:2px solid #ffc107}.calendar-view-container .calendar-grid .calendar-weeks .calendar-week .calendar-day .day-number{font-weight:600;color:#495057;margin-bottom:.25rem}.calendar-view-container .calendar-grid .calendar-weeks .calendar-week .calendar-day .day-entries .entry-dot{width:8px;height:8px;border-radius:50%;display:inline-block;margin-right:2px;margin-bottom:2px}.heatmap-view-container .heatmap-header{margin-bottom:2rem}.heatmap-view-container .heatmap-header h5{color:#495057;font-weight:600}.heatmap-view-container .heatmap-header .heatmap-legend .legend-colors{display:flex;margin:0 1rem}.heatmap-view-container .heatmap-header .heatmap-legend .legend-colors .legend-color{width:12px;height:12px;margin-right:2px;border-radius:2px}.heatmap-view-container .heatmap-header .heatmap-legend span{font-size:.875rem;color:#6c757d}.heatmap-view-container .heatmap-grid .heatmap-months{display:flex;margin-bottom:.5rem}.heatmap-view-container .heatmap-grid .heatmap-months .month-label{flex:1;text-align:center;font-size:.8rem;font-weight:600;color:#495057}.heatmap-view-container .heatmap-grid .heatmap-weeks .heatmap-week{display:flex;margin-bottom:2px}.heatmap-view-container .heatmap-grid .heatmap-weeks .heatmap-week .heatmap-day{flex:1;aspect-ratio:1;border-radius:2px;margin-right:2px;transition:opacity .2s ease}.heatmap-view-container .heatmap-grid .heatmap-weeks .heatmap-week .heatmap-day:hover{opacity:.8}.heatmap-view-container .heatmap-grid .heatmap-weeks .heatmap-week .heatmap-day:last-child{margin-right:0}.card-view-container{padding:1rem;height:100%;overflow-y:auto;overflow-x:hidden}.card-view-container[data-theme=white]{background-color:#f6f8ff;color:#000}.card-view-container[data-theme=white] .attendance-card{background-color:#f6f8ff;border-color:#d9d9db;color:#000}.card-view-container[data-theme=white] .attendance-card:hover{background-color:#007bff1a}.card-view-container[data-theme=white] .attendance-card .card-header{background-color:#f8f9fa;color:#000;border-bottom-color:#d9d9db}.card-view-container[data-theme=white] .attendance-card .card-body{background-color:#f6f8ff;color:#000}.card-view-container[data-theme=white] .attendance-card .badge.bg-success{background-color:#84ca81;color:#f6f8ff}.card-view-container[data-theme=white] .attendance-card .badge.bg-danger{background-color:#ea5353;color:#f6f8ff}.card-view-container[data-theme=white] .attendance-card .badge.bg-warning{background-color:#fff3dc;color:#000}.card-view-container[data-theme=white] .attendance-card .badge.bg-info{background-color:#e8fbfd;color:#00bad1}.card-view-container[data-theme=blue]{background-color:#f0f8ff;color:#1e3a5f}.card-view-container[data-theme=blue] .attendance-card{background-color:#f6f8ff;border-color:#b3d9ff;color:#1e3a5f}.card-view-container[data-theme=blue] .attendance-card:hover{background-color:#1e3a5f1a}.card-view-container[data-theme=blue] .attendance-card .card-header{background-color:#e6f3ff;color:#1e3a5f;border-bottom-color:#b3d9ff}.card-view-container[data-theme=blue] .attendance-card .card-body{background-color:#f6f8ff;color:#1e3a5f}.card-view-container[data-theme=blue] .attendance-card .badge.bg-success{background-color:#69db7c;color:#f6f8ff}.card-view-container[data-theme=blue] .attendance-card .badge.bg-danger{background-color:#ff8787;color:#f6f8ff}.card-view-container[data-theme=blue] .attendance-card .badge.bg-warning{background-color:#ffd43b;color:#1e3a5f}.card-view-container[data-theme=blue] .attendance-card .badge.bg-info{background-color:#74c0fc;color:#f6f8ff}.card-view-container .row{margin:0}.card-view-container .row .col-xl-4,.card-view-container .row .col-lg-6,.card-view-container .row .col-md-6,.card-view-container .row .col-sm-12{padding:.5rem}.card-view-container .attendance-card{transition:background-color .2s ease;border:1px solid #d9d9db;border-radius:4px;overflow:hidden;height:100%;display:flex;flex-direction:column;font-family:sans-serif;font-size:16px}.card-view-container .attendance-card:hover{box-shadow:0 2px 4px #0000001a}.card-view-container .attendance-card.expanded .card-body{max-height:none}.card-view-container .attendance-card .card-header{padding:8px;border-bottom:1px solid #d9d9db;flex-shrink:0;font-weight:500}.card-view-container .attendance-card .card-header .employee-avatar{margin-right:.75rem;flex-shrink:0}.card-view-container .attendance-card .card-header .employee-avatar img,.card-view-container .attendance-card .card-header .employee-avatar .avatar-placeholder{border:1px solid #d9d9db;width:40px;height:40px;border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:16px;font-weight:400}.card-view-container .attendance-card .card-header .flex-grow-1{min-width:0}.card-view-container .attendance-card .card-header h6{margin:0;font-weight:500;font-size:16px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.card-view-container .attendance-card .card-header small{opacity:.9;font-weight:400;font-size:16px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.card-view-container .attendance-card .card-header .card-actions{flex-shrink:0}.card-view-container .attendance-card .card-header .card-actions .btn{background-color:transparent;border:1px solid #d9d9db;color:inherit;padding:.25rem .5rem}.card-view-container .attendance-card .card-header .card-actions .btn:hover{background-color:#007bff1a}.card-view-container .attendance-card .card-header .card-actions .btn i{font-size:.8rem}.card-view-container .attendance-card .card-body{padding:8px;flex:1;display:flex;flex-direction:column}.card-view-container .attendance-card .card-body .info-item{text-align:center;margin-bottom:.5rem}.card-view-container .attendance-card .card-body .info-item small{display:block;font-weight:400;color:#6c757d;text-transform:uppercase;font-size:12px;letter-spacing:.5px;margin-bottom:.25rem}.card-view-container .attendance-card .card-body .info-item span{font-size:16px;font-weight:400;color:inherit}.card-view-container .attendance-card .card-body .badge{font-size:12px;padding:.25rem .5rem;border-radius:4px;font-weight:400;text-transform:uppercase;letter-spacing:.5px;border:none}.card-view-container .attendance-card .card-body .badge.bg-success,.card-view-container .attendance-card .card-body .badge.bg-danger{color:#f6f8ff}.card-view-container .attendance-card .card-body .badge.bg-warning{color:#000}.card-view-container .attendance-card .card-body .badge.bg-secondary{color:#f6f8ff}.card-view-container .attendance-card .card-body .card-details{margin-top:1rem}.card-view-container .attendance-card .card-body .card-details .section-title{font-size:14px;font-weight:500;color:inherit;margin-bottom:.75rem;display:flex;align-items:center}.card-view-container .attendance-card .card-body .card-details .section-title i{margin-right:.5rem;opacity:.8}.card-view-container .attendance-card .card-body .card-details .breaks-list .break-item,.card-view-container .attendance-card .card-body .card-details .breaks-list .leave-item,.card-view-container .attendance-card .card-body .card-details .short-leave-list .break-item,.card-view-container .attendance-card .card-body .card-details .short-leave-list .leave-item{background-color:inherit;border:1px solid #d9d9db;border-radius:4px;padding:8px;margin-bottom:.5rem;cursor:pointer;transition:all .25s cubic-bezier(.4,0,.2,1);transform:translateZ(0)}.card-view-container .attendance-card .card-body .card-details .breaks-list .break-item .d-flex,.card-view-container .attendance-card .card-body .card-details .breaks-list .leave-item .d-flex,.card-view-container .attendance-card .card-body .card-details .short-leave-list .break-item .d-flex,.card-view-container .attendance-card .card-body .card-details .short-leave-list .leave-item .d-flex{gap:.75rem;align-items:center}.card-view-container .attendance-card .card-body .card-details .breaks-list .break-item .d-flex small,.card-view-container .attendance-card .card-body .card-details .breaks-list .leave-item .d-flex small,.card-view-container .attendance-card .card-body .card-details .short-leave-list .break-item .d-flex small,.card-view-container .attendance-card .card-body .card-details .short-leave-list .leave-item .d-flex small{font-weight:500;color:inherit;margin-bottom:.25rem}.card-view-container .attendance-card .card-body .card-details .breaks-list .break-item .d-flex .text-muted,.card-view-container .attendance-card .card-body .card-details .breaks-list .leave-item .d-flex .text-muted,.card-view-container .attendance-card .card-body .card-details .short-leave-list .break-item .d-flex .text-muted,.card-view-container .attendance-card .card-body .card-details .short-leave-list .leave-item .d-flex .text-muted{font-size:12px;color:#6c757d}.card-view-container .attendance-card .card-body .card-details .breaks-list .break-item .d-flex .badge,.card-view-container .attendance-card .card-body .card-details .breaks-list .leave-item .d-flex .badge,.card-view-container .attendance-card .card-body .card-details .short-leave-list .break-item .d-flex .badge,.card-view-container .attendance-card .card-body .card-details .short-leave-list .leave-item .d-flex .badge{font-size:10px;padding:.2rem .4rem}.card-view-container .attendance-card .card-body .card-details .additional-details .row .col-6{margin-bottom:.5rem}.card-view-container .attendance-card .card-body .card-details .additional-details .row .col-6 small{font-weight:400;color:#6c757d;text-transform:uppercase;font-size:12px;letter-spacing:.5px;margin-bottom:.25rem}.card-view-container .attendance-card .card-body .card-details .additional-details .row .col-6 span{font-weight:400;color:inherit;font-size:14px}@media (max-width: 1200px){.card-view-container .row .col-xl-4{flex:0 0 50%;max-width:50%}}@media (max-width: 768px){.card-view-container .row .col-xl-4,.card-view-container .col-lg-6,.card-view-container .col-md-6{flex:0 0 100%;max-width:100%}.card-view-container .attendance-card .card-body{padding:8px}.card-view-container .attendance-card .card-body .info-item small{font-size:10px}.card-view-container .attendance-card .card-body .info-item span{font-size:14px}}@media (max-width: 576px){.card-view-container{padding:.5rem}.card-view-container .row .col-sm-12{padding:.25rem}.card-view-container .attendance-card .card-header{padding:8px}.card-view-container .attendance-card .card-header h6,.card-view-container .attendance-card .card-header small{font-size:14px}.card-view-container .attendance-card .card-body{padding:8px}}.btn-xs{padding:.125rem .3rem!important;font-size:.9rem!important;border-radius:.2rem!important;line-height:1.5!important}.form-select.form-select-sm:invalid{border-color:#d9d9db!important}.form-select.form-select-sm:valid{border-color:#d9d9db!important}.date-range-container{gap:8px;flex-wrap:nowrap;align-items:center}.date-range-btn{padding:6px 12px;font-size:14px;font-weight:500;border-radius:6px;transition:all .25s cubic-bezier(.4,0,.2,1);white-space:nowrap;display:inline-flex;align-items:center;justify-content:center;min-height:36px;transform:translateZ(0);position:relative;overflow:hidden}.date-range-btn:before{content:\"\";position:absolute;top:50%;left:50%;width:0;height:0;background:#fff3;border-radius:50%;transform:translate(-50%,-50%);transition:width .25s,height .25s}.date-range-btn:active:before{width:300px;height:300px}.calendar-btn{border-color:#0d6efd;color:#0d6efd;background-color:transparent}.calendar-btn:hover{background-color:#0d6efd;color:#fff;transform:translateY(-1px);box-shadow:0 4px 12px #0d6efd4d}.clear-btn{border-color:#dc3545;color:#dc3545;background-color:transparent}.clear-btn:hover{background-color:#dc3545;color:#fff;transform:translateY(-1px);box-shadow:0 4px 12px #dc35454d}.date-range-label{font-size:14px;font-weight:500;padding:4px 8px;min-width:180px;text-align:center;white-space:nowrap;cursor:pointer}.date-range-btn .bi{font-size:14px;transition:transform .2s ease}.date-range-btn:hover .bi{transform:scale(1.1)}@media (max-width: 768px){.date-range-container{flex-wrap:wrap;justify-content:flex-start}.date-range-label{min-width:100%;margin-top:8px;order:3}}.date-range-btn:focus{outline:none;box-shadow:0 0 0 3px #0d6efd40}.clear-btn:focus{box-shadow:0 0 0 3px #dc354540}.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}.action-buttons-row ::ng-deep .button:active .svg-icon svg path{stroke:#6f61cf!important}.action-buttons-row ::ng-deep .button:focus .svg-icon svg path{stroke:#6f61cf!important}.badge-overflow-wrapper{width:100%;min-width:0;display:flex;align-items:center}.custom-overlay-wrapper{position:fixed;top:0;left:0;width:100%;height:100%;background-color:#00000080;display:flex;justify-content:center;align-items:center;z-index:9999}.custom-overlay{background:#fff;border-radius:8px;box-shadow:0 4px 12px #00000026;min-width:300px;max-width:400px}.custom-modal-body{padding:20px;text-align:center}.custom-modal-body .modal-message{font-size:16px;margin-bottom:20px;color:#333}.custom-modal-body .modal-actions{display:flex;gap:10px;justify-content:center}.custom-modal-body .modal-actions button{padding:8px 16px;border:none;border-radius:4px;cursor:pointer;font-size:14px;transition:background-color .2s ease}.custom-modal-body .modal-actions button.btn-confirm{background-color:#007bff;color:#fff}.custom-modal-body .modal-actions button.btn-confirm:hover{background-color:#0056b3}.custom-modal-body .modal-actions button.btn-cancel{background-color:#6c757d;color:#fff}.custom-modal-body .modal-actions button.btn-cancel:hover{background-color:#545b62}\n"] }]
9229
+ }], ctorParameters: () => [{ type: i0.Injector }, { type: i0.ViewContainerRef }, { type: CommonService }], propDecorators: { rowAnimation: [{
9230
+ type: Input
9231
+ }], onShortBreakClick: [{
8846
9232
  type: Output
8847
9233
  }], searchEvent: [{
8848
9234
  type: Output
@@ -8922,6 +9308,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
8922
9308
  type: Input
8923
9309
  }], loading: [{
8924
9310
  type: Input
9311
+ }], dataSetLoading: [{
9312
+ type: Input
8925
9313
  }], verticalScrollbarWidth: [{
8926
9314
  type: Input
8927
9315
  }], horizintalScrollbarWidth: [{
@@ -9122,5 +9510,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
9122
9510
  * Generated bundle index. Do not edit.
9123
9511
  */
9124
9512
 
9125
- export { CommonService, MsTimeSheetService, TimeSheetComponent, TimezoneFormatPipe };
9513
+ export { CommonService, MsTimeSheetService, RowAnimationType, TimeSheetComponent, TimezoneFormatPipe, sortingAnimation };
9126
9514
  //# sourceMappingURL=ms-time-sheet.mjs.map