ms-time-sheet 0.0.9 → 0.0.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,17 +1,17 @@
1
1
  import * as i0 from '@angular/core';
2
- import { Injectable, Pipe, EventEmitter, Output, Input, Component, inject, ChangeDetectorRef, ElementRef, NgZone, ViewChild, HostListener, ChangeDetectionStrategy } from '@angular/core';
3
- import * as i5 from 'ngx-bootstrap/datepicker';
2
+ import { Injectable, EventEmitter, Pipe, Output, Input, Component, inject, ChangeDetectorRef, ElementRef, NgZone, ViewChild, HostListener, ChangeDetectionStrategy } from '@angular/core';
3
+ import * as i6 from 'ngx-bootstrap/datepicker';
4
4
  import { BsDatepickerModule } from 'ngx-bootstrap/datepicker';
5
- import * as i4 from '@angular/cdk/drag-drop';
5
+ import * as i5 from '@angular/cdk/drag-drop';
6
6
  import { moveItemInArray, DragDropModule } from '@angular/cdk/drag-drop';
7
7
  import { trigger, state, transition, style, animate } from '@angular/animations';
8
- import * as i2 from '@angular/forms';
8
+ import * as i3 from '@angular/forms';
9
9
  import { FormsModule } from '@angular/forms';
10
- import * as i3 from 'ng-inline-svg';
10
+ import * as i4 from 'ng-inline-svg';
11
11
  import { InlineSVGModule } from 'ng-inline-svg';
12
- import * as i1 from '@angular/common';
13
- import { CommonModule, formatDate } from '@angular/common';
14
- import * as i6 from '@angular/cdk/scrolling';
12
+ import * as i2 from '@angular/common';
13
+ import { CommonModule, DatePipe } from '@angular/common';
14
+ import * as i7 from '@angular/cdk/scrolling';
15
15
  import { ScrollingModule } from '@angular/cdk/scrolling';
16
16
  import { Subject, BehaviorSubject, throttleTime, distinctUntilChanged, debounceTime } from 'rxjs';
17
17
 
@@ -170,6 +170,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
170
170
 
171
171
  class CommonService {
172
172
  constructor() {
173
+ this.globalSearch = new EventEmitter();
174
+ this.userData = null;
173
175
  this.activeFilteredColumns = [];
174
176
  }
175
177
  gethasVisibleColumns(columns) {
@@ -283,7 +285,6 @@ class CommonService {
283
285
  return result;
284
286
  }
285
287
  async applyFiltersToColumns(columns, filters) {
286
- debugger;
287
288
  for (const col of columns) {
288
289
  if (!col.query) {
289
290
  col.query = {
@@ -318,6 +319,35 @@ class CommonService {
318
319
  }
319
320
  return columns;
320
321
  }
322
+ setUserData(user) {
323
+ this.userData = user;
324
+ }
325
+ formatDateTimeWithPrefs() {
326
+ let lsUser = this.userData;
327
+ let timeZone = lsUser?.business_id?.time_zone ? lsUser?.business_id?.time_zone : 'UTC';
328
+ let dateFormat = lsUser?.date_format ? this.convertMomentToAngularDateFormat(lsUser.date_format) : 'MM/dd/yyyy';
329
+ let timeFormat = !lsUser?.business_id?.is_24_hour_format ? 'h:mm a' : 'H:mm';
330
+ return { timeZone, dateFormat, timeFormat };
331
+ }
332
+ convertMomentToAngularDateFormat(momentFormat) {
333
+ // Convert moment.js date format to Angular DatePipe format
334
+ return momentFormat
335
+ .replace(/DD/g, 'dd') // Day of month: DD -> dd
336
+ .replace(/YYYY/g, 'yyyy') // Year: YYYY -> yyyy
337
+ .replace(/YY/g, 'yy') // Year: YY -> yy
338
+ .replace(/MM/g, 'MM') // Month: MM -> MM (same)
339
+ .replace(/M/g, 'M') // Month: M -> M (same)
340
+ .replace(/HH/g, 'HH') // Hour 24: HH -> HH (same)
341
+ .replace(/H/g, 'H') // Hour 24: H -> H (same)
342
+ .replace(/hh/g, 'h') // Hour 12: hh -> h
343
+ .replace(/h/g, 'h') // Hour 12: h -> h (same)
344
+ .replace(/mm/g, 'mm') // Minute: mm -> mm (same)
345
+ .replace(/m/g, 'm') // Minute: m -> m (same)
346
+ .replace(/ss/g, 'ss') // Second: ss -> ss (same)
347
+ .replace(/s/g, 's') // Second: s -> s (same)
348
+ .replace(/A/g, 'a') // AM/PM: A -> a
349
+ .replace(/a/g, 'a'); // AM/PM: a -> a (same)
350
+ }
321
351
  updateActiveFilteredColumns(columns) {
322
352
  const collectFiltered = (cols) => {
323
353
  let result = [];
@@ -788,7 +818,7 @@ class BadgeOverflowComponent {
788
818
  this.updateBadgeVisibility();
789
819
  }
790
820
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: BadgeOverflowComponent, deps: [{ token: i0.ElementRef }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
791
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: BadgeOverflowComponent, isStandalone: true, selector: "app-badge-overflow", inputs: { badges: "badges", maxWidth: "maxWidth" }, outputs: { badgeMouseEnter: "badgeMouseEnter", badgeMouseLeave: "badgeMouseLeave", overflowCountClick: "overflowCountClick" }, ngImport: i0, template: "<div class=\"badge-overflow-container\" #container>\r\n <span\r\n *ngFor=\"let badge of visibleBadges; let i = index\"\r\n class=\"badge\"\r\n [class]=\"badge.class || 'badge-secondary'\"\r\n \r\n (mouseenter)=\"onBadgeMouseEnter($event, badge)\"\r\n (mouseleave)=\"onBadgeMouseLeave($event, badge)\"\r\n >\r\n {{ badge.text }}\r\n </span>\r\n <span\r\n *ngIf=\"overflowCount > 0\"\r\n class=\"badge badge-overflow-count\"\r\n [title]=\"getOverflowTooltip()\"\r\n (click)=\"onOverflowCountClick($event)\"\r\n >\r\n +{{ overflowCount }}\r\n </span>\r\n</div>", styles: [".badge-overflow-container{display:flex;flex-wrap:nowrap;gap:4px;align-items:center;min-width:0;overflow:hidden;width:100%}.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;color:#fff!important;&:hover{transform:scale(1.15) translateY(-2px);box-shadow:0 6px 16px #007bff40}&:active{transform:scale(1.08) translateY(-1px);transition-duration:.15s}}.break-color-paid{background-color:#4caf50!important;border-color:#4caf50!important}.break-color-unpaid{background-color:#f44336!important;border-color:#f44336!important}.break-color-lunch{background-color:#2196f3!important;border-color:#2196f3!important}.break-color-default{background-color:#f44336!important;border-color:#f44336!important}.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;font-size:12px;line-height:1;text-transform:uppercase;letter-spacing:.5px;&:hover{background-color:#5a6268!important;border-color:#5a6268!important;transform:scale(1.15) translateY(-2px);box-shadow:0 6px 16px #007bff40}&:active{transform:scale(1.08) translateY(-1px);transition-duration:.15s}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] }); }
821
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: BadgeOverflowComponent, isStandalone: true, selector: "app-badge-overflow", inputs: { badges: "badges", maxWidth: "maxWidth" }, outputs: { badgeMouseEnter: "badgeMouseEnter", badgeMouseLeave: "badgeMouseLeave", overflowCountClick: "overflowCountClick" }, ngImport: i0, template: "<div class=\"badge-overflow-container\" #container>\r\n <span\r\n *ngFor=\"let badge of visibleBadges; let i = index\"\r\n class=\"badge\"\r\n [class]=\"badge.class || 'badge-secondary'\"\r\n \r\n (mouseenter)=\"onBadgeMouseEnter($event, badge)\"\r\n (mouseleave)=\"onBadgeMouseLeave($event, badge)\"\r\n >\r\n {{ badge.text }}\r\n </span>\r\n <span\r\n *ngIf=\"overflowCount > 0\"\r\n class=\"badge badge-overflow-count\"\r\n [title]=\"getOverflowTooltip()\"\r\n (click)=\"onOverflowCountClick($event)\"\r\n >\r\n +{{ overflowCount }}\r\n </span>\r\n</div>", styles: [".badge-overflow-container{display:flex;flex-wrap:nowrap;gap:4px;align-items:center;min-width:0;overflow:hidden;width:100%}.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;color:#fff!important;&:hover{transform:scale(1.15) translateY(-2px);box-shadow:0 6px 16px #007bff40}&:active{transform:scale(1.08) translateY(-1px);transition-duration:.15s}}.break-color-paid{background-color:#4caf50!important;border-color:#4caf50!important}.break-color-unpaid{background-color:#f44336!important;border-color:#f44336!important}.break-color-lunch{background-color:#2196f3!important;border-color:#2196f3!important}.break-color-default{background-color:#f44336!important;border-color:#f44336!important}.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;font-size:12px;line-height:1;text-transform:uppercase;letter-spacing:.5px;&:hover{background-color:#5a6268!important;border-color:#5a6268!important;transform:scale(1.15) translateY(-2px);box-shadow:0 6px 16px #007bff40}&:active{transform:scale(1.08) translateY(-1px);transition-duration:.15s}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] }); }
792
822
  }
793
823
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: BadgeOverflowComponent, decorators: [{
794
824
  type: Component,
@@ -991,13 +1021,17 @@ class TimeSheetComponent {
991
1021
  this.removeCharacters.forEach(item => {
992
1022
  result = result.replace(new RegExp(item.find, 'g'), item.replace);
993
1023
  });
994
- return result;
1024
+ // Insert spaces before capital letters (for camelCase)
1025
+ result = result.replace(/([a-z])([A-Z])/g, '$1 $2');
1026
+ // Capitalize first letter of each word
1027
+ return result.replace(/\b\w/g, l => l.toUpperCase());
995
1028
  }
996
- constructor(injector, vcr) {
1029
+ constructor(injector, vcr, commonService) {
997
1030
  // Constructor is now empty - dependencies injected above
998
1031
  // This enables better tree shaking as the injector can eliminate unused dependencies
999
1032
  this.injector = injector;
1000
1033
  this.vcr = vcr;
1034
+ this.commonService = commonService;
1001
1035
  // **************************************//
1002
1036
  // ********** Input Goes Here *********** //
1003
1037
  // **************************************//
@@ -1204,6 +1238,8 @@ class TimeSheetComponent {
1204
1238
  this.changeLayout = new EventEmitter();
1205
1239
  // Filter Apply event;
1206
1240
  this.filterOptions = new EventEmitter();
1241
+ // Filter cleared event with flag
1242
+ this.filterCleared = new EventEmitter();
1207
1243
  this.genericEvent = new EventEmitter();
1208
1244
  this.tablePresetConfig = new EventEmitter();
1209
1245
  this.sortingOrderOptions = new EventEmitter();
@@ -1344,6 +1380,8 @@ class TimeSheetComponent {
1344
1380
  replace: ' '
1345
1381
  }
1346
1382
  ];
1383
+ // Inject DatePipe for formatting
1384
+ this.datePipe = inject(DatePipe);
1347
1385
  this.lastScrollTime = 0;
1348
1386
  this.previousVelocity = 0;
1349
1387
  this.previousScrollDirection = 'none';
@@ -1611,6 +1649,7 @@ class TimeSheetComponent {
1611
1649
  this.searchTextForFilterDropDown = '';
1612
1650
  this.isFilterOpen = false;
1613
1651
  this.showFilters = this.showSideMenu ? false : false;
1652
+ this.columnFilter = 'none';
1614
1653
  this.firstValue = '';
1615
1654
  this.firstCondition = '';
1616
1655
  this.secondValue = '';
@@ -1729,7 +1768,8 @@ class TimeSheetComponent {
1729
1768
  ranges: this.getCustomRanges(), // Updated with new range
1730
1769
  showClearButton: true, // Attempts to show clear (using external button)
1731
1770
  returnFocusToInput: true,
1732
- displayMonths: 2 // Show two months
1771
+ displayMonths: 2, // Show two months
1772
+ maxDate: new Date() // Prevent selecting future dates
1733
1773
  };
1734
1774
  this.buttons = [];
1735
1775
  this.emailClicked = new EventEmitter();
@@ -1755,6 +1795,7 @@ class TimeSheetComponent {
1755
1795
  this.initializeLazyModules();
1756
1796
  }
1757
1797
  ngOnInit() {
1798
+ this.prefs = this.commonService.formatDateTimeWithPrefs();
1758
1799
  this.tableFilterViewId = this.selectedPresetId;
1759
1800
  // Initialize action buttons
1760
1801
  // this.initializeButtons();
@@ -3188,20 +3229,24 @@ class TimeSheetComponent {
3188
3229
  event.preventDefault();
3189
3230
  event.stopPropagation();
3190
3231
  this.isMenueHidden = true;
3191
- const containerWidth = this.dataGridContainer?.nativeElement?.offsetWidth;
3192
3232
  this.activeCol = child;
3193
3233
  this.activeFilterCell = null;
3194
- const x = event.clientX;
3195
- // Use requestAnimationFrame for better performance
3234
+ const clickX = event.clientX;
3235
+ const screenWidth = window.innerWidth;
3236
+ const menuWidth = 240; // your menu size
3196
3237
  requestAnimationFrame(() => {
3197
3238
  const element = this.getCachedElement('.column-menu');
3198
3239
  if (element) {
3199
- if (x > (containerWidth / 2)) {
3200
- element.style.left = `${x - 240}px`;
3240
+ let leftPos = clickX;
3241
+ // If menu overflows on right → open to the left
3242
+ if (clickX + menuWidth > screenWidth) {
3243
+ leftPos = clickX - menuWidth;
3201
3244
  }
3202
- else {
3203
- element.style.left = `${x}px`;
3245
+ // If menu overflows on left → push to 0
3246
+ if (leftPos < 0) {
3247
+ leftPos = 0;
3204
3248
  }
3249
+ element.style.left = `${leftPos}px`;
3205
3250
  }
3206
3251
  this.isMenueHidden = false;
3207
3252
  this.cdr.markForCheck();
@@ -4766,6 +4811,7 @@ class TimeSheetComponent {
4766
4811
  this.cdr.detectChanges();
4767
4812
  const filteredColumns = this.commonSevice.getFiltersFromColumns(this.columns, this.filtersConfig);
4768
4813
  this.filterOptions.emit(filteredColumns); // Emit updated filters to API
4814
+ this.filterCleared.emit(true); // Emit filter cleared event with true flag
4769
4815
  const event = { eventType: 'reset' };
4770
4816
  this.genericEvent.emit(event);
4771
4817
  }
@@ -4913,10 +4959,12 @@ class TimeSheetComponent {
4913
4959
  this.genericEvent.emit(event);
4914
4960
  }
4915
4961
  onPageSizeChange() {
4962
+ debugger;
4963
+ this.paginationConfig.selectedPageSize;
4916
4964
  this.paginationConfig.page = 1;
4917
4965
  const event = {
4918
4966
  obj: {
4919
- limit: this.paginationConfig.limit,
4967
+ limit: +this.paginationConfig.selectedPageSize, //this.paginationConfig.limit,
4920
4968
  page: this.paginationConfig.page,
4921
4969
  },
4922
4970
  eventType: 'pageChange',
@@ -4941,6 +4989,8 @@ class TimeSheetComponent {
4941
4989
  }));
4942
4990
  this.tableFilterViewId = data.id;
4943
4991
  this.presetName = data.name;
4992
+ // Emit filter cleared event when preset is applied (assuming filters are reset)
4993
+ this.filterCleared.emit(true);
4944
4994
  if (data?.is_deafult) {
4945
4995
  return this.actionPreset(data, 'setPreset');
4946
4996
  }
@@ -5027,6 +5077,35 @@ class TimeSheetComponent {
5027
5077
  trackByTable(index) {
5028
5078
  return index;
5029
5079
  }
5080
+ // Check if column is mandatory (last two columns)
5081
+ isMandatory(col) {
5082
+ const index = this.columns.indexOf(col);
5083
+ return index >= this.columns.length - 2;
5084
+ }
5085
+ // Check if all non-mandatory columns are visible
5086
+ areAllNonMandatoryVisible() {
5087
+ return this.columns.slice(0, -2).every(col => col.is_visible);
5088
+ }
5089
+ // Check if all non-mandatory columns are hidden
5090
+ areAllNonMandatoryHidden() {
5091
+ return this.columns.slice(0, -2).every(col => !col.is_visible);
5092
+ }
5093
+ // Toggle all non-mandatory visible columns
5094
+ toggleAllVisibleColumns() {
5095
+ const allVisible = this.areAllNonMandatoryVisible();
5096
+ this.columns.slice(0, -2).forEach(col => {
5097
+ col.is_visible = !allVisible;
5098
+ });
5099
+ this.onSideMenuColumnsVisibilityChange();
5100
+ }
5101
+ // Toggle all non-mandatory invisible columns
5102
+ toggleAllInvisibleColumns() {
5103
+ const allHidden = this.areAllNonMandatoryHidden();
5104
+ this.columns.slice(0, -2).forEach(col => {
5105
+ col.is_visible = allHidden;
5106
+ });
5107
+ this.onSideMenuColumnsVisibilityChange();
5108
+ }
5030
5109
  // Track expanded cells as a Set of unique row+col identifiers
5031
5110
  getCellKey(row, col) {
5032
5111
  return `${this.getRowId(row)}_${col?.field}`;
@@ -5815,7 +5894,7 @@ class TimeSheetComponent {
5815
5894
  if (!value)
5816
5895
  return '-';
5817
5896
  if (this.isDate(value)) {
5818
- return formatDate(new Date(value), 'shortTime', 'en-US');
5897
+ return this.formatTime(value);
5819
5898
  }
5820
5899
  return value.toString();
5821
5900
  }
@@ -6199,7 +6278,7 @@ class TimeSheetComponent {
6199
6278
  const value = this.getNestedValue(row, col.field);
6200
6279
  if (col.field === 'clock_in_time' || col.field === 'clock_out_time') {
6201
6280
  if (value) {
6202
- return new Date(value).toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' });
6281
+ return this.formatTime(value);
6203
6282
  }
6204
6283
  }
6205
6284
  return value;
@@ -6280,194 +6359,6 @@ class TimeSheetComponent {
6280
6359
  }
6281
6360
  return title;
6282
6361
  }
6283
- getTooltipContent(dataItem, field) {
6284
- if (!dataItem || !field) {
6285
- return '<div class="tooltip-content">No details available</div>';
6286
- }
6287
- let html = '';
6288
- // Handle manual logs tooltip
6289
- if (field === 'manual_logs') {
6290
- if (!dataItem?.manually_logs || dataItem.manually_logs.length === 0) {
6291
- return '<div class="tooltip-content">No manual logs available</div>';
6292
- }
6293
- html += '<div class="modal-area">';
6294
- html += '<div class="table-responsive iis-scrollbar">';
6295
- html += '<table class="table table-row-primary-100 gs-0 gy-3" style="font-size: xx-small;">';
6296
- html += '<thead>';
6297
- html += '<tr class="fw-bolder text-muted bg-light ">';
6298
- html += '<th class="center ps-2" style="width: 20%;">Name</th>';
6299
- html += '<th class="center">Date/Time</th>';
6300
- html += '<th class="center">Previous Time</th>';
6301
- html += '<th class="center">Updated Time</th>';
6302
- html += '<th class="center">Status</th>';
6303
- html += '<th class="center pe-2">Remarks</th>';
6304
- html += '</tr>';
6305
- html += '</thead>';
6306
- html += '<tbody>';
6307
- dataItem.manually_logs.forEach((item) => {
6308
- // Handle breaks
6309
- if (item.breaks && item.breaks.length > 0) {
6310
- item.breaks.forEach((breakItem) => {
6311
- // Break In
6312
- if (breakItem?.break_in?.status) {
6313
- html += '<tr>';
6314
- html += `<td class="center"><a class="text-primary" title="${item?.updated_by?.full_name}">${item?.updated_by?.full_name?.length > 25 ? item?.updated_by?.full_name.slice(0, 25) + '...' : item?.updated_by?.full_name}</a></td>`;
6315
- html += `<td class="center"><a class="text-primary">${item?.log_date ? new Date(item.log_date).toLocaleDateString() + ' ' + new Date(item.log_date).toLocaleTimeString() : '-'}</a></td>`;
6316
- html += `<td class="center"><a class="text-primary">${breakItem?.break_in?.previous_state != '-' ? (breakItem?.break_in?.previous_state ? new Date(breakItem.break_in.previous_state).toLocaleDateString() + ' ' + new Date(breakItem.break_in.previous_state).toLocaleTimeString() : '-') : '-'}</a></td>`;
6317
- html += `<td class="center"><a class="text-primary">${breakItem?.break_in?.time ? new Date(breakItem.break_in.time).toLocaleDateString() + ' ' + new Date(breakItem.break_in.time).toLocaleTimeString() : '-'}</a></td>`;
6318
- html += `<td class="center"><a class="text-primary capitalize">${breakItem?.break_name} (${breakItem?.break_in?.status ? this.transformStatus(breakItem.break_in.status) : '-'})</a></td>`;
6319
- html += `<td class="center pe-2"><a class="text-primary" title="${item?.remarks}">${item?.remarks?.length > 50 ? item.remarks.slice(0, 50) + '...' : item?.remarks}</a></td>`;
6320
- html += '</tr>';
6321
- }
6322
- // Break Out
6323
- if (breakItem?.break_out?.status) {
6324
- html += '<tr>';
6325
- html += `<td class="center"><a class="text-primary" title="${item?.updated_by?.full_name}">${item?.updated_by?.full_name?.length > 25 ? item?.updated_by?.full_name.slice(0, 25) + '...' : item?.updated_by?.full_name}</a></td>`;
6326
- html += `<td class="center"><a class="text-primary">${item?.log_date ? new Date(item.log_date).toLocaleDateString() + ' ' + new Date(item.log_date).toLocaleTimeString() : '-'}</a></td>`;
6327
- html += `<td class="center"><a class="text-primary">${breakItem?.break_out?.previous_state != '-' ? (breakItem?.break_out?.previous_state ? new Date(breakItem.break_out.previous_state).toLocaleDateString() + ' ' + new Date(breakItem.break_out.previous_state).toLocaleTimeString() : '-') : '-'}</a></td>`;
6328
- html += `<td class="center"><a class="text-primary">${breakItem?.break_out?.time ? new Date(breakItem.break_out.time).toLocaleDateString() + ' ' + new Date(breakItem.break_out.time).toLocaleTimeString() : '-'}</a></td>`;
6329
- html += `<td class="center"><a class="text-primary capitalize">${breakItem?.break_name} (${breakItem?.break_out?.status ? this.transformStatus(breakItem.break_out.status) : '-'})</a></td>`;
6330
- html += `<td class="center pe-2"><a class="text-primary" title="${item?.remarks}">${item?.remarks?.length > 50 ? item.remarks.slice(0, 50) + '...' : item?.remarks}</a></td>`;
6331
- html += '</tr>';
6332
- }
6333
- });
6334
- }
6335
- // Clock In
6336
- if (item.clock_in?.status) {
6337
- html += '<tr style="border-color: #f1f1f1;">';
6338
- html += `<td class="center ps-2"><a class="text-primary" title="${item?.updated_by?.full_name}">${item?.updated_by?.full_name?.length > 25 ? item?.updated_by?.full_name.slice(0, 25) + '...' : item?.updated_by?.full_name}</a></td>`;
6339
- html += `<td class="center"><a class="text-primary">${item?.log_date ? new Date(item.log_date).toLocaleDateString() + ' ' + new Date(item.log_date).toLocaleTimeString() : '-'}</a></td>`;
6340
- html += `<td class="center"><a class="text-primary">${item?.clock_in?.previous_state != '-' ? (item?.clock_in?.previous_state ? new Date(item.clock_in.previous_state).toLocaleDateString() + ' ' + new Date(item.clock_in.previous_state).toLocaleTimeString() : '-') : '-'}</a></td>`;
6341
- html += `<td class="center"><a class="text-primary">${item?.clock_in?.time ? new Date(item.clock_in.time).toLocaleDateString() + ' ' + new Date(item.clock_in.time).toLocaleTimeString() : '-'}</a></td>`;
6342
- html += `<td class="center"><a class="text-primary capitalize">${item?.clock_in?.status ? this.transformStatus(item.clock_in.status) : '-'}</a></td>`;
6343
- html += `<td class="center pe-2"><a class="text-primary" title="${item?.remarks}">${item?.remarks?.length > 50 ? item.remarks.slice(0, 50) + '...' : item?.remarks}</a></td>`;
6344
- html += '</tr>';
6345
- }
6346
- // Clock Out
6347
- if (item.clock_out?.status) {
6348
- html += '<tr>';
6349
- html += `<td class="center"><a class="text-primary" title="${item?.updated_by?.full_name}">${item?.updated_by?.full_name?.length > 25 ? item?.updated_by?.full_name.slice(0, 25) + '...' : item?.updated_by?.full_name}</a></td>`;
6350
- html += `<td class="center"><a class="text-primary">${item?.log_date ? new Date(item.log_date).toLocaleDateString() + ' ' + new Date(item.log_date).toLocaleTimeString() : '-'}</a></td>`;
6351
- html += `<td class="center"><a class="text-primary">${item?.clock_out?.previous_state != '-' && item?.clock_out?.previous_state != 'Absent' ? (item?.clock_out?.previous_state ? new Date(item.clock_out.previous_state).toLocaleDateString() + ' ' + new Date(item.clock_out.previous_state).toLocaleTimeString() : '-') : '-'}</a></td>`;
6352
- html += `<td class="center"><a class="text-primary">${item?.clock_out?.time ? new Date(item.clock_out.time).toLocaleDateString() + ' ' + new Date(item.clock_out.time).toLocaleTimeString() : '-'}</a></td>`;
6353
- html += `<td class="center"><a class="text-primary capitalize">${item?.clock_out?.status ? this.transformStatus(item.clock_out.status) : '-'}</a></td>`;
6354
- html += `<td class="center pe-2"><a class="text-primary" title="${item?.remarks}">${item?.remarks?.length > 50 ? item.remarks.slice(0, 50) + '...' : item?.remarks}</a></td>`;
6355
- html += '</tr>';
6356
- }
6357
- });
6358
- html += '</tbody>';
6359
- html += '</table>';
6360
- html += '</div>';
6361
- html += '</div>';
6362
- return html;
6363
- }
6364
- // Handle single break tooltip
6365
- if (field === 'single_break') {
6366
- html += '<div class="tooltip-content">';
6367
- html += '<h4 class="tooltip-title">Break Details</h4>';
6368
- html += '<ul class="tooltip-list">';
6369
- const name = dataItem.break_type?.data_value_name || 'Unnamed Break';
6370
- const duration = dataItem.break_duration || 0;
6371
- const startTime = dataItem.break_in_time ? new Date(dataItem.break_in_time).toLocaleTimeString() : 'N/A';
6372
- const endTime = dataItem.break_out_time ? new Date(dataItem.break_out_time).toLocaleTimeString() : 'N/A';
6373
- const status = dataItem.breakInstatus || 'Unknown';
6374
- const taken = (dataItem.break_in_time && dataItem.break_out_time) ? 'Taken' : 'Not Taken';
6375
- html += `<li><strong>${name}</strong></li>`;
6376
- html += `<li>Duration: ${duration} minutes</li>`;
6377
- html += `<li>Start: ${startTime} | End: ${endTime}</li>`;
6378
- html += `<li>Status: ${status} (${taken})</li>`;
6379
- html += '</ul>';
6380
- html += '</div>';
6381
- return html;
6382
- }
6383
- // Handle 'breaks' array with improved accordion-like design
6384
- if (field === 'breaks') {
6385
- const breaks = dataItem[field] || [];
6386
- if (!Array.isArray(breaks) || breaks.length === 0) {
6387
- html += '<div class="break-tooltip-container">';
6388
- html += '<div class="break-tooltip-header">';
6389
- html += '<i class="bi bi-clock-history"></i>';
6390
- html += '<span class="break-tooltip-title">Break Details</span>';
6391
- html += '</div>';
6392
- html += '<div class="break-tooltip-body">';
6393
- html += '<div class="no-breaks-message">';
6394
- html += '<i class="bi bi-info-circle"></i>';
6395
- html += '<span>No breaks recorded for this day</span>';
6396
- html += '</div>';
6397
- html += '</div>';
6398
- html += '</div>';
6399
- return html;
6400
- }
6401
- let totalMinutes = 0;
6402
- breaks.forEach((b) => {
6403
- if (b)
6404
- totalMinutes += b.break_duration || 0;
6405
- });
6406
- html += '<div class="break-tooltip-container">';
6407
- html += '<div class="break-tooltip-header">';
6408
- html += '<i class="bi bi-clock-history"></i>';
6409
- html += '<span class="break-tooltip-title">Break Details</span>';
6410
- html += '<span class="break-total-badge">Total: ' + totalMinutes + 'm</span>';
6411
- html += '</div>';
6412
- html += '<div class="break-tooltip-body">';
6413
- breaks.forEach((b, index) => {
6414
- if (!b)
6415
- return;
6416
- const duration = b.break_duration || 0;
6417
- const name = b.break_type?.data_value_name || `Break ${index + 1}`;
6418
- const startTime = b.break_in_time ? new Date(b.break_in_time).toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' }) : '--:--';
6419
- const endTime = b.break_out_time ? new Date(b.break_out_time).toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' }) : '--:--';
6420
- const availableTime = b.minimum_break_percentage ? `${b.minimum_break_percentage}%` : 'N/A';
6421
- const status = b.breakInstatus || 'Unknown';
6422
- const taken = (b.break_in_time && b.break_out_time) ? 'Taken' : 'Not Taken';
6423
- const statusColor = taken === 'Taken' ? 'success' : 'warning';
6424
- html += '<div class="break-card">';
6425
- html += '<div class="break-card-header">';
6426
- html += `<div class="break-name">${name}</div>`;
6427
- html += `<div class="break-duration">${duration}m</div>`;
6428
- html += '</div>';
6429
- html += '<div class="break-card-body">';
6430
- html += '<div class="break-times">';
6431
- html += `<div class="time-slot"><i class="bi bi-play-circle"></i> ${startTime}</div>`;
6432
- html += `<div class="time-separator">→</div>`;
6433
- html += `<div class="time-slot"><i class="bi bi-stop-circle"></i> ${endTime}</div>`;
6434
- html += '</div>';
6435
- html += '<div class="break-details">';
6436
- html += `<div class="detail-item"><span class="label">Available:</span> <span class="value">${availableTime}</span></div>`;
6437
- html += `<div class="detail-item"><span class="label">Status:</span> <span class="status-${statusColor}">${status} (${taken})</span></div>`;
6438
- html += '</div>';
6439
- html += '</div>';
6440
- html += '</div>';
6441
- });
6442
- html += '</div>';
6443
- html += '</div>';
6444
- }
6445
- // Handle 'short_breaks' single object (existing logic)
6446
- else if (field === 'short_breaks') {
6447
- const shortBreak = dataItem[field];
6448
- if (!shortBreak || !shortBreak.short_break_duration) {
6449
- html += '<div class="tooltip-content">';
6450
- html += '<h4 class="tooltip-title">Short Break Details</h4>';
6451
- html += '<p style="color: #666; font-style: italic;">No short break recorded for this day</p>';
6452
- html += '</div>';
6453
- return html;
6454
- }
6455
- html += '<div class="tooltip-content">';
6456
- html += '<h4 class="tooltip-title">Short Break Details</h4>';
6457
- html += '<ul class="tooltip-list">';
6458
- const name = shortBreak.short_break_name || 'Quick Break';
6459
- const type = shortBreak.short_break_name ? ` (${shortBreak.short_break_name})` : '';
6460
- html += `<li>${name}${type}: ${shortBreak.short_break_duration} minutes</li>`;
6461
- html += '</ul>';
6462
- html += '</div>';
6463
- }
6464
- else {
6465
- html += '<div class="tooltip-content">';
6466
- html += '<p style="color: #666; font-style: italic;">No details available for this field</p>';
6467
- html += '</div>';
6468
- }
6469
- return html;
6470
- }
6471
6362
  enableTooltipEdit() {
6472
6363
  this.tooltipEditing = true;
6473
6364
  this.tooltipMinutes = this.currentTooltipData.duration || 0;
@@ -6953,6 +6844,8 @@ class TimeSheetComponent {
6953
6844
  // Clear all filters in filtersConfig
6954
6845
  this.filtersConfig = [];
6955
6846
  this.filterOptions.emit(this.filtersConfig);
6847
+ // Emit filter cleared event with true only if preset is selected
6848
+ this.filterCleared.emit(this.tableFilterViewId ? true : false);
6956
6849
  this.cdr.markForCheck();
6957
6850
  }
6958
6851
  onResizeDetailColumn(event, row, col) {
@@ -7429,6 +7322,14 @@ class TimeSheetComponent {
7429
7322
  // return words.slice(0, 2).join(' ').toUpperCase();
7430
7323
  // }
7431
7324
  selectRange(range, drp) {
7325
+ // Prevent future dates
7326
+ const today = new Date();
7327
+ today.setHours(23, 59, 59, 999); // End of today
7328
+ if (range[0] > today || range[1] > today) {
7329
+ // Reset to current date range
7330
+ this.bsRangeValue = [new Date(), new Date()];
7331
+ return;
7332
+ }
7432
7333
  this.bsRangeValue = range;
7433
7334
  this.isDefaultDateRange = false; // User has selected a range, no longer default
7434
7335
  // Auto-apply when selecting from predefined ranges
@@ -7459,6 +7360,14 @@ class TimeSheetComponent {
7459
7360
  drp.hide();
7460
7361
  }
7461
7362
  onApply(drp) {
7363
+ // Prevent future dates
7364
+ const today = new Date();
7365
+ today.setHours(23, 59, 59, 999); // End of today
7366
+ if (this.bsRangeValue[0] > today || this.bsRangeValue[1] > today) {
7367
+ // Reset to current date range
7368
+ this.bsRangeValue = [new Date(), new Date()];
7369
+ return;
7370
+ }
7462
7371
  this.isDefaultDateRange = false; // User has applied a range, no longer default
7463
7372
  // Determine if it's a single day selection
7464
7373
  const isSingleDaySelected = this.bsRangeValue.length === 2 &&
@@ -7478,6 +7387,8 @@ class TimeSheetComponent {
7478
7387
  }
7479
7388
  // Define custom ranges including new "Last 30 Days"
7480
7389
  getCustomRanges() {
7390
+ const startDate = new Date();
7391
+ const endDate = new Date();
7481
7392
  const today = new Date();
7482
7393
  const yesterday = new Date(today);
7483
7394
  yesterday.setDate(today.getDate() - 1);
@@ -7487,12 +7398,20 @@ class TimeSheetComponent {
7487
7398
  last30DaysStart.setDate(today.getDate() - 30);
7488
7399
  const thisMonthStart = new Date(today.getFullYear(), today.getMonth(), 1);
7489
7400
  const thisMonthEnd = new Date(today.getFullYear(), today.getMonth() + 1, 0);
7401
+ // Ensure this month doesn't include future dates
7402
+ if (thisMonthEnd > today) {
7403
+ thisMonthEnd.setTime(today.getTime());
7404
+ }
7490
7405
  const lastMonthEnd = new Date(today.getFullYear(), today.getMonth(), 0);
7491
7406
  const lastMonthStart = new Date(today.getFullYear(), today.getMonth() - 1, 1);
7492
7407
  const last3MonthsStart = new Date(today);
7493
7408
  last3MonthsStart.setMonth(today.getMonth() - 3);
7494
7409
  const thisYearStart = new Date(today.getFullYear(), 0, 1);
7495
7410
  const thisYearEnd = new Date(today.getFullYear(), 11, 31);
7411
+ // Ensure this year doesn't include future dates
7412
+ if (thisYearEnd > today) {
7413
+ thisYearEnd.setTime(today.getTime());
7414
+ }
7496
7415
  return [
7497
7416
  {
7498
7417
  value: [yesterday, yesterday],
@@ -7521,7 +7440,11 @@ class TimeSheetComponent {
7521
7440
  {
7522
7441
  value: [thisYearStart, thisYearEnd],
7523
7442
  label: 'This Year'
7524
- }
7443
+ },
7444
+ // {
7445
+ // value: [startDate, endDate],
7446
+ // label: 'Apply'
7447
+ // }
7525
7448
  ];
7526
7449
  }
7527
7450
  // Handle range change when Apply is clicked
@@ -7558,6 +7481,8 @@ class TimeSheetComponent {
7558
7481
  const start = new Date(this.bsRangeValue[0]);
7559
7482
  const end = new Date(this.bsRangeValue[1]);
7560
7483
  const oneDay = 24 * 60 * 60 * 1000; // 1 day in milliseconds
7484
+ const today = new Date();
7485
+ today.setHours(23, 59, 59, 999); // End of today
7561
7486
  let newStart;
7562
7487
  let newEnd;
7563
7488
  if (direction === 'left') {
@@ -7565,8 +7490,12 @@ class TimeSheetComponent {
7565
7490
  newEnd = new Date(end.getTime() - oneDay);
7566
7491
  }
7567
7492
  else {
7493
+ // Prevent navigating to future dates
7568
7494
  newStart = new Date(start.getTime() + oneDay);
7569
7495
  newEnd = new Date(end.getTime() + oneDay);
7496
+ if (newEnd > today) {
7497
+ return; // Don't navigate to future
7498
+ }
7570
7499
  }
7571
7500
  this.bsRangeValue = [newStart, newEnd];
7572
7501
  this.isDefaultDateRange = false;
@@ -7583,6 +7512,14 @@ class TimeSheetComponent {
7583
7512
  if (!range || range.length !== 2 || !range[0] || !range[1]) {
7584
7513
  return;
7585
7514
  }
7515
+ // Prevent future dates
7516
+ const today = new Date();
7517
+ today.setHours(23, 59, 59, 999); // End of today
7518
+ if (range[0] > today || range[1] > today) {
7519
+ // Reset to current date range
7520
+ this.bsRangeValue = [new Date(), new Date()];
7521
+ return;
7522
+ }
7586
7523
  this.isDefaultDateRange = false; // User has selected a range, no longer default
7587
7524
  const isSingleDay = range[0].getTime() === range[1].getTime();
7588
7525
  const eventData = {
@@ -7885,23 +7822,23 @@ class TimeSheetComponent {
7885
7822
  return 'badge-danger';
7886
7823
  case 'block':
7887
7824
  return 'badge-secondary';
7888
- case 'earlyin':
7825
+ case 'early in':
7889
7826
  return 'badge-warning';
7890
- case 'lateout':
7827
+ case 'late out':
7891
7828
  return 'badge-warning';
7892
- case 'earlyout':
7829
+ case 'early out':
7893
7830
  return 'badge-warning';
7894
7831
  case 'lateness':
7895
7832
  return 'badge-warning';
7896
7833
  case 'leave':
7897
7834
  return 'badge-secondary';
7898
- case 'onshortleave':
7835
+ case 'on short leave':
7899
7836
  return 'badge-info';
7900
- case 'misspunchout':
7837
+ case 'miss punch out':
7901
7838
  return 'badge-danger';
7902
- case 'ontimeout':
7839
+ case 'on time out':
7903
7840
  return 'badge-success';
7904
- case 'publicholiday':
7841
+ case 'public holiday':
7905
7842
  return 'badge-info';
7906
7843
  default:
7907
7844
  return 'badge-secondary';
@@ -7988,20 +7925,38 @@ class TimeSheetComponent {
7988
7925
  // event.stopPropagation();
7989
7926
  // }
7990
7927
  formatDate(date) {
7991
- if (!date) {
7928
+ if (!date)
7992
7929
  return '';
7930
+ return this.datePipe.transform(date, this.prefs.dateFormat, this.prefs.timeZone) || '';
7931
+ }
7932
+ getTimeValue(value) {
7933
+ if (!value || value === '-')
7934
+ return '';
7935
+ // If object from backend { value: '09:00' }
7936
+ if (value?.value)
7937
+ return value.value;
7938
+ // If object { name: '09:00' }
7939
+ if (value?.name)
7940
+ return value.name;
7941
+ // If datetime like "2025-11-20T09:00:00Z"
7942
+ if (typeof value === 'string' && value.includes('T')) {
7943
+ return value.split('T')[1].substring(0, 5); // => "09:00"
7944
+ }
7945
+ // If plain time "09:00"
7946
+ return value;
7947
+ }
7948
+ formatTime(value) {
7949
+ if (!value)
7950
+ return '-';
7951
+ value = this.getTimeValue(value); // normalize first
7952
+ // If getTimeValue returned empty, return dash
7953
+ if (!value)
7954
+ return '-';
7955
+ // When plain "09:00" → convert to valid date
7956
+ if (/^\d{2}:\d{2}$/.test(value)) {
7957
+ value = `1970-01-01T${value}:00Z`; // UTC safe
7993
7958
  }
7994
- const myDate = new Date(date);
7995
- if (isNaN(myDate.getTime())) {
7996
- return 'Invalid Date';
7997
- }
7998
- // Provide fallbacks for missing timezone preferences
7999
- const dateFormat = this.timezonePrefs?.dateFormat || 'dd/MM/yyyy';
8000
- const timeFormat = this.timezonePrefs?.timeFormat || 'HH:mm';
8001
- const timeZone = this.timezonePrefs?.timeZone || 'UTC';
8002
- const fullFormat = `${dateFormat} ${timeFormat}`;
8003
- return formatDate(myDate, fullFormat, 'en-US', // Locale, you can make this dynamic if needed
8004
- timeZone);
7959
+ return this.datePipe.transform(value, this.prefs.timeFormat, this.prefs.timeZone) || '-';
8005
7960
  }
8006
7961
  // Tooltip state for Short Leave
8007
7962
  // showShortLeaveTooltipModal: boolean = false;
@@ -8044,8 +7999,8 @@ class TimeSheetComponent {
8044
7999
  }, 50); // 50ms is enough for layout to settle
8045
8000
  }
8046
8001
  }
8047
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: TimeSheetComponent, deps: [{ token: i0.Injector }, { token: i0.ViewContainerRef }], target: i0.ɵɵFactoryTarget.Component }); }
8048
- 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", enableInfiniteScroll: "enableInfiniteScroll", hasMoreData: "hasMoreData", loadingMore: "loadingMore", detailsIconPosition: "detailsIconPosition", detailsPosition: "detailsPosition", buttons: "buttons", isStartDateNotEqualToEndDate: "isStartDateNotEqualToEndDate" }, outputs: { onShortBreakClick: "onShortBreakClick", searchEvent: "searchEvent", loadMoreData: "loadMoreData", changeLayout: "changeLayout", filterOptions: "filterOptions", 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] | date:'shortDate' }} - {{ bsRangeValue[1] | date:'shortDate' }}\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 ></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 *ngIf=\"loadingMore && enableInfiniteScroll\" class=\"text-center p-2\" [style.height.px]=\"rowHeight\">\r\n <div class=\"spinner-border text-primary\" role=\"status\"></div> Loading more...\r\n</div>\r\n <div *ngIf=\"!(loadingMore && enableInfiniteScroll)\" 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 <div\r\n *ngIf=\"false\"\r\n class=\"card-view-container p-3\"\r\n [style.height]=\"bodyWrapperHeight\"\r\n style=\"overflow-y: auto; overflow-x: hidden\"\r\n #mainScroll\r\n (scroll)=\"onMainScroll($event)\"\r\n >\r\n <div class=\"row g-3\">\r\n <div\r\n *ngFor=\"let row of dataSet; let i = index; trackBy: trackById\"\r\n class=\"col-xl-4 col-lg-6 col-md-6 col-sm-12\"\r\n >\r\n <div class=\"card h-100 shadow-sm attendance-card\" [class.expanded]=\"row.isCardExpanded\">\r\n <!-- Card Header -->\r\n <div class=\"card-header d-flex align-items-center p-3\">\r\n <div class=\"employee-avatar me-3\">\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 <img\r\n [width]=\"40\"\r\n [height]=\"40\"\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=\"avatar\"\r\n class=\"rounded-circle\"\r\n />\r\n </ng-container>\r\n <ng-template #placeholder>\r\n <div\r\n class=\"avatar-placeholder rounded-circle d-flex align-items-center justify-content-center text-white fw-bold\"\r\n [style.width.px]=\"40\"\r\n [style.height.px]=\"40\"\r\n [style.fontSize.px]=\"16\"\r\n [style.backgroundColor]=\"getAvatarColor(row?.User?.full_name || row?.full_name || row?.name)\"\r\n >\r\n {{ getInitialss(row?.User?.full_name || row?.full_name || row?.name) }}\r\n </div>\r\n </ng-template>\r\n </div>\r\n <div class=\"flex-grow-1\">\r\n <h6 class=\"mb-1 fw-bold\">{{ row?.User?.full_name || row?.full_name || row?.name || 'N/A' }}</h6>\r\n <small class=\"text-muted\">{{ row?.attendanceDate | date:'mediumDate' }}</small>\r\n </div>\r\n <div class=\"card-actions\">\r\n <button\r\n class=\"btn btn-sm btn-outline-primary\"\r\n (click)=\"row.isCardExpanded = !row.isCardExpanded\"\r\n [title]=\"row.isCardExpanded ? 'Collapse' : 'Expand'\"\r\n >\r\n <i class=\"bi\" [class]=\"row.isCardExpanded ? 'bi-chevron-up' : 'bi-chevron-down'\"></i>\r\n </button>\r\n </div>\r\n </div>\r\n\r\n <!-- Card Body -->\r\n <div class=\"card-body p-3\">\r\n <!-- Basic Attendance Info -->\r\n <div class=\"row g-2 mb-3\">\r\n <div class=\"col-6\">\r\n <div class=\"info-item\">\r\n <small class=\"text-muted d-block\">Clock In</small>\r\n <span class=\"fw-semibold\">{{ row?.clock_in_time ? (row.clock_in_time | date:'shortTime') : '--:--' }}</span>\r\n </div>\r\n </div>\r\n <div class=\"col-6\">\r\n <div class=\"info-item\">\r\n <small class=\"text-muted d-block\">Clock Out</small>\r\n <span class=\"fw-semibold\">{{ row?.clock_out_time ? (row.clock_out_time | date:'shortTime') : '--:--' }}</span>\r\n </div>\r\n </div>\r\n <div class=\"col-6\">\r\n <div class=\"info-item\">\r\n <small class=\"text-muted d-block\">Total Hours</small>\r\n <span class=\"fw-semibold\">{{ calculateTotalHours(row) }}</span>\r\n </div>\r\n </div>\r\n <div class=\"col-6\">\r\n <div class=\"info-item\">\r\n <small class=\"text-muted d-block\">Status</small>\r\n <span class=\"badge\" [class]=\"getStatusBadgeClass(row?.attendanceStatus)\">{{ row?.attendanceStatus || 'Unknown' }}</span>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Expandable Details -->\r\n <div class=\"card-details\" *ngIf=\"row.isCardExpanded\">\r\n <hr class=\"my-3\">\r\n\r\n <!-- All Column Data Section -->\r\n <div class=\"all-columns-section mb-3\">\r\n <h6 class=\"section-title mb-3\">\r\n <i class=\"bi bi-table me-2\"></i>All Details\r\n </h6>\r\n <div class=\"row g-2\">\r\n <ng-container *ngFor=\"let col of centerColumns; trackBy: trackByField\">\r\n <div class=\"col-md-6 col-lg-4\" *ngIf=\"col.is_visible !== false\">\r\n <div class=\"column-data-item p-2 border rounded\">\r\n <small class=\"text-muted d-block fw-semibold\">{{ col.header }}</small>\r\n <span class=\"fw-medium\">\r\n <ng-container *ngTemplateOutlet=\"cellContent; context: { row: row, col: col }\"></ng-container>\r\n </span>\r\n </div>\r\n </div>\r\n </ng-container>\r\n <ng-container *ngFor=\"let col of leftPinnedColumns; trackBy: trackByField\">\r\n <div class=\"col-md-6 col-lg-4\" *ngIf=\"col.is_visible !== false\">\r\n <div class=\"column-data-item p-2 border rounded\">\r\n <small class=\"text-muted d-block fw-semibold\">{{ col.header }}</small>\r\n <span class=\"fw-medium\">\r\n <ng-container *ngTemplateOutlet=\"cellContent; context: { row: row, col: col }\"></ng-container>\r\n </span>\r\n </div>\r\n </div>\r\n </ng-container>\r\n <ng-container *ngFor=\"let col of rightPinnedColumns; trackBy: trackByField\">\r\n <div class=\"col-md-6 col-lg-4\" *ngIf=\"col.is_visible !== false\">\r\n <div class=\"column-data-item p-2 border rounded\">\r\n <small class=\"text-muted d-block fw-semibold\">{{ col.header }}</small>\r\n <span class=\"fw-medium\">\r\n <ng-container *ngTemplateOutlet=\"cellContent; context: { row: row, col: col }\"></ng-container>\r\n </span>\r\n </div>\r\n </div>\r\n </ng-container>\r\n </div>\r\n </div>\r\n\r\n <!-- Breaks Section -->\r\n <div class=\"breaks-section mb-3\" *ngIf=\"row?.breaks?.length\">\r\n <h6 class=\"section-title mb-2\">\r\n <i class=\"bi bi-clock-history me-2\"></i>Breaks\r\n </h6>\r\n <div class=\"breaks-list\">\r\n <div\r\n *ngFor=\"let breakItem of row.breaks; let bIndex = index\"\r\n class=\"break-item p-2 border rounded mb-2\"\r\n \r\n (mouseenter)=\"showBreakTooltip($event, breakItem)\"\r\n (mouseleave)=\"hideBreakTooltip()\"\r\n >\r\n <div class=\"d-flex justify-content-between align-items-center\">\r\n <div>\r\n <small class=\"fw-semibold\">{{ breakItem?.break_type?.data_value_name || ('Break ' + (bIndex + 1)) }}</small>\r\n <div class=\"text-muted small\">\r\n {{ breakItem?.break_in_time ? (breakItem.break_in_time | date:'shortTime') : '--:--' }} -\r\n {{ breakItem?.break_out_time ? (breakItem.break_out_time | date:'shortTime') : '--:--' }}\r\n </div>\r\n </div>\r\n <div class=\"text-end\">\r\n <span class=\"badge badge-info\">{{ breakItem?.break_duration || 0 }}m</span>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Short Breaks Section -->\r\n <div class=\"short-breaks-section mb-3\" *ngIf=\"row?.short_breaks\">\r\n <h6 class=\"section-title mb-2\">\r\n <i class=\"bi bi-pause-circle me-2\"></i>Short Breaks\r\n </h6>\r\n <div class=\"short-break-item p-2 border rounded\">\r\n <div class=\"d-flex justify-content-between align-items-center\">\r\n <div>\r\n <small class=\"fw-semibold\">{{ row.short_breaks?.short_break_name || 'Quick Break' }}</small>\r\n </div>\r\n <div class=\"text-end\">\r\n <span class=\"badge badge-warning\">{{ row.short_breaks?.short_break_duration || 0 }}m</span>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Short Leave Section -->\r\n <div class=\"short-leave-section mb-3\" *ngIf=\"row?.short_leave?.length\">\r\n <h6 class=\"section-title mb-2\">\r\n <i class=\"bi bi-calendar-x me-2\"></i>Short Leave\r\n </h6>\r\n <div class=\"short-leave-list\">\r\n <div\r\n *ngFor=\"let leave of row.short_leave\"\r\n class=\"leave-item p-2 border rounded mb-2\"\r\n >\r\n <div class=\"d-flex justify-content-between align-items-center\">\r\n <div>\r\n <small class=\"fw-semibold\">{{ leave?.leave_type || 'Leave' }}</small>\r\n <div class=\"text-muted small\">{{ leave?.minutes || 0 }} minutes</div>\r\n </div>\r\n <div class=\"text-end\">\r\n <span class=\"badge badge-danger\">Leave</span>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Manual Logs Section -->\r\n <div class=\"manual-logs-section mb-3\" *ngIf=\"row?.manually_logs?.length\">\r\n <h6 class=\"section-title mb-2\">\r\n <i class=\"bi bi-pencil-square me-2\"></i>Manual Logs\r\n </h6>\r\n <button\r\n class=\"btn btn-sm btn-outline-info\"\r\n (click)=\"openManualLogsModal($event, row)\"\r\n \r\n >\r\n <i class=\"bi bi-eye me-1\"></i>View Details\r\n </button>\r\n </div>\r\n\r\n <!-- Additional Details -->\r\n <div class=\"additional-details\">\r\n <div class=\"row g-2\">\r\n <div class=\"col-6\" *ngIf=\"row?.overtime_hours\">\r\n <small class=\"text-muted d-block\">Overtime</small>\r\n <span class=\"fw-semibold\">{{ row.overtime_hours }}h</span>\r\n </div>\r\n <div class=\"col-6\" *ngIf=\"row?.late_minutes\">\r\n <small class=\"text-muted d-block\">Late Minutes</small>\r\n <span class=\"fw-semibold\">{{ row.late_minutes }}m</span>\r\n </div>\r\n <div class=\"col-6\" *ngIf=\"row?.early_departure_minutes\">\r\n <small class=\"text-muted d-block\">Early Departure</small>\r\n <span class=\"fw-semibold\">{{ row.early_departure_minutes }}m</span>\r\n </div>\r\n <div class=\"col-6\" *ngIf=\"row?.message\">\r\n <small class=\"text-muted d-block\">Remarks</small>\r\n <span class=\"fw-semibold text-truncate d-block\" [title]=\"row.message\">{{ row.message }}</span>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\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) + (hasMoreData ? 1000 : 0)\"></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\r\n <div\r\n class=\"pagination-container\"\r\n [style.height.px]=\"footerRowHeight\"\r\n [style.padding.px]=\"footerPadding\"\r\n >\r\n <div class=\"page-size\">\r\n <select\r\n [(ngModel)]=\"paginationConfig.limit\"\r\n (change)=\"onPageSizeChange()\"\r\n >\r\n <option *ngFor=\"let size of pageSizeOptions\" [value]=\"size\">\r\n {{ size }}\r\n </option>\r\n </select>\r\n <span class=\"\"> 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 *ngIf=\"row?.details?.data?.length\"\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 *ngIf=\"row?.details?.data?.length\"\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 border-right\"\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>\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 <div class=\"resize-handle\" (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 <!-- 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 {{ getNestedValue(d, col.field)?.value || getNestedValue(d, col.field)?.name || getNestedValue(d, col.field) || '-' }}\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 [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>\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-handle\" (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 <!-- Data Table Section with Virtual Scroll -->\r\n <cdk-virtual-scroll-viewport\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 <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 {{ getNestedValue(d, col.field)?.value || getNestedValue(d, col.field)?.name || getNestedValue(d, col.field) || '-' }}\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 [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>\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-handle\" (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]=\"rowHeight\" *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 <!-- 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 {{ getNestedValue(d, col.field)?.value || getNestedValue(d, col.field)?.name || getNestedValue(d, col.field) || '-' }}\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 <!-- 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) | date: dateFormat)\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)?.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 -->\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 <div class=\"break-tooltip-body\">\r\n <div><i class=\"bi bi-play-circle\"></i> In: {{ currentBreakTooltip.break_in_time | date:'shortTime' }}</div>\r\n <div><i class=\"bi bi-stop-circle\"></i> Out: {{ currentBreakTooltip.break_out_time | date:'shortTime' }}</div>\r\n <div><i class=\"bi bi-clock\"></i> Duration: {{ currentBreakTooltip.break_duration }} min</div>\r\n </div>\r\n</div>\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 <div class=\"break-tooltip-body\">\r\n <div><i class=\"bi bi-play-circle\"></i> Start: {{ currentShortBreakTooltip.start_time | date:'shortTime' }}</div>\r\n <div><i class=\"bi bi-stop-circle\"></i> End: {{ currentShortBreakTooltip.end_time | date:'shortTime' }}</div>\r\n <div><i class=\"bi bi-clock\"></i> Duration: {{ currentShortBreakTooltip.short_break_duration }} min</div>\r\n </div>\r\n</div>\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\"\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\"\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\" [class.visually-hidden]=\"isMenueHidden\">\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 || 'contain'\"\r\n (ngModelChange)=\"col.query.first_condition = $event\"\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 == '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 #filterMenueTextchInput\r\n />\r\n\r\n <ng-container *ngIf=\"col.query?.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=\"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 <ng-container *ngIf=\"col.query.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 || 'contain'\"\r\n (ngModelChange)=\"col.query.second_condition = $event\"\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 == '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 />\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\">\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 || 'contain'\"\r\n (ngModelChange)=\"col!.query!.first_condition = $event\"\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)]=\"col!.query!.first_value\"\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 || 'contain'\"\r\n (ngModelChange)=\"col!.query.second_condition = $event\"\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)]=\"col!.query.second_value\"\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\">\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 | date : \"MMM d, y\" }}</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\" *ngIf=\"hasAnyVisibleColumn\">\r\n Show in table\r\n </div>\r\n <!-- Item -->\r\n <ng-container\r\n *ngFor=\"\r\n let col of columns | filter : topShowHideColumns : 'header';\r\n trackBy: trackByField\r\n \"\r\n >\r\n <div\r\n *ngIf=\"col.is_visible\"\r\n class=\"list-group-item border-0 px-0 d-flex justify-content-between align-items-center\"\r\n >\r\n <div class=\"d-flex gap-1\">\r\n <div>\r\n <span\r\n *ngIf=\"!col?.pinned\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/grip-vertical.svg'\r\n \"\r\n class=\"cursor-grap data-grid-svg-icon\"\r\n (mousedown)=\"$event.preventDefault()\"\r\n ></span>\r\n <span\r\n *ngIf=\"col?.pinned\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/pin-blue.svg'\r\n \"\r\n class=\"cursor-grap data-grid-svg-icon\"\r\n (mousedown)=\"$event.preventDefault()\"\r\n ></span>\r\n </div>\r\n <div class=\"fw-semibold\">\r\n {{ col.header }}\r\n </div>\r\n </div>\r\n <div\r\n *ngIf=\"!col?.query?.first_value && !col?.query?._ids?.length\"\r\n class=\"d-flex align-items-center cursor-pointer\"\r\n (click)=\"toggleColumnVisibility(col, false)\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/eye.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n </div>\r\n <div\r\n *ngIf=\"col?.query?.first_value || col?.query?._ids?.length\"\r\n class=\"d-flex align-items-center\"\r\n style=\"opacity: 0.5\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/eye.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n </div>\r\n </div>\r\n </ng-container>\r\n\r\n <!-- Item End Here -->\r\n\r\n <div\r\n class=\"dropdown-divider\"\r\n *ngIf=\"hasAnyVisibleColumn && hasAnyInVisibleColumn\"\r\n ></div>\r\n\r\n <div\r\n class=\"muted-text show-hide-table-label\"\r\n *ngIf=\"hasAnyInVisibleColumn\"\r\n >\r\n Hide in table\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 />\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 <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 </select>\r\n </div>\r\n <div class=\"mb-2\">\r\n <input\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Enter first value\"\r\n type=\"search\"\r\n [type]=\"\r\n selectedColumnForFilter.type == 'string'\r\n ? 'text'\r\n : selectedColumnForFilter.type\r\n \"\r\n [(ngModel)]=\"firstValue\"\r\n />\r\n </div>\r\n <div *ngIf=\"firstValue\">\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 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 <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 </select>\r\n </div>\r\n\r\n <div class=\"mb-2\">\r\n <!-- Second value input -->\r\n <input\r\n [type]=\"\r\n selectedColumnForFilter.type == 'string'\r\n ? 'text'\r\n : selectedColumnForFilter.type\r\n \"\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Enter second value\"\r\n type=\"search\"\r\n [(ngModel)]=\"secondValue\"\r\n />\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<!-- 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) | date:'shortDate') : '-' }}\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 ? ((getNestedValue(row, col.field) || getNestedValue(parentRow, col.field)) | date:'shortTime') : '-' }}\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 <!-- 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 </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 | date:'short') : (selectedManualLogsRow?.attendanceDate && selectedManualLogsRow.attendanceDate !== '--' ? (selectedManualLogsRow.attendanceDate | date:'short') : '-') }}</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", 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}.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:-15px!important;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}.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{position:absolute;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}.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}.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;height: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: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: i1.NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { kind: "directive", type: i1.NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { kind: "directive", type: i1.NgSwitchDefault, selector: "[ngSwitchDefault]" }, { kind: "pipe", type: i1.TitleCasePipe, name: "titlecase" }, { kind: "pipe", type: i1.DatePipe, name: "date" }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i2.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i2.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: i2.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i2.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i2.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i2.RadioControlValueAccessor, selector: "input[type=radio][formControlName],input[type=radio][formControl],input[type=radio][ngModel]", inputs: ["name", "formControlName", "value"] }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i2.PatternValidator, selector: "[pattern][formControlName],[pattern][formControl],[pattern][ngModel]", inputs: ["pattern"] }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: InlineSVGModule }, { kind: "directive", type: i3.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: i4.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: i4.CdkDropListGroup, selector: "[cdkDropListGroup]", inputs: ["cdkDropListGroupDisabled"], exportAs: ["cdkDropListGroup"] }, { kind: "directive", type: i4.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: i4.CdkDragHandle, selector: "[cdkDragHandle]", inputs: ["cdkDragHandleDisabled"] }, { kind: "directive", type: i4.CdkDragPreview, selector: "ng-template[cdkDragPreview]", inputs: ["data", "matchSize"] }, { kind: "directive", type: i4.CdkDragPlaceholder, selector: "ng-template[cdkDragPlaceholder]", inputs: ["data"] }, { kind: "ngmodule", type: BsDatepickerModule }, { kind: "directive", type: i5.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: i5.BsDaterangepickerInputDirective, selector: "input[bsDaterangepicker]" }, { kind: "ngmodule", type: ScrollingModule }, { kind: "directive", type: i6.CdkFixedSizeVirtualScroll, selector: "cdk-virtual-scroll-viewport[itemSize]", inputs: ["itemSize", "minBufferPx", "maxBufferPx"] }, { kind: "directive", type: i6.CdkVirtualForOf, selector: "[cdkVirtualFor][cdkVirtualForOf]", inputs: ["cdkVirtualForOf", "cdkVirtualForTrackBy", "cdkVirtualForTemplate", "cdkVirtualForTemplateCacheSize"] }, { kind: "component", type: i6.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"] }], animations: [
8002
+ 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 }); }
8003
+ 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", enableInfiniteScroll: "enableInfiniteScroll", hasMoreData: "hasMoreData", loadingMore: "loadingMore", detailsIconPosition: "detailsIconPosition", detailsPosition: "detailsPosition", buttons: "buttons", isStartDateNotEqualToEndDate: "isStartDateNotEqualToEndDate" }, outputs: { onShortBreakClick: "onShortBreakClick", searchEvent: "searchEvent", loadMoreData: "loadMoreData", 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 {{ formatDate(bsRangeValue[0]) }} - {{ formatDate(bsRangeValue[1]) }}\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 ></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 *ngIf=\"loadingMore && enableInfiniteScroll\" class=\"text-center p-2\" [style.height.px]=\"rowHeight\">\r\n <div class=\"spinner-border text-primary\" role=\"status\"></div> Loading more...\r\n</div>\r\n <div *ngIf=\"!(loadingMore && enableInfiniteScroll)\" 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) + (hasMoreData ? 1000 : 0)\"></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 *ngIf=\"row?.details?.data?.length\"\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 *ngIf=\"row?.details?.data?.length\"\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 border-right\"\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>\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 <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 {{ getNestedValue(d, col.field)?.value || getNestedValue(d, col.field)?.name || getNestedValue(d, col.field) || '-' }}\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 [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>\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 <!-- Data Table Section with Virtual Scroll -->\r\n <cdk-virtual-scroll-viewport\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 <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) ? formatDate(getNestedValue(d, col.field)) : '-')\r\n : col.type === 'time'\r\n ? formatTime(getTimeValue(getNestedValue(d, col.field)))\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 [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>\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]=\"rowHeight\" *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 {{ getNestedValue(d, col.field)?.value || getNestedValue(d, col.field)?.name || getNestedValue(d, col.field) || '-' }}\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 ? formatDate(getNestedValue(row, col.field))\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 ? formatTime(getTimeValue(getNestedValue(row, col.field)))\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: {{ formatTime(getTimeValue(currentBreakTooltip.break_in_time)) }}\r\n </div>\r\n\r\n <div>\r\n <i class=\"bi bi-stop-circle\"></i>\r\n Out: {{ formatTime(getTimeValue(currentBreakTooltip.break_out_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: {{ formatTime(getTimeValue(currentShortBreakTooltip.start_time)) }}\r\n </div>\r\n\r\n <div>\r\n <i class=\"bi bi-stop-circle\"></i>\r\n End: {{ formatTime(getTimeValue(currentShortBreakTooltip.end_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\"\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\"\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\" [class.visually-hidden]=\"isMenueHidden\">\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 || 'contain'\"\r\n (ngModelChange)=\"col.query.first_condition = $event\"\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 == '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 || 'contain'\"\r\n (ngModelChange)=\"col.query.second_condition = $event\"\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 == '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\">\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 || 'contain'\"\r\n (ngModelChange)=\"col!.query!.first_condition = $event\"\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' : 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 || 'contain'\"\r\n (ngModelChange)=\"col!.query.second_condition = $event\"\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' : 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 {{ formatDate(table?.createdAt) }}</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 <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 </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 <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 </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<!-- 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) ? formatDate(getNestedValue(row, col.field) || getNestedValue(parentRow, col.field)) : '-' }}\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 ? formatTime(getTimeValue(getNestedValue(row, col.field) || getNestedValue(parentRow, col.field))) : '-' }}\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 </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 !== '--' ? formatDate(item.log_date) : (selectedManualLogsRow?.attendanceDate && selectedManualLogsRow.attendanceDate !== '--' ? formatDate(selectedManualLogsRow.attendanceDate) : '-') }}</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", 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}.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}.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)}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}.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"] }], animations: [
8049
8004
  trigger('accordionToggle', [
8050
8005
  state('collapsed', style({ height: '0px', overflow: 'hidden' })),
8051
8006
  state('expanded', style({ height: '*', overflow: 'visible' })),
@@ -8071,7 +8026,7 @@ class TimeSheetComponent {
8071
8026
  }
8072
8027
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: TimeSheetComponent, decorators: [{
8073
8028
  type: Component,
8074
- args: [{ selector: 'time-sheet', standalone: true, imports: [CommonModule, FormsModule, InlineSVGModule, FilterPipe, PinnedColumnsPipe, DragDropModule, BsDatepickerModule, ScrollingModule, BadgeOverflowComponent], changeDetection: ChangeDetectionStrategy.OnPush, animations: [
8029
+ args: [{ selector: 'time-sheet', standalone: true, imports: [CommonModule, FormsModule, InlineSVGModule, FilterPipe, PinnedColumnsPipe, DragDropModule, BsDatepickerModule, ScrollingModule, BadgeOverflowComponent, DatePipe,], changeDetection: ChangeDetectionStrategy.OnPush, animations: [
8075
8030
  trigger('accordionToggle', [
8076
8031
  state('collapsed', style({ height: '0px', overflow: 'hidden' })),
8077
8032
  state('expanded', style({ height: '*', overflow: 'visible' })),
@@ -8093,8 +8048,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
8093
8048
  transition('void => *', animate('300ms ease-out')),
8094
8049
  transition('* => void', animate('300ms ease-in')),
8095
8050
  ])
8096
- ], 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] | date:'shortDate' }} - {{ bsRangeValue[1] | date:'shortDate' }}\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 ></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 *ngIf=\"loadingMore && enableInfiniteScroll\" class=\"text-center p-2\" [style.height.px]=\"rowHeight\">\r\n <div class=\"spinner-border text-primary\" role=\"status\"></div> Loading more...\r\n</div>\r\n <div *ngIf=\"!(loadingMore && enableInfiniteScroll)\" 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 <div\r\n *ngIf=\"false\"\r\n class=\"card-view-container p-3\"\r\n [style.height]=\"bodyWrapperHeight\"\r\n style=\"overflow-y: auto; overflow-x: hidden\"\r\n #mainScroll\r\n (scroll)=\"onMainScroll($event)\"\r\n >\r\n <div class=\"row g-3\">\r\n <div\r\n *ngFor=\"let row of dataSet; let i = index; trackBy: trackById\"\r\n class=\"col-xl-4 col-lg-6 col-md-6 col-sm-12\"\r\n >\r\n <div class=\"card h-100 shadow-sm attendance-card\" [class.expanded]=\"row.isCardExpanded\">\r\n <!-- Card Header -->\r\n <div class=\"card-header d-flex align-items-center p-3\">\r\n <div class=\"employee-avatar me-3\">\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 <img\r\n [width]=\"40\"\r\n [height]=\"40\"\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=\"avatar\"\r\n class=\"rounded-circle\"\r\n />\r\n </ng-container>\r\n <ng-template #placeholder>\r\n <div\r\n class=\"avatar-placeholder rounded-circle d-flex align-items-center justify-content-center text-white fw-bold\"\r\n [style.width.px]=\"40\"\r\n [style.height.px]=\"40\"\r\n [style.fontSize.px]=\"16\"\r\n [style.backgroundColor]=\"getAvatarColor(row?.User?.full_name || row?.full_name || row?.name)\"\r\n >\r\n {{ getInitialss(row?.User?.full_name || row?.full_name || row?.name) }}\r\n </div>\r\n </ng-template>\r\n </div>\r\n <div class=\"flex-grow-1\">\r\n <h6 class=\"mb-1 fw-bold\">{{ row?.User?.full_name || row?.full_name || row?.name || 'N/A' }}</h6>\r\n <small class=\"text-muted\">{{ row?.attendanceDate | date:'mediumDate' }}</small>\r\n </div>\r\n <div class=\"card-actions\">\r\n <button\r\n class=\"btn btn-sm btn-outline-primary\"\r\n (click)=\"row.isCardExpanded = !row.isCardExpanded\"\r\n [title]=\"row.isCardExpanded ? 'Collapse' : 'Expand'\"\r\n >\r\n <i class=\"bi\" [class]=\"row.isCardExpanded ? 'bi-chevron-up' : 'bi-chevron-down'\"></i>\r\n </button>\r\n </div>\r\n </div>\r\n\r\n <!-- Card Body -->\r\n <div class=\"card-body p-3\">\r\n <!-- Basic Attendance Info -->\r\n <div class=\"row g-2 mb-3\">\r\n <div class=\"col-6\">\r\n <div class=\"info-item\">\r\n <small class=\"text-muted d-block\">Clock In</small>\r\n <span class=\"fw-semibold\">{{ row?.clock_in_time ? (row.clock_in_time | date:'shortTime') : '--:--' }}</span>\r\n </div>\r\n </div>\r\n <div class=\"col-6\">\r\n <div class=\"info-item\">\r\n <small class=\"text-muted d-block\">Clock Out</small>\r\n <span class=\"fw-semibold\">{{ row?.clock_out_time ? (row.clock_out_time | date:'shortTime') : '--:--' }}</span>\r\n </div>\r\n </div>\r\n <div class=\"col-6\">\r\n <div class=\"info-item\">\r\n <small class=\"text-muted d-block\">Total Hours</small>\r\n <span class=\"fw-semibold\">{{ calculateTotalHours(row) }}</span>\r\n </div>\r\n </div>\r\n <div class=\"col-6\">\r\n <div class=\"info-item\">\r\n <small class=\"text-muted d-block\">Status</small>\r\n <span class=\"badge\" [class]=\"getStatusBadgeClass(row?.attendanceStatus)\">{{ row?.attendanceStatus || 'Unknown' }}</span>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Expandable Details -->\r\n <div class=\"card-details\" *ngIf=\"row.isCardExpanded\">\r\n <hr class=\"my-3\">\r\n\r\n <!-- All Column Data Section -->\r\n <div class=\"all-columns-section mb-3\">\r\n <h6 class=\"section-title mb-3\">\r\n <i class=\"bi bi-table me-2\"></i>All Details\r\n </h6>\r\n <div class=\"row g-2\">\r\n <ng-container *ngFor=\"let col of centerColumns; trackBy: trackByField\">\r\n <div class=\"col-md-6 col-lg-4\" *ngIf=\"col.is_visible !== false\">\r\n <div class=\"column-data-item p-2 border rounded\">\r\n <small class=\"text-muted d-block fw-semibold\">{{ col.header }}</small>\r\n <span class=\"fw-medium\">\r\n <ng-container *ngTemplateOutlet=\"cellContent; context: { row: row, col: col }\"></ng-container>\r\n </span>\r\n </div>\r\n </div>\r\n </ng-container>\r\n <ng-container *ngFor=\"let col of leftPinnedColumns; trackBy: trackByField\">\r\n <div class=\"col-md-6 col-lg-4\" *ngIf=\"col.is_visible !== false\">\r\n <div class=\"column-data-item p-2 border rounded\">\r\n <small class=\"text-muted d-block fw-semibold\">{{ col.header }}</small>\r\n <span class=\"fw-medium\">\r\n <ng-container *ngTemplateOutlet=\"cellContent; context: { row: row, col: col }\"></ng-container>\r\n </span>\r\n </div>\r\n </div>\r\n </ng-container>\r\n <ng-container *ngFor=\"let col of rightPinnedColumns; trackBy: trackByField\">\r\n <div class=\"col-md-6 col-lg-4\" *ngIf=\"col.is_visible !== false\">\r\n <div class=\"column-data-item p-2 border rounded\">\r\n <small class=\"text-muted d-block fw-semibold\">{{ col.header }}</small>\r\n <span class=\"fw-medium\">\r\n <ng-container *ngTemplateOutlet=\"cellContent; context: { row: row, col: col }\"></ng-container>\r\n </span>\r\n </div>\r\n </div>\r\n </ng-container>\r\n </div>\r\n </div>\r\n\r\n <!-- Breaks Section -->\r\n <div class=\"breaks-section mb-3\" *ngIf=\"row?.breaks?.length\">\r\n <h6 class=\"section-title mb-2\">\r\n <i class=\"bi bi-clock-history me-2\"></i>Breaks\r\n </h6>\r\n <div class=\"breaks-list\">\r\n <div\r\n *ngFor=\"let breakItem of row.breaks; let bIndex = index\"\r\n class=\"break-item p-2 border rounded mb-2\"\r\n \r\n (mouseenter)=\"showBreakTooltip($event, breakItem)\"\r\n (mouseleave)=\"hideBreakTooltip()\"\r\n >\r\n <div class=\"d-flex justify-content-between align-items-center\">\r\n <div>\r\n <small class=\"fw-semibold\">{{ breakItem?.break_type?.data_value_name || ('Break ' + (bIndex + 1)) }}</small>\r\n <div class=\"text-muted small\">\r\n {{ breakItem?.break_in_time ? (breakItem.break_in_time | date:'shortTime') : '--:--' }} -\r\n {{ breakItem?.break_out_time ? (breakItem.break_out_time | date:'shortTime') : '--:--' }}\r\n </div>\r\n </div>\r\n <div class=\"text-end\">\r\n <span class=\"badge badge-info\">{{ breakItem?.break_duration || 0 }}m</span>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Short Breaks Section -->\r\n <div class=\"short-breaks-section mb-3\" *ngIf=\"row?.short_breaks\">\r\n <h6 class=\"section-title mb-2\">\r\n <i class=\"bi bi-pause-circle me-2\"></i>Short Breaks\r\n </h6>\r\n <div class=\"short-break-item p-2 border rounded\">\r\n <div class=\"d-flex justify-content-between align-items-center\">\r\n <div>\r\n <small class=\"fw-semibold\">{{ row.short_breaks?.short_break_name || 'Quick Break' }}</small>\r\n </div>\r\n <div class=\"text-end\">\r\n <span class=\"badge badge-warning\">{{ row.short_breaks?.short_break_duration || 0 }}m</span>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Short Leave Section -->\r\n <div class=\"short-leave-section mb-3\" *ngIf=\"row?.short_leave?.length\">\r\n <h6 class=\"section-title mb-2\">\r\n <i class=\"bi bi-calendar-x me-2\"></i>Short Leave\r\n </h6>\r\n <div class=\"short-leave-list\">\r\n <div\r\n *ngFor=\"let leave of row.short_leave\"\r\n class=\"leave-item p-2 border rounded mb-2\"\r\n >\r\n <div class=\"d-flex justify-content-between align-items-center\">\r\n <div>\r\n <small class=\"fw-semibold\">{{ leave?.leave_type || 'Leave' }}</small>\r\n <div class=\"text-muted small\">{{ leave?.minutes || 0 }} minutes</div>\r\n </div>\r\n <div class=\"text-end\">\r\n <span class=\"badge badge-danger\">Leave</span>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Manual Logs Section -->\r\n <div class=\"manual-logs-section mb-3\" *ngIf=\"row?.manually_logs?.length\">\r\n <h6 class=\"section-title mb-2\">\r\n <i class=\"bi bi-pencil-square me-2\"></i>Manual Logs\r\n </h6>\r\n <button\r\n class=\"btn btn-sm btn-outline-info\"\r\n (click)=\"openManualLogsModal($event, row)\"\r\n \r\n >\r\n <i class=\"bi bi-eye me-1\"></i>View Details\r\n </button>\r\n </div>\r\n\r\n <!-- Additional Details -->\r\n <div class=\"additional-details\">\r\n <div class=\"row g-2\">\r\n <div class=\"col-6\" *ngIf=\"row?.overtime_hours\">\r\n <small class=\"text-muted d-block\">Overtime</small>\r\n <span class=\"fw-semibold\">{{ row.overtime_hours }}h</span>\r\n </div>\r\n <div class=\"col-6\" *ngIf=\"row?.late_minutes\">\r\n <small class=\"text-muted d-block\">Late Minutes</small>\r\n <span class=\"fw-semibold\">{{ row.late_minutes }}m</span>\r\n </div>\r\n <div class=\"col-6\" *ngIf=\"row?.early_departure_minutes\">\r\n <small class=\"text-muted d-block\">Early Departure</small>\r\n <span class=\"fw-semibold\">{{ row.early_departure_minutes }}m</span>\r\n </div>\r\n <div class=\"col-6\" *ngIf=\"row?.message\">\r\n <small class=\"text-muted d-block\">Remarks</small>\r\n <span class=\"fw-semibold text-truncate d-block\" [title]=\"row.message\">{{ row.message }}</span>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\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) + (hasMoreData ? 1000 : 0)\"></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\r\n <div\r\n class=\"pagination-container\"\r\n [style.height.px]=\"footerRowHeight\"\r\n [style.padding.px]=\"footerPadding\"\r\n >\r\n <div class=\"page-size\">\r\n <select\r\n [(ngModel)]=\"paginationConfig.limit\"\r\n (change)=\"onPageSizeChange()\"\r\n >\r\n <option *ngFor=\"let size of pageSizeOptions\" [value]=\"size\">\r\n {{ size }}\r\n </option>\r\n </select>\r\n <span class=\"\"> 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 *ngIf=\"row?.details?.data?.length\"\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 *ngIf=\"row?.details?.data?.length\"\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 border-right\"\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>\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 <div class=\"resize-handle\" (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 <!-- 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 {{ getNestedValue(d, col.field)?.value || getNestedValue(d, col.field)?.name || getNestedValue(d, col.field) || '-' }}\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 [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>\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-handle\" (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 <!-- Data Table Section with Virtual Scroll -->\r\n <cdk-virtual-scroll-viewport\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 <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 {{ getNestedValue(d, col.field)?.value || getNestedValue(d, col.field)?.name || getNestedValue(d, col.field) || '-' }}\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 [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>\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-handle\" (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]=\"rowHeight\" *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 <!-- 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 {{ getNestedValue(d, col.field)?.value || getNestedValue(d, col.field)?.name || getNestedValue(d, col.field) || '-' }}\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 <!-- 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) | date: dateFormat)\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)?.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 -->\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 <div class=\"break-tooltip-body\">\r\n <div><i class=\"bi bi-play-circle\"></i> In: {{ currentBreakTooltip.break_in_time | date:'shortTime' }}</div>\r\n <div><i class=\"bi bi-stop-circle\"></i> Out: {{ currentBreakTooltip.break_out_time | date:'shortTime' }}</div>\r\n <div><i class=\"bi bi-clock\"></i> Duration: {{ currentBreakTooltip.break_duration }} min</div>\r\n </div>\r\n</div>\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 <div class=\"break-tooltip-body\">\r\n <div><i class=\"bi bi-play-circle\"></i> Start: {{ currentShortBreakTooltip.start_time | date:'shortTime' }}</div>\r\n <div><i class=\"bi bi-stop-circle\"></i> End: {{ currentShortBreakTooltip.end_time | date:'shortTime' }}</div>\r\n <div><i class=\"bi bi-clock\"></i> Duration: {{ currentShortBreakTooltip.short_break_duration }} min</div>\r\n </div>\r\n</div>\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\"\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\"\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\" [class.visually-hidden]=\"isMenueHidden\">\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 || 'contain'\"\r\n (ngModelChange)=\"col.query.first_condition = $event\"\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 == '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 #filterMenueTextchInput\r\n />\r\n\r\n <ng-container *ngIf=\"col.query?.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=\"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 <ng-container *ngIf=\"col.query.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 || 'contain'\"\r\n (ngModelChange)=\"col.query.second_condition = $event\"\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 == '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 />\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\">\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 || 'contain'\"\r\n (ngModelChange)=\"col!.query!.first_condition = $event\"\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)]=\"col!.query!.first_value\"\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 || 'contain'\"\r\n (ngModelChange)=\"col!.query.second_condition = $event\"\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)]=\"col!.query.second_value\"\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\">\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 | date : \"MMM d, y\" }}</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\" *ngIf=\"hasAnyVisibleColumn\">\r\n Show in table\r\n </div>\r\n <!-- Item -->\r\n <ng-container\r\n *ngFor=\"\r\n let col of columns | filter : topShowHideColumns : 'header';\r\n trackBy: trackByField\r\n \"\r\n >\r\n <div\r\n *ngIf=\"col.is_visible\"\r\n class=\"list-group-item border-0 px-0 d-flex justify-content-between align-items-center\"\r\n >\r\n <div class=\"d-flex gap-1\">\r\n <div>\r\n <span\r\n *ngIf=\"!col?.pinned\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/grip-vertical.svg'\r\n \"\r\n class=\"cursor-grap data-grid-svg-icon\"\r\n (mousedown)=\"$event.preventDefault()\"\r\n ></span>\r\n <span\r\n *ngIf=\"col?.pinned\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/pin-blue.svg'\r\n \"\r\n class=\"cursor-grap data-grid-svg-icon\"\r\n (mousedown)=\"$event.preventDefault()\"\r\n ></span>\r\n </div>\r\n <div class=\"fw-semibold\">\r\n {{ col.header }}\r\n </div>\r\n </div>\r\n <div\r\n *ngIf=\"!col?.query?.first_value && !col?.query?._ids?.length\"\r\n class=\"d-flex align-items-center cursor-pointer\"\r\n (click)=\"toggleColumnVisibility(col, false)\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/eye.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n </div>\r\n <div\r\n *ngIf=\"col?.query?.first_value || col?.query?._ids?.length\"\r\n class=\"d-flex align-items-center\"\r\n style=\"opacity: 0.5\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/eye.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n </div>\r\n </div>\r\n </ng-container>\r\n\r\n <!-- Item End Here -->\r\n\r\n <div\r\n class=\"dropdown-divider\"\r\n *ngIf=\"hasAnyVisibleColumn && hasAnyInVisibleColumn\"\r\n ></div>\r\n\r\n <div\r\n class=\"muted-text show-hide-table-label\"\r\n *ngIf=\"hasAnyInVisibleColumn\"\r\n >\r\n Hide in table\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 />\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 <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 </select>\r\n </div>\r\n <div class=\"mb-2\">\r\n <input\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Enter first value\"\r\n type=\"search\"\r\n [type]=\"\r\n selectedColumnForFilter.type == 'string'\r\n ? 'text'\r\n : selectedColumnForFilter.type\r\n \"\r\n [(ngModel)]=\"firstValue\"\r\n />\r\n </div>\r\n <div *ngIf=\"firstValue\">\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 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 <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 </select>\r\n </div>\r\n\r\n <div class=\"mb-2\">\r\n <!-- Second value input -->\r\n <input\r\n [type]=\"\r\n selectedColumnForFilter.type == 'string'\r\n ? 'text'\r\n : selectedColumnForFilter.type\r\n \"\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Enter second value\"\r\n type=\"search\"\r\n [(ngModel)]=\"secondValue\"\r\n />\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<!-- 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) | date:'shortDate') : '-' }}\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 ? ((getNestedValue(row, col.field) || getNestedValue(parentRow, col.field)) | date:'shortTime') : '-' }}\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 <!-- 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 </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 | date:'short') : (selectedManualLogsRow?.attendanceDate && selectedManualLogsRow.attendanceDate !== '--' ? (selectedManualLogsRow.attendanceDate | date:'short') : '-') }}</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", 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}.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:-15px!important;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}.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{position:absolute;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}.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}.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;height: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"] }]
8097
- }], ctorParameters: () => [{ type: i0.Injector }, { type: i0.ViewContainerRef }], propDecorators: { onShortBreakClick: [{
8051
+ ], 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 {{ formatDate(bsRangeValue[0]) }} - {{ formatDate(bsRangeValue[1]) }}\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 ></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 *ngIf=\"loadingMore && enableInfiniteScroll\" class=\"text-center p-2\" [style.height.px]=\"rowHeight\">\r\n <div class=\"spinner-border text-primary\" role=\"status\"></div> Loading more...\r\n</div>\r\n <div *ngIf=\"!(loadingMore && enableInfiniteScroll)\" 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) + (hasMoreData ? 1000 : 0)\"></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 *ngIf=\"row?.details?.data?.length\"\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 *ngIf=\"row?.details?.data?.length\"\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 border-right\"\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>\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 <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 {{ getNestedValue(d, col.field)?.value || getNestedValue(d, col.field)?.name || getNestedValue(d, col.field) || '-' }}\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 [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>\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 <!-- Data Table Section with Virtual Scroll -->\r\n <cdk-virtual-scroll-viewport\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 <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) ? formatDate(getNestedValue(d, col.field)) : '-')\r\n : col.type === 'time'\r\n ? formatTime(getTimeValue(getNestedValue(d, col.field)))\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 [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>\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]=\"rowHeight\" *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 {{ getNestedValue(d, col.field)?.value || getNestedValue(d, col.field)?.name || getNestedValue(d, col.field) || '-' }}\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 ? formatDate(getNestedValue(row, col.field))\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 ? formatTime(getTimeValue(getNestedValue(row, col.field)))\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: {{ formatTime(getTimeValue(currentBreakTooltip.break_in_time)) }}\r\n </div>\r\n\r\n <div>\r\n <i class=\"bi bi-stop-circle\"></i>\r\n Out: {{ formatTime(getTimeValue(currentBreakTooltip.break_out_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: {{ formatTime(getTimeValue(currentShortBreakTooltip.start_time)) }}\r\n </div>\r\n\r\n <div>\r\n <i class=\"bi bi-stop-circle\"></i>\r\n End: {{ formatTime(getTimeValue(currentShortBreakTooltip.end_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\"\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\"\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\" [class.visually-hidden]=\"isMenueHidden\">\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 || 'contain'\"\r\n (ngModelChange)=\"col.query.first_condition = $event\"\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 == '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 || 'contain'\"\r\n (ngModelChange)=\"col.query.second_condition = $event\"\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 == '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\">\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 || 'contain'\"\r\n (ngModelChange)=\"col!.query!.first_condition = $event\"\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' : 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 || 'contain'\"\r\n (ngModelChange)=\"col!.query.second_condition = $event\"\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' : 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 {{ formatDate(table?.createdAt) }}</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 <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 </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 <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 </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<!-- 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) ? formatDate(getNestedValue(row, col.field) || getNestedValue(parentRow, col.field)) : '-' }}\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 ? formatTime(getTimeValue(getNestedValue(row, col.field) || getNestedValue(parentRow, col.field))) : '-' }}\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 </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 !== '--' ? formatDate(item.log_date) : (selectedManualLogsRow?.attendanceDate && selectedManualLogsRow.attendanceDate !== '--' ? formatDate(selectedManualLogsRow.attendanceDate) : '-') }}</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", 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}.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}.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)}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}.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"] }]
8052
+ }], ctorParameters: () => [{ type: i0.Injector }, { type: i0.ViewContainerRef }, { type: CommonService }], propDecorators: { onShortBreakClick: [{
8098
8053
  type: Output
8099
8054
  }], searchEvent: [{
8100
8055
  type: Output
@@ -8258,6 +8213,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
8258
8213
  type: Output
8259
8214
  }], filterOptions: [{
8260
8215
  type: Output
8216
+ }], filterCleared: [{
8217
+ type: Output
8261
8218
  }], genericEvent: [{
8262
8219
  type: Output
8263
8220
  }], tablePresetConfig: [{
@@ -8380,5 +8337,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
8380
8337
  * Generated bundle index. Do not edit.
8381
8338
  */
8382
8339
 
8383
- export { MsTimeSheetService, TimeSheetComponent };
8340
+ export { CommonService, MsTimeSheetService, TimeSheetComponent };
8384
8341
  //# sourceMappingURL=ms-time-sheet.mjs.map