ms-time-sheet 0.0.19 → 0.0.21

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.
@@ -1360,7 +1360,19 @@ const sortingAnimation = trigger('listSort', [
1360
1360
  class TimeSheetComponent {
1361
1361
  // For Short Break Tooltip
1362
1362
  hideShortBreakTooltip() {
1363
- this.currentShortBreakTooltip = null;
1363
+ // Clear any pending show
1364
+ if (this.tooltipShowTimeout) {
1365
+ clearTimeout(this.tooltipShowTimeout);
1366
+ this.tooltipShowTimeout = null;
1367
+ }
1368
+ // Debounced hide
1369
+ if (this.tooltipHideTimeout) {
1370
+ clearTimeout(this.tooltipHideTimeout);
1371
+ }
1372
+ this.tooltipHideTimeout = setTimeout(() => {
1373
+ this.currentShortBreakTooltip = null; // 👈 main state reset
1374
+ this.tooltipHideTimeout = null;
1375
+ }, 150);
1364
1376
  }
1365
1377
  // Computed taskbar actions based on isSingleDay
1366
1378
  get computedTaskbarActions() {
@@ -1538,12 +1550,18 @@ class TimeSheetComponent {
1538
1550
  getBreakBadges(breaks) {
1539
1551
  if (!Array.isArray(breaks))
1540
1552
  return [];
1541
- return breaks.map(breakItem => ({
1542
- text: `${breakItem.break_duration}m`,
1543
- class: this.getBreakColorClass(breakItem.break_type?.data_value_name || breakItem.breakType),
1544
- tooltip: `Break: ${breakItem.break_duration || 0} minutes`,
1545
- data: breakItem // Include full break item data for tooltip
1546
- }));
1553
+ return breaks.map(breakItem => {
1554
+ // Prefer total_minutes_logged if available and truthy; otherwise use break_duration
1555
+ const displayMinutes = breakItem.total_minutes_logged
1556
+ ? breakItem.total_minutes_logged
1557
+ : breakItem.break_duration?.toString() || '0';
1558
+ return {
1559
+ text: `${displayMinutes}m`,
1560
+ class: this.getBreakColorClass(breakItem.break_type?.data_value_name || breakItem.breakType),
1561
+ tooltip: `Break: ${displayMinutes} minutes`,
1562
+ data: breakItem
1563
+ };
1564
+ });
1547
1565
  }
1548
1566
  getShortBreakBadges(shortBreak) {
1549
1567
  if (!shortBreak || !shortBreak.short_break_duration || shortBreak.short_break_duration <= 0)
@@ -3800,6 +3818,7 @@ class TimeSheetComponent {
3800
3818
  this.justFinishedSelecting = false;
3801
3819
  this.activePresetDropdownId = null;
3802
3820
  this.confirmDeletePresetId = null;
3821
+ this.hideShortBreakTooltip();
3803
3822
  }
3804
3823
  onMouseUpEndSelection() {
3805
3824
  this.justFinishedSelecting = true;
@@ -4305,6 +4324,12 @@ class TimeSheetComponent {
4305
4324
  getRowId(row) {
4306
4325
  return row.id ?? row._id;
4307
4326
  }
4327
+ isInInput(target) {
4328
+ if (!target)
4329
+ return false;
4330
+ const element = target;
4331
+ return ['INPUT', 'TEXTAREA', 'SELECT'].includes(element.tagName) || element.isContentEditable;
4332
+ }
4308
4333
  /**
4309
4334
  * Toggle a single row selection.
4310
4335
  */
@@ -6317,7 +6342,7 @@ class TimeSheetComponent {
6317
6342
  event.preventDefault();
6318
6343
  this.rowSelectedIndexes.clear();
6319
6344
  const safeSub = subColIndex ?? 0;
6320
- const key = `${rowIndex}-${colIndex}-${safeSub}-${field}`;
6345
+ const key = `${rowIndex}-${colIndex}-${safeSub}-${section}`;
6321
6346
  this.selectionStart = { rowIndex, colIndex, subColIndex: safeSub, field, key };
6322
6347
  this.isSelecting = true;
6323
6348
  this.selectedKeys.clear();
@@ -6670,6 +6695,49 @@ class TimeSheetComponent {
6670
6695
  this.handleDetailShortcuts(event, focus.row, focus.section);
6671
6696
  return;
6672
6697
  }
6698
+ // Check if we're in an input field
6699
+ const isInInput = this.isInInput(event.target);
6700
+ // Search shortcut: Ctrl+F to focus search input
6701
+ if ((event.ctrlKey || event.metaKey) && event.key.toLowerCase() === 'f') {
6702
+ event.preventDefault();
6703
+ if (this.searchInput) {
6704
+ this.searchInput.nativeElement.focus();
6705
+ this.searchInput.nativeElement.select();
6706
+ }
6707
+ return;
6708
+ }
6709
+ // Pagination shortcuts
6710
+ if (event.key === 'PageDown') {
6711
+ event.preventDefault();
6712
+ this.goToPage(this.paginationConfig.page + 1);
6713
+ return;
6714
+ }
6715
+ if (event.key === 'PageUp') {
6716
+ event.preventDefault();
6717
+ this.goToPage(this.paginationConfig.page - 1);
6718
+ return;
6719
+ }
6720
+ // Scroll shortcuts with arrow keys (when not in input fields)
6721
+ if (!isInInput && ['ArrowUp', 'ArrowDown', 'ArrowLeft', 'ArrowRight'].includes(event.key)) {
6722
+ event.preventDefault();
6723
+ const scrollAmount = 50;
6724
+ if (this.mainScroll?.nativeElement) {
6725
+ if (event.key === 'ArrowUp') {
6726
+ this.mainScroll.nativeElement.scrollTop -= scrollAmount;
6727
+ }
6728
+ else if (event.key === 'ArrowDown') {
6729
+ this.mainScroll.nativeElement.scrollTop += scrollAmount;
6730
+ }
6731
+ else if (event.key === 'ArrowLeft') {
6732
+ this.mainScroll.nativeElement.scrollLeft -= scrollAmount;
6733
+ }
6734
+ else if (event.key === 'ArrowRight') {
6735
+ this.mainScroll.nativeElement.scrollLeft += scrollAmount;
6736
+ }
6737
+ }
6738
+ return;
6739
+ }
6740
+ // Existing shortcuts
6673
6741
  if ((event.ctrlKey || event.metaKey) && event.key.toLowerCase() === 'c') {
6674
6742
  const selectedData = this.getSelectedDataForCopy();
6675
6743
  event.preventDefault();
@@ -6688,6 +6756,10 @@ class TimeSheetComponent {
6688
6756
  event.preventDefault();
6689
6757
  this.redo();
6690
6758
  }
6759
+ else if ((event.ctrlKey || event.metaKey) && event.key.toLowerCase() === 'a') {
6760
+ event.preventDefault();
6761
+ this.selectAllCells();
6762
+ }
6691
6763
  }
6692
6764
  undo() {
6693
6765
  if (this.undoStack.length > 0) {
@@ -6703,6 +6775,54 @@ class TimeSheetComponent {
6703
6775
  this.visibleRows = this.cloneData(nextState);
6704
6776
  }
6705
6777
  }
6778
+ selectAllCells() {
6779
+ // Clear any prior selection
6780
+ this.selectedKeys.clear();
6781
+ this.selectedCells = [];
6782
+ // Iterate over all visible (flattened) rows
6783
+ for (let rowIndex = 0; rowIndex <= this.flattenedData.length; rowIndex++) {
6784
+ const row = this.flattenedData[rowIndex];
6785
+ // Only select data rows (skip group headers)
6786
+ if (row?.isGroup)
6787
+ continue;
6788
+ // Iterate over center columns with their indices
6789
+ for (let colIndex = 0; colIndex < this.centerColumns.length; colIndex++) {
6790
+ const col = this.centerColumns[colIndex];
6791
+ if (col.children) {
6792
+ for (let subIndex = 0; subIndex < col.children.length; subIndex++) {
6793
+ const child = col.children[subIndex];
6794
+ if (child.is_visible !== false && !child['isRowGrouped']) {
6795
+ const key = `${rowIndex}-${colIndex}-${subIndex}-center`;
6796
+ this.selectedKeys.add(key);
6797
+ this.selectedCells.push({
6798
+ rowIndex,
6799
+ colIndex,
6800
+ subColIndex: subIndex,
6801
+ field: child.field,
6802
+ key
6803
+ });
6804
+ }
6805
+ }
6806
+ }
6807
+ else {
6808
+ if (col.is_visible !== false) {
6809
+ const key = `${rowIndex}-${colIndex}-0-center`;
6810
+ this.selectedKeys.add(key);
6811
+ this.selectedCells.push({
6812
+ rowIndex,
6813
+ colIndex,
6814
+ subColIndex: 0,
6815
+ field: col.field,
6816
+ key
6817
+ });
6818
+ }
6819
+ }
6820
+ }
6821
+ }
6822
+ // Update selection boundaries for border rendering
6823
+ this.updateSelectionBoundaries();
6824
+ this.cdr.markForCheck();
6825
+ }
6706
6826
  async onPaste(event) {
6707
6827
  const target = event.target;
6708
6828
  // Allow typing in inputs — but still allow paste if cell is selected
@@ -9331,7 +9451,7 @@ class TimeSheetComponent {
9331
9451
  };
9332
9452
  }
9333
9453
  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 }); }
9334
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: TimeSheetComponent, isStandalone: true, selector: "time-sheet", inputs: { rowAnimation: "rowAnimation", paginationConfig: "paginationConfig", dataSet: "dataSet", columns: "columns", rowHeight: "rowHeight", headerRowHeight: "headerRowHeight", showVerticalBorder: "showVerticalBorder", evenRowsBackgroundColor: "evenRowsBackgroundColor", oddRowsBackgroundColor: "oddRowsBackgroundColor", headerBackgroundColor: "headerBackgroundColor", checkboxesBackgroundColor: "checkboxesBackgroundColor", showColumnsGrouping: "showColumnsGrouping", rowHoverColor: "rowHoverColor", leftPinnedBackgroundColor: "leftPinnedBackgroundColor", bodyBackgroundColor: "bodyBackgroundColor", rightPinnedBackgroundColor: "rightPinnedBackgroundColor", sidemenuBackgroundColor: "sidemenuBackgroundColor", bodyTextColor: "bodyTextColor", headerTextColor: "headerTextColor", headerTextFontsSize: "headerTextFontsSize", bodyTextFontsSize: "bodyTextFontsSize", headerFontWeight: "headerFontWeight", bodyFontWeight: "bodyFontWeight", checkedRowBackgroundColor: "checkedRowBackgroundColor", dropdownsBackgroundColor: "dropdownsBackgroundColor", footerRowHeight: "footerRowHeight", topGroupedBadgesBackgroundColor: "topGroupedBadgesBackgroundColor", showRowsGrouping: "showRowsGrouping", showFilterRow: "showFilterRow", fontFaimly: "fontFaimly", showSideMenu: "showSideMenu", footerPadding: "footerPadding", topFilterRowHeight: "topFilterRowHeight", rowShadingEnabled: "rowShadingEnabled", showSerialNumber: "showSerialNumber", enableExport: "enableExport", singleSpaAssetsPath: "singleSpaAssetsPath", filtersConfig: "filtersConfig", loading: "loading", dataSetLoading: "dataSetLoading", verticalScrollbarWidth: "verticalScrollbarWidth", horizintalScrollbarWidth: "horizintalScrollbarWidth", showCellDetailsBox: "showCellDetailsBox", dateFormat: "dateFormat", tableSearch: "tableSearch", actions: "actions", config: "config", showTaskbar: "showTaskbar", tableName: "tableName", listingType: "listingType", checkboxState: "checkboxState", taskbarActions: "taskbarActions", sortingConfig: "sortingConfig", tableFilterViewId: "tableFilterViewId", selectedTableLayout: "selectedTableLayout", selectedPresetId: "selectedPresetId", closeDropdown: "closeDropdown", globalSearchText: "globalSearchText", nestedTablerowFontsize: "nestedTablerowFontsize", nestedTableHeaderRowHeight: "nestedTableHeaderRowHeight", nestedTablerowHeight: "nestedTablerowHeight", gridType: "gridType", isSingleDay: "isSingleDay", leftPinnedBoxshadow: "leftPinnedBoxshadow", rightPinnedBoxshadow: "rightPinnedBoxshadow", enableAccordionShadow: "enableAccordionShadow", enableAccordionSeparators: "enableAccordionSeparators", enableRowShading: "enableRowShading", selectedRowsBackgroundColor: "selectedRowsBackgroundColor", nestedTableHeaderBAckgroundColor: "nestedTableHeaderBAckgroundColor", tableView: "tableView", columnThreedotsMunuConfig: "columnThreedotsMunuConfig", timezonePrefs: "timezonePrefs", enableProgressiveLoading: "enableProgressiveLoading", progressiveChunkSize: "progressiveChunkSize", progressiveDelay: "progressiveDelay", detailsIconPosition: "detailsIconPosition", detailsPosition: "detailsPosition", singleOpen: "singleOpen", buttons: "buttons", isStartDateNotEqualToEndDate: "isStartDateNotEqualToEndDate" }, outputs: { onShortBreakClick: "onShortBreakClick", searchEvent: "searchEvent", changeLayout: "changeLayout", filterOptions: "filterOptions", filterCleared: "filterCleared", genericEvent: "genericEvent", tablePresetConfig: "tablePresetConfig", sortingOrderOptions: "sortingOrderOptions", createUpdateConfigListing: "createUpdateConfigListing", loadMore: "loadMore", emailClicked: "emailClicked", addAttendanceClicked: "addAttendanceClicked", backPayClicked: "backPayClicked", grandTotalClicked: "grandTotalClicked", printClicked: "printClicked", exportClicked: "exportClicked", exportDailyClicked: "exportDailyClicked", deleteClicked: "deleteClicked", closeTaskbar: "closeTaskbar" }, 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\">\n <!-- <h1>abu </h1> -->\n <div\n class=\"d-flex justify-content-between mb-3 align-items-center position-relative\"\n >\n <div class=\"col-4 global-search position-relative\">\n\n <span\n\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/search.svg'\"\n class=\"data-grid-svg-icon mx-2 position-absolute icon\"\n ></span>\n <input\n style=\"height: 36px\"\n class=\"form-control\"\n placeholder=\"Search all columns and press Enter\"\n [(ngModel)]=\"tableSearch\"\n (keydown.enter)=\"onGlobalSearch()\"\n\n />\n <span\n *ngIf=\"tableSearch\"\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/x.svg'\"\n class=\"data-grid-svg-icon position-absolute end-0 top-50 translate-middle-y me-2 cursor-pointer\"\n (click)=\"onSearchReset()\"\n title=\"Clear search\"\n ></span>\n\n </div>\n\n <!-- Date Picker Buttons -->\n <!-- Date Picker Section - Improved Version -->\n<div class=\"position-relative d-flex justify-content-center align-items-center ms-2 date-range-container\">\n\n <!-- Hidden Date Picker Input -->\n <input\n type=\"text\"\n class=\"form-control\"\n bsDaterangepicker\n #picker=\"bsDaterangepicker\"\n [(ngModel)]=\"bsRangeValue\"\n [bsConfig]=\"bsConfig\"\n (bsValueChange)=\"onRangeSelected($event, picker)\"\n style=\"opacity: 0; width: 0; height: 0; position: absolute;\"\n />\n\n <!-- Left Arrow Button -->\n <span\n class=\"text-primary cursor-pointer me-2 date-range-btn arrow-btn\"\n (click)=\"navigateDate('left')\"\n title=\"Previous Date Range\"\n *ngIf=\"bsRangeValue && bsRangeValue.length > 0\"\n >\n <span class=\"bi bi-chevron-left\"></span>\n </span>\n\n <!-- Date Range Label -->\n <span\n *ngIf=\"bsRangeValue && bsRangeValue.length > 0\"\n class=\"text-primary date-range-label cursor-pointer\"\n (click)=\"togglePicker(picker)\"\n title=\"Click to open calendar\"\n >\n {{ bsRangeValue[0] | timezoneFormat:prefs:'date' }} - {{ bsRangeValue[1] | timezoneFormat:prefs:'date' }}\n </span>\n\n <!-- Right Arrow Button -->\n <span\n class=\"text-primary cursor-pointer ms-2 date-range-btn arrow-btn\"\n (click)=\"navigateDate('right')\"\n title=\"Next Date Range\"\n *ngIf=\"bsRangeValue && bsRangeValue.length > 0\"\n >\n <span class=\"bi bi-chevron-right\"></span>\n </span>\n\n\n\n</div>\n\n <div class=\"d-flex gap-2 align-items-center table-right-top-actions\">\n\n <!-- Pivot Mode Button -->\n <!-- <a\n href=\"JavaScript:void(0)\"\n class=\"button button-small btn btn-active-primary border border-primary me-2 header-icon\"\n (click)=\"togglePivotMode()\"\n [class.active]=\"pivotMode\"\n title=\"Toggle Pivot Mode\"\n >\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/pivot.svg'\"\n class=\"svg-icon svg-icon-2\"\n ></span>\n </a> -->\n\n <div class=\"action-buttons-row d-flex gap-2 align-items-center\">\n <a\n href=\"JavaScript:void(0)\"\n class=\"button button-small btn btn-active-primary border border-primary p-0 d-flex align-items-center justify-content-center px-3\"\n (click)=\"togglePicker(picker)\"\n title=\"Select Date Range\"\n >\n <span class=\"bi bi-calendar3 text-primary\"></span>\n <span class=\"label-hidden text-white\">Calendar</span>\n </a>\n <button\n *ngIf=\"bsRangeValue && bsRangeValue.length > 0 && !isDefaultDateRange\"\n type=\"button\"\n class=\"button button-small btn btn-active-danger border border-danger p-0 d-flex align-items-center justify-content-center px-3\"\n (click)=\"clearDateRange()\"\n title=\"Clear Date Range\"\n >\n <span class=\"bi bi-x-circle text-danger\"></span>\n <span class=\"label-hidden text-white\">Clear</span>\n </button>\n</div>\n<ng-container *ngFor=\"let button of buttons\">\n <div\n class=\"action-buttons-row d-flex align-items-center\"\n *ngIf=\"getButtonPermission(button) && (!button.condition || (button.condition === '!isSingleDay' && !isSingleDay) || (button.condition === 'isSingleDay' && isSingleDay))\"\n >\n <a\n href=\"JavaScript:void(0)\"\n (click)=\"onActionButtonClick(button.name)\"\n class=\"button\"\n [title]=\"button.name\"\n >\n <span\n *ngIf=\"button.is_showIcon\"\n [inlineSVG]=\"button.iconPath\"\n class=\"svg-icon\"\n ></span>\n <span\n class=\"label-hidden\"\n >{{ button.name }}</span\n >\n </a>\n </div>\n</ng-container>\n\n<!-- Calendar Button -->\n\n\n<!-- Existing filter, settings, etc. -->\n <div\n *ngIf=\"!showFilterRow\"\n class=\"cursor-pointer position-relative action-buttons-row d-flex align-items-center\"\n (click)=\"toggleOpenFilter()\"\n [class.active]=\"showFilters\"\n >\n <a\n href=\"JavaScript:void(0)\"\n class=\"button button-small btn btn-active-primary border border-primary p-0 d-flex align-items-center justify-content-center px-3\"\n >\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\"\n class=\"svg-icon svg-icon-2\"\n ></span>\n <span class=\"label-hidden text-white\">Filters</span>\n </a>\n <span\n *ngIf=\"activeFilteredColumns?.length\"\n style=\"\n width: 7px;\n height: 7px;\n box-shadow: 0px 0px 3px #0022ff;\n background-color: rgb(0, 60, 255);\n position: absolute;\n right: 16px;\n top: 10px;\n \"\n class=\"rounded-circle d-block\"\n ></span>\n </div>\n <div\n class=\"cursor-pointer d-none\"\n (click)=\"toggleActions('advance-filter')\"\n [class.active]=\"activeTopButton === 'advance-filter'\"\n >\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/zoom-charge.svg'\"\n class=\"data-grid-svg-icon top-icon me-2\"\n ></span>\n </div>\n <div\n class=\"cursor-pointer action-buttons-row\"\n (click)=\"toggleActions('setting')\"\n [class.active]=\"\n activeTopButton === 'setting' ||\n activeTopButton === 'table-layout' ||\n activeTopButton === 'table-presets' ||\n activeTopButton === 'show-hide-columns'\n \"\n >\n <!-- <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/settings-2.svg'\"\n class=\"data-grid-svg-icon top-icon me-2\"\n ></span> -->\n <a\n href=\"JavaScript:void(0)\"\n class=\"button button-small btn btn-active-primary border border-primary p-0 d-flex align-items-center justify-content-center px-3\"\n >\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/settings-2.svg'\"\n class=\"svg-icon svg-icon-2\"\n ></span>\n <span class=\"label-hidden text-white\">Setting</span>\n </a>\n\n <div\n *ngIf=\"activeTopButton === 'setting'\"\n class=\"actions-dropdown mt-1 actions-dropdown-setting\"\n style=\"position: absolute\"\n >\n <div class=\"dropdown-menu show shadow custom-menu\">\n <!-- Table Layout -->\n <a\n class=\"dropdown-item d-flex justify-content-between align-items-center cursor-pointer\"\n (click)=\"$event.stopPropagation(); toggleActions('table-layout')\"\n >\n <span\n ><span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/table-2.svg'\n \"\n class=\"data-grid-svg-icon me-2\"\n ></span>\n Table Layout</span\n >\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\n \"\n class=\"data-grid-svg-icon me-2\"\n ></span>\n </a>\n <!-- Table Presets -->\n <a\n (click)=\"$event.stopPropagation(); toggleActions('table-presets')\"\n class=\"dropdown-item d-flex justify-content-between align-items-center cursor-pointer\"\n >\n <span\n ><span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/list-details.svg'\n \"\n class=\"data-grid-svg-icon me-2\"\n ></span>\n Table Presets</span\n >\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\n \"\n class=\"data-grid-svg-icon me-2\"\n ></span>\n </a>\n\n <!-- Columns -->\n <a\n *ngIf=\"!showSideMenu\"\n (click)=\"\n $event.stopPropagation(); toggleActions('show-hide-columns')\n \"\n class=\"dropdown-item d-flex justify-content-between align-items-center cursor-pointer\"\n >\n <span\n ><span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/eye.svg'\"\n class=\"data-grid-svg-icon me-2\"\n ></span>\n Columns</span\n >\n <div class=\"d-flex gap-2\">\n <span class=\"muted-text\">{{ columnsCount }}</span>\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\n \"\n class=\"data-grid-svg-icon me-2\"\n ></span>\n </div>\n </a>\n\n <div class=\"dropdown-divider\"></div>\n\n <!-- Filter -->\n <a\n class=\"dropdown-item cursor-pointer\"\n (click)=\"toggleOpenFilter(); activeTopButton = ''\"\n *ngIf=\"!showFilterRow\"\n >\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\n \"\n class=\"data-grid-svg-icon me-2 mt-1 cursor-pointer\"\n ></span>\n Filter\n </a>\n\n <!-- Download -->\n <!-- <a\n class=\"dropdown-item cursor-pointer\"\n (click)=\"downloadCsv('csv')\"\n >\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/download.svg'\n \"\n class=\"data-grid-svg-icon me-2 cursor-pointer\"\n ></span>\n CSV Export\n </a> -->\n <!-- <a\n *ngIf=\"enableExport\"\n class=\"dropdown-item cursor-pointer\"\n (click)=\"downloadCsv('xlsx')\"\n >\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/download.svg'\n \"\n class=\"data-grid-svg-icon me-2 cursor-pointer\"\n ></span>\n Excel Export\n </a> -->\n <!-- Font Family & Font Size -->\n <div class=\"px-2 pb-2 pt-2\">\n <div class=\"d-flex gap-2\">\n <!-- Font Family -->\n <select\n class=\"form-select form-select-sm\"\n [(ngModel)]=\"fontFaimly\"\n (change)=\"onFontChange()\"\n >\n <option *ngFor=\"let font of fontFamilies\" [value]=\"font\">\n {{ font }}\n </option>\n </select>\n\n <!-- Font Size -->\n <select\n class=\"form-select form-select-sm\"\n (change)=\"onFontChange()\"\n [(ngModel)]=\"bodyTextFontsSize\"\n >\n <option *ngFor=\"let size of fontSizes\" [value]=\"size\">\n {{ size }}\n </option>\n </select>\n </div>\n </div>\n </div>\n </div>\n\n <!-- Table Layout -->\n\n <ng-container *ngIf=\"activeTopButton === 'table-layout'\">\n <div\n *ngTemplateOutlet=\"tableLayout\"\n class=\"actions-dropdown mt-1\"\n style=\"position: absolute\"\n ></div>\n </ng-container>\n\n <!-- Table Presets -->\n <ng-container *ngIf=\"activeTopButton === 'table-presets'\">\n <div\n *ngTemplateOutlet=\"tablePreset\"\n class=\"actions-dropdown mt-1\"\n style=\"position: absolute\"\n ></div>\n </ng-container>\n\n <!-- Table Presets -->\n <ng-container *ngIf=\"activeTopButton === 'show-hide-columns'\">\n <div\n *ngTemplateOutlet=\"showHideColumns\"\n class=\"actions-dropdown mt-1\"\n style=\"position: absolute\"\n ></div>\n </ng-container>\n </div>\n <div>\n <!-- Example single danger button -->\n\n <!-- <button\n type=\"button\"\n class=\"btn btn-primary btn-sm d-flex gap-2 action-button\"\n (click)=\"toggleActions('actions')\"\n >\n Action\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/Vector.svg'\"\n class=\"data-grid-svg-icon\"\n ></span>\n </button>\n <div\n *ngIf=\"activeTopButton === 'actions'\"\n class=\"actions-dropdown mt-1\"\n >\n <div class=\"dropdown-menu show\">\n <a class=\"dropdown-item\" href=\"#\">Action</a>\n <a class=\"dropdown-item\" href=\"#\">Another action</a>\n <a class=\"dropdown-item\" href=\"#\">Something else here</a>\n <div class=\"dropdown-divider\"></div>\n <a class=\"dropdown-item\" href=\"#\">Separated link</a>\n </div>\n </div> -->\n </div>\n </div>\n </div>\n\n <div\n *ngIf=\"showFilters && !showFilterRow\"\n class=\"top-filter-row border-top py-2 d-flex justify-content-between align-items-center\"\n [style.height.px]=\"topFilterRowHeight\"\n >\n <!-- LEFT SIDE (Filter tags + Filter button) -->\n <div class=\"d-flex gap-2 align-items-center\">\n <ng-container *ngIf=\"activeFilteredColumns?.length\">\n <div\n *ngFor=\"let col of activeFilteredColumns; trackBy: trackByField\"\n class=\"filter-tags\"\n >\n <div\n (click)=\"\n isActiveFilterOpen = true;\n activeTopButton = 'filter-columns';\n openFilter(col)\n \"\n class=\"d-flex justify-content-center align-items-center muted-text add-filter-button active-filters\"\n style=\"white-space: nowrap\"\n [class.active]=\"\n col?.field == selectedColumnForFilter?.field &&\n isActiveFilterOpen &&\n activeTopButton == 'filter-columns'\n \"\n >\n <span class=\"header-tag mt-0 d-flex align-items-center\">\n <span\n *ngIf=\"col?.pinned\"\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/pin.svg'\"\n class=\"data-grid-svg-icon me-2\"\n ></span>\n {{ col.header }}\n <span\n (click)=\"\n $event.stopPropagation(); removeColumnFilterFromColumn(col)\n \"\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/cross-primary.svg'\n \"\n class=\"data-grid-svg-icon cross-secondary ms-2 mb-1\"\n ></span>\n </span>\n </div>\n\n <ng-container\n *ngIf=\"\n activeTopButton === 'filter-columns' &&\n col?.field == selectedColumnForFilter?.field &&\n isActiveFilterOpen\n \"\n >\n <div\n *ngTemplateOutlet=\"filterColumns; context: { column: col }\"\n class=\"actions-dropdown mt-1\"\n ></div>\n </ng-container>\n </div>\n </ng-container>\n\n <!-- Filter Button -->\n <div class=\"add-filter-button-menu\">\n <div\n (click)=\"toggleActions('filter-columns'); isActiveFilterOpen = false\"\n class=\"d-flex justify-content-center align-items-center muted-text add-filter-button button-filter\"\n style=\"width: 70px\"\n >\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/plus.svg'\"\n class=\"me-2 data-grid-svg-icon\"\n ></span>\n Filter\n </div>\n\n <ng-container\n *ngIf=\"activeTopButton === 'filter-columns' && !isActiveFilterOpen\"\n >\n <div\n *ngTemplateOutlet=\"filterColumns\"\n class=\"actions-dropdown mt-1\"\n ></div>\n </ng-container>\n </div>\n </div>\n\n <!-- RIGHT SIDE (Update + Reset) -->\n <div class=\"d-flex gap-3 align-items-center\">\n <div\n (click)=\"savePreset()\"\n class=\"text-primary cursor-pointer all-filters-reset-button\"\n *ngIf=\"!checkFilterChangesEffect()\"\n >\n Update View\n </div>\n\n <div\n class=\"text-primary cursor-pointer all-filters-reset-button\"\n *ngIf=\"!tableFilterViewId && activeFilteredColumns?.length\"\n (click)=\"clearAllFilters()\"\n >\n Reset\n </div>\n </div>\n </div>\n\n <div\n [style.height]=\"\n showFilters ? 'calc(100% - ' + topFilterRowHeight + 'px)' : '100%'\n \"\n cdkDropListGroup\n class=\"data-grid-table-wrapper overflow-hidden\"\n #dataGridContainer\n [style.fontFamily]=\"fontFaimly\"\n >\n <div\n *ngIf=\"showRowsGrouping\"\n [style.height.px]=\"headerRowHeight\"\n [cdkDropListData]=\"columns\"\n [style.backgroundColor]=\"\n topGroupedBadgesBackgroundColor || headerBackgroundColor\n \"\n cdkDropList\n (cdkDropListEntered)=\"enterToTopRowGrouping($event)\"\n (cdkDropListExited)=\"exitedFromTheTopRow($event)\"\n (cdkDropListDropped)=\"onDropTopGroup($event)\"\n [cdkDropListEnterPredicate]=\"canEnterToRowsGrouping\"\n id=\"rows-grouping-top-container\"\n class=\"border-below d-flex px-4 align-items-center\"\n >\n <div class=\"d-flex gap-2 align-items-center me-5\">\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/justify.svg'\"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n <div *ngIf=\"!draggingInGroupArea && !groupedColumns?.length\">\n Drag here to set row groups\n </div>\n <ng-container\n *ngFor=\"\n let child of groupedColumns;\n let i = index;\n trackBy: trackByField\n \"\n >\n <ng-container\n *ngTemplateOutlet=\"\n topGroupingRowPlaceholder;\n context: {\n $implicit: child,\n showChevron:\n groupedColumns.length > 1 && i != groupedColumns.length - 1\n }\n \"\n ></ng-container>\n </ng-container>\n </div>\n\n\n\n\n</div>\n<div\n class=\"d-flex overflow-hidden\"\n [style.height]=\"\n 'calc(100% - ' +\n (showRowsGrouping\n ? headerRowHeight + footerRowHeight\n : footerRowHeight) +\n 'px)'\n \"\n>\n <div\n class=\"h-100\"\n [style.width]=\"\n !showSideMenu\n ? '100%'\n : sideMenuVisible\n ? 'calc(100% - 280px)'\n : 'calc(100% - 30px)'\n \"\n >\n <div class=\"h-100 transition position-relative w-100\">\n <!-- ##################################################################################################################################################################################### -->\n <!-- ##################################################################################################################################################################################### -->\n <!-- Data Grid Header starts here -->\n <!-- ##################################################################################################################################################################################### -->\n <!-- ##################################################################################################################################################################################### -->\n\n <div\n class=\"data-grid-header-wrapper w-100\"\n [style.color]=\"headerTextColor\"\n [style.fontSize.px]=\"headerTextFontsSize\"\n [style.backgroundColor]=\"headerBackgroundColor\"\n [class.border-below]=\"!hasAnyVisibleColumn\"\n [style.height.px]=\"\n showColumnsGrouping && showFilterRow\n ? headerRowHeight * 3\n : showColumnsGrouping || showFilterRow\n ? headerRowHeight * 2\n : headerRowHeight\n \"\n >\n <!-- ********************************************************************************* -->\n <!-- ********************************************************************************* -->\n <!-- Data Grid Left Pinned Header starts here -->\n <!-- ********************************************************************************* -->\n <!-- ********************************************************************************* -->\n <div class=\"data-grid-header left-pinned\" #leftPinnedHeader>\n <div\n *ngIf=\"showSerialNumber\"\n [style.backgroundColor]=\"checkboxesBackgroundColor\"\n class=\"select-all-checkbox-cell border-below\"\n [style.width.px]=\"65\"\n [style.height.px]=\"\n showColumnsGrouping && showFilterRow\n ? headerRowHeight * 3\n : showColumnsGrouping || showFilterRow\n ? headerRowHeight * 2\n : headerRowHeight\n \"\n >\n S.No</div>\n <div\n [style.backgroundColor]=\"checkboxesBackgroundColor\"\n class=\"select-all-checkbox-cell border-below\"\n [style.height.px]=\"\n showColumnsGrouping && showFilterRow\n ? headerRowHeight * 3\n : showColumnsGrouping || showFilterRow\n ? headerRowHeight * 2\n : headerRowHeight\n \"\n >\n <input\n *ngIf=\"hasAnyVisibleColumn\"\n type=\"checkbox\"\n [indeterminate]=\"isIndeterminateState(dataSet)\"\n [checked]=\"isAllSelected(dataSet)\"\n (change)=\"toggleSelectAll(dataSet)\"\n />\n </div>\n <div\n class=\"d-flex\"\n cdkDropList\n id=\"left-pinned-header\"\n cdkDropListOrientation=\"horizontal\"\n [cdkDropListData]=\"leftPinnedColumns\"\n (cdkDropListEntered)=\"onDropListEnter($event, 'left')\"\n (cdkDropListSorted)=\"\n onSortGroup($event, 'previewLeftPinnedColumns')\n \"\n (cdkDropListDropped)=\"onDropGroup()\"\n style=\"min-width: 0.2px\"\n [style.background-color]=\"headerBackgroundColor\"\n >\n <div\n class=\"dragable-header\"\n cdkDrag\n [cdkDragData]=\"col\"\n *ngFor=\"\n let col of leftPinnedColumns;\n let i = index;\n trackBy: trackByField\n \"\n >\n <ng-container\n *ngTemplateOutlet=\"\n headerCell;\n context: {\n $implicit: col,\n index: i,\n section: 'previewLeftPinnedColumns'\n }\n \"\n ></ng-container>\n <ng-template cdkDragPreview\n ><div class=\"p-2 border d-flex gap-2\">\n <div>\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath +\n 'data-grid/icons/arrows-move.svg'\n \"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n </div>\n <div>{{ col.header }}</div>\n </div>\n </ng-template>\n <ng-template cdkDragPlaceholder>\n <div *ngIf=\"!draggingInGroupArea\">\n <div\n *ngTemplateOutlet=\"\n headerCell;\n context: {\n $implicit: col,\n index: i,\n section: ''\n }\n \"\n ></div>\n </div>\n <div\n *ngIf=\"draggingInGroupArea\"\n class=\"d-flex gap-2 ms-2\"\n style=\"opacity: 0.6\"\n >\n <ng-container\n *ngIf=\"col?.children?.length; else singleCol\"\n >\n <ng-container\n *ngFor=\"\n let child of col.children;\n let i = index;\n trackBy: trackByField\n \"\n >\n <ng-container\n *ngTemplateOutlet=\"\n topGroupingRowPlaceholder;\n context: {\n $implicit: child,\n showChevron:\n col.children.length > 1 &&\n i != col.children.length - 1\n }\n \"\n ></ng-container>\n </ng-container>\n </ng-container>\n\n <ng-template #singleCol>\n <ng-container\n *ngTemplateOutlet=\"\n topGroupingRowPlaceholder;\n context: {\n $implicit: col,\n showChevron: col?.children?.length > 1\n }\n \"\n ></ng-container>\n </ng-template>\n </div>\n </ng-template>\n </div>\n </div>\n </div>\n\n <!-- ********************************************************************************* -->\n <!-- ********************************************************************************* -->\n <!-- Data Grid Center Pinned Header starts here -->\n <!-- ********************************************************************************* -->\n <!-- ********************************************************************************* -->\n <div\n class=\"data-grid-header center-scrollable\"\n #centerPinnedHeader\n (scroll)=\"onCenterHeaderScroll($event)\"\n id=\"center-pinned-header\"\n cdkDropList\n [cdkDropListConnectedTo]=\"\n showRowsGrouping ? ['rows-grouping-top-container'] : []\n \"\n [cdkDropListData]=\"centerColumns\"\n cdkDropListOrientation=\"horizontal\"\n [cdkDropListSortingDisabled]=\"\n isDisableColumnGrouping && draggingInGroupArea\n \"\n (cdkDropListEntered)=\"onDropListEnter($event, 'center')\"\n (cdkDropListSorted)=\"onSortGroup($event, 'previewCenterColumns')\"\n (cdkDropListDropped)=\"onDropGroup()\"\n [style.maxWidth]=\"\n 'calc(100% - ' +\n (rightPinnedHeader.offsetWidth + leftPinnedHeader.offsetWidth) +\n 'px)'\n \"\n >\n <div\n *ngIf=\"groupedColumns?.length\"\n style=\"min-width: 200px\"\n class=\"h-100 align-items-center\"\n #columnsGroupedBox\n id=\"groupBoxHeaderDiv\"\n >\n <div\n class=\"d-flex w-100 justify-content-between align-items-center border-below\"\n [style.height.px]=\"\n showFilterRow ? headerRowHeight * 2 : headerRowHeight\n \"\n >\n <div class=\"ps-3\">Group</div>\n <div class=\"d-flex\">\n <div\n class=\"three-dots cursor-pointer\"\n (click)=\"openThreeDotsMenu($event, 'group')\"\n >\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath +\n 'data-grid/icons/three-dots-vertical.svg'\n \"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n </div>\n <div\n (mousedown)=\"onResizeGroupBox($event)\"\n class=\"resize-handle\"\n style=\"margin-right: -2px\"\n >\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath +\n 'data-grid/icons/resize-handle.svg'\n \"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n </div>\n </div>\n </div>\n\n <div\n [style.height.px]=\"headerRowHeight\"\n class=\"border-below\"\n ></div>\n </div>\n <!-- <span\n class=\"d-flex align-items-center justify-content-center cursor-pointer border-below\"\n style=\"min-width: 30px; height: 100%;\"\n *ngIf=\"gridType === 'TimeSheet' && !areDatesSelectedAndEqual\"\n >\n </span> -->\n <div\n class=\"dragable-header\"\n (cdkDragStarted)=\"\n checkColumnGroupingStatus(col); dragStartOnGroup(col)\n \"\n cdkDrag\n [cdkDragData]=\"col\"\n *ngFor=\"\n let col of centerColumns;\n let i = index;\n trackBy: trackById\n \"\n >\n <ng-container\n *ngTemplateOutlet=\"\n headerCell;\n context: {\n $implicit: col,\n index: i,\n section: 'previewCenterColumns'\n }\n \"\n >\n </ng-container>\n <ng-template cdkDragPreview\n ><div class=\"p-2 border d-flex gap-2\">\n <div>\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath +\n 'data-grid/icons/arrows-move.svg'\n \"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n </div>\n <div>{{ col.header }}</div>\n </div>\n </ng-template>\n <ng-template cdkDragPlaceholder>\n <div *ngIf=\"!draggingInGroupArea\">\n <div\n *ngTemplateOutlet=\"\n headerCell;\n context: {\n $implicit: col,\n index: i,\n section: 'centerColumns'\n }\n \"\n ></div>\n </div>\n <div\n *ngIf=\"draggingInGroupArea\"\n class=\"d-flex gap-2 ms-2\"\n style=\"opacity: 0.6\"\n >\n <ng-container *ngIf=\"col?.children?.length; else singleCol\">\n <ng-container\n *ngFor=\"\n let child of col.children;\n let i = index;\n trackBy: trackById\n \"\n >\n <ng-container *ngIf=\"child?.is_groupable\">\n <ng-container\n *ngTemplateOutlet=\"\n topGroupingRowPlaceholder;\n context: {\n $implicit: child,\n showChevron:\n col.children.length > 1 &&\n i != col.children.length - 1\n }\n \"\n ></ng-container>\n </ng-container>\n </ng-container>\n </ng-container>\n\n <ng-template #singleCol>\n <ng-container *ngIf=\"col?.is_groupable\">\n <ng-container\n *ngTemplateOutlet=\"\n topGroupingRowPlaceholder;\n context: {\n $implicit: col,\n showChevron: col?.children?.length > 1\n }\n \"\n ></ng-container>\n </ng-container>\n </ng-template>\n </div>\n </ng-template>\n </div>\n <div *ngIf=\"!areDatesSelectedAndEqual\" class=\"header-cell border-below\" [style.width.px]=\"30\" [style.height.px]=\"headerRowHeight\" [style.backgroundColor]=\"headerBackgroundColor\"></div>\n </div>\n\n <!-- ********************************************************************************* -->\n <!-- ********************************************************************************* -->\n <!-- Data Grid Right Pinned Header starts here -->\n <!-- ********************************************************************************* -->\n <!-- ********************************************************************************* -->\n <div\n cdkDropList\n id=\"right-pinned-header\"\n [cdkDropListConnectedTo]=\"\n showRowsGrouping ? ['rows-grouping-top-container'] : []\n \"\n cdkDropListOrientation=\"horizontal\"\n class=\"data-grid-header right-pinned\"\n (cdkDropListSorted)=\"\n onSortGroup($event, 'previewRightPinnedColumns')\n \"\n (cdkDropListEntered)=\"onDropListEnter($event, 'right')\"\n (cdkDropListDropped)=\"onDropGroup()\"\n #rightPinnedHeader\n class=\"right-pinned-header d-flex\"\n style=\"min-width: 0.2px\"\n >\n <div\n class=\"dragable-header\"\n cdkDrag\n [cdkDragData]=\"col\"\n *ngFor=\"\n let col of rightPinnedColumns;\n let i = index;\n trackBy: trackById\n \"\n >\n <ng-container\n *ngTemplateOutlet=\"\n headerCell;\n context: {\n $implicit: col,\n pinnedRight: true,\n index: i,\n section: 'previewRightPinnedColumns'\n }\n \"\n ></ng-container>\n <ng-template cdkDragPreview\n ><div class=\"p-2 border d-flex gap-2\">\n <div>\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath +\n 'data-grid/icons/arrows-move.svg'\n \"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n </div>\n <div>{{ col.header }}</div>\n </div>\n </ng-template>\n <ng-template cdkDragPlaceholder>\n <div *ngIf=\"!draggingInGroupArea\">\n <div\n *ngTemplateOutlet=\"\n headerCell;\n context: {\n $implicit: col,\n index: i,\n section: 'centerColumns'\n }\n \"\n ></div>\n </div>\n <div\n *ngIf=\"draggingInGroupArea\"\n class=\"d-flex gap-2 ms-2\"\n style=\"opacity: 0.6\"\n >\n <ng-container *ngIf=\"col?.children?.length; else singleCol\">\n <ng-container\n *ngFor=\"\n let child of col.children;\n let i = index;\n trackBy: trackById\n \"\n >\n <ng-container\n *ngTemplateOutlet=\"\n topGroupingRowPlaceholder;\n context: {\n $implicit: child,\n showChevron:\n col.children.length > 1 &&\n i != col.children.length - 1\n }\n \"\n ></ng-container>\n </ng-container>\n </ng-container>\n\n <ng-template #singleCol>\n <ng-container\n *ngTemplateOutlet=\"\n topGroupingRowPlaceholder;\n context: {\n $implicit: col,\n showChevron: col?.children?.length > 1\n }\n \"\n ></ng-container>\n </ng-template>\n </div>\n </ng-template>\n </div>\n </div>\n </div>\n\n <!--########################################################################################################################################################################################################################### -->\n <!--########################################################################################################################################################################################################################### -->\n <!-- Data Grid Body starts here -->\n <!--########################################################################################################################################################################################################################### -->\n <!--########################################################################################################################################################################################################################### -->\n <div\n class=\"h-100 d-flex justify-content-center align-items-center\"\n *ngIf=\"!dataSet.length && !loading\"\n >\n No Record Found\n </div>\n\n <div\n class=\"position-absolute w-100 h-100 d-flex justify-content-center align-items-center loading-overlay\"\n *ngIf=\"loading\"\n style=\"\n z-index: 999;\n background: rgba(255, 255, 255, 0.8);\n backdrop-filter: blur(1px);\n \"\n >\n <div class=\"text-center p-2\">\n <div class=\"spinner-border text-primary\" role=\"status\"></div> Loading...\n</div>\n </div>\n\n <!-- Card View -->\n \n\n <!-- Table View -->\n <div\n class=\"data-grid-body-wrapper position-relative d-flex\"\n [style.height]=\"bodyWrapperHeight\"\n style=\"overflow-y: auto; overflow-x: hidden\"\n #mainScroll\n (scroll)=\"onMainScroll($event)\"\n *ngIf=\"dataSet.length\"\n >\n <!-- LEFT PINNED -->\n <div [style.height.px]=\"!groupedColumns.length ? originalDataSet.length * rowHeight: 0\"></div>\n <div [class.h-100]=\"originalDataSet.length <= 10\">\n <div\n class=\"data-grid-body left-pinned-body w-100\"\n style=\"overflow-y: hidden\"\n [class.border-right]=\"hasLeftPinnedColumns\"\n [class.transparent-border-right]=\"!hasLeftPinnedColumns\"\n *ngIf=\"!loading && !dataSetLoading\"\n [@rowDynamic]=\"rowAnimation\"\n [style.transform]=\"\n 'translateY(' + startIndex * rowHeight + 'px)'\n \"\n >\n <ng-container\n *ngFor=\"\n let row of visibleRows;\n let i = index;\n trackBy: trackById\n \"\n >\n <ng-container\n *ngTemplateOutlet=\"\n rowCell;\n context: {\n $implicit: row,\n columns: previewLeftPinnedColumns,\n isEven: (startIndex + i) % 2 === 0,\n isOdd: (startIndex + i) % 2 !== 0,\n isLeft: true,\n section: 'left'\n }\n \"\n ></ng-container>\n </ng-container>\n </div>\n </div>\n\n <!-- CENTER -->\n <div\n class=\"\"\n [style.width.px]=\"centerPinnedHeader.clientWidth\"\n >\n <div\n class=\"data-grid-body center-scrollable\"\n [@rowDynamic]=\"rowAnimation\" *ngIf=\"!loading && !dataSetLoading\"\n style=\"overflow-y: hidden; overflow-x: auto\"\n [style.transform]=\"\n 'translateY(' + startIndex * rowHeight + 'px)'\n \"\n [style.backgroundColor]=\"bodyBackgroundColor\"\n #centerScrollableBody\n (scroll)=\"onCenterBodyScroll($event)\"\n [style.boxShadow]=\"leftPinnedBoxshadow\"\n\n >\n <ng-container \n *ngFor=\"\n let row of visibleRows;\n let i = index;\n trackBy: trackById\n \"\n >\n <ng-container\n *ngTemplateOutlet=\"\n rowCell;\n context: {\n $implicit: row,\n columns: previewCenterColumns,\n isEven: (startIndex + i) % 2 === 0,\n isOdd: (startIndex + i) % 2 !== 0,\n section: 'center'\n }\n \"\n ></ng-container>\n </ng-container>\n </div>\n </div>\n\n <!-- RIGHT PINNED -->\n <div\n class=\"right-pinned-body-wrapper\"\n *ngIf=\"hasRightPinnedColumns\"\n [class.h-100]=\"originalDataSet.length <= 10\"\n [style.max-width.px]=\"isScrollbarVisible ? rightPinnedHeader.offsetWidth - 15: rightPinnedHeader.offsetWidth\"\n >\n <div\n class=\"data-grid-body right-pinned-body w-100\"\n style=\"overflow-y: hidden\"\n [style.transform]=\"\n 'translateY(' + startIndex * rowHeight + 'px)'\n \"\n [style.boxShadow]=\"rightPinnedBoxshadow\"\n *ngIf=\"!loading && !dataSetLoading\"\n [@rowDynamic]=\"rowAnimation\"\n >\n <ng-container\n *ngFor=\"\n let row of visibleRows;\n let i = index;\n trackBy: trackById\n \"\n >\n <ng-container\n *ngTemplateOutlet=\"\n rowCell;\n context: {\n $implicit: row,\n columns: previewRightPinnedColumns,\n isEven: (startIndex + i) % 2 === 0,\n isOdd: (startIndex + i) % 2 !== 0,\n section: 'right'\n }\n \"\n ></ng-container>\n </ng-container>\n </div>\n </div>\n </div>\n <!-- Vertical Fake scroll Bar -->\n <div\n (scroll)=\"onMainFakeScroll($event)\"\n class=\"fake-scrollbar fake-scrollbar-vertical d-none\"\n [style.scrollbarWidth]=\"verticalScrollbarWidth\"\n [style.top.px]=\"\n showColumnsGrouping && showFilterRow\n ? headerRowHeight * 3\n : showColumnsGrouping || showFilterRow\n ? headerRowHeight * 2\n : headerRowHeight\n \"\n #fakeScroll\n [style.height]=\"bodyWrapperHeight\"\n style=\"\n overflow-y: auto;\n overflow-x: hidden;\n width: 17px;\n position: absolute;\n right: 0;\n background-color: f1f2f3;\n z-index: 10;\n \"\n >\n <div [style.height.px]=\"rowHeight * (paginationConfig.totalResults || flattenedData.length)\"></div>\n </div>\n </div>\n\n <!-- Horizintal Fake Scrollbars -->\n <div class=\"d-flex justify-content-between\" *ngIf=\"dataSet.length\">\n <div\n [style.scrollbarWidth]=\"horizintalScrollbarWidth\"\n class=\"fake-horizintal-scrollbar\"\n #fakeScroll\n [style.width.px]=\"leftPinnedHeader.offsetWidth\"\n style=\"overflow-x: scroll\"\n ></div>\n <div\n [style.scrollbarWidth]=\"horizintalScrollbarWidth\"\n (scroll)=\"onHorizintalFakeScroll($event)\"\n class=\"fake-horizintal-scrollbar\"\n #horizintalFakeScroll\n [style.width.px]=\"centerPinnedHeader.offsetWidth\"\n >\n <div [style.width.px]=\"centerPinnedHeader.scrollWidth\"></div>\n </div>\n <div\n [style.scrollbarWidth]=\"horizintalScrollbarWidth\"\n class=\"fake-horizintal-scrollbar\"\n #fakeScroll\n [style.width.px]=\"rightPinnedHeader.offsetWidth\"\n style=\"overflow-x: scroll\"\n ></div>\n </div>\n </div>\n\n <!-- Side Menu Implemented Here -->\n <div\n *ngIf=\"showSideMenu && !hasOpenAccordion\"\n [style.width.px]=\"sideMenuVisible ? 280 : 30\"\n class=\"right-menu h-100\"\n [style.backgroundColor]=\"sidemenuBackgroundColor\"\n >\n <div class=\"h-100 d-flex flex-row-reverse\">\n <div\n style=\"width: 30px\"\n class=\"d-flex flex-column align-items-center cursor-pointer\"\n [class.border-start]=\"sideMenuVisible\"\n >\n <div\n (click)=\"toggleSideMenu('cols')\"\n [class.bg-white]=\"\n currentOpenedSideMenue == 'cols' && sideMenuVisible\n \"\n [class.border-below]=\"sideMenuVisible\"\n class=\"columns-button d-flex flex-column align-items-center\"\n >\n <div>\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/ui-checks-grid.svg'\n \"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n </div>\n <div class=\"side-menue-text\">Columns</div>\n </div>\n\n <div\n (click)=\"toggleSideMenu('filtrs')\"\n [class.bg-white]=\"\n currentOpenedSideMenue == 'filtrs' && sideMenuVisible\n \"\n [class.border-below]=\"\n sideMenuVisible && currentOpenedSideMenue == 'filtrs'\n \"\n class=\"columns-button d-flex flex-column align-items-center\"\n >\n <div>\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\n \"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n </div>\n <div class=\"side-menue-text\">Filter</div>\n </div>\n </div>\n <div\n class=\"h-100\"\n *ngIf=\"sideMenuVisible\"\n [ngStyle]=\"{ width: sideMenuVisible ? '250px' : '' }\"\n >\n <div class=\"h-100\">\n <ng-container\n *ngIf=\"currentOpenedSideMenue == 'cols' && sideMenuVisible\"\n >\n <ng-container *ngTemplateOutlet=\"columnPannel\"></ng-container>\n <!-- Column Items -->\n <div class=\"column-panel-body px-3\">\n <ng-container\n *ngFor=\"let col of columns; trackBy: trackByField\"\n >\n <ng-container\n *ngTemplateOutlet=\"columnPanelItem; context: { col: col }\"\n ></ng-container>\n </ng-container>\n </div>\n <hr />\n\n <div class=\"side-menu-row-groups\" style=\"height: 30%\">\n <ng-container\n *ngTemplateOutlet=\"sideMenuRowGroups\"\n ></ng-container>\n </div>\n </ng-container>\n <ng-container\n *ngIf=\"currentOpenedSideMenue == 'filtrs' && sideMenuVisible\"\n >\n <ng-container *ngTemplateOutlet=\"sideFilters\"></ng-container>\n </ng-container>\n </div>\n </div>\n </div>\n </div>\n </div>\n <div [style.height.px]=\"footerRowHeight\" class=\"border-top\">\n <!-- Rows: <span class=\"fw-500 ms-1\">{{ dataSet.length }}</span> -->\n <div\n class=\"pagination-container\"\n [style.height.px]=\"footerRowHeight\"\n [style.padding.px]=\"footerPadding\"\n >\n <div class=\"page-size\">\n <select\n [(ngModel)]=\"paginationConfig.selectedPageSize\"\n (change)=\"onPageSizeChange()\"\n >\n <option *ngFor=\"let size of pageSizeOptions\" [value]=\"size\">\n {{ size }}\n </option>\n </select>\n <span class=\"\"> per page </span>\n </div>\n\n <div class=\"page-info\">\n Results: {{ startPageIndex }}-{{ endPageIndex }}\n of\n {{ paginationConfig.totalResults }}\n </div>\n\n <div class=\"page-buttons\">\n <button\n (click)=\"goToPage(paginationConfig.page - 1)\"\n [disabled]=\"paginationConfig.page === 1\"\n >\n \u2039\n </button>\n\n <ng-container *ngFor=\"let page of visiblePages\">\n <button\n *ngIf=\"page !== '...'\"\n (click)=\"goToPage(page)\"\n [class.active]=\"page === paginationConfig.page\"\n >\n {{ page }}\n </button>\n <span *ngIf=\"page === '...'\">...</span>\n </ng-container>\n\n <button\n (click)=\"goToPage(paginationConfig.page + 1)\"\n [disabled]=\"paginationConfig.page === paginationConfig.totalResults\"\n >\n \u203A\n </button>\n </div>\n </div>\n </div>\n </div>\n</div>\n\n<!-- ------------------------------------------------------------------------------------------------------------------------ -->\n<!-- ------------------------------------------------------------------------------------------------------------------------ -->\n<!-- Header Cell Template -->\n<!-- ------------------------------------------------------------------------------------------------------------------------ -->\n<!-- ------------------------------------------------------------------------------------------------------------------------ -->\n\n<ng-template\n #headerCell\n let-col\n let-pinnedRight=\"pinnedRight\"\n let-i=\"index\"\n let-sections=\"section\"\n let-calledFromNestedPlaceholder=\"calledFromNestedPlaceholder\"\n>\n <div>\n <!-- Group Header -->\n <ng-container *ngIf=\"col.children?.length > 0; else flatHeader\">\n <div cdkDroplistGroup class=\"group-column-wrapper\">\n <!-- Parent Header -->\n <div\n *ngIf=\"shouldTheGroupHeaderShow(col)\"\n class=\"header-cell group-header\"\n [style.height.px]=\"headerRowHeight\"\n [style.min-height.px]=\"headerRowHeight\"\n [style.max-height.px]=\"headerRowHeight\"\n [class.border-right]=\"showVerticalBorder\"\n [style.gridColumn]=\"'span ' + col.children.length\"\n [style.fontWeight]=\"headerFontWeight\"\n [class.flex-row-reverse]=\"pinnedRight\"\n [class.justify-content-end]=\"pinnedRight\"\n style=\"grid-row: 1\"\n >\n <div\n class=\"group-header-content\"\n [title]=\"col.header\"\n [class.ms-2]=\"pinnedRight\"\n >\n {{ col.header }}\n </div>\n <div\n class=\"resize-handle\"\n (dblclick)=\"autosizeColumn(col.children)\"\n (mousedown)=\"onResizeGroup($event, col, pinnedRight)\"\n >\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/resize-handle.svg'\n \"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n </div>\n </div>\n\n <!-- Child Headers and Filters -->\n\n <div\n class=\"d-flex\"\n cdkDropList\n cdkDropListOrientation=\"horizontal\"\n [cdkDropListData]=\"col.children\"\n (cdkDropListSorted)=\"onChildDroplistSorted($event, sections)\"\n (cdkDropListDropped)=\"onChildDroplistDroped($event)\"\n [cdkDropListSortingDisabled]=\"false\"\n [cdkDropListConnectedTo]=\"\n showRowsGrouping ? ['rows-grouping-top-container'] : []\n \"\n >\n <div\n cdkDrag\n [cdkDragData]=\"child\"\n *ngFor=\"let child of col.children; let i = index\"\n >\n <!-- Child Header -->\n <ng-container *ngIf=\"child.is_visible && !child['isRowGrouped']\">\n <div\n cdkDragHandle\n class=\"header-cell one-row-header-cells cursor-pointer\"\n [class.border-right]=\"showVerticalBorder\"\n [attr.field]=\"child.field\"\n [style.width.px]=\"child.width\"\n [style.min-width.px]=\"child.width\"\n [style.min-height.px]=\"headerRowHeight\"\n [style.max-height.px]=\"headerRowHeight\"\n [style.fontWeight]=\"headerFontWeight\"\n style=\"grid-row: 2\"\n [class.filter-applied-on-text]=\"isFilterAppliedOnColumn(child)\"\n >\n <div\n class=\"d-flex justify-content-between h-100 align-items-center w-100\"\n >\n <div\n class=\"d-flex justify-content-between w-100\"\n [class.flex-row-reverse]=\"pinnedRight\"\n >\n <div\n class=\"text-ellipsis h-100 d-flex align-items-center w-100\"\n [title]=\"col.header\"\n [class.w-100]=\"pinnedRight\"\n >\n <div\n class=\"text-ellipsis h-100\"\n [class.editable-header]=\"child?.is_editable\"\n (click)=\"openThreeDotsMenu($event, child); openFilteronThreeDotsClick(child)\"\n >\n {{ child.header }}\n </div>\n </div>\n\n <div\n class=\"position-relative d-flex\"\n [class.flex-row-reverse]=\"pinnedRight\"\n >\n <div\n [class.me-2]=\"pinnedRight\"\n class=\"d-flex align-items-center\"\n *ngIf=\"child.pinned\"\n >\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/pin-blue.svg'\n \"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n </div>\n <div\n class=\"three-dots p-1\"\n (click)=\"openThreeDotsMenu($event, child)\"\n style=\"cursor: pointer\"\n >\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath +\n 'data-grid/icons/three-dots-vertical.svg'\n \"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n </div>\n\n <!-- Only show menu if this column is active -->\n <div\n class=\"position-absolute\"\n *ngIf=\"activeCol === child\"\n style=\"top: -50%; z-index: 21\"\n [style.left.px]=\"\n -(!child?.pinned ? centerPinnedHeader.scrollLeft : 0)\n \"\n >\n <ng-container\n *ngTemplateOutlet=\"\n columnMenu;\n context: { col: child }\n \"\n ></ng-container>\n </div>\n\n <div\n class=\"resize-handle\"\n (dblclick)=\"autosizeColumn(child)\"\n (mousedown)=\"onResizeColumn($event, child)\"\n >\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath +\n 'data-grid/icons/resize-handle.svg'\n \"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n </div>\n </div>\n </div>\n </div>\n </div>\n\n <!-- Filter Cell -->\n <div\n *ngIf=\"showFilterRow\"\n [style.backgroundColor]=\"headerBackgroundColor\"\n class=\"header-cell filter-cell\"\n [class.border-right]=\"showVerticalBorder\"\n [attr.field]=\"child.field\"\n [style.width.px]=\"child.width\"\n [style.min-width.px]=\"child.width\"\n [style.height.px]=\"headerRowHeight\"\n [style.min-height.px]=\"headerRowHeight\"\n [style.max-height.px]=\"headerRowHeight\"\n [class.border-right]=\"showVerticalBorder\"\n style=\"grid-row: 3\"\n >\n <div\n class=\"header-cell filter-cell\"\n [attr.field]=\"col.field\"\n [style.width.px]=\"col.width\"\n [style.min-width.px]=\"col.width\"\n [style.height.px]=\"headerRowHeight\"\n [style.min-height.px]=\"headerRowHeight\"\n [style.max-height.px]=\"headerRowHeight\"\n >\n <input\n type=\"text\"\n class=\"form-control form-control-sm\"\n placeholder=\"Filter\"\n [(ngModel)]=\"col.filterValue\"\n (ngModelChange)=\"onFilterChange(col)\"\n />\n <span\n class=\"filter-icon-wrapper\"\n (click)=\"$event.stopPropagation(); openFilter(child)\"\n [class.filter-applied]=\"isFilterAppliedOnColumn(child)\"\n ><span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\n \"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n <span\n *ngIf=\"isFilterAppliedOnColumn(child)\"\n style=\"\n width: 7px;\n height: 7px;\n box-shadow: 0px 0px 3px #7486ff;\n background-color: rgb(0 163 233);\n position: absolute;\n right: 4px;\n top: 12px;\n \"\n class=\"rounded-circle d-block\"\n ></span\n ></span>\n\n <div\n class=\"position-absolute filter-row-filter-wrapper\"\n *ngIf=\"activeFilterCell?.field == child?.field\"\n style=\"top: 100%; right: 0; z-index: 99\"\n [style.left.px]=\"\n child?.pinned ? 0 : -centerPinnedHeader.scrollLeft\n \"\n >\n <ng-container\n *ngTemplateOutlet=\"filterMenu; context: { col: child }\"\n ></ng-container>\n </div>\n </div>\n </div>\n </ng-container>\n <ng-template cdkDragPreview\n ><div class=\"p-2 border d-flex gap-2\">\n <div\n *ngIf=\"\n !draggingInGroupArea ||\n (child.is_groupable && draggingInGroupArea)\n \"\n >\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/arrows-move.svg'\n \"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n </div>\n <div *ngIf=\"draggingInGroupArea && !child.is_groupable\">\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/ban.svg'\n \"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n </div>\n <div>{{ child.header }}</div>\n </div>\n </ng-template>\n <ng-template cdkDragPlaceholder>\n <div *ngIf=\"!draggingInGroupArea\" class=\"position-relative\">\n <div\n *ngTemplateOutlet=\"\n childHeaderPlaceholder;\n context: {\n $implicit: child,\n index: i,\n sections: sections,\n calledFromNestedPlaceholder: true,\n }\n \"\n ></div>\n </div>\n <div\n *ngIf=\"draggingInGroupArea && child?.is_groupable\"\n class=\"d-flex gap-2 ms-2\"\n style=\"opacity: 0.6\"\n >\n <ng-container\n *ngTemplateOutlet=\"\n topGroupingRowPlaceholder;\n context: {\n $implicit: child,\n showChevron: false,\n pinnedRight: pinnedRight,\n sections: sections,\n index: i\n }\n \"\n ></ng-container>\n </div>\n </ng-template>\n </div>\n </div>\n </div>\n </ng-container>\n\n <!-- Flat Header || Single Header Cell-->\n <ng-template #flatHeader>\n <div class=\"group-column-wrapper\">\n <!-- Full-height Header Cell (spans 2 rows visually) -->\n <div\n class=\"header-cell one-row-header-cells\"\n [attr.field]=\"col.field\"\n [style.width.px]=\"col.width\"\n [style.min-width.px]=\"col.width\"\n [class.border-right]=\"showVerticalBorder\"\n [style.min-height.px]=\"\n showColumnsGrouping ? headerRowHeight * 2 : headerRowHeight\n \"\n [style.height.px]=\"\n showColumnsGrouping ? headerRowHeight * 2 : headerRowHeight\n \"\n [style.fontWeight]=\"headerFontWeight\"\n style=\"grid-row: 1 / span 2\"\n >\n <div\n class=\"d-flex justify-content-between h-100 align-items-center w-100\"\n >\n <div\n class=\"d-flex justify-content-between w-100\"\n [class.flex-row-reverse]=\"pinnedRight\"\n >\n <div\n class=\"text-ellipsis h-100 d-flex align-items-center w-100\"\n [title]=\"col.header\"\n >\n <div\n class=\"text-ellipsis h-100 cursor-pointer\"\n [class.editable-header]=\"col?.is_editable\"\n [class.filter-applied-on-text]=\"isFilterAppliedOnColumn(col)\"\n (click)=\"openThreeDotsMenu($event, col); openFilteronThreeDotsClick(col)\"\n >\n {{ col.header }}\n </div>\n </div>\n\n <div\n class=\"position-relative d-flex\"\n [class.flex-row-reverse]=\"pinnedRight\"\n >\n <div\n [class.me-2]=\"pinnedRight\"\n class=\"d-flex align-items-center\"\n *ngIf=\"col?.pinned\"\n >\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/pin-blue.svg'\n \"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n </div>\n <div\n [class.me-2]=\"col.order_by\"\n class=\"d-flex align-items-center\"\n *ngIf=\"sortingConfig?.field == col.field\"\n >\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath +\n (sortingConfig?.order_by == 'desc'\n ? 'data-grid/icons/sort-desc.svg'\n : 'data-grid/icons/sort-asc.svg')\n \"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center mt-1\"\n ></span>\n </div>\n <div\n class=\"three-dots p-1\"\n (click)=\"openThreeDotsMenu($event, col)\"\n style=\"cursor: pointer\"\n >\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath +\n 'data-grid/icons/three-dots-vertical.svg'\n \"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n </div>\n\n <!-- Only show menu if this column is active -->\n <div\n class=\"position-absolute\"\n *ngIf=\"activeCol === col\"\n style=\"top: -50%; z-index: 21\"\n [style.left.px]=\"\n -(!col?.pinned ? centerPinnedHeader.scrollLeft : 0)\n \"\n >\n <ng-container\n *ngTemplateOutlet=\"columnMenu; context: { col: col }\"\n ></ng-container>\n </div>\n\n <div\n class=\"resize-handle\"\n [class.w-100]=\"col.pinned == 'right'\"\n (dblclick)=\"autosizeColumn(col)\"\n (mousedown)=\"onResizeColumn($event, col)\"\n >\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/resize-handle.svg'\n \"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n </div>\n </div>\n </div>\n </div>\n </div>\n\n <!-- Filter Cell -->\n <div\n *ngIf=\"showFilterRow\"\n [style.backgroundColor]=\"headerBackgroundColor\"\n class=\"header-cell filter-cell\"\n [class.border-right]=\"showVerticalBorder\"\n [attr.field]=\"col.field\"\n [style.width.px]=\"col.width\"\n [style.min-width.px]=\"col.width\"\n [style.height.px]=\"headerRowHeight\"\n [style.min-height.px]=\"headerRowHeight\"\n [style.max-height.px]=\"headerRowHeight\"\n >\n <input\n type=\"text\"\n class=\"form-control form-control-sm\"\n placeholder=\"Filter\"\n [(ngModel)]=\"col.filterValue\"\n (ngModelChange)=\"onFilterChange(col)\"\n />\n <span\n class=\"filter-icon-wrapper\"\n (click)=\"$event.stopPropagation(); openFilter(col)\"\n [class.filter-applied]=\"isFilterAppliedOnColumn(col)\"\n ><span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n <span\n *ngIf=\"isFilterAppliedOnColumn(col)\"\n style=\"\n width: 7px;\n height: 7px;\n box-shadow: 0px 0px 3px #7486ff;\n background-color: rgb(0 163 233);\n position: absolute;\n right: 4px;\n top: 12px;\n \"\n class=\"rounded-circle d-block\"\n ></span\n ></span>\n\n <div\n class=\"position-absolute filter-row-filter-wrapper\"\n *ngIf=\"activeFilterCell === col\"\n style=\"top: 100%; right: 0; z-index: 99\"\n [style.left.px]=\"col?.pinned ? 0 : -centerPinnedHeader.scrollLeft\"\n >\n <ng-container\n *ngTemplateOutlet=\"filterMenu; context: { col: col }\"\n ></ng-container>\n </div>\n </div>\n </div>\n </ng-template>\n </div>\n</ng-template>\n\n<!-- -------------------------------------------------------------------------------------------------------------------------------------------------------------------- -->\n<!-- -------------------------------------------------------------------------------------------------------------------------------------------------------------------- -->\n<!-- Body Cell Template -->\n<!-- -------------------------------------------------------------------------------------------------------------------------------------------------------------------- -->\n<!-- -------------------------------------------------------------------------------------------------------------------------------------------------------------------- -->\n\n<ng-template\n #rowCell\n let-row\n let-columns=\"columns\"\n let-isEven=\"isEven\"\n let-isOdd=\"isOdd\"\n let-isLeftSection=\"isLeft\"\n let-section=\"section\"\n let-rowIndex=\"rowIndex\"\n>\n <!-- Check if row is a group -->\n <ng-container\n *ngTemplateOutlet=\"groupRowTemplate; context: { $implicit: row, depth: 0 }\"\n ></ng-container>\n <ng-template #groupRowTemplate let-row let-depth=\"depth\">\n <ng-container *ngIf=\"row.isGroup; else regularRow\">\n <!-- Group Header -->\n <div\n class=\"group-header-row border-below d-flex align-items-center\"\n [style.height.px]=\"rowHeight\"\n [style.width]=\"\n section == 'center'\n ? centerScrollableBody?.nativeElement?.scrollWidth + 'px'\n : '100%'\n \"\n >\n <div\n *ngIf=\"section == 'left'\"\n class=\"h-100 d-flex\"\n [style.width.px]=\"leftPinnedHeader.offsetWidth - 1\"\n [class.row-selected]=\"rowSelectedIndexes.has(row.__virtualIndex)\"\n >\n <div\n *ngIf=\"showSerialNumber\"\n style=\"width: 50px\"\n class=\"d-flex align-items-center h-100 border-right justify-content-end pe-2 s-no\"\n [style.backgroundColor]=\"checkboxesBackgroundColor\"\n [style.width.px]=\"65\"\n [style.cursor]=\"\n 'url(' +\n singleSpaAssetsPath +\n 'data-grid/icons/arrow-right.svg), auto'\n \"\n (mousedown)=\"onRowMouseDown(row.__virtualIndex, $event)\"\n (mouseover)=\"onRowMouseOver(row.__virtualIndex, $event)\"\n >\n {{ row.__virtualIndex }}\n </div>\n <div\n style=\"width: 50px\"\n class=\"d-flex align-items-center justify-content-center h-100 border-right\"\n [style.backgroundColor]=\"checkboxesBackgroundColor\"\n [class.row-selected]=\"rowSelectedIndexes.has(row.__virtualIndex)\"\n [class.left-selection-border]=\"\n rowSelectedIndexes.has(row.__virtualIndex)\n \"\n [class.first-row-selected]=\"firstSelectedRow == row.__virtualIndex\"\n [class.last-row-selected]=\"lastSelectedRow == row.__virtualIndex\"\n >\n <input style=\"width: 16px; height: 16px\" type=\"checkbox\" />\n </div>\n </div>\n\n <div\n *ngIf=\"section == 'center'\"\n [style.width.px]=\"centerPinnedHeader.scrollWidth\"\n class=\"d-flex align-items-center ps-2 h-100\"\n [class.row-selected]=\"rowSelectedIndexes.has(row.__virtualIndex)\"\n [class.first-row-selected]=\"firstSelectedRow == row.__virtualIndex\"\n [class.last-row-selected]=\"lastSelectedRow == row.__virtualIndex\"\n >\n <div\n class=\"d-flex align-items-center justify-content-between\"\n [style.paddingLeft.px]=\"depth > 0 ? depth * 16 : 0\"\n >\n <span class=\"me-2 filter-icon-wrapper\" (click)=\"toggleExpand(row)\">\n <span\n class=\"data-grid-svg-icon\"\n [inlineSVG]=\"\n row.isExpand\n ? singleSpaAssetsPath + 'data-grid/icons/chevron-down.svg'\n : singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\n \"\n ></span>\n </span>\n <strong (click)=\"toggleExpand(row)\" class=\"cursor-pointer\">\n {{ row.groupValue }} ({{ countLeafRows(row) }})\n </strong>\n </div>\n </div>\n\n <div\n *ngIf=\"section == 'right'\"\n [style.width.px]=\"rightPinnedHeader.offsetWidth\"\n [class.row-selected]=\"rowSelectedIndexes.has(row.__virtualIndex)\"\n [class.first-row-selected]=\"firstSelectedRow == row.__virtualIndex\"\n [class.last-row-selected]=\"lastSelectedRow == row.__virtualIndex\"\n ></div>\n </div>\n\n <!-- Recursive Children -->\n <div class=\"group-children\" *ngIf=\"row.isExpand\">\n <ng-container\n *ngFor=\"let child of row.children; let i = index; trackBy: trackById\"\n >\n <ng-container *ngIf=\"child.isGroup; else dataRow\">\n <!-- Recursive call for nested group -->\n <ng-container\n *ngTemplateOutlet=\"\n groupRowTemplate;\n context: { $implicit: child, depth: depth + 1 }\n \"\n ></ng-container>\n </ng-container>\n\n <ng-template #dataRow>\n <!-- Regular data row -->\n <ng-container\n *ngTemplateOutlet=\"\n rowCell;\n context: {\n $implicit: child,\n columns: columns,\n isEven: i % 2 === 0,\n isOdd: i % 2 !== 0,\n isLeft: isLeftSection,\n section: section\n }\n \"\n ></ng-container>\n </ng-template>\n </ng-container>\n </div>\n </ng-container>\n </ng-template>\n\n <!-- Regular row (not a group) -->\n <ng-template #regularRow>\n <div class=\"d-flex\" [style.height.px]=\"rowHeight\">\n <span\n class=\"d-flex align-items-center justify-content-center cursor-pointer border-below\"\n style=\"min-width: 30px; height: 100%;\"\n *ngIf=\"section == 'center' && gridType === 'TimeSheet' && detailsIconPosition === 'start' && !areDatesSelectedAndEqual\"\n [ngStyle]=\"{\n 'background-color':\n hoveredRowId === (row._id || row.id)\n ? rowHoverColor\n : isRowSelected(row)\n ? checkedRowBackgroundColor\n : isEven\n ? evenRowsBackgroundColor\n : oddRowsBackgroundColor\n }\"\n (click)=\"toggleExpand(row)\"\n >\n <span\n class=\"data-grid-svg-icon\"\n [inlineSVG]=\"\n row.isDetailsExpand\n ? singleSpaAssetsPath + 'data-grid/icons/chevron-down.svg'\n : singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\n \"\n ></span>\n </span>\n <div\n [style.min-width.px]=\"\n section == 'center' && groupedColumns!.length ? groupBoxPadding : 0\n \"\n [class.row-selected]=\"rowSelectedIndexes.has(row.__virtualIndex)\"\n [class.first-row-selected]=\"firstSelectedRow == row.__virtualIndex\"\n [class.last-row-selected]=\"lastSelectedRow == row.__virtualIndex\"\n (contextmenu)=\"onRightClick($event, row, row?.details?.data?.length ? 'accordion-parent' : 'main')\"\n [style.height.px]=\"rowHeight\"\n class=\"data-grid-row h-100\"\n [class.even-row]=\"isEven\"\n [class.odd-row]=\"isOdd\"\n [class.hovered-row]=\"hoveredRowId === (row._id || row.id)\"\n (mouseenter)=\"onRowHover(row)\"\n (mouseleave)=\"onRowLeave()\"\n [ngStyle]=\"{\n 'background-color':\n hoveredRowId === (row._id || row.id)\n ? rowHoverColor\n : isRowSelected(row)\n ? checkedRowBackgroundColor\n : isEven\n ? evenRowsBackgroundColor\n : oddRowsBackgroundColor\n }\"\n ></div>\n <div\n (contextmenu)=\"onRightClick($event, row, row?.details?.data?.length ? 'accordion-parent' : 'main')\"\n [style.height.px]=\"rowHeight\"\n class=\"data-grid-row\"\n [class.even-row]=\"isEven\"\n [class.odd-row]=\"isOdd\"\n [class.hovered-row]=\"hoveredRowId === (row._id || row.id)\"\n (mouseenter)=\"onRowHover(row)\"\n (mouseleave)=\"onRowLeave()\"\n [ngStyle]=\"{\n 'background-color':\n hoveredRowId === (row._id || row.id)\n ? rowHoverColor\n : isRowSelected(row)\n ? checkedRowBackgroundColor\n : isEven\n ? evenRowsBackgroundColor\n : oddRowsBackgroundColor\n }\"\n >\n <div\n [style.backgroundColor]=\"checkboxesBackgroundColor\"\n class=\"select-all-checkbox-cell justify-content-end pe-2 s-no\"\n [style.width.px]=\"65\"\n *ngIf=\"isLeftSection && showSerialNumber\"\n [style.cursor]=\"\n 'url(' +\n singleSpaAssetsPath +\n 'data-grid/icons/arrow-right.svg), auto'\n \"\n (mousedown)=\"onRowMouseDown(row.__virtualIndex, $event)\"\n (mouseover)=\"onRowMouseOver(row.__virtualIndex, $event)\"\n >\n {{ row.__virtualIndex }}\n </div>\n <div\n [style.backgroundColor]=\"\n rowSelectedIndexes.has(row.__virtualIndex)\n ? selectedRowsBackgroundColor\n : checkboxesBackgroundColor\n \"\n class=\"select-all-checkbox-cell\"\n *ngIf=\"isLeftSection\"\n [class.left-selection-border]=\"\n rowSelectedIndexes.has(row.__virtualIndex)\n \"\n [class.first-row-selected]=\"firstSelectedRow == row.__virtualIndex\"\n [class.last-row-selected]=\"lastSelectedRow == row.__virtualIndex\"\n >\n <input\n *ngIf=\"hasAnyVisibleColumn\"\n type=\"checkbox\"\n [checked]=\"isRowSelected(row)\"\n (change)=\"toggleRowSelection(row)\"\n />\n </div>\n\n <!-- Render all columns -->\n <ng-container\n *ngFor=\"\n let col of columns;\n trackBy: trackByField;\n let colIndex = index\n \"\n >\n <ng-container *ngIf=\"col.children?.length > 0; else flatColumn\">\n <ng-container\n *ngFor=\"\n let child of col.children;\n trackBy: trackByField;\n let subColIndex = index\n \"\n >\n <ng-container *ngIf=\"child?.is_visible && !child?.isRowGrouped\">\n <ng-container\n *ngTemplateOutlet=\"\n cellTemplate;\n context: {\n col: child,\n row: row,\n rowIndex: rowIndex,\n colIndex: colIndex,\n subColIndex: subColIndex,\n section: section\n }\n \"\n ></ng-container>\n </ng-container>\n </ng-container>\n </ng-container>\n\n <ng-template #flatColumn>\n <ng-container\n *ngTemplateOutlet=\"\n cellTemplate;\n context: {\n col: col,\n row: row,\n rowIndex: rowIndex,\n colIndex: colIndex,\n subColIndex: null,\n section: section\n }\n \"\n ></ng-container>\n </ng-template>\n </ng-container>\n </div>\n\n <span\n class=\"d-flex align-items-center justify-content-center cursor-pointer border-below\"\n style=\"min-width: 30px; height: 100%;\"\n *ngIf=\"section == 'center' && gridType === 'TimeSheet' && detailsIconPosition === 'end' && !areDatesSelectedAndEqual\"\n [ngStyle]=\"{\n 'background-color':\n hoveredRowId === (row._id || row.id)\n ? rowHoverColor\n : isRowSelected(row)\n ? checkedRowBackgroundColor\n : isEven\n ? evenRowsBackgroundColor\n : oddRowsBackgroundColor\n }\"\n (click)=\"toggleExpand(row)\"\n >\n <span\n class=\"data-grid-svg-icon\"\n [inlineSVG]=\"\n row.isDetailsExpand\n ? singleSpaAssetsPath + 'data-grid/icons/chevron-down.svg'\n : singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\n \"\n ></span>\n </span>\n </div>\n <!-- LEFT PINNED: Empty table to keep alignment -->\n <div *ngIf=\"section === 'left' && row.isDetailsExpand && !isSingleDay\" class=\"accordion-details data-grid-accordion-section\" [style.color]=\"headerTextColor\" style=\"max-height: 350px; min-height: 150px ; overflow: hidden;\">\n <table class=\"nested-table table table-sm w-100 mb-0 data-grid-accordion-table\" [class.show-shadow]=\"rowShadingEnabled\">\n <thead>\n <tr [style.height.px]=\"nestedTableHeaderRowHeight\" [style.backgroundColor]=\"headerBackgroundColor\" [style.color]=\"headerTextColor\" [style.fontSize.px]=\"headerTextFontsSize\" [style.fontWeight]=\"headerFontWeight\">\n <th *ngFor=\"let _ of [1, 2, 3, 4, 5]\"></th>\n </tr>\n </thead>\n <tbody>\n <tr [style.height.px]=\"nestedTablerowHeight\" *ngFor=\"let _ of row.details.data\" [style.backgroundColor]=\"headerBackgroundColor\">\n <td *ngFor=\"let __ of [1, 2, 3, 4, 5]\"></td>\n </tr>\n </tbody>\n </table>\n </div>\n\n<!-- CENTER SECTION: Actual details table -->\n\n<div *ngIf=\"section === 'center' && row.isDetailsExpand && !isSingleDay\" class=\"accordion-details-wrapper data-grid-accordion\" [style.fontFamily]=\"fontFaimly\" [style.fontSize.px]=\"bodyTextFontsSize\" style=\"display: flex; width: 100%; max-height: 350px; min-height: 150px ; overflow: hidden ; \">\n <!-- LEFT SECTION OF ACCORDION -->\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;\">\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;\">\n <thead>\n <tr [style.height.px]=\"nestedTableHeaderRowHeight\" [style.backgroundColor]=\"headerBackgroundColor\" [style.color]=\"headerTextColor\" [style.fontSize.px]=\"headerTextFontsSize\" [style.fontWeight]=\"headerFontWeight\">\n <ng-container *ngFor=\"let col of row.details.columns | pinnedColumns:'left'; trackBy: trackByField\">\n <th *ngIf=\"col.is_visible !== false\"\n class=\"px-4\"\n [class.filter-applied]=\"isAccordionColumnFiltered(row, col)\"\n [style.color]=\"isAccordionColumnFiltered(row, col) ? '#007bff' : headerTextColor\"\n [attr.field]=\"col.field\"\n [attr.pinned]=\"col.pinned\"\n [style.width.px]=\"col.width || 200\"\n [style.min-width.px]=\"col.width || 200\">\n <div class=\"d-flex justify-content-between align-items-center\" style=\"width: 100%;\">\n <span class=\"d-flex align-items-center gap-1\" style=\"overflow: hidden; width: 100%;\">\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>\n <span class=\"text-truncate\" style=\"flex: 1; min-width: 0;\" title=\"{{ col.header }}\">{{ col.header }}</span>\n <span *ngIf=\"isAccordionColumnFiltered(row, col)\"\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\"\n class=\"data-grid-svg-icon text-primary ms-1\"\n style=\"font-size: 12px;\"></span>\n </span>\n <span class=\"three-dots p-1\"\n (click)=\"openDetailThreeDotsMenus($event, col, row, $any($event.currentTarget))\">\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/three-dots-vertical.svg'\" class=\"data-grid-svg-icon\"></span>\n </span>\n </div>\n <!-- <div class=\"resize-handles\" (mousedown)=\"onResizeDetailColumn($event, row, col)\">\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/resize-handle.svg'\" class=\"data-grid-svg-icon text-primary\"></span>\n </div> -->\n <ng-container *ngIf=\"activeDetailCol?.field == col.field && activeDetailRow === row\">\n <div class=\"position-absolute detail-column-menu-wrapper\"\n [style.top.px]=\"nestedTableHeaderRowHeight\"\n [style.left.px]=\"0\">\n <ng-container *ngTemplateOutlet=\"detailColumnMenu; context: { col: col, row: row }\"></ng-container>\n </div>\n </ng-container>\n </th>\n </ng-container>\n </tr>\n </thead>\n <tbody>\n <tr [style.height.px]=\"nestedTablerowHeight\" *ngFor=\"let d of row.details.data; let j = index; trackBy: trackById\" [ngStyle]=\"getAccordionRowStyle(j, row)\">\n <ng-container *ngFor=\"let col of row.details.columns | pinnedColumns:'left'; let localK = index; trackBy: trackByField\">\n <td *ngIf=\"col.is_visible !== false\"\n class=\"px-4\"\n (mousedown)=\"startDetailSelection(row, j, localK, col.field, $event, 'left')\"\n (mouseenter)=\"extendDetailSelection(row, j, localK, col.field, $event, 'left')\"\n [class.selected-cell]=\"isDetailCellSelected(row, j, localK, col.field, 'left')\"\n [attr.field]=\"col.field\"\n [attr.pinned]=\"col.pinned\"\n [style.fontSize.px]=\"bodyTextFontsSize\"\n (dblclick)=\"enableDetailEdits(row, d, col)\"\n [class.active-cell-detail]=\"isActiveDetailCell(row, d, col)\">\n <!-- Use the same rendering logic as center section -->\n <ng-container [ngSwitch]=\"col.field\">\n\n <ng-container *ngSwitchCase=\"'manually_logs'\" class=\"d-flex justify-content-start align-items-center pointer position-relative\">\n <ng-container *ngIf=\"d.manually_logs?.length > 0; else noManualLogsIcon\">\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/eye.svg'\"\n class=\"data-grid-svg-icon text-primary\"\n style=\"cursor: pointer; font-size: 16px;\"\n (mouseenter)=\"showManualLogsTooltip($event, row, d)\"\n (mouseleave)=\"hideManualLogsTooltip()\">\n </span>\n </ng-container>\n <ng-template #noManualLogsIcon>\u2013</ng-template>\n</ng-container>\n <!-- Breaks -->\n <ng-container *ngSwitchCase=\"'breaks'\">\n <ng-container *ngIf=\"d[col.field]?.length; else noBreaksLeft\">\n <app-badge-overflow\n [badges]=\"getBreakBadges(d[col.field])\"\n [maxWidth]=\"col.width || 200\"\n (badgeMouseEnter)=\"showBreakTooltip($event.event, $event.badge.data)\"\n (badgeMouseLeave)=\"hideBreakTooltip()\"\n (overflowCountClick)=\"onDetailBadgeOverflowCountClick(col, d)\">\n</app-badge-overflow>\n </ng-container>\n <ng-template #noBreaksLeft>\n <div >\n -\n </div>\n </ng-template>\n </ng-container>\n\n <!-- Short Breaks -->\n <ng-container *ngSwitchCase=\"'short_breaks'\">\n <ng-container *ngIf=\"d[col.field]?.short_break_duration; else noShortBreakLeft\">\n <div (dblclick)=\"onShortBreakClick.emit(d)\">\n <app-badge-overflow\n [badges]=\"getShortBreakBadges(d[col.field])\"\n [maxWidth]=\"col.width || 200\"\n (badgeMouseEnter)=\"showShortBreakTooltip($event.event, d)\"\n (badgeMouseLeave)=\"hideShortBreakTooltip()\"\n (badgeClick)=\"handleShortBreakClick(d, $event)\"\n (overflowCountClick)=\"onDetailBadgeOverflowCountClick(col, d)\">\n </app-badge-overflow>\n </div>\n </ng-container>\n <ng-template #noShortBreakLeft>\n <div >-</div>\n </ng-template>\n </ng-container>\n\n <!-- Short Leave -->\n <!-- Short Leave -->\n<ng-container *ngSwitchCase=\"'short_leave'\">\n <ng-container *ngIf=\"row.short_leave && row.short_leave.length > 0; else noShortLeaveMain\">\n <div class=\"w-100 d-flex main-progress-bar justify-content-center align-items-center\" \n style=\"background-color: rgb(111, 97, 207); height: 20px; border-radius: 4px; position: relative;\"\n (mouseenter)=\"showShortLeaveTooltip($event, row)\"\n (mouseleave)=\"hideShortLeaveTooltip()\">\n <span class=\"d-block\" [style.min-width.%]=\"row.short_leave[0].short_leave_time_percentage\" \n style=\"background-color: rgb(238, 99, 82); height: 100%; border-radius: 4px;\"></span>\n <span style=\"position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); color: white; font-size: 12px; font-weight: bold;\">\n {{ row.short_leave[0].short_leave_time_percentage }}%\n </span>\n </div>\n </ng-container>\n <ng-template #noShortLeaveMain>-</ng-template>\n</ng-container>\n\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()\">\n <div style=\"overflow: hidden; text-overflow: ellipsis; white-space: nowrap; width: 100%;\" [class.restriction-indicator]=\"row.attendance_log_detail?.length > 0\" title=\"{{ d.is_un_restricted ? 'Yes' : 'No' }}\">\n {{ d.is_un_restricted ? 'Yes' : 'No' }}\n </div>\n</div>\n\n <div *ngSwitchCase=\"'is_payroll_processed'\" class=\"d-flex justify-content-start flex-column pointer position-relative\" >\n <div style=\"overflow: hidden; text-overflow: ellipsis; white-space: nowrap; width: 100%;\">\n {{ d.is_payroll_processed ? 'Yes' : 'No' }}\n </div>\n </div>\n\n\n <!-- Status -->\n <ng-container *ngSwitchCase=\"'status'\">\n <ng-container *ngIf=\"getNestedValue(d, col.field); else noStatus\">\n <span class=\"badge\" [class]=\"getStatusBadgeClass(getNestedValue(d, col.field))\">\n {{ transformStatus(getNestedValue(d, col.field)) }}\n </span>\n </ng-container>\n <ng-template #noStatus>-</ng-template>\n</ng-container>\n\n<!-- Attendance Status -->\n<ng-container *ngSwitchCase=\"'attendanceStatus'\">\n <ng-container *ngIf=\"getNestedValue(d, col.field); else noAttendanceStatus\">\n <span class=\"badge\" [class]=\"getAttendanceStatusBadgeClass(getNestedValue(d, col.field))\">\n {{ transformStatus(getNestedValue(d, col.field)) }}\n </span>\n </ng-container>\n <ng-template #noAttendanceStatus>-</ng-template>\n</ng-container>\n\n <!-- Default fallback -->\n <ng-container *ngSwitchDefault>\n <div style=\"overflow: hidden; text-overflow: ellipsis; white-space: nowrap; width: 100%;\" title=\"{{\n col.type === 'date'\n ? (getNestedValue(d, col.field) ? (getNestedValue(d, col.field) | timezoneFormat:prefs:'date') : '-')\n : col.type === 'time'\n ? ((getTimeValue(getNestedValue(d, col.field)) | timezoneFormat:prefs:'time'))\n : (getNestedValue(d, col.field)?.value || getNestedValue(d, col.field)?.name || getNestedValue(d, col.field) || '-')\n }}\">{{ col.type === 'date'\n ? (getNestedValue(d, col.field) ? (getNestedValue(d, col.field) | timezoneFormat:prefs:'date') : '-')\n : col.type === 'time'\n ? ((getTimeValue(getNestedValue(d, col.field)) | timezoneFormat:prefs:'time'))\n : (getNestedValue(d, col.field)?.value || getNestedValue(d, col.field)?.name || getNestedValue(d, col.field) || '-')\n }}</div>\n </ng-container>\n </ng-container>\n </td>\n </ng-container>\n </tr>\n</tbody>\n </table>\n </div>\n\n <!-- CENTER SECTION OF ACCORDION (WITH VIRTUAL SCROLL) -->\n\n<div class=\"accordion-center-section data-grid-accordion-section\" style=\"flex: 1; min-width: 0; display: flex; flex-direction: column; overflow: hidden;\">\n <!-- Header Section -->\n <div class=\"header-container\" style=\"overflow-x: auto; scrollbar-width: none; -ms-overflow-style: none;\" #headerContainer (scroll)=\"syncScroll($event)\">\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%;\">\n <thead>\n <tr\n [style.height.px]=\"nestedTableHeaderRowHeight\"\n cdkDropList\n [cdkDropListData]=\"row?.details.columns\"\n cdkDropListOrientation=\"horizontal\"\n (cdkDropListDropped)=\"dropColumn($event, row)\"\n >\n <ng-container *ngFor=\"let col of row.details.columns; let i = index\">\n <th\n *ngIf=\"col.is_visible !== false && !col.pinned\"\n class=\"px-4\"\n cdkDrag\n [attr.field]=\"col.field\"\n [class.filter-applied]=\"isAccordionColumnFiltered(row, col)\"\n [style.width.px]=\"col.width || 200\"\n [style.min-width.px]=\"col.width || 200\"\n [style.backgroundColor]=\"headerBackgroundColor\"\n [style.color]=\"isAccordionColumnFiltered(row, col) ? '#007bff' : headerTextColor\"\n [style.fontSize.px]=\"headerTextFontsSize\"\n [style.fontWeight]=\"headerFontWeight\"\n style=\"cursor: move; position: relative;\">\n <div class=\"d-flex justify-content-between align-items-center\" style=\"width: 100%;\">\n <span class=\"d-flex align-items-center gap-1\" style=\"overflow: hidden; width: 100%;\">\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>\n <span class=\"text-truncate\" style=\"flex: 1; min-width: 0;\" title=\"{{ col.header }}\">{{ col.header }}</span>\n <span *ngIf=\"isAccordionColumnFiltered(row, col)\"\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\"\n class=\"data-grid-svg-icon text-primary ms-1\"\n style=\"font-size: 12px;\"></span>\n </span>\n <span class=\"three-dots p-1\"\n (click)=\"openDetailThreeDotsMenus($event, col, row, $any($event.currentTarget))\">\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/three-dots-vertical.svg'\" class=\"data-grid-svg-icon\"></span>\n </span>\n </div>\n <!-- <div class=\"resize-handles\" (mousedown)=\"onResizeDetailColumn($event, row, col)\">\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/resize-handle.svg'\" class=\"data-grid-svg-icon text-primary\"></span>\n </div> -->\n <ng-container *ngIf=\"activeDetailCol?.field == col.field && activeDetailRow === row\">\n <div class=\"position-absolute detail-column-menu-wrapper\" [style.top.px]=\"nestedTableHeaderRowHeight\" [style.left.px]=\"0\">\n <ng-container *ngTemplateOutlet=\"detailColumnMenu; context: { col: col, row: row }\"></ng-container>\n </div>\n </ng-container>\n </th>\n </ng-container>\n </tr>\n </thead>\n </table>\n </div>\n\n <!-- Group Badges (if any) -->\n <div *ngIf=\"row.details?.groupedColumns?.length\" class=\"detail-group-badges\">\n <span *ngFor=\"let g of row.details.groupedColumns; trackBy: trackByField\" class=\"badge bg-light text-dark me-1\">\n {{ g.header }}\n <span class=\"ms-1 cursor-pointer\" (click)=\"ungroupDetailColumn(g, row)\" [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/x.svg'\"></span>\n </span>\n </div>\n\n <!-- No Data Message when filtered results are empty -->\n <div *ngIf=\"row.details.data.length === 0\" class=\"d-flex justify-content-center align-items-center\" style=\"flex: 1; min-height: 104px ;\">\n <div class=\"text-center text-muted\">\n <div class=\"mb-2\">\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\" class=\"data-grid-svg-icon text-muted\" style=\"font-size: 24px;\"></span>\n </div>\n <div class=\"fw-bold\">No records found for this filter.</div>\n </div>\n </div>\n\n <!-- Data Table Section with Virtual Scroll -->\n <cdk-virtual-scroll-viewport\n *ngIf=\"row.details.data.length > 0\"\n itemSize=\"{{ nestedTablerowHeight }}\"\n minBufferPx=\"200\"\n maxBufferPx=\"400\"\n class=\"detail-virtual-scroll\"\n [attr.data-detail-row-id]=\"row._id || row.id\"\n style=\"flex: 1; overflow: auto;\"\n #dataContainer\n (scroll)=\"syncVerticalScroll($event)\"\n (scroll)=\"syncScroll($event)\">\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%;\">\n <tbody>\n <tr\n class=\"cursor-pointer data-grid-accordion-row\"\n *cdkVirtualFor=\"let d of row.details.data; trackBy: trackById; let j = index\"\n (contextmenu)=\"onRightClick($event, d, 'accordion-child')\"\n [style.height.px]=\"nestedTablerowHeight\"\n [ngStyle]=\"getAccordionRowStyle(j, row)\">\n <ng-container *ngFor=\"let col of row.details.columns; let k = index\">\n <td\n *ngIf=\"col.is_visible !== false && !col.pinned\"\n class=\"px-4\"\n (mousedown)=\"startDetailSelection(row, j, k, col.field, $event, 'center')\"\n (mouseenter)=\"extendDetailSelection(row, j, k, col.field, $event, 'center')\"\n [class.selected-cell]=\"isDetailCellSelected(row, j, k, col.field, 'center')\"\n [attr.field]=\"col.field\"\n [style.width.px]=\"col.width || 200\"\n [style.min-width.px]=\"col.width || 200\"\n [style.fontSize.px]=\"bodyTextFontsSize\"\n [class.active-cell-detail]=\"isActiveDetailCell(row, d, col)\"\n style=\"cursor: pointer; position: relative; overflow: visible; cursor: cell; \">\n <div class=\"time-sheet-container\" style=\"overflow: visible; display: flex; gap: 4px; align-items: center; height: 100%; \">\n <ng-container *ngIf=\"col.field === 'breaks' || col.field === 'short_breaks'; else defaultDetailCell\">\n <ng-container *ngIf=\"col.field === 'breaks'\">\n <ng-container *ngIf=\"d[col.field]?.length; else noBreaks\">\n <span *ngFor=\"let breakItem of d[col.field]; let breakIndex = index\"\n class=\"circle-value badge-outline break-on text-center\"\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'\"\n (mouseenter)=\"showBreakTooltip($event, breakItem)\"\n (mouseleave)=\"hideBreakTooltip()\">\n {{ breakItem.break_duration }}m\n</span>\n </ng-container>\n <ng-template #noBreaks>\n <div\n \n >\n -\n</div>\n</ng-template>\n</ng-container>\n <ng-container *ngIf=\"col.field === 'short_breaks' && !isDetailEditing(row, d, col)\">\n <ng-container *ngIf=\"d[col.field]?.short_break_duration; else noShortBreak\">\n <div (dblclick)=\"onShortBreakClick.emit(d)\">\n <app-badge-overflow\n [badges]=\"getShortBreakBadges(d[col.field])\"\n [maxWidth]=\"col.width || 200\"\n (badgeMouseEnter)=\"showShortBreakTooltip($event.event, d)\"\n (badgeMouseLeave)=\"hideShortBreakTooltip()\"\n (badgeClick)=\"handleShortBreakClick(d, $event)\"\n (overflowCountClick)=\"onDetailBadgeOverflowCountClick(col, d)\">\n </app-badge-overflow>\n </div>\n </ng-container>\n <ng-template #noShortBreak>\n <div >-</div>\n </ng-template>\n</ng-container>\n <ng-container *ngIf=\"isDetailEditing(row, d, col)\">\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;\" />\n </ng-container>\n </ng-container>\n <ng-template #defaultDetailCell>\n <span class=\"d-flex align-items-center h-100\">\n <ng-container *ngIf=\"!isDetailEditing(row, d, col)\">\n <ng-container [ngSwitch]=\"col.field\">\n <!-- \u2705 SHORT LEAVE: Progress bar in detail rows -->\n <div *ngSwitchCase=\"'short_leave'\" class=\"position-relative\" style=\"min-width: 100px; width: 200px;\">\n <ng-container *ngIf=\"d.short_leave && d.short_leave.length > 0; else noShortLeaveDetail\">\n <div\n class=\"w-100 d-flex main-progress-bar\"\n style=\"background-color: rgb(111, 97, 207); height: 20px; border-radius: 4px; position: relative;\"\n (mouseenter)=\"showShortLeaveTooltip($event, d)\"\n (mouseleave)=\"hideShortLeaveTooltip()\"\n >\n <span\n class=\"d-block\"\n [style.min-width.%]=\"d.short_leave[0].short_leave_time_percentage\"\n style=\"background-color: rgb(238, 99, 82); height: 100%; border-radius: 4px;\"\n ></span>\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>\n </div>\n </ng-container>\n <ng-template #noShortLeaveDetail>\n <div >-</div>\n </ng-template>\n </div>\n\n <!-- Status -->\n<ng-container *ngSwitchCase=\"'status'\">\n <ng-container *ngIf=\"getNestedValue(d, col.field); else noStatus\">\n <span class=\"badge\" [class]=\"getStatusBadgeClass(getNestedValue(d, col.field))\">\n {{ transformStatus(getNestedValue(d, col.field)) }}\n </span>\n </ng-container>\n <ng-template #noStatus>-</ng-template>\n</ng-container>\n\n<!-- Attendance Status -->\n<ng-container *ngSwitchCase=\"'attendanceStatus'\">\n <ng-container *ngIf=\"getNestedValue(d, col.field); else noAttendanceStatus\">\n <span class=\"badge\" [class]=\"getAttendanceStatusBadgeClass(getNestedValue(d, col.field))\">\n {{ transformStatus(getNestedValue(d, col.field)) }}\n </span>\n </ng-container>\n <ng-template #noAttendanceStatus>-</ng-template>\n</ng-container>\n\n <!-- Existing cases -->\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()\">\n <div class=\"popover__wrapper\" style=\"overflow: hidden; text-overflow: ellipsis; white-space: nowrap; width: 100%;\" [class.restriction-indicator]=\"row.attendance_log_detail?.length > 0\">\n {{ d.is_un_restricted ? 'Yes' : 'No' }}\n </div>\n </div>\n\n <div *ngSwitchCase=\"'is_payroll_processed'\" class=\"d-flex justify-content-start flex-column pointer position-relative\" >\n <div style=\"overflow: hidden; text-overflow: ellipsis; white-space: nowrap; width: 100%;\" title=\"{{ d.is_payroll_processed ? 'Yes' : 'No' }}\">\n {{ d.is_payroll_processed ? 'Yes' : 'No' }}\n </div>\n </div>\n <div *ngSwitchCase=\"'manually_logs'\" class=\"d-flex justify-content-start align-items-center pointer position-relative\">\n <ng-container *ngIf=\"d.manually_logs?.length > 0; else noManualLogsIcon\">\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>\n </ng-container>\n <ng-template #noManualLogsIcon>\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>\n </ng-template>\n </div>\n\n <!-- Default fallback -->\n <div *ngSwitchDefault style=\"overflow: hidden; text-overflow: ellipsis; white-space: nowrap; width: 100%;\" title=\"{{\n col.type === 'date'\n ? (getNestedValue(d, col.field) ? (getNestedValue(d, col.field) | timezoneFormat:prefs:'date') : '-')\n : col.type === 'time'\n ? ((getTimeValue(getNestedValue(d, col.field)) | timezoneFormat:prefs:'time'))\n : (getNestedValue(d, col.field)?.value || getNestedValue(d, col.field)?.name || getNestedValue(d, col.field) || '-')\n }}\">\n {{\n col.type === 'date'\n ? (getNestedValue(d, col.field) ? (getNestedValue(d, col.field) | timezoneFormat:prefs:'date') : '-')\n : col.type === 'time'\n ? ((getTimeValue(getNestedValue(d, col.field)) | timezoneFormat:prefs:'time'))\n : (getNestedValue(d, col.field)?.value || getNestedValue(d, col.field)?.name || getNestedValue(d, col.field) || '-')\n }}\n </div>\n</ng-container>\n </ng-container>\n <ng-container *ngIf=\"isDetailEditing(row, d, col)\">\n <ng-container [ngSwitch]=\"col.type\">\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;\" />\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;\" />\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;\" />\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;\" />\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;\" />\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;\">\n <option *ngFor=\"let option of col.column_dropdown_value\" [ngValue]=\"option?.value || option\">\n {{ option?.label || option?.name || option }}\n </option>\n </select>\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;\" />\n </ng-container>\n </ng-container>\n </span>\n </ng-template>\n </div>\n </td>\n </ng-container>\n </tr>\n </tbody>\n </table>\n </cdk-virtual-scroll-viewport>\n</div>\n\n <!-- RIGHT SECTION OF ACCORDION -->\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;\">\n <table class=\"nested-table table-sm mb-0 data-grid-accordion-table\" [class.show-shadow]=\"rowShadingEnabled\" style=\"table-layout: fixed; width: auto;\">\n <thead>\n <tr [style.height.px]=\"nestedTableHeaderRowHeight\" [style.backgroundColor]=\"headerBackgroundColor\" [style.color]=\"headerTextColor\" [style.fontSize.px]=\"headerTextFontsSize\" [style.fontWeight]=\"headerFontWeight\">\n <ng-container *ngFor=\"let col of row.details.columns | pinnedColumns:'right'; trackBy: trackByField\">\n <th *ngIf=\"col.is_visible !== false\"\n class=\"px-4\"\n [class.filter-applied]=\"isAccordionColumnFiltered(row, col)\"\n [style.width.px]=\"col.width || 200\"\n [style.min-width.px]=\"col.width || 200\"\n [style.color]=\"isAccordionColumnFiltered(row, col) ? '#007bff' : headerTextColor\"\n [attr.field]=\"col.field\"\n [attr.pinned]=\"col.pinned\">\n <div class=\"d-flex justify-content-between align-items-center\" style=\"width: 100%;\">\n <span class=\"d-flex align-items-center gap-1\" style=\"overflow: hidden; width: 100%;\">\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/pin-blue.svg'\"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"></span>\n <span class=\"text-truncate\" style=\"flex: 1; min-width: 0;\" title=\"{{ col.header }}\">{{ col.header }}</span>\n <span *ngIf=\"isAccordionColumnFiltered(row, col)\"\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\"\n class=\"data-grid-svg-icon text-primary ms-1\"\n style=\"font-size: 12px;\"></span>\n </span>\n <span class=\"three-dots p-1\"\n (click)=\"openDetailThreeDotsMenus($event, col, row, $any($event.currentTarget))\">\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/three-dots-vertical.svg'\" class=\"data-grid-svg-icon\"></span>\n </span>\n </div>\n\n <!-- <div class=\"resize-handles\" (mousedown)=\"onResizeDetailColumn($event, row, col)\">\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/resize-handle.svg'\" class=\"data-grid-svg-icon text-primary\"></span>\n </div> -->\n <ng-container *ngIf=\"activeDetailCol?.field == col.field && activeDetailRow === row\">\n <div class=\"position-absolute detail-column-menu-wrapper\"\n [style.top.px]=\"nestedTableHeaderRowHeight\"\n [style.left.px]=\"0\">\n <ng-container *ngTemplateOutlet=\"detailColumnMenu; context: { col: col, row: row }\"></ng-container>\n </div>\n </ng-container>\n </th>\n </ng-container>\n </tr>\n </thead>\n <tbody>\n <tr [style.height.px]=\"nestedTablerowHeight\" *ngFor=\"let d of row.details.data; let j = index; trackBy: trackById\" [ngStyle]=\"getAccordionRowStyle(j, row)\">\n <ng-container *ngFor=\"let col of row.details.columns | pinnedColumns:'right'; let localK = index; trackBy: trackByField\">\n <td *ngIf=\"col.is_visible !== false\"\n class=\"px-4\"\n [attr.field]=\"col.field\"\n [attr.pinned]=\"col.pinned\"\n (mousedown)=\"startDetailSelection(row, j, localK, col.field, $event, 'right')\"\n (mouseenter)=\"extendDetailSelection(row, j, localK, col.field, $event, 'right')\"\n [class.selected-cell]=\"isDetailCellSelected(row, j, localK, col.field, 'right')\"\n [style.fontSize.px]=\"bodyTextFontsSize\"\n [class.active-cell-detail]=\"isActiveDetailCell(row, d, col)\">\n <ng-container [ngSwitch]=\"col.field\">\n\n <ng-container *ngSwitchCase=\"'manually_logs'\" class=\"d-flex justify-content-start align-items-center pointer position-relative\">\n <ng-container *ngIf=\"d.manually_logs?.length > 0; else noManualLogsIcon\">\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/eye.svg'\"\n class=\"data-grid-svg-icon text-primary\"\n style=\"cursor: pointer; font-size: 16px;\"\n (mouseenter)=\"showManualLogsTooltip($event, row, d)\"\n (mouseleave)=\"hideManualLogsTooltip()\">\n </span>\n </ng-container>\n <ng-template #noManualLogsIcon>\u2013</ng-template>\n</ng-container>\n <!-- Breaks -->\n <ng-container *ngSwitchCase=\"'breaks'\">\n <ng-container *ngIf=\"d[col.field]?.length; else noBreaksLeft\">\n <app-badge-overflow\n [badges]=\"getBreakBadges(d[col.field])\"\n [maxWidth]=\"col.width || 200\"\n (badgeMouseEnter)=\"showBreakTooltip($event.event, $event.badge.data)\"\n (badgeMouseLeave)=\"hideBreakTooltip()\"\n (overflowCountClick)=\"onDetailBadgeOverflowCountClick(col, d)\">\n</app-badge-overflow>\n </ng-container>\n <ng-template #noBreaksLeft>\n <div>\n -\n </div>\n </ng-template>\n </ng-container>\n\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()\">\n <div style=\"overflow: hidden; text-overflow: ellipsis; white-space: nowrap; width: 100%;\" [class.restriction-indicator]=\"row.attendance_log_detail?.length > 0\" title=\"{{ d.is_un_restricted ? 'Yes' : 'No' }}\">\n {{ d.is_un_restricted ? 'Yes' : 'No' }}\n </div>\n </div>\n\n <div *ngSwitchCase=\"'is_payroll_processed'\" class=\"d-flex justify-content-start flex-column pointer position-relative\" >\n <div style=\"overflow: hidden; text-overflow: ellipsis; white-space: nowrap; width: 100%;\" title=\"{{ d.is_payroll_processed ? 'Yes' : 'No' }}\">\n {{ d.is_payroll_processed ? 'Yes' : 'No' }}\n </div>\n </div>\n\n <!-- Short Breaks -->\n <ng-container *ngSwitchCase=\"'short_breaks'\">\n <ng-container *ngIf=\"d[col.field]?.short_break_duration; else noShortBreakLeft\">\n <div (dblclick)=\"onShortBreakClick.emit(d)\">\n <app-badge-overflow\n [badges]=\"getShortBreakBadges(d[col.field])\"\n [maxWidth]=\"col.width || 200\"\n (badgeMouseEnter)=\"showShortBreakTooltip($event.event, d)\"\n (badgeMouseLeave)=\"hideShortBreakTooltip()\"\n (badgeClick)=\"handleShortBreakClick(d, $event)\"\n (overflowCountClick)=\"onDetailBadgeOverflowCountClick(col, d)\">\n </app-badge-overflow>\n </div>\n </ng-container>\n <ng-template #noShortBreakLeft>\n <div >-</div>\n </ng-template>\n </ng-container>\n\n <!-- Short Leave -->\n <!-- Short Leave -->\n<ng-container *ngSwitchCase=\"'short_leave'\">\n <ng-container *ngIf=\"row.short_leave && row.short_leave.length > 0; else noShortLeaveMain\">\n <div class=\"w-100 d-flex main-progress-bar justify-content-center align-items-center\" \n style=\"background-color: rgb(111, 97, 207); height: 20px; border-radius: 4px; position: relative;\"\n (mouseenter)=\"showShortLeaveTooltip($event, row)\"\n (mouseleave)=\"hideShortLeaveTooltip()\">\n <span class=\"d-block\" [style.min-width.%]=\"row.short_leave[0].short_leave_time_percentage\" \n style=\"background-color: rgb(238, 99, 82); height: 100%; border-radius: 4px;\"></span>\n <span style=\"position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); color: white; font-size: 12px; font-weight: bold;\">\n {{ row.short_leave[0].short_leave_time_percentage }}%\n </span>\n </div>\n </ng-container>\n <ng-template #noShortLeaveMain>-</ng-template>\n</ng-container>\n\n<ng-container *ngSwitchCase=\"'status'\">\n <ng-container *ngIf=\"getNestedValue(d, col.field); else noStatus\">\n <span class=\"badge\" [class]=\"getStatusBadgeClass(getNestedValue(d, col.field))\">\n {{ transformStatus(getNestedValue(d, col.field)) }}\n </span>\n </ng-container>\n <ng-template #noStatus>-</ng-template>\n</ng-container>\n\n<!-- Attendance Status -->\n<ng-container *ngSwitchCase=\"'attendanceStatus'\">\n <ng-container *ngIf=\"getNestedValue(d, col.field); else noAttendanceStatus\">\n <span class=\"badge\" [class]=\"getAttendanceStatusBadgeClass(getNestedValue(d, col.field))\">\n {{ transformStatus(getNestedValue(d, col.field)) }}\n </span>\n </ng-container>\n <ng-template #noAttendanceStatus>-</ng-template>\n</ng-container>\n\n <!-- Default -->\n <ng-container *ngSwitchDefault>\n<div style=\"overflow: hidden; text-overflow: ellipsis; white-space: nowrap; width: 100%;\" title=\"{{\n col.type === 'date'\n ? (getNestedValue(d, col.field) ? (getNestedValue(d, col.field) | timezoneFormat:prefs:'date') : '-')\n : col.type === 'time'\n ? ((getTimeValue(getNestedValue(d, col.field)) | timezoneFormat:prefs:'time'))\n : (getNestedValue(d, col.field)?.value || getNestedValue(d, col.field)?.name || getNestedValue(d, col.field) || '-')\n}}\">{{ col.type === 'date'\n ? (getNestedValue(d, col.field) ? (getNestedValue(d, col.field) | timezoneFormat:prefs:'date') : '-')\n : col.type === 'time'\n ? ((getTimeValue(getNestedValue(d, col.field)) | timezoneFormat:prefs:'time'))\n : (getNestedValue(d, col.field)?.value || getNestedValue(d, col.field)?.name || getNestedValue(d, col.field) || '-')\n}}</div>\n</ng-container>\n</ng-container>\n </td>\n </ng-container>\n </tr>\n</tbody>\n </table>\n\n </div>\n\n <!-- DETAIL SIDE MENU (Sticky on right end) -->\n <!-- <div class=\"detail-side-menu-wrapper\" >\n <div style=\"width: 30px\" class=\"d-flex flex-column align-items-center \">\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\">\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/ui-checks-grid.svg'\" class=\"data-grid-svg-icon\"></span>\n <div class=\"side-menue-text\">Columns</div>\n </div>\n \n </div>\n\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);\">\n <ng-container *ngIf=\"row.details.sideMenu.currentTab === 'cols'\">\n <div class=\"px-3 py-2 border-bottom d-flex align-items-center\">\n <strong class=\"me-auto\">Columns</strong>\n <input type=\"text\" class=\"form-control form-control-sm\" placeholder=\"Search...\" [(ngModel)]=\"row.details.sideMenu.columnSearch\" style=\"width: 120px; font-size: 12px;\" />\n </div>\n <div class=\"side-menu-scrollable\">\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\">\n <input type=\"checkbox\" class=\"form-check-input me-2\" [(ngModel)]=\"col.is_visible\" (change)=\"onDetailColumnVisibilityChange(row)\" />\n <span>{{ col.header }}</span>\n </div>\n </div>\n </ng-container>\n\n <ng-container *ngIf=\"row.details.sideMenu.currentTab === 'filtrs'\">\n <div class=\"px-3 py-2 border-bottom d-flex align-items-center\">\n <strong class=\"me-auto\">Filters</strong>\n <input type=\"text\" class=\"form-control form-control-sm\" placeholder=\"Search...\" [(ngModel)]=\"row.details.sideMenu.columnSearch\" style=\"width: 120px; font-size: 12px;\" />\n </div>\n <div class=\"side-menu-scrollable\">\n <div *ngFor=\"let col of row.details.columns | filter: row.details.sideMenu.columnSearch:'header'; trackBy: trackByField\" class=\"mb-3\">\n <div class=\"d-flex justify-content-between align-items-center cursor-pointer\" (click)=\"col.expandedFilter = !col.expandedFilter\">\n <label class=\"mb-0 small\">{{ col.header }}</label>\n <span class=\"toggle-icon data-grid-svg-icon\" [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\" [class.rotate]=\"col.expandedFilter\"></span>\n </div>\n <div *ngIf=\"col.expandedFilter\" class=\"mt-2 filter-input-container ps-3 pe-3\">\n <ng-container *ngIf=\"col.type === 'dropdown'; else textFilter\">\n <div class=\"p-1\">\n <input\n type=\"text\"\n class=\"form-control form-control-sm mb-2\"\n placeholder=\"Search...\"\n [(ngModel)]=\"col.searchValue\"\n />\n\n <div class=\"form-check mb-1 ms-1\">\n <input\n class=\"form-check-input\"\n type=\"checkbox\"\n [checked]=\"\n row.details.filters[col.field]?._ids?.length == col.column_dropdown_value?.length\n \"\n (change)=\"toggleSelectAllDetailFilters(col, row, $event)\"\n id=\"detail_selectAll_{{ col.field }}\"\n />\n <label class=\"form-check-label\" for=\"detail_selectAll_{{ col.field }}\">\n Select All\n </label>\n </div>\n\n <div class=\"dropdown-options\">\n <div\n class=\"form-check mb-1 ms-1\"\n *ngFor=\"\n let option of col?.column_dropdown_value\n | filter : col.searchValue : 'value';\n trackBy: trackById\n \"\n >\n <input\n class=\"form-check-input\"\n type=\"checkbox\"\n [value]=\"option\"\n [checked]=\"\n row.details.filters[col.field]?._ids?.includes(option?._id || option?.id || option)\n \"\n (change)=\"onDetailOptionToggle(col, option, row)\"\n id=\"detail_option_{{ col.field }}_{{\n option?.id || option?._id || option\n }}\"\n />\n <label\n class=\"form-check-label\"\n [for]=\"\n 'detail_option_' +\n col.field +\n '_' +\n (option?.id || option?._id || option)\n \"\n >\n {{ option.value || option }}\n </label>\n </div>\n </div>\n </div>\n </ng-container>\n\n <ng-template #textFilter>\n <div class=\"filter-text-section\">\n <div class=\"form-group mb-2\">\n <select\n class=\"form-select form-select-sm\"\n [(ngModel)]=\"row.details.filters[col.field].first_condition\"\n (ngModelChange)=\"applyDetailRowFilter(row)\"\n >\n <option value=\"contain\">Contains</option>\n <option value=\"equal\">Equals</option>\n <option value=\"before\">Begins With</option>\n <option value=\"after\">Ends With</option>\n </select>\n </div>\n\n <input\n [type]=\"col.type == 'date' ? 'date' : 'text'\"\n class=\"form-control form-control-sm mb-3\"\n placeholder=\"Value\"\n [(ngModel)]=\"row.details.filters[col.field].first_value\"\n (ngModelChange)=\"applyDetailRowFilter(row)\"\n />\n\n <ng-container *ngIf=\"row.details.filters[col.field]?.first_value\">\n <div class=\"form-group mb-2\">\n <div class=\"form-check form-check-inline\">\n <input\n class=\"form-check-input filter-radio-inputs\"\n type=\"radio\"\n name=\"detail_condition_{{ col.field }}\"\n [(ngModel)]=\"row.details.filters[col.field].condition\"\n (ngModelChange)=\"applyDetailRowFilter(row)\"\n value=\"and\"\n id=\"detail_and_{{ col.field }}\"\n />\n <label class=\"form-check-label\" for=\"detail_and_{{ col.field }}\"\n >AND</label\n >\n </div>\n <div class=\"form-check form-check-inline\">\n <input\n class=\"form-check-input filter-radio-inputs\"\n type=\"radio\"\n name=\"detail_condition_{{ col.field }}\"\n [(ngModel)]=\"row.details.filters[col.field].condition\"\n (ngModelChange)=\"applyDetailRowFilter(row)\"\n value=\"or\"\n id=\"detail_or_{{ col.field }}\"\n />\n <label class=\"form-check-label\" for=\"detail_or_{{ col.field }}\"\n >OR</label\n >\n </div>\n <div class=\"form-check form-check-inline\">\n <input\n class=\"form-check-input filter-radio-inputs\"\n type=\"radio\"\n name=\"detail_condition_{{ col.field }}\"\n [(ngModel)]=\"row.details.filters[col.field].condition\"\n (ngModelChange)=\"applyDetailRowFilter(row)\"\n value=\"none\"\n id=\"detail_none_{{ col.field }}\"\n />\n <label class=\"form-check-label\" for=\"detail_none_{{ col.field }}\"\n >None</label\n >\n </div>\n </div>\n\n <ng-container *ngIf=\"row.details.filters[col.field].condition !== 'none'\">\n <div class=\"form-group mb-2\">\n <select\n class=\"form-select form-select-sm\"\n [(ngModel)]=\"row.details.filters[col.field].second_condition\"\n (ngModelChange)=\"applyDetailRowFilter(row)\"\n >\n <option value=\"contain\">Contains</option>\n <option value=\"equal\">Equals</option>\n <option value=\"before\">Begins With</option>\n <option value=\"after\">Ends With</option>\n </select>\n </div>\n\n <input\n [type]=\"col.type == 'date' ? 'date' : 'text'\"\n class=\"form-control form-control-sm mb-2\"\n placeholder=\"Second Value\"\n [(ngModel)]=\"row.details.filters[col.field].second_value\"\n (ngModelChange)=\"applyDetailRowFilter(row)\"\n />\n </ng-container>\n </ng-container>\n </div>\n </ng-template>\n </div>\n </div>\n </div>\n </ng-container>\n </div>\n </div> -->\n</div>\n\n<!-- Detail Side Menu -->\n\n\n\n<!-- Popover for Restriction Logs (is_un_restricted) -->\n<!-- <div\n *ngIf=\"restrictionTooltipVisible\"\n class=\"popover__content m-l-10 popoverRestriction position-absolute border rounded bg-white p-3\"\n [style.left.px]=\"restrictionTooltipPosition.x\"\n [style.top.px]=\"restrictionTooltipPosition.y\"\n (mouseenter)=\"preventRestrictionTooltipHide()\"\n (mouseleave)=\"hideRestrictionTooltip()\"\n style=\"z-index: 1000; min-width: 300px; font-size: 12px;\"\n @tooltipAnimation\n>\n <div class=\"modal-area px-0 py-0\">\n <div class=\"table-responsive\">\n <table class=\"table table-row-primary-100 gs-0 gy-2 mb-0\">\n <thead>\n <tr class=\"fw-bolder text-muted bg-light\">\n <th class=\"center ps-2\">Clock in</th>\n <th class=\"center\">Clock out</th>\n <th class=\"center\">Log Hr</th>\n <th class=\"center\">Log Min</th>\n <th class=\"center pe-2\">Status</th>\n </tr>\n </thead>\n <tbody>\n <tr *ngFor=\"let item of currentRestrictionLogs\">\n <td class=\"center ps-2\">\n <span class=\"text-primary\"> {{ item?.clock_in_time | date:'shortTime'}}</span>\n </td>\n <td class=\"center\">\n <span class=\"text-primary\">{{ item?.clock_out_time | date:'shortTime'}}</span>\n </td>\n <td class=\"center\">\n <span class=\"text-primary\">{{ item?.logged_hours }}</span>\n </td>\n <td class=\"center\">\n <span class=\"text-primary\">{{ item?.logged_minutes }}</span>\n </td>\n <td class=\"center\">\n <span class=\"badge bg-light text-dark border\">\n {{ item?.status ? (item.status | titlecase) : 'N/A' }}\n </span>\n </td>\n </tr>\n </tbody>\n </table>\n </div>\n </div>\n</div> -->\n\n<!-- Popover for Manual Logs -->\n<!-- <div\n *ngIf=\"manualLogsTooltipVisible\"\n class=\"popover__content position-absolute border rounded bg-white p-3\"\n [style.left.px]=\"manualLogsTooltipPosition.x\"\n [style.top.px]=\"manualLogsTooltipPosition.y\"\n (mouseenter)=\"preventManualLogsTooltipHide()\"\n (mouseleave)=\"hideManualLogsTooltip()\"\n style=\"z-index: 1000; min-width: 500px; font-size: 12px;\"\n @tooltipAnimation\n>\n <div class=\"modal-area px-0 py-0\">\n <ng-container *ngIf=\"currentManualLogs.length > 0; else noManualLogs\">\n <div class=\"table-responsive\">\n <table class=\"table table-row-primary-100 gs-0 gy-2 mb-0\">\n <thead>\n <tr class=\"fw-bolder text-muted bg-light\">\n <th class=\"center ps-2\" style=\"width: 18%;\">Name</th>\n <th class=\"center\">Date/Time</th>\n <th class=\"center\">Previous Time</th>\n <th class=\"center\">Updated Time</th>\n <th class=\"center\">Status</th>\n <th class=\"center pe-2\">Remarks</th>\n </tr>\n </thead>\n <tbody>\n <tr *ngFor=\"let log of currentManualLogs\">\n <td class=\"center ps-2\">\n <span class=\"text-primary\">{{ log.name }}</span>\n </td>\n <td class=\"center\">\n <span class=\"text-primary\">{{ log.date_time }}</span>\n </td>\n <td class=\"center\">\n <span class=\"text-primary\">{{ log.previous_time }}</span>\n </td>\n <td class=\"center\">\n <span class=\"text-primary\">{{ log.updated_time }}</span>\n </td>\n <td class=\"center\">\n <span class=\"badge bg-light text-dark border\">\n {{ log.log_status ? (log.log_status | titlecase) : 'N/A' }}\n </span>\n </td>\n <td class=\"center pe-2\">\n <span class=\"text-primary\">{{ log.remarks }}</span>\n </td>\n </tr>\n </tbody>\n </table>\n </div>\n </ng-container>\n </div>\n\n <ng-template #noManualLogs>\n <div class=\"text-center p-3\">\n <p class=\"text-muted mb-0\">No manual logs available for this record.</p>\n </div>\n </ng-template>\n</div> -->\n\n\n\n\n<!-- Existing Custom Tooltip for Breaks -->\n\n\n\n\n\n <!-- RIGHT PINNED: Empty table to keep alignment -->\n <div *ngIf=\"section === 'right' && row.isDetailsExpand && !isSingleDay\" class=\"accordion-details data-grid-accordion-section\" style=\"max-height: 350px; min-height: 150px ; overflow: hidden;\">\n <table class=\"nested-table table table-sm w-100 mb-0 data-grid-accordion-table\" [class.show-shadow]=\"rowShadingEnabled\">\n <thead>\n <tr [style.height.px]=\"nestedTableHeaderRowHeight\" [style.backgroundColor]=\"headerBackgroundColor\">\n <th *ngFor=\"let _ of [1, 2, 3, 4, 5]\">&nbsp;</th>\n </tr>\n </thead>\n <tbody>\n <tr [style.height.px]=\"nestedTablerowHeight\" *ngFor=\"let _ of row.details.data\" [style.backgroundColor]=\"headerBackgroundColor\">\n <td *ngFor=\"let __ of [1, 2, 3, 4, 5]\">&nbsp;</td>\n </tr>\n </tbody>\n </table>\n </div>\n\n </ng-template>\n</ng-template>\n\n<!-- Actual Cell is Here -->\n<ng-template\n #cellTemplate\n let-col=\"col\"\n let-row=\"row\"\n let-section=\"section\"\n let-subColIndex=\"subColIndex\"\n let-rowIndex=\"rowIndex\"\n let-colIndex=\"colIndex\"\n>\n <div\n (click)=\"disableEdit(row, col); setActiveCell(row, col)\"\n [style.fontWeight]=\"bodyFontWeight\"\n [class.border-right]=\"showVerticalBorder\"\n class=\"cell overflow-visible position-relative\"\n [attr.field]=\"col.field\"\n [style.width.px]=\"col.width\"\n [style.min-width.px]=\"col.width\"\n [style.fontSize.px]=\"bodyTextFontsSize\"\n [class.active-cell]=\"\n isActiveCell(row, col) && !isEditing(row, col) && selectedKeys.size == 1\n \"\n (dblclick)=\"$event.preventDefault(); enableEdit(row, col)\"\n [class.row-selected]=\"rowSelectedIndexes.has(row.__virtualIndex)\"\n [class.first-row-selected]=\"firstSelectedRow === row.__virtualIndex\"\n [class.last-row-selected]=\"lastSelectedRow === row.__virtualIndex\"\n tabindex=\"0\"\n (keydown.enter)=\"$event.preventDefault(); enableEdit(row, col)\"\n (mousedown)=\"\n startSelection(\n row.__virtualIndex,\n colIndex,\n subColIndex ?? 0,\n col.field,\n $event,\n section\n )\n \"\n (mouseenter)=\"\n extendSelection(\n row.__virtualIndex,\n colIndex,\n subColIndex ?? 0,\n col.field,\n $event,\n section\n )\n \"\n (mouseup)=\"endSelection()\"\n [class.selected-cell]=\"\n isSelected(\n row.__virtualIndex,\n colIndex,\n subColIndex ?? 0,\n col.field,\n section\n )\n \"\n [class.top-border]=\"\n isTopBorder(row.__virtualIndex, colIndex, subColIndex, section)\n \"\n [class.bottom-border]=\"\n isBottomBorder(row.__virtualIndex, colIndex, subColIndex, section)\n \"\n [class.left-border]=\"\n isLeftBorder(row.__virtualIndex, colIndex, subColIndex, section)\n \"\n [class.right-border]=\"\n isRightBorder(row.__virtualIndex, colIndex, subColIndex, section)\n \"\n [class.top-left-corner]=\"\n isTopLeftCorner(row.__virtualIndex, colIndex, subColIndex, section)\n \"\n [class.top-right-corner]=\"\n isTopRightCorner(row.__virtualIndex, colIndex, subColIndex, section)\n \"\n [class.bottom-left-corner]=\"\n isBottomLeftCorner(row.__virtualIndex, colIndex, subColIndex, section)\n \"\n [class.bottom-right-corner]=\"\n isBottomRightCorner(row.__virtualIndex, colIndex, subColIndex, section)\n \"\n >\n <!-- (mousedown)=\"startSelection(row.__virtualIndex, colIndex, subColIndex ?? 0, col.field, $event)\"\n (mouseenter)=\"extendSelection(row.__virtualIndex, colIndex, subColIndex ?? 0, col.field, $event)\"\n (mouseup)=\"endSelection()\"\n [class.selected-cell]=\"isSelected(row.__virtualIndex, colIndex, subColIndex ?? 0, col.field)\" -->\n <div class=\"table-cell\" [class.active-for-editing]=\"isEditing(row, col) && getNestedValue(row, col.field)?.length <= 50\">\n <div\n (click)=\"$event.stopPropagation()\"\n *ngIf=\"isEditing(row, col) && getNestedValue(row, col.field)?.length <= 50; else viewMode\"\n >\n <ng-container [ngSwitch]=\"col.type\">\n <!-- Text Input -->\n <input\n [style.height.px]=\"rowHeight - 10\"\n *ngSwitchCase=\"'input'\"\n type=\"text\"\n [(ngModel)]=\"row[col.field]\"\n (blur)=\"disableEdit(row, col)\"\n autofocus\n class=\"form-control form-control-sm\"\n (mousedown)=\"$event.stopPropagation()\"\n />\n\n <!-- Number Input -->\n <input\n [style.height.px]=\"rowHeight - 8\"\n *ngSwitchCase=\"'number'\"\n #numberInput=\"ngModel\"\n #numberRef\n (keypress)=\"allowOnlyNumbers($event)\"\n type=\"number\"\n required\n [(ngModel)]=\"row[col.field]\"\n (blur)=\"disableEdit(row, col)\"\n autofocus\n (keydown.enter)=\"numberRef.blur()\"\n class=\"form-control form-control-sm\"\n [ngClass]=\"{\n 'is-invalid': numberInput.invalid\n }\"\n (mousedown)=\"$event.stopPropagation()\"\n />\n\n <!-- Date Input -->\n <input\n [style.height.px]=\"rowHeight - 8\"\n *ngSwitchCase=\"'date'\"\n type=\"date\"\n [(ngModel)]=\"row[col.field]\"\n (blur)=\"disableEdit(row, col)\"\n autofocus\n class=\"form-control form-control-sm\"\n #dateInput=\"ngModel\"\n [ngClass]=\"{\n 'is-invalid': dateInput.invalid\n }\"\n (mousedown)=\"$event.stopPropagation()\"\n />\n\n <!-- Dropdown -->\n <!-- ng-select like dropdown -->\n <div\n *ngSwitchCase=\"'dropdown'\"\n class=\"dropdown w-100\"\n (blur)=\"disableEdit(row, col)\"\n >\n <!-- Trigger -->\n <button\n class=\"form-select form-select-sm text-start w-100 text-ellipsis\"\n type=\"button\"\n data-bs-toggle=\"dropdown\"\n aria-expanded=\"false\"\n [style.minHeight.px]=\"rowHeight - 10\"\n data-bs-display=\"static\"\n (mousedown)=\"$event.stopPropagation()\"\n >\n <ng-container>\n {{\n getNestedValue(row, col.field)?.value ||\n getNestedValue(row, col.field)?.name ||\n getNestedValue(row, col.field)\n }}\n </ng-container>\n <ng-template #placeholder> Select options... </ng-template>\n </button>\n\n <!-- Menu -->\n <div\n class=\"dropdown-menu w-100 p-0 cell-editing-dropdown-menu rounded-3\"\n [class.show]=\"isEditing(row, col)\"\n >\n <!-- Search -->\n <div class=\"px-2 py-1\">\n <input\n type=\"text\"\n class=\"form-control form-control-sm\"\n placeholder=\"Search...\"\n [(ngModel)]=\"editinDropdownSearch\"\n />\n </div>\n\n <!-- Options -->\n <div\n class=\"cell-editin-dropdown\"\n style=\"max-height: 200px; overflow: auto\"\n >\n <div\n (click)=\"\n setNestedValue(row, col, option, true);\n disableEdit(row, col)\n \"\n class=\"px-2 py-1 d-flex align-items-center item\"\n *ngFor=\"\n let option of col.column_dropdown_value\n | filter : editinDropdownSearch : 'value'\n \"\n >\n <label\n class=\"form-check-label d-flex align-items-center mb-0\"\n [for]=\"col.field + '-' + option.value || option\"\n >\n {{ option.value || option }}\n </label>\n </div>\n </div>\n </div>\n </div>\n\n <input\n *ngSwitchCase=\"'email'\"\n [style.height.px]=\"rowHeight - 10\"\n [style.maxHeight.px]=\"rowHeight - 10\"\n #emailModel=\"ngModel\"\n #emailInput\n type=\"email\"\n [(ngModel)]=\"row[col.field]\"\n name=\"{{ col.field }}\"\n required\n pattern=\"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$\"\n (blur)=\"disableEdit(row, col, emailModel)\"\n (keydown.enter)=\"\n emailModel.control.markAsTouched(); emailInput.blur()\n \"\n autofocus\n class=\"form-control form-control-sm\"\n [ngClass]=\"{\n 'is-invalid': emailModel.invalid\n }\"\n (mousedown)=\"$event.stopPropagation()\"\n />\n <!-- Default fallback -->\n <input\n *ngSwitchDefault\n [style.height.px]=\"rowHeight - 10\"\n [style.maxHeight.px]=\"rowHeight - 10\"\n #textModel=\"ngModel\"\n #textInput\n type=\"text\"\n [(ngModel)]=\"row[col.field]\"\n name=\"{{ col.field }}\"\n required\n (blur)=\"disableEdit(row, col, textModel)\"\n (keydown.enter)=\"\n textModel.control.markAsTouched(); textInput.blur()\n \"\n autofocus\n class=\"form-control form-control-sm\"\n [ngClass]=\"{\n 'is-invalid': textModel.invalid\n }\"\n (mousedown)=\"$event.stopPropagation()\"\n />\n </ng-container>\n </div>\n\n <!-- Display mode -->\n <ng-template #viewMode>\n <div\n class=\"d-flex justify-between items-center w-100\"\n [ngClass]=\"getCellClasses(col, getNestedValue(row, col.field))\"\n >\n <!-- Text cell -->\n <div class=\"d-flex align-items-center w-100\">\n <div\n #cellText\n class=\"text-ellipsis flex-grow-1\"\n \n >\n <ng-container *ngIf=\"col.type !== 'image'\">\n <ng-container [ngSwitch]=\"col.field\">\n <!-- Breaks -->\n <ng-container *ngSwitchCase=\"'breaks'\">\n <ng-container *ngIf=\"getNestedValue(row, 'breaks')?.length; else noBreaksMain\">\n <app-badge-overflow\n [badges]=\"getBreakBadges(getNestedValue(row, 'breaks'))\"\n [maxWidth]=\"col.width || 200\"\n (badgeMouseEnter)=\"showBreakTooltip($event.event, $event.badge.data)\"\n (badgeMouseLeave)=\"hideBreakTooltip()\"\n (overflowCountClick)=\"onBadgeOverflowCountClick(col)\">\n </app-badge-overflow>\n </ng-container>\n <ng-template #noBreaksMain>\n <div >\n -\n </div>\n </ng-template>\n </ng-container>\n\n <!-- Short Breaks -->\n <ng-container *ngSwitchCase=\"'short_breaks'\">\n <ng-container *ngIf=\"row.short_breaks?.short_break_duration && row.short_breaks.short_break_duration > 0; else noShortBreak\">\n <div (dblclick)=\"onShortBreakClick.emit(row)\"> <app-badge-overflow\n [badges]=\"getShortBreakBadges(row.short_breaks)\"\n [maxWidth]=\"col.width || 200\"\n (badgeMouseEnter)=\"showShortBreakTooltip($event.event, row)\"\n (badgeMouseLeave)=\"hideShortBreakTooltip()\"\n (badgeClick)=\"handleShortBreakClick(row, $event)\"\n (overflowCountClick)=\"onShortBreakOverflowCountClick(col)\">\n </app-badge-overflow> </div>\n \n \n </ng-container>\n <ng-template #noShortBreak>\n <div >-</div>\n </ng-template>\n </ng-container>\n\n <!-- Short Leave -->\n <!-- Short Leave -->\n<ng-container *ngSwitchCase=\"'short_leave'\">\n <ng-container *ngIf=\"row.short_leave && row.short_leave.length > 0; else noShortLeaveMain\">\n <div class=\"w-100 d-flex main-progress-bar justify-content-center align-items-center\" \n style=\"background-color: rgb(111, 97, 207); height: 20px; border-radius: 4px; position: relative;\"\n (mouseenter)=\"showShortLeaveTooltip($event, row)\"\n (mouseleave)=\"hideShortLeaveTooltip()\">\n <span class=\"d-block\" [style.min-width.%]=\"row.short_leave[0].short_leave_time_percentage\" \n style=\"background-color: rgb(238, 99, 82); height: 100%; border-radius: 4px;\"></span>\n <span style=\"position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); color: white; font-size: 12px; font-weight: bold;\">\n {{ row.short_leave[0].short_leave_time_percentage }}%\n </span>\n </div>\n </ng-container>\n <ng-template #noShortLeaveMain>-</ng-template>\n</ng-container>\n\n <!-- Status -->\n <ng-container *ngSwitchCase=\"'status'\">\n <span class=\"badge\" [class]=\"getStatusBadgeClass(getNestedValue(row, col.field))\">\n {{ transformStatus(getNestedValue(row, col.field)) || '-' }}\n </span>\n </ng-container>\n\n <!-- Attendance Status -->\n <ng-container *ngSwitchCase=\"'attendanceStatus'\">\n <span class=\"badge\" [class]=\"getAttendanceStatusBadgeClass(getNestedValue(row, col.field))\">\n {{ transformStatus(getNestedValue(row, col.field)) || '-' }}\n </span>\n </ng-container>\n\n <!-- Payroll Processed -->\n <ng-container *ngSwitchCase=\"'is_payroll_processed'\">\n <span class=\"badge\" [class]=\"getNestedValue(row, col.field) ? 'badge-success' : 'badge-secondary'\">\n {{ getNestedValue(row, col.field) ? 'Yes' : 'No' }}\n </span>\n </ng-container>\n\n <!-- Restriction -->\n <ng-container *ngSwitchCase=\"'is_un_restricted'\">\n <span class=\"badge\" [class]=\"getNestedValue(row, col.field) ? 'badge-success' : 'badge-secondary'\">\n {{ getNestedValue(row, col.field) ? 'Yes' : 'No' }}\n </span>\n </ng-container>\n\n <!-- Default -->\n <ng-container *ngSwitchDefault>\n {{\n !isNestedValueArray(row, col.field)\n ? col.type === 'date'\n ? (isDate(getNestedValue(row, col.field))\n ? ((getNestedValue(row, col.field)) | timezoneFormat:prefs:'date' )\n : (getNestedValue(row, col.field)?.value ||\n getNestedValue(row, col.field)?.name ||\n getNestedValue(row, col.field) ||\n '-'))\n : col.type === 'time'\n ? ((getTimeValue(getNestedValue(row, col.field)) | timezoneFormat:prefs:'time'))\n : (getNestedValue(row, col.field)?.value ||\n getNestedValue(row, col.field)?.name ||\n getNestedValue(row, col.field) ||\n '-')\n : (getNestedValue(row, col.field)?.[0]?.department_name ||\n getNestedValue(row, col.field)?.[0]?.roleName ||\n '-')\n }}\n </ng-container>\n </ng-container>\n </ng-container>\n <ng-container *ngIf=\"col.type == 'image'\">\n <ng-container\n *ngTemplateOutlet=\"\n defaultImagePlaceholder;\n context: {\n row: row,\n col: col,\n }\n \"\n ></ng-container>\n </ng-container>\n </div>\n\n <!-- Active dot and eye icon for employee name -->\n <span *ngIf=\"col.field === 'User' && hasManualLogs(row) && !row.isDetailsExpand\" class=\"badge badge-dot badge-success ms-1\" (mouseenter)=\"showManualLogsTooltip($event, row, row)\"></span>\n <i *ngIf=\"col.field === 'User' && hasManualLogs(row)\" class=\"bi bi-eye ms-1\" (mouseenter)=\"showManualLogsTooltip($event, row, row)\"></i>\n </div>\n\n <!-- Expand / Collapse icon for multiple data showing in one coll-->\n\n <!-- <span\n *ngIf=\"\n (isOverflowing(cellText) &&\n showCellDetailsBox &&\n getNestedValue(row, col.field)?.length > 50) ||\n (isNestedValueArray(row, col.field) &&\n getNestedValue(row, col.field)?.length > 1)\n \"\n class=\"toggle-icon data-grid-svg-icon ms-2 cursor-pointer\"\n [inlineSVG]=\"\n isExpanded(row, col)\n ? singleSpaAssetsPath + 'data-grid/icons/chevron-down.svg'\n : singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\n \"\n (click)=\"\n $event.stopPropagation();\n toggleExpandOfLongCellText(row, col, columns, true)\n \"\n (dblclick)=\"$event.preventDefault(); $event.stopPropagation()\"\n ></span> -->\n </div>\n\n <!-- Expanded text -->\n <div\n class=\"position-absolute w-100\"\n *ngIf=\"isExpanded(row, col)\"\n [style.zIndex]=\"getZIndex(row, col)\"\n style=\"top: 100%; left: 0\"\n >\n <ng-container\n *ngTemplateOutlet=\"\n fullTextTemplate;\n context: {\n row: row,\n col: col,\n isArray: isNestedValueArray(row, col.field)\n }\n \"\n ></ng-container>\n </div>\n </ng-template>\n\n\n \n\n\n\n </div>\n </div>\n</ng-template>\n\n<div\n *ngIf=\"currentBreakTooltip\"\n class=\"custom-break-tooltip\"\n [style.--tooltip-x.px]=\"tooltipPosition.x\"\n [style.--tooltip-y.px]=\"tooltipPosition.y\"\n @tooltipAnimationBottom\n>\n <div class=\"break-tooltip-header\">\n <strong>{{ currentBreakTooltip.break_type?.data_value_name || 'Break' }}</strong>\n <span class=\"text-muted ms-2\">\n {{ currentBreakTooltip.breakInstatus === 'breakOut' ? 'Taken' : 'On Break' }}\n </span>\n </div>\n\n <div class=\"break-tooltip-body\">\n <div>\n <i class=\"bi bi-play-circle\"></i>\n In: {{ currentBreakTooltip.break_in_time | timezoneFormat:prefs:'time' }}\n </div>\n \n <div>\n <i class=\"bi bi-stop-circle\"></i>\n Out: {{ currentBreakTooltip.break_out_time | timezoneFormat:prefs:'time' }}\n </div>\n \n <div>\n <i class=\"bi bi-clock\"></i>\n Duration: {{ currentBreakTooltip.break_duration }} min\n </div>\n </div>\n</div>\n\n\n\n\n\n<!-- Short Break Tooltip -->\n<!-- Short Break Tooltip (Table Format) -->\n<div\n *ngIf=\"currentShortBreakTooltip\"\n class=\"custom-break-tooltip\"\n [style.--tooltip-x.px]=\"tooltipPosition.x\"\n [style.--tooltip-y.px]=\"tooltipPosition.y\"\n @tooltipAnimationBottom\n>\n <div class=\"break-tooltip-header\">\n <strong>{{ currentShortBreakTooltip.name }}</strong>\n </div>\n <div class=\"break-tooltip-body\">\n <table class=\"short-break-table\">\n <thead>\n <tr>\n <th>Start Time</th>\n <th>End Time</th>\n <th>Duration</th>\n </tr>\n </thead>\n <tbody>\n <tr *ngFor=\"let detail of currentShortBreakTooltip.details\">\n <td>\n {{\n detail.start_time\n ? (detail.start_time | timezoneFormat:prefs:'time')\n : 'N/A'\n }}\n </td>\n <td>\n {{\n detail.end_time\n ? (detail.end_time | timezoneFormat:prefs:'time')\n : 'N/A'\n }}\n </td>\n <td>{{ detail.duration }} min</td>\n </tr>\n <tr *ngIf=\"currentShortBreakTooltip.details.length === 0\">\n <td colspan=\"3\" class=\"text-center text-muted\">No timing details</td>\n </tr>\n </tbody>\n </table>\n </div>\n</div>\n\n\n\n\n<!-- Headers Action List On clicking three dots -->\n\n<ng-template #columnMenu let-col=\"col\">\n <div\n class=\"column-menu three-dots-col-menu\"\n [class.visually-hidden]=\"isMenueHidden\"\n *ngIf=\"activeCol && !isThreeDotsFilterOpen && !loading\"\n [style.backgroundColor]=\"dropdownsBackgroundColor\"\n >\n <!-- Sort Ascending -->\n <div class=\"border-below pb-2\" [class.disable-sorting]=\"!col.is_sortable\">\n <span class=\"muted-text fs-7\" style=\"margin-left: 12px\">Sort</span>\n <div\n *ngIf=\"\n columnThreedotsMunuConfig?.showAscending &&\n (sortingConfig?.field != col.field ||\n sortingConfig?.order_by == 'desc')\n \"\n class=\"column-menu-item\"\n (click)=\"sortAsc(activeCol)\"\n >\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrow-up.svg'\"\n class=\"data-grid-svg-icon me-2\"\n ></span>\n Sort Ascending\n </div>\n\n <!-- Sort Descending -->\n <div\n *ngIf=\"\n columnThreedotsMunuConfig?.showDescending &&\n (sortingConfig?.field != col.field ||\n sortingConfig?.order_by == 'asc')\n \"\n class=\"column-menu-item\"\n (click)=\"sortDesc(activeCol)\"\n >\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrow-down.svg'\"\n class=\"data-grid-svg-icon me-2\"\n ></span>\n Sort Descending\n </div>\n\n <div\n *ngIf=\"\n sortingConfig?.field === col.field &&\n (sortingConfig?.order_by === 'asc' ||\n sortingConfig?.order_by === 'desc')\n \"\n class=\"column-menu-item\"\n (click)=\"resetSort(activeCol)\"\n >\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/arrow-counterclockwise.svg'\n \"\n class=\"data-grid-svg-icon me-2\"\n ></span>\n Reset Sort\n </div>\n </div>\n <div class=\"py-2 border-below three-dots-filter\">\n <div\n *ngIf=\"columnThreedotsMunuConfig?.showFilter && !(col.is_search_able === false )\"\n class=\"column-menu-item three-dots-filter\"\n (click)=\"openFilteronThreeDotsClick(col)\"\n >\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\"\n class=\"data-grid-svg-icon me-2\"\n ></span>\n Filter\n </div>\n </div>\n\n <div class=\"py-2 border-below\">\n <span class=\"muted-text fs-7\" style=\"margin-left: 12px\">Pin</span>\n <div\n *ngIf=\"columnThreedotsMunuConfig?.showPinleft && col?.pinned !== 'left'\"\n class=\"column-menu-item\"\n (click)=\"updateColumnPinInSourceByField(activeCol, 'left')\"\n >\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/pin-left.svg'\"\n class=\"data-grid-svg-icon me-2\"\n ></span\n >Pin Left\n </div>\n\n <div\n *ngIf=\"\n columnThreedotsMunuConfig?.showPinright && col?.pinned !== 'right'\n \"\n class=\"column-menu-item\"\n (click)=\"updateColumnPinInSourceByField(activeCol, 'right')\"\n >\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/pin-right.svg'\"\n class=\"data-grid-svg-icon data-grid-svg-icon me-2\"\n ></span\n >Pin Right\n </div>\n\n <div\n *ngIf=\"col?.pinned\"\n class=\"column-menu-item\"\n (click)=\"updateColumnPinInSourceByField(activeCol, null)\"\n >\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/layout-three-columns.svg'\n \"\n class=\"data-grid-svg-icon me-2\"\n ></span\n >Unpin\n </div>\n </div>\n\n <div\n *ngIf=\"columnThreedotsMunuConfig?.showAutosizeThisColumn\"\n class=\"column-menu-item\"\n (click)=\"autosizeColumn(activeCol)\"\n >\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/arrows-expand-vertical.svg'\n \"\n class=\"me-2\"\n ></span>\n Autosize This Column\n </div>\n\n <!-- Autosize All Columns -->\n <div\n *ngIf=\"columnThreedotsMunuConfig?.showAutosizeAllColumns\"\n class=\"column-menu-item\"\n (click)=\"autosizeAllColumns()\"\n >\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/arrows-angle-expand.svg'\n \"\n class=\"data-grid-svg-icon me-2\"\n ></span\n >Autosize All Columns\n </div>\n\n <!-- Group By -->\n <div\n *ngIf=\"showRowsGrouping && !(col.is_groupable === false)\"\n class=\"column-menu-item\"\n (click)=\"groupBy(activeCol)\"\n >\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/diagram-3.svg'\"\n class=\"data-grid-svg-icon me-2\"\n ></span>\n Group by {{ col.header }}\n </div>\n\n <!-- Choose Columns -->\n <!-- <div\n *ngIf=\"columnThreedotsMunuConfig?.showChoseColumns\"\n class=\"column-menu-item\"\n (click)=\"chooseColumns()\"\n >\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/ui-checks-grid.svg'\"\n class=\"data-grid-svg-icon me-2\"\n ></span>\n Choose Columns\n </div> -->\n\n <!-- Reset Columns -->\n <!-- <div\n *ngIf=\"columnThreedotsMunuConfig?.showResetColumns\"\n class=\"column-menu-item\"\n (click)=\"resetColumns()\"\n >\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/arrow-counterclockwise.svg'\n \"\n class=\"data-grid-svg-icon me-2\"\n ></span\n >Reset Columns\n </div> -->\n </div>\n <div *ngIf=\"isThreeDotsFilterOpen\" class=\"three-dots-col-menu position-relative\" [style.left.px]=\"-140\" >\n <ng-container\n *ngTemplateOutlet=\"filterMenu; context: { col: col }\"\n ></ng-container>\n </div>\n</ng-template>\n\n\n\n<!-- Filter Menue -->\n<ng-template #filterMenu let-col=\"col\">\n <div\n class=\"filter-menu-container filter-menu\"\n [style.backgroundColor]=\"dropdownsBackgroundColor\"\n >\n <!-- Dropdown Type -->\n <ng-container *ngIf=\"col.type === 'dropdown'; else textFilter\">\n <div class=\"filter-dropdown-section p-1\">\n <input\n type=\"text\"\n class=\"form-control form-control-sm mb-2\"\n placeholder=\"Search...\"\n [(ngModel)]=\"addFilterDropdownSearch\"\n #filterMenueSearchInput\n />\n\n <div class=\"form-check mb-1\">\n <input\n class=\"form-check-input\"\n type=\"checkbox\"\n [checked]=\"isAllSideFilterOptionsSelected(col)\"\n (change)=\"toggleSelectAllSideFilters(col, $event)\"\n id=\"selectAll_{{ col.field }}\"\n />\n <label class=\"form-check-label\" for=\"selectAll_{{ col.field }}\">\n Select All\n </label>\n </div>\n\n <div class=\"dropdown-options\">\n <div class=\"form-check mb-1\"\n *ngFor=\"\n let option of getColumnOptions(col)\n | filter : addFilterDropdownSearch : 'value';\n trackBy: trackById\n\">\n <input\n class=\"form-check-input\"\n type=\"checkbox\"\n [checked]=\"isOptionSelected(col, option)\"\n [value]=\"option\"\n (change)=\"onOptionToggle(col, option)\"\n />\n <label class=\"form-check-label\">\n {{ option.value || option }}\n </label>\n </div>\n</div>\n </div>\n </ng-container>\n\n <!-- Text Filter Section -->\n <ng-template #textFilter>\n <div class=\"filter-text-section\">\n <div class=\"form-group mb-2\">\n <select\n class=\"form-select form-select-sm\"\n [ngModel]=\"col.query.first_condition || (col.type === 'date' || col.type === 'time' ? 'equal' : 'contain')\"\n (ngModelChange)=\"col.query.first_condition = $event\"\n >\n <ng-container *ngIf=\"col.type === 'date' || col.type === 'time'; else textOptions\">\n <option value=\"equal\">Equal to</option>\n <option value=\"not_equal\">Not Equal</option>\n <option value=\"after\">After</option>\n <option value=\"before\">Before</option>\n </ng-container>\n <ng-template #textOptions>\n <option value=\"contain\">Contains</option>\n <option value=\"equal\">Equals</option>\n <option value=\"before\">Begins With</option>\n <option value=\"after\">Ends With</option>\n </ng-template>\n </select>\n </div>\n\n <input\n [type]=\"col.type == 'string' ? 'text' : col.type\"\n class=\"form-control form-control-sm mb-3\"\n placeholder=\"Value\"\n [(ngModel)]=\"col.query.first_value\"\n [min]=\"col.type == 'number' ? 0 : null\"\n (input)=\"col.type == 'number' && $any($event.target).value < 0 ? $any($event.target).value = 0 : null\"\n (keydown)=\"col.type == 'number' && $event.key === '-' ? $event.preventDefault() : null\"\n [class.number-input]=\"col.type == 'number'\"\n #filterMenueTextchInput\n />\n\n <ng-container >\n <div class=\"form-group mb-2\">\n <div class=\"form-check form-check-inline\">\n <input\n class=\"form-check-input filter-radio-inputs\"\n type=\"radio\"\n name=\"condition\"\n [(ngModel)]=\"condition\"\n value=\"and\"\n id=\"and_{{ col.field }}\"\n />\n <label class=\"form-check-label\" for=\"and_{{ col.field }}\"\n >AND</label\n >\n </div>\n <div class=\"form-check form-check-inline\">\n <input\n class=\"form-check-input filter-radio-inputs\"\n type=\"radio\"\n name=\"condition\"\n [(ngModel)]=\"condition\"\n value=\"or\"\n id=\"or_{{ col.field }}\"\n />\n <label class=\"form-check-label\" for=\"or_{{ col.field }}\"\n >OR</label\n >\n </div>\n <div class=\"form-check form-check-inline\">\n <input\n class=\"form-check-input filter-radio-inputs\"\n type=\"radio\"\n name=\"condition\"\n [(ngModel)]=\"condition\"\n value=\"none\"\n id=\"none_{{ col.field }}\"\n />\n <label class=\"form-check-label\" for=\"none_{{ col.field }}\"\n >None</label\n >\n </div>\n </div>\n\n <ng-container *ngIf=\"col.query?.first_value && condition !== 'none'\">\n <div class=\"form-group mb-2\">\n <select\n class=\"form-select form-select-sm\"\n [ngModel]=\"col.query.second_condition || (col.type === 'date' || col.type === 'time' ? 'equal' : 'contain')\"\n (ngModelChange)=\"col.query.second_condition = $event\"\n >\n <ng-container *ngIf=\"col.type === 'date' || col.type === 'time'; else textOptionsSecond\">\n <option value=\"equal\">Equal to</option>\n <option value=\"not_equal\">Not Equal</option>\n <option value=\"after\">After</option>\n <option value=\"before\">Before</option>\n </ng-container>\n <ng-template #textOptionsSecond>\n <option value=\"contain\">Contains</option>\n <option value=\"equal\">Equals</option>\n <option value=\"before\">Begins With</option>\n <option value=\"after\">Ends With</option>\n </ng-template>\n </select>\n </div>\n\n <input\n [type]=\"col.type == 'string' ? 'text' : col.type\"\n class=\"form-control form-control-sm mb-2\"\n placeholder=\"Second Value\"\n [(ngModel)]=\"col.query.second_value\"\n [min]=\"col.type == 'number' ? 0 : null\"\n (input)=\"col.type == 'number' && $any($event.target).value < 0 ? $any($event.target).value = 0 : null\"\n (keydown)=\"col.type == 'number' && $event.key === '-' ? $event.preventDefault() : null\"\n [class.number-input]=\"col.type == 'number'\"\n />\n </ng-container>\n </ng-container>\n </div>\n </ng-template>\n\n <!-- Actions -->\n <div class=\"d-flex gap-2 mt-2\">\n <div\n class=\"btn btn-sm btn-primary d-flex justify-content-center align-items-center w-100\"\n style=\"height: 22px\"\n (click)=\"applyFilterFromFilterRow(col)\"\n >\n Apply\n </div>\n <div\n class=\"btn btn-sm btn-secondary d-flex justify-content-center align-items-center w-100\"\n style=\"height: 22px\"\n (click)=\"resetSideFilter(col)\"\n >\n Reset\n </div>\n </div>\n </div>\n</ng-template>\n\n<!-- Side Menue -->\n\n<!-- Add this new template for accordion detail column menu -->\n<ng-template #detailColumnMenu let-col=\"col\" let-row=\"row\">\n <div\n class=\"column-menu three-dots-col-menu detail-column-menu\"\n [class.visually-hidden]=\"isDetailMenueHidden\"\n *ngIf=\"activeDetailCol\"\n [style.backgroundColor]=\"dropdownsBackgroundColor\"\n >\n <!-- Sort Ascending -->\n <!-- <div class=\"border-below pb-2\" [class.disable-sorting]=\"!col.is_sortable\">\n <span class=\"muted-text fs-7\" style=\"margin-left: 12px\">Sort</span> -->\n <!-- <div\n *ngIf=\"columnThreedotsMunuConfig?.showAscending\"\n class=\"column-menu-item\"\n (click)=\"sortDetailAsc(activeDetailCol, row)\"\n >\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrow-up.svg'\"\n class=\"data-grid-svg-icon me-2\"\n ></span>\n Sort Ascending\n </div> -->\n\n <!-- Sort Descending -->\n <!-- <div\n *ngIf=\"columnThreedotsMunuConfig?.showDescending\"\n class=\"column-menu-item\"\n (click)=\"sortDetailDesc(activeDetailCol, row)\"\n >\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrow-down.svg'\"\n class=\"data-grid-svg-icon me-2\"\n ></span>\n Sort Descending\n </div> -->\n\n <!-- <div\n *ngIf=\"col?.sortOrder\"\n class=\"column-menu-item\"\n (click)=\"resetDetailSort(activeDetailCol, row)\"\n >\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/arrow-counterclockwise.svg'\n \"\n class=\"data-grid-svg-icon me-2\"\n ></span>\n Reset Sort\n </div> -->\n <!-- </div> -->\n\n <div class=\"py-2 border-below\" *ngIf=\"isColumnFilterable(col)\">\n <span class=\"muted-text fs-7\" style=\"margin-left: 12px\">Filter</span>\n <div\n *ngIf=\"columnThreedotsMunuConfig?.showFilter\"\n class=\"column-menu-item\"\n (click)=\"openDetailFilterMenu($event, col, row)\"\n >\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\"\n class=\"data-grid-svg-icon me-2\"\n ></span>\n Filter\n </div>\n </div>\n\n <div class=\"py-2 border-below\">\n <span class=\"muted-text fs-7\" style=\"margin-left: 12px\">Pin</span>\n <div\n *ngIf=\"columnThreedotsMunuConfig?.showPinleft && col?.pinned !== 'left'\"\n class=\"column-menu-item\"\n (click)=\"updateDetailColumnPin(activeDetailCol, row, 'left')\"\n >\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/pin-left.svg'\"\n class=\"data-grid-svg-icon me-2\"\n ></span\n >Pin Left\n </div>\n\n <div\n *ngIf=\"\n columnThreedotsMunuConfig?.showPinright && col?.pinned !== 'right'\n \"\n class=\"column-menu-item\"\n (click)=\"updateDetailColumnPin(activeDetailCol, row, 'right')\"\n >\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/pin-right.svg'\"\n class=\"data-grid-svg-icon data-grid-svg-icon me-2\"\n ></span\n >Pin Right\n </div>\n\n <div\n *ngIf=\"col?.pinned\"\n class=\"column-menu-item\"\n (click)=\"updateDetailColumnPin(activeDetailCol, row, null)\"\n >\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/layout-three-columns.svg'\n \"\n class=\"data-grid-svg-icon me-2\"\n ></span\n >Unpin\n </div>\n </div>\n\n <div\n *ngIf=\"columnThreedotsMunuConfig?.showAutosizeThisColumn\"\n class=\"column-menu-item\"\n (click)=\"autosizeDetailColumn(activeDetailCol, row)\"\n >\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/arrows-expand-vertical.svg'\n \"\n class=\"me-2\"\n ></span>\n Autosize This Column\n </div>\n\n <!-- Autosize All Columns -->\n <div\n *ngIf=\"columnThreedotsMunuConfig?.showAutosizeAllColumns\"\n class=\"column-menu-item\"\n (click)=\"autosizeAllDetailColumns(row)\"\n >\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/arrows-angle-expand.svg'\n \"\n class=\"data-grid-svg-icon me-2\"\n ></span\n >Autosize All Columns\n </div>\n\n\n <!-- Choose Columns -->\n <div\n *ngIf=\"columnThreedotsMunuConfig?.showChoseColumns\"\n class=\"column-menu-item\"\n (click)=\"openDetailChooseColumns(row)\"\n>\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/ui-checks-grid.svg'\"\n class=\"data-grid-svg-icon me-2\"\n ></span>\n Choose Columns\n</div>\n\n <!-- Reset Columns -->\n <!-- <div\n *ngIf=\"columnThreedotsMunuConfig?.showResetColumns\"\n class=\"column-menu-item\"\n (click)=\"resetDetailColumns(row)\"\n >\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/arrow-counterclockwise.svg'\n \"\n class=\"data-grid-svg-icon me-2\"\n ></span\n >Reset Columns\n </div> -->\n </div>\n</ng-template>\n\n<!-- Column Pannel / Pivot Mode / Searching -->\n\n<ng-template #columnPannel>\n <div class=\"column-panel-header\">\n <!-- Pivot Toggle -->\n <div\n class=\"form-check form-switch d-flex align-items-center mb-2 pivot-mode px-5 ms-2\"\n >\n <input\n class=\"form-check-input me-2\"\n type=\"checkbox\"\n id=\"pivotToggle\"\n [(ngModel)]=\"pivotMode\"\n />\n <label class=\"form-check-label\" for=\"pivotToggle\">Pivot Mode</label>\n </div>\n\n <!-- Select All & Search -->\n <div class=\"d-flex align-items-center mb-2 px-3\">\n <span class=\"filter-icon-wrapper me-2\" *ngIf=\"showColumnsGrouping\">\n <span\n class=\"toggle-icon data-grid-svg-icon\"\n [inlineSVG]=\"\n accordionState === 'all'\n ? singleSpaAssetsPath + 'data-grid/icons/chevron-down.svg'\n : accordionState === 'some'\n ? singleSpaAssetsPath + 'data-grid/icons/dash.svg'\n : singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\n \"\n (click)=\"toggleAllAccordions()\"\n ></span>\n </span>\n <input\n type=\"checkbox\"\n class=\"form-check-input me-2\"\n [checked]=\"allColumnsSelected()\"\n (change)=\"toggleAllColumnsVisibility()\"\n />\n <input\n type=\"text\"\n class=\"form-control form-control-sm\"\n placeholder=\"Search columns...\"\n [(ngModel)]=\"columnSearch\"\n />\n </div>\n\n <!-- Separator -->\n <hr class=\"my-2\" />\n </div>\n</ng-template>\n\n<!-- Right Columns Menue -->\n\n<!-- Column Panel Item Template -->\n<ng-template #columnPanelItem let-col=\"col\">\n <!-- Group Column -->\n <ng-container *ngIf=\"col.children?.length\">\n <div class=\"column-group d-flex align-items-center mb-2\">\n <span class=\"filter-icon-wrapper me-2\">\n <span\n class=\"toggle-icon data-grid-svg-icon\"\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\n \"\n [class.rotate]=\"col.expanded\"\n (click)=\"col.expanded = !col.expanded\"\n ></span>\n </span>\n <input\n type=\"checkbox\"\n class=\"form-check-input me-2\"\n [id]=\"'group_' + col.header\"\n [checked]=\"isColumnVisible(col)\"\n (change)=\"toggleGroupVisibility(col)\"\n />\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/grid-3x2-gap.svg'\"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center me-2\"\n ></span>\n <label\n class=\"d-flex align-items-center mb-0 w-100\"\n [for]=\"'group_' + col.header\"\n style=\"cursor: pointer\"\n >\n <span class=\"text-truncate\">{{ col.header }}</span>\n </label>\n </div>\n <div *ngIf=\"col.expanded\" class=\"ps-4\">\n <ng-container *ngFor=\"let child of col.children; trackBy: trackByField\">\n <ng-container\n *ngTemplateOutlet=\"columnPanelItem; context: { col: child }\"\n ></ng-container>\n </ng-container>\n </div>\n </ng-container>\n\n <!-- Leaf Column -->\n <ng-container *ngIf=\"!col.children?.length\">\n <div class=\"d-flex align-items-center mb-2\">\n <span class=\"me-2\" style=\"width: 1.5rem\"></span>\n <input\n type=\"checkbox\"\n class=\"form-check-input me-2\"\n [(ngModel)]=\"col.is_visible\"\n [id]=\"'col_' + col.field\"\n (change)=\"onSideMenuColumnsVisibilityChange()\"\n />\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/grid-3x2-gap.svg'\"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center me-2\"\n ></span>\n <label\n class=\"d-flex align-items-center mb-0 w-100\"\n [for]=\"'col_' + col.field\"\n style=\"cursor: pointer\"\n >\n <span class=\"text-truncate\">{{ col.header }}</span>\n </label>\n </div>\n </ng-container>\n</ng-template>\n<!-- Columns Side Filter -->\n<ng-template #sideFilters>\n <div class=\"py-3 px-2 pe-3 h-100\">\n <div class=\"d-flex align-items-center mb-2\">\n <span class=\"filter-icon-wrapper me-2\">\n <span\n class=\"toggle-icon data-grid-svg-icon\"\n [inlineSVG]=\"\n filterAccordionState === 'all'\n ? singleSpaAssetsPath + 'data-grid/icons/chevron-down.svg'\n : filterAccordionState === 'some'\n ? singleSpaAssetsPath + 'data-grid/icons/dash.svg'\n : singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\n \"\n (click)=\"toggleAllFilterAccordions()\"\n ></span>\n </span>\n\n <input\n type=\"text\"\n class=\"form-control form-control-sm\"\n placeholder=\"Search...\"\n [(ngModel)]=\"columnSearch\"\n />\n </div>\n <div\n class=\"overflow-auto side-filter-columns-wrapper\"\n style=\"height: calc(100% - 120px); scrollbar-width: thin\"\n >\n <ng-container\n *ngFor=\"\n let col of columns | filter : columnSearch : 'header';\n trackBy: trackByField\n \"\n >\n <ng-container\n *ngTemplateOutlet=\"filterPannelItem; context: { col: col }\"\n ></ng-container>\n </ng-container>\n </div>\n <!-- Apply and Reset Buttons -->\n <!-- <div class=\"d-flex gap-2 mt-3 px-2\">\n <button\n class=\"btn btn-sm btn-primary d-flex justify-content-center align-items-center flex-fill\"\n style=\"height: 32px;\"\n (click)=\"applySideMenuFilters()\"\n >\n Apply\n </button>\n <button\n class=\"btn btn-sm btn-secondary d-flex justify-content-center align-items-center flex-fill\"\n style=\"height: 32px;\"\n (click)=\"resetSideMenuFilters()\"\n >\n Reset\n </button>\n </div> -->\n </div>\n</ng-template>\n\n<ng-template #filterPannelItem let-col=\"col\">\n <!-- Group Column -->\n <ng-container *ngIf=\"col.children?.length\">\n <div class=\"column-group d-flex align-items-center mb-2\">\n <!-- Chevron toggle -->\n <span class=\"filter-icon-wrapper me-2\">\n <span\n class=\"toggle-icon data-grid-svg-icon\"\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\n \"\n [class.rotate]=\"col.expandedFilter\"\n (click)=\"col.expandedFilter = !col.expandedFilter\"\n ></span>\n </span>\n\n <!-- Group label toggle -->\n <label\n class=\"d-flex align-items-center mb-0 w-100\"\n style=\"cursor: pointer\"\n (click)=\"col.expandedFilter = !col.expandedFilter\"\n >\n <span class=\"fw-bold text-truncate\"\n >{{ col.header }}\n <span\n class=\"text-primary ms-1\"\n *ngIf=\"col?.query?._ids?.length || col?.query?._first_value\"\n >*</span\n >\n </span>\n </label>\n </div>\n\n <!-- Children columns -->\n <div *ngIf=\"col.expandedFilter\" class=\"ps-4\">\n <ng-container *ngFor=\"let child of col.children; trackBy: trackByField\">\n <ng-container\n *ngTemplateOutlet=\"filterPannelItem; context: { col: child }\"\n ></ng-container>\n </ng-container>\n </div>\n </ng-container>\n\n <!-- Leaf Column -->\n <ng-container *ngIf=\"!col.children?.length\">\n <div class=\"d-flex align-items-center mb-2\">\n <span\n class=\"me-2 filter-icon-wrapper me-2\"\n (click)=\"col.expandedFilter = !col.expandedFilter\"\n >\n <span\n class=\"toggle-icon data-grid-svg-icon\"\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\n \"\n [class.rotate]=\"col.expandedFilter\"\n ></span>\n </span>\n\n <label\n class=\"d-flex align-items-center mb-0 w-100\"\n style=\"cursor: pointer\"\n (click)=\"col.expandedFilter = !col.expandedFilter\"\n >\n <span class=\"text-truncate fw-bold\">{{ col.header }}</span>\n </label>\n </div>\n\n <!-- Show filter when expanded -->\n <div *ngIf=\"col.expandedFilter\" class=\"ps-4 pe-3\">\n <ng-container\n *ngTemplateOutlet=\"sideNestedFilter; context: { col: col }\"\n ></ng-container>\n </div>\n </ng-container>\n</ng-template>\n\n<!-- Side Nested Filters -->\n<ng-template #sideNestedFilter let-col=\"col\">\n <div class=\"\">\n <!-- Dropdown Type -->\n <ng-container *ngIf=\"col.type === 'dropdown'; else textFilter\">\n <div class=\"p-1\">\n <!-- Search -->\n <input\n type=\"text\"\n class=\"form-control form-control-sm mb-2\"\n placeholder=\"Search...\"\n [(ngModel)]=\"col.searchValue\"\n />\n\n <!-- Select All -->\n <div class=\"form-check mb-1 ms-1\">\n <input\n class=\"form-check-input\"\n type=\"checkbox\"\n [checked]=\"\n col.query?._ids?.length == col?.column_dropdown_value?.length\n \"\n (change)=\"toggleSelectAllSideFilters(col, $event)\"\n id=\"selectAll_{{ col.field }}\"\n />\n <label class=\"form-check-label\" for=\"selectAll_{{ col.field }}\">\n Select All\n </label>\n </div>\n\n <!-- Options -->\n <div class=\"dropdown-options\">\n <div\n class=\"form-check mb-1 ms-1\"\n *ngFor=\"\n let option of col?.column_dropdown_value\n | filter : addFilterDropdownSearch : 'header'\n \"\n >\n <input\n class=\"form-check-input\"\n type=\"checkbox\"\n [value]=\"option\"\n [checked]=\"isOptionSelected(col, option)\"\n (change)=\"onOptionToggle(col, option)\"\n id=\"option_{{ col.field }}_{{\n option?.id || option?._id || option\n }}\"\n />\n <label\n class=\"form-check-label\"\n [for]=\"\n 'option_' +\n col.field +\n '_' +\n (option?.id || option?._id || option)\n \"\n >\n {{ option.value || option }}\n </label>\n </div>\n </div>\n\n <!-- Actions -->\n <!-- <div class=\"d-flex gap-2 mt-2\">\n <div\n class=\"btn btn-sm btn-primary d-flex justify-content-center align-items-center\"\n style=\"height: 22px;\"\n (click)=\"applySideMenuFilters()\"\n >\n Apply\n </div>\n <div\n class=\"btn btn-sm btn-secondary d-flex justify-content-center align-items-center\"\n style=\"height: 22px;\"\n (click)=\"resetSideMenuFilters()\"\n >\n Reset\n </div>\n </div> -->\n </div>\n </ng-container>\n\n <!-- Text Filter Section -->\n <ng-template #textFilter>\n <div class=\"filter-text-section\">\n <div class=\"form-group mb-2\">\n <select\n class=\"form-select form-select-sm\"\n [ngModel]=\"col!.query!.first_condition || (col.type === 'date' || col.type === 'time' ? 'equal' : 'contain')\"\n (ngModelChange)=\"col!.query!.first_condition = $event\"\n >\n <ng-container *ngIf=\"col.type === 'date' || col.type === 'time'; else textOptions\">\n <option value=\"equal\">Equal to</option>\n <option value=\"not_equal\">Not Equal</option>\n <option value=\"after\">After</option>\n <option value=\"before\">Before</option>\n </ng-container>\n <ng-template #textOptions>\n <option value=\"contain\">Contains</option>\n <option value=\"equal\">Equals</option>\n <option value=\"before\">Begins With</option>\n <option value=\"after\">Ends With</option>\n </ng-template>\n </select>\n </div>\n\n <input\n [type]=\"col.type == 'date' ? 'date' : col.type == 'number' ? 'number' : 'text'\"\n class=\"form-control form-control-sm mb-3\"\n placeholder=\"Value\"\n [(ngModel)]=\"col!.query!.first_value\"\n [min]=\"col.type == 'number' ? 0 : null\"\n (input)=\"col.type == 'number' && $any($event.target).value < 0 ? $any($event.target).value = 0 : null\"\n (keydown)=\"col.type == 'number' && $event.key === '-' ? $event.preventDefault() : null\"\n [class.number-input]=\"col.type == 'number'\"\n />\n\n <ng-container *ngIf=\"col?.query?.first_value && col?.query?.condition !== 'none'\">\n <div class=\"form-group mb-2\">\n <div class=\"form-check form-check-inline\">\n <input\n class=\"form-check-input filter-radio-inputs\"\n type=\"radio\"\n name=\"condition\"\n [(ngModel)]=\"col!.query.condition\"\n value=\"and\"\n id=\"and_{{ col.field }}\"\n />\n <label class=\"form-check-label\" for=\"and_{{ col.field }}\"\n >AND</label\n >\n </div>\n <div class=\"form-check form-check-inline\">\n <input\n class=\"form-check-input filter-radio-inputs\"\n type=\"radio\"\n name=\"condition\"\n [(ngModel)]=\"col!.query.condition\"\n value=\"or\"\n id=\"or_{{ col.field }}\"\n />\n <label class=\"form-check-label\" for=\"or_{{ col.field }}\"\n >OR</label\n >\n </div>\n <div class=\"form-check form-check-inline\">\n <input\n class=\"form-check-input filter-radio-inputs\"\n type=\"radio\"\n name=\"condition\"\n [(ngModel)]=\"col!.query.condition\"\n value=\"none\"\n id=\"none_{{ col.field }}\"\n />\n <label class=\"form-check-label\" for=\"none_{{ col.field }}\"\n >None</label\n >\n </div>\n </div>\n\n <div class=\"form-group mb-2\">\n <select\n class=\"form-select form-select-sm\"\n [ngModel]=\"col!.query.second_condition || (col.type === 'date' || col.type === 'time' ? 'equal' : 'contain')\"\n (ngModelChange)=\"col!.query.second_condition = $event\"\n >\n <ng-container *ngIf=\"col.type === 'date' || col.type === 'time'; else textOptionsSecond\">\n <option value=\"equal\">Equal to</option>\n <option value=\"not_equal\">Not Equal</option>\n <option value=\"after\">After</option>\n <option value=\"before\">Before</option>\n </ng-container>\n <ng-template #textOptionsSecond>\n <option value=\"contain\">Contains</option>\n <option value=\"equal\">Equals</option>\n <option value=\"before\">Begins With</option>\n <option value=\"after\">Ends With</option>\n </ng-template>\n </select>\n </div>\n\n <input\n [type]=\"col.type == 'date' ? 'date' : col.type == 'number' ? 'number' : 'text'\"\n class=\"form-control form-control-sm mb-2\"\n placeholder=\"Second Value\"\n [(ngModel)]=\"col!.query.second_value\"\n [min]=\"col.type == 'number' ? 0 : null\"\n (input)=\"col.type == 'number' && $any($event.target).value < 0 ? $any($event.target).value = 0 : null\"\n (keydown)=\"col.type == 'number' && $event.key === '-' ? $event.preventDefault() : null\"\n [class.number-input]=\"col.type == 'number'\"\n />\n </ng-container>\n\n <!-- Apply and Reset Buttons -->\n <div class=\"d-flex gap-2 mt-2\">\n <div\n class=\"btn btn-sm btn-primary d-flex justify-content-center align-items-center w-100\"\n style=\"height: 22px\"\n (click)=\"applyFilterFromFilterRow(col)\"\n >\n Apply\n </div>\n <div\n class=\"btn btn-sm btn-secondary d-flex justify-content-center align-items-center w-100\"\n style=\"height: 22px\"\n (click)=\"resetSideFilter(col)\"\n >\n Reset\n </div>\n </div>\n </div>\n </ng-template>\n </div>\n</ng-template>\n\n<!-- Centr Overlay for showing the chose columns -->\n\n<div *ngIf=\"showColumnPanel\" class=\"custom-modal-overlay\" (click)=\"closeModalColumnPanel()\">\n <div\n class=\"custom-modal-content\"\n [style.backgroundColor]=\"dropdownsBackgroundColor\"\n (click)=\"$event.stopPropagation()\"\n >\n <ng-container *ngTemplateOutlet=\"modalColumnPannel\"></ng-container>\n </div>\n</div>\n\n<!-- The existing ng-template you provided -->\n<ng-template #modalColumnPannel>\n <div class=\"column-panel-header\">\n <div\n class=\"d-flex justify-content-between align-items-center px-2 ps-3 rounded-top-2 moda-header\"\n [style.height.px]=\"48\"\n >\n Choose Columns\n <span class=\"filter-icon-wrapper\" (click)=\"closeModalColumnPanel()\"\n ><span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/x.svg'\"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span\n ></span>\n </div>\n <hr class=\"my-0\" />\n <div>\n <div class=\"d-flex align-items-center px-2 pe-3\" [style.height.px]=\"48\">\n <span class=\"filter-icon-wrapper me-2\" *ngIf=\"showColumnsGrouping\">\n <span\n class=\"toggle-icon data-grid-svg-icon\"\n [inlineSVG]=\"\n accordionState === 'all'\n ? singleSpaAssetsPath + 'data-grid/icons/chevron-down.svg'\n : accordionState === 'some'\n ? singleSpaAssetsPath + 'data-grid/icons/dash.svg'\n : singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\n \"\n (click)=\"toggleAllAccordions()\"\n ></span>\n </span>\n <input\n type=\"checkbox\"\n class=\"form-check-input me-2\"\n [checked]=\"allColumnsSelected()\"\n (change)=\"toggleAllColumnsVisibility()\"\n />\n <input\n type=\"text\"\n class=\"form-control form-control-sm\"\n placeholder=\"Search columns...\"\n [(ngModel)]=\"choseColumnsSearch\"\n />\n </div>\n\n <hr class=\"mt-0 mb-1\" />\n <div class=\"px-2 overlay-scrollable\">\n <ng-container\n *ngFor=\"\n let col of columns | filter : choseColumnsSearch : 'header';\n trackBy: trackByField\n \"\n >\n <ng-container\n *ngTemplateOutlet=\"columnPanelItem; context: { col: col }\"\n ></ng-container>\n </ng-container>\n </div>\n </div>\n </div>\n</ng-template>\n\n<ng-template #sideMenuRowGroups>\n <div class=\"d-flex flex-column h-100\">\n <div class=\"px-3 h-100\">\n <div class=\"d-flex gap-3 mb-4\">\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/justify.svg'\"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n <span>Row Groups</span>\n </div>\n <div class=\"h-50\">\n <div\n class=\"px-3 py-2 border-dashed h-100 d-flex justify-content-center align-items-center\"\n style=\"font-size: 14px\"\n >\n Drag here to set row Groups\n </div>\n </div>\n </div>\n\n <hr class=\"mt-4\" />\n\n <div class=\"px-3 h-100\">\n <div class=\"d-flex gap-3 mb-4\">\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/justify.svg'\"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n <span>Values</span>\n </div>\n <div class=\"h-50 d-flex\">\n <div\n class=\"px-3 py-2 border-dashed h-100 d-flex justify-content-center align-items-center\"\n style=\"font-size: 14px\"\n >\n Drag here aggregate\n </div>\n </div>\n </div>\n </div>\n</ng-template>\n\n<!-- *************************************************** -->\n<!-- *************************************************** -->\n<!-- *************************************************** -->\n<!-- Drag Preview Template -->\n<!-- *************************************************** -->\n<!-- *************************************************** -->\n<ng-template #dragPreview let-col>\n <div class=\"p-2 border d-flex gap-2\">\n <div>\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrows-move.svg'\"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n </div>\n <div>{{ col.header }}</div>\n </div>\n</ng-template>\n\n<!-- Drag Placeholder Template -->\n<ng-template\n #dragPlaceholder\n let-col\n let-i=\"index\"\n let-section=\"section\"\n let-draggingInGroupArea=\"draggingInGroupArea\"\n>\n <div *ngIf=\"!draggingInGroupArea\">\n <div\n *ngTemplateOutlet=\"\n headerCell;\n context: { $implicit: col, index: i, section: section }\n \"\n ></div>\n </div>\n <div *ngIf=\"draggingInGroupArea\">New Placeholder</div>\n</ng-template>\n\n<!-- Top Group Row Placeholder -->\n<ng-template #topGroupingRowPlaceholder let-col let-showChevron=\"showChevron\">\n <div class=\"d-flex gap-2\">\n <div\n class=\"d-flex gap-2 top-row-grouping-placeholder\"\n [style.backgroundColor]=\"topGroupedBadgesBackgroundColor\"\n >\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/grid-3x2-gap.svg'\"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n <span>{{ col.header }}</span>\n <span\n (click)=\"ungroupColumn(col)\"\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/x.svg'\"\n class=\"cursor-pointer data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n </div>\n </div>\n <div *ngIf=\"showChevron\" style=\"opacity: 0.6; font-size: 14px\">\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n </div>\n</ng-template>\n\n<ng-template\n #childHeaderPlaceholder\n let-col\n let-pinnedRight=\"pinnedRight\"\n let-i=\"index\"\n let-sections=\"sections\"\n>\n <div\n class=\"header-cell one-row-header-cells\"\n [class.border-right]=\"showVerticalBorder\"\n [style.width.px]=\"col.width\"\n [style.min-width.px]=\"col.width\"\n [style.min-height.px]=\"headerRowHeight\"\n [style.max-height.px]=\"headerRowHeight\"\n [class.border-right]=\"showVerticalBorder\"\n [style.fontWeight]=\"headerFontWeight\"\n >\n <div class=\"d-flex justify-content-between h-100 align-items-center w-100\">\n <div\n class=\"d-flex justify-content-between w-100\"\n [class.flex-row-reverse]=\"pinnedRight\"\n >\n <div\n class=\"text-ellipsis h-100 d-flex align-items-center\"\n [title]=\"col.header\"\n [class.w-100]=\"pinnedRight\"\n >\n {{ col.header }}\n </div>\n\n <div\n class=\"position-relative d-flex\"\n [class.flex-row-reverse]=\"pinnedRight\"\n >\n <div class=\"three-dots p-1\" style=\"cursor: pointer\">\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/three-dots-vertical.svg'\n \"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n </div>\n\n <div class=\"resize-handle\">\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/resize-handle.svg'\n \"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n </div>\n </div>\n </div>\n </div>\n </div>\n <div\n *ngIf=\"showFilterRow\"\n [style.backgroundColor]=\"headerBackgroundColor\"\n class=\"header-cell filter-cell\"\n [class.border-right]=\"showVerticalBorder\"\n [style.width.px]=\"col.width\"\n [style.min-width.px]=\"col.width\"\n [style.height.px]=\"headerRowHeight\"\n [style.min-height.px]=\"headerRowHeight\"\n [style.max-height.px]=\"headerRowHeight\"\n [class.border-right]=\"showVerticalBorder\"\n style=\"grid-row: 3\"\n >\n <div\n class=\"header-cell filter-cell\"\n [style.backgroundColor]=\"headerBackgroundColor\"\n [style.width.px]=\"col.width\"\n [style.min-width.px]=\"col.width\"\n [style.height.px]=\"headerRowHeight\"\n [style.min-height.px]=\"headerRowHeight\"\n [style.max-height.px]=\"headerRowHeight\"\n >\n <input\n type=\"text\"\n class=\"form-control form-control-sm\"\n placeholder=\"Filter\"\n [(ngModel)]=\"col.filterValue\"\n />\n <span\n class=\"filter-icon-wrapper\"\n (click)=\"activeFilterCell = col; activeCol = null\"\n ><span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span\n ></span>\n\n <div\n class=\"position-absolute\"\n *ngIf=\"activeFilterCell === col\"\n style=\"top: 100%; right: 0; z-index: 10; left: 0\"\n ></div>\n </div>\n </div>\n</ng-template>\n\n<ng-template #tableLayout>\n <div\n (click)=\"$event.stopPropagation()\"\n class=\"p-3 shadow rounded-3 bg-white actions-dropdown mt-1 dropdown-menu show shadow custom-menu table-layout\"\n style=\"width: 320px\"\n >\n <div class=\"d-flex align-items-center mb-3\">\n <button\n class=\"btn btn-link p-0\"\n style=\"margin-left: -10px\"\n (click)=\"toggleActions('setting')\"\n >\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrow-left.svg'\"\n class=\"data-grid-svg-icon me-2\"\n ></span>\n </button>\n <h6 class=\"mb-0 ms-2\" style=\"font-weight: 500\">Table Layout</h6>\n </div>\n <hr class=\"my-2\" />\n <div class=\"w-100 mb-3 d-flex\" role=\"group\">\n <input\n type=\"radio\"\n class=\"btn-check layout-button-check\"\n name=\"layoutSize\"\n id=\"small\"\n autocomplete=\"off\"\n (change)=\"changeTableLayout($event, 'small')\"\n [checked]=\"selectedTableLayout == 'small'\"\n />\n <label\n class=\"border d-flex flex-column align-items-center layout-button\"\n for=\"small\"\n [ngStyle]=\"{\n color: selectedTableLayout == 'small' ? '#000' : '#727272'\n }\"\n >\n <div class=\"preview-box border mb-1\" style=\"height: 8px\"></div>\n Small\n </label>\n\n <input\n type=\"radio\"\n class=\"btn-check layout-button-check\"\n name=\"layoutSize\"\n id=\"medium\"\n autocomplete=\"off\"\n [checked]=\"selectedTableLayout == 'medium'\"\n (change)=\"changeTableLayout($event, 'medium')\"\n />\n <label\n class=\"border mx-3 d-flex flex-column align-items-center layout-button\"\n for=\"medium\"\n [ngStyle]=\"{\n color: selectedTableLayout == 'medium' ? '#000' : '#727272'\n }\"\n >\n <div class=\"preview-box border mb-1\" style=\"height: 12px\"></div>\n Medium\n </label>\n\n <input\n type=\"radio\"\n class=\"btn-check layout-button-check\"\n name=\"layoutSize\"\n id=\"large\"\n autocomplete=\"off\"\n (change)=\"changeTableLayout($event, 'large')\"\n [checked]=\"selectedTableLayout == 'large'\"\n />\n <label\n class=\"border d-flex flex-column align-items-center layout-button\"\n for=\"large\"\n [ngStyle]=\"{\n color: selectedTableLayout == 'large' ? '#000' : '#727272'\n }\"\n >\n <div class=\"preview-box border mb-1\" style=\"height: 16px\"></div>\n Large\n </label>\n </div>\n\n <hr class=\"my-2\" />\n <div class=\"d-flex justify-content-between align-items-center mb-2\">\n <span>Show separators</span>\n <div class=\"form-check form-switch m-0\">\n <input\n class=\"form-check-input\"\n type=\"checkbox\"\n id=\"separators\"\n [(ngModel)]=\"showVerticalBorder\"\n (change)=\"emitConfigUpdate()\"\n />\n </div>\n </div>\n <div class=\"d-flex justify-content-between align-items-center\">\n <span>Row shading</span>\n <div class=\"form-check form-switch m-0\">\n <input\n class=\"form-check-input\"\n [(ngModel)]=\"rowShadingEnabled\"\n (change)=\"toggleRowShading()\"\n type=\"checkbox\"\n id=\"rowShading\"\n />\n </div>\n </div>\n </div>\n</ng-template>\n\n<ng-template #tablePreset>\n <div\n *ngIf=\"activeSubButton !== 'save-preset'\"\n (click)=\"$event.stopPropagation();\"\n class=\"p-3 shadow rounded-3 bg-white actions-dropdown mt-1 dropdown-menu show shadow custom-menu table-layout\"\n style=\"width: 280px\"\n >\n <!-- Header -->\n <div class=\"d-flex justify-content-between align-items-center mb-3\">\n <div class=\"d-flex align-items-center\">\n <button\n class=\"btn btn-link p-0\"\n style=\"margin-left: -10px\"\n (click)=\"toggleActions('setting')\"\n >\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrow-left.svg'\"\n class=\"data-grid-svg-icon\"\n ></span>\n </button>\n <h6 class=\"mb-0 ms-2\" style=\"font-weight: 500\">Table Presets</h6>\n </div>\n <!-- Save/Update Preset Button -->\n <div>\n <a\n class=\"text-decoration-none btn btn-link\"\n type=\"button\"\n id=\"savePresetDropdown\"\n (click)=\"$event.stopPropagation(); toggleSubActions('save-preset')\"\n >\n {{ tableFilterViewId && tableFilterViewId !== 'default' ? 'Update Preset' : 'Save Preset' }}\n </a>\n </div>\n </div>\n\n <!-- Search -->\n <div class=\"mb-3\">\n <div class=\"col-12 global-search\">\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/search.svg'\"\n class=\"data-grid-svg-icon mx-2 position-absolute icon\"\n ></span>\n <input\n class=\"form-control form-control-sm\"\n placeholder=\"Search...\"\n [(ngModel)]=\"searchTextPresetTable\"\n type=\"search\"\n />\n </div>\n </div>\n\n <!-- Preset List -->\n <ng-container\n *ngIf=\"\n tableView | filter : searchTextPresetTable : 'name' as filteredList\n \"\n >\n <!-- If filteredList exists and none is default -> show fallback -->\n <div class=\"\" (click)=\"selectDefault()\">\n <div class=\"fw-semibold\">Default View\n <span\n *ngIf=\"tableFilterViewId === 'default'\"\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/check-blue.svg'\"\n class=\"me-2\"\n ></span>\n </div>\n </div>\n <div class=\"d-flex justify-content-between\">\n <small class=\"text-dark\">Created by system</small>\n <span\n *ngIf=\"tableFilterViewId === 'default'\"\n class=\"badge bg-light text-primary ms-2\"\n >Default</span\n >\n <div\n class=\"dropdown d-flex justify-content-end\"\n *ngIf=\"tableFilterViewId\"\n >\n <a\n href=\"javascript:void(0)\"\n class=\"muted-text\"\n data-bs-toggle=\"dropdown\"\n >\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/horizontal-dots.svg'\n \"\n class=\"me-2\"\n ></span>\n </a>\n <ul class=\"dropdown-menu dropdown-menu-end\">\n <a\n (click)=\"actionPreset({ id: 'default' }, 'setPreset')\"\n class=\"dropdown-item d-flex align-items-center\"\n >\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/star.svg'\"\n class=\"me-2\"\n ></span>\n Set as default\n </a>\n </ul>\n </div>\n </div>\n\n <!-- The list: render each table from filteredList -->\n <div\n class=\"list-group list-group-flush\"\n *ngFor=\"let table of filteredList; trackBy: trackByTable\"\n >\n <!-- Item -->\n <div\n class=\"list-group-item px-0 d-flex justify-content-between align-items-center\"\n >\n <div (click)=\"selectFilter(table)\">\n <div class=\"fw-semibold\" style=\"cursor: pointer;\">\n {{ table?.name }}\n <!-- {{table?.is_temp}} -->\n <span\n *ngIf=\"table?.is_temp\"\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/check-blue.svg'\n \"\n class=\"me-2\"\n ></span>\n <span\n *ngIf=\"table?.is_default\"\n class=\"badge bg-light text-primary ms-2\"\n >Default</span\n >\n </div>\n <small class=\"text-dark\"\n >Created {{ table?.createdAt | timezoneFormat:prefs:'date' }}</small\n >\n </div>\n\n <div class=\"d-flex align-items-center\">\n <span\n *ngIf=\"table?.is_default\"\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/check-blue.svg'\n \"\n class=\"me-2\"\n ></span>\n\n <div class=\"dropdown position-relative\" *ngIf=\"!table?.is_default\">\n <a href=\"javascript:void(0)\" class=\"muted-text\" (click)=\"togglePresetDropdown(table.id)\">\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/horizontal-dots.svg'\" class=\"me-2\"></span>\n </a>\n\n <div\n *ngIf=\"activePresetDropdownId === table.id\"\n class=\"dropdown-menu dropdown-menu-end show position-absolute\"\n style=\"z-index: 1000; top: 100%; right: 0; min-width: 180px\"\n (click)=\"$event.stopPropagation()\"\n >\n <a\n [class.d-none]=\"confirmDeletePresetId === table.id\"\n (click)=\"setPresetAsDefault(table); activePresetDropdownId = null;\"\n class=\"dropdown-item d-flex align-items-center\"\n >\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/star.svg'\" class=\"me-2\"></span>\n Set as default\n </a>\n\n <ng-container *ngIf=\"confirmDeletePresetId !== table.id; else confirmBlock\">\n <a\n (click)=\"confirmDeletePresetId = table.id\"\n class=\"dropdown-item d-flex align-items-center text-danger\"\n >\n <span style=\"margin-top: -4px\" [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/trash-red.svg'\" class=\"me-2\"></span>\n Delete\n </a>\n </ng-container>\n\n <ng-template #confirmBlock>\n <div class=\"dropdown-item\"><b>Delete preset</b></div>\n <div class=\"dropdown-item text-center\">\n <div class=\"mb-2\">\n Are you sure you want to delete the <br />\n <b>\u201C{{ table?.name }}\u201D</b> preset?\n </div>\n <button\n class=\"btn btn-sm btn-light me-2\"\n (click)=\"confirmDeletePresetId = null\"\n >\n Cancel\n </button>\n <button\n class=\"btn btn-sm btn-danger delete-preset\"\n (click)=\"actionPreset(table, 'deletePreset'); confirmDeletePresetId = null; activePresetDropdownId = null;\"\n >\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/trash-red.svg'\" class=\"confirm-preset-delete\"></span>\n Delete\n </button>\n </div>\n </ng-template>\n </div>\n</div>\n </div>\n </div>\n <!-- Item End Here -->\n </div>\n\n </ng-container>\n </div>\n\n <div\n (click)=\"$event.stopPropagation()\"\n *ngIf=\"activeSubButton == 'save-preset'\"\n class=\"dropdown-menu p-3 badge mt-4 save-preset-dropdown mt-1\"\n aria-labelledby=\"savePresetDropdown\"\n style=\"min-width: 250px\"\n >\n <div class=\"fw-bold fs-14px mb-2\">Save preset</div>\n <div class=\"fs-14px mb-2\" style=\"line-height: 20px\">\n This will save the current table adjustments as a preset.\n </div>\n <!-- Input -->\n <div class=\"mb-2\">\n <label for=\"presetName\" class=\"form-label fs-12px fw-bold\"\n >Preset Name</label\n >\n <div class=\"col-12 global-search\">\n <input\n #presetNameCtrl=\"ngModel\"\n required\n [(ngModel)]=\"presetName\"\n [ngClass]=\"{\n 'is-invalid':\n presetNameCtrl.invalid &&\n (presetNameCtrl.dirty || presetNameCtrl.touched)\n }\"\n class=\"form-control form-control-sm ps-2\"\n placeholder=\"Enter preset name\"\n type=\"text\"\n />\n </div>\n </div>\n\n <!-- Checkbox -->\n <div class=\"form-check mb-2\">\n <input\n class=\"form-check-input\"\n [(ngModel)]=\"presetFilter\"\n type=\"checkbox\"\n id=\"saveFilters\"\n />\n <label class=\"form-check-label mt-1\" for=\"saveFilters\">\n Save active filters\n </label>\n </div>\n\n <!-- Save Button -->\n <div class=\"d-flex justify-content-center gap-2\" style=\"height: 32px\">\n <button\n type=\"button\"\n style=\"height: 32px\"\n class=\"btn border w-100 d-flex align-items-center justify-content-center btn-light\"\n (click)=\"$event.stopPropagation(); toggleActions('table-presets')\"\n style=\"margin-top: -2px\"\n >\n <span>Cancel</span>\n </button>\n <button\n [disabled]=\"closeDropdown.preset.loading\"\n (click)=\"savePreset(presetNameCtrl)\"\n type=\"button\"\n style=\"height: 32px\"\n class=\"btn btn-primary w-100 d-flex align-items-center justify-content-center\"\n >\n <span style=\"margin-top: -2px\">\n <ng-container *ngIf=\"!closeDropdown.preset.loading && (!tableFilterViewId || tableFilterViewId === 'default')\"\n >Save</ng-container\n >\n <ng-container *ngIf=\"!closeDropdown.preset.loading && tableFilterViewId && tableFilterViewId !== 'default'\"\n >Update</ng-container\n >\n <ng-container *ngIf=\"closeDropdown.preset.loading\"\n ><span class=\"spinner-border spinner-border-sm\"></span\n ></ng-container>\n </span>\n </button>\n </div>\n </div>\n</ng-template>\n\n<ng-template #showHideColumns>\n <div\n (click)=\"$event.stopPropagation()\"\n class=\"p-3 shadow rounded-3 bg-white actions-dropdown mt-1 dropdown-menu show shadow custom-menu table-layout\"\n style=\"width: 280px\"\n >\n <!-- Header -->\n <div class=\"d-flex justify-content-between align-items-center mb-3\">\n <div class=\"d-flex align-items-center\">\n <button\n class=\"btn btn-link p-0\"\n style=\"margin-left: -10px\"\n (click)=\"toggleActions('setting')\"\n >\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrow-left.svg'\"\n class=\"data-grid-svg-icon\"\n ></span>\n </button>\n <h6 class=\"mb-0 ms-2\" style=\"font-weight: 500\">Columns</h6>\n </div>\n <a\n (click)=\"resetColumns()\"\n href=\"javascript:void(0)\"\n class=\"text-primary text-decoration-none\"\n >Reset</a\n >\n </div>\n\n <!-- Search -->\n <div class=\"mb-3\">\n <div class=\"col-12 global-search\">\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/search.svg'\"\n class=\"mx-2 position-absolute icon data-grid-svg-icon\"\n ></span>\n <input\n class=\"form-control form-control-sm\"\n placeholder=\"Search column\"\n type=\"search\"\n [(ngModel)]=\"topShowHideColumns\"\n />\n </div>\n </div>\n <!-- Preset List -->\n <div\n class=\"list-group list-group-flush\"\n style=\"\n max-height: calc(100vh - 300px);\n overflow: auto;\n scrollbar-width: thin;\n \"\n >\n <div class=\"muted-text show-hide-table-label d-flex justify-content-between\" *ngIf=\"hasAnyVisibleColumn\">\n Show in table\n <div class=\"form-check\">\n <input\n type=\"checkbox\"\n id=\"show_hide_all\"\n class=\"form-check-input\"\n [checked]=\"areAllNonMandatoryVisible()\"\n (change)=\"toggleAllVisibleColumns()\"\n />\n <label for=\"show_hide_all\" class=\"form-check-label fw-semibold\">Show/Hide All</label>\n </div>\n </div>\n <!-- <div class=\"d-flex align-items-center mb-2\" *ngIf=\"hasAnyVisibleColumn\">\n <input\n type=\"checkbox\"\n class=\"form-check-input me-2\"\n [checked]=\"areAllNonMandatoryVisible()\"\n (change)=\"toggleAllVisibleColumns()\"\n />\n <label class=\"form-check-label fw-semibold\">Show All</label>\n </div> -->\n <!-- Item -->\n <ng-container\n *ngFor=\"\n let col of columns | filter : topShowHideColumns : 'header';\n trackBy: trackByField\n \"\n >\n <div\n *ngIf=\"col.is_visible\"\n class=\"list-group-item border-0 px-0 d-flex justify-content-between align-items-center\"\n >\n <div class=\"d-flex gap-1\">\n <div>\n <span\n *ngIf=\"!col?.pinned\"\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/grip-vertical.svg'\n \"\n class=\"cursor-grap data-grid-svg-icon\"\n (mousedown)=\"$event.preventDefault()\"\n ></span>\n <span\n *ngIf=\"col?.pinned\"\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/pin-blue.svg'\n \"\n class=\"cursor-grap data-grid-svg-icon\"\n (mousedown)=\"$event.preventDefault()\"\n ></span>\n </div>\n <div class=\"fw-semibold\">\n {{ col.header }}\n </div>\n </div>\n <div\n *ngIf=\"!col?.query?.first_value && !col?.query?._ids?.length && !isMandatory(col)\"\n class=\"d-flex align-items-center cursor-pointer\"\n (click)=\"toggleColumnVisibility(col, false)\"\n >\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/eye.svg'\"\n class=\"data-grid-svg-icon me-2\"\n ></span>\n </div>\n <div\n *ngIf=\"(!col?.query?.first_value && !col?.query?._ids?.length && isMandatory(col)) || (col?.query?.first_value || col?.query?._ids?.length)\"\n class=\"d-flex align-items-center\"\n style=\"opacity: 0.5\"\n >\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/eye.svg'\"\n class=\"data-grid-svg-icon me-2\"\n ></span>\n </div>\n </div>\n </ng-container>\n\n <!-- Item End Here -->\n\n <div\n class=\"dropdown-divider\"\n *ngIf=\"hasAnyVisibleColumn && hasAnyInVisibleColumn\"\n ></div>\n\n <!-- <div\n class=\"muted-text show-hide-table-label\"\n *ngIf=\"hasAnyInVisibleColumn\"\n >\n Hide in table\n </div>\n <div class=\"d-flex align-items-center mb-2\" *ngIf=\"hasAnyInVisibleColumn\">\n <input\n type=\"checkbox\"\n id=\"hide_show_all\"\n class=\"form-check-input me-2\"\n [checked]=\"areAllNonMandatoryHidden()\"\n (change)=\"toggleAllInvisibleColumns()\"\n />\n <label class=\"form-check-label fw-semibold\">Hide All</label>\n </div> -->\n\n \n\n\n\n <div class=\"muted-text show-hide-table-label d-flex justify-content-between\" *ngIf=\"hasAnyInVisibleColumn\">\n Hide in table\n <div class=\"form-check\">\n <input\n type=\"checkbox\"\n id=\"hide_show_all\"\n class=\"form-check-input\"\n [checked]=\"areAllNonMandatoryHidden()\"\n (change)=\"toggleAllInvisibleColumns()\"\n />\n <label for=\"hide_show_all\" class=\"form-check-label fw-semibold\">Hide/Show All</label>\n </div>\n </div>\n <div class=\"list-group list-group-flush\">\n <ng-container *ngFor=\"let col of columns; trackBy: trackByField\">\n <div\n *ngIf=\"!col.is_visible\"\n class=\"list-group-item border-0 px-0 d-flex justify-content-between align-items-center\"\n >\n <div class=\"d-flex gap-1\">\n <div>\n <span\n *ngIf=\"!col?.pinned\"\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/grip-vertical.svg'\n \"\n class=\"data-grid-svg-icon cursor-grap\"\n (mousedown)=\"$event.preventDefault()\"\n ></span>\n <span\n *ngIf=\"col?.pinned\"\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/pin-blue.svg'\n \"\n class=\"data-grid-svg-icon cursor-grap\"\n (mousedown)=\"$event.preventDefault()\"\n ></span>\n </div>\n <div class=\"fw-semibold\">\n {{ col.header }}\n </div>\n </div>\n <div\n class=\"d-flex align-items-center cursor-pointer\"\n (click)=\"toggleColumnVisibility(col, true)\"\n >\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/eye-cross.svg'\n \"\n class=\"data-grid-svg-icon me-2\"\n ></span>\n </div>\n </div>\n </ng-container>\n </div>\n\n <!-- Item End Here -->\n </div>\n </div>\n</ng-template>\n\n<ng-template #filterColumns let-col=\"column\">\n <div\n @slideToggle\n *ngIf=\"!isFilterOpen && activeTopButton == 'filter-columns'\"\n (click)=\"$event.stopPropagation()\"\n class=\"shadow rounded-3 bg-white actions-dropdown mt-1 show shadow custom-menu table-layout filter-columns\"\n style=\"width: 280px; right: unset; max-width: 230px\"\n >\n <div class=\"mb-2 px-3\">\n <div class=\"col-12 global-search\">\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/search.svg'\"\n class=\"data-grid-svg-icon mx-2 position-absolute icon\"\n ></span>\n <input\n class=\"form-control form-control-sm\"\n placeholder=\"Filter by\"\n type=\"search\"\n [(ngModel)]=\"addFilterColumnInput\"\n />\n </div>\n </div>\n <div\n class=\"list-group list-group-flush\"\n style=\"max-height: calc(100vh - 500px); overflow: auto\"\n >\n <ng-container\n *ngFor=\"\n let col of columns | filter : addFilterColumnInput : 'header';\n trackBy: trackByField\n \"\n >\n <div\n (click)=\"openFilter(col)\"\n *ngIf=\"\n col.is_visible &&\n !col?.query?.first_value &&\n !col?.query?._ids?.length\n \"\n class=\"list-group-item border-0 px-0 d-flex justify-content-between align-items-center dropdown-item cursor-pointer\"\n >\n <div class=\"d-flex gap-1\">\n <div style=\"margin-top: -3px\"></div>\n <div class=\"fw-semibold\">\n {{ col.header }}\n </div>\n </div>\n </div>\n </ng-container>\n </div>\n </div>\n\n <!-- Dropdown -->\n <div\n @slideToggle\n *ngIf=\"isFilterOpen && selectedColumnForFilter.type == 'dropdown'\"\n (click)=\"$event.stopPropagation()\"\n class=\"shadow rounded-3 bg-white actions-dropdown mt-1 show shadow custom-menu table-layout filter-columns\"\n style=\"width: 280px; right: unset; max-width: 230px\"\n >\n <div class=\"px-3 my-2 border-below py-1 pb-2 mb-3 d-flex ps-1\">\n <span\n (click)=\"toggleActions('filter-columns'); isActiveFilterOpen = false\"\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrow-left.svg'\"\n class=\"data-grid-svg-icon me-2 cursor-pointer\"\n ></span\n ><b>{{ selectedColumnForFilter?.header }}</b>\n </div>\n <div class=\"mb-2 px-3\">\n <div\n class=\"col-12 global-search position-relative border rounded d-flex align-items-center flex-wrap px-2 filter-serach-inpt\"\n >\n <span\n *ngFor=\"let selected of selectedFilterOptions\"\n class=\"badge d-flex align-items-center gap-1 me-1 mb-1\"\n >\n {{ selected?.value ? selected.value : selected }}\n <span\n (click)=\"toggleSelectionInFilter(selected)\"\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/cross-primary.svg'\n \"\n class=\"me-2\"\n ></span>\n </span>\n <input\n class=\"form-control form-control-sm border-0 flex-grow-1\"\n style=\"padding: 0\"\n [placeholder]=\"selectedFilterOptions!.length ? '' : 'Filter by'\"\n type=\"search\"\n [(ngModel)]=\"searchTextForFilterDropDown\"\n (keydown.backspace)=\"handleBackspace($event)\"\n (ngModelChange)=\"selectedFilterOptions.length === 0 ? condition = 'none' : null\"\n />\n </div>\n </div>\n <div\n class=\"list-group list-group-flush\"\n style=\"max-height: calc(100vh - 600px); overflow: auto\"\n >\n <ng-container\n *ngFor=\"\n let col of selectedColumnForFilter.column_dropdown_value\n | filter : searchTextForFilterDropDown : 'value';\n let i = index\n \"\n >\n <div\n class=\"list-group-item border-0 px-2 d-flex justify-content-between align-items-center dropdown-item cursor-pointer\"\n >\n <div class=\"form-check\">\n <input\n class=\"form-check-input\"\n type=\"checkbox\"\n [id]=\"i\"\n [checked]=\"currentFilterSelectedIds.has(col.id || col._id || col)\"\n (change)=\"toggleSelectionInFilter(col)\"\n />\n <label class=\"form-check-label fw-semibold\" [for]=\"i\">\n {{ col?.value || col?.name || col }}\n </label>\n </div>\n </div>\n </ng-container>\n </div>\n <div\n class=\"d-flex justify-content-center gap-2 px-2 border-top\"\n style=\"height: 38px\"\n >\n <button\n type=\"button\"\n style=\"height: 32px\"\n class=\"btn btn-outline-secondary btn-light border w-100 d-flex align-items-center justify-content-center mt-1 btn-light\"\n (click)=\"$event.stopPropagation(); resetFilterChanges()\"\n >\n <span>Cancel</span>\n </button>\n <button\n type=\"button\"\n style=\"height: 32px\"\n class=\"btn btn-primary w-100 d-flex align-items-center justify-content-center mt-1\"\n (click)=\"applyDropdownFilter()\"\n >\n <span style=\"margin-top: -2px\">Save</span>\n </button>\n </div>\n </div>\n\n <!-- For Text fields and number fields-->\n\n <div\n @slideToggle\n *ngIf=\"\n isFilterOpen &&\n (selectedColumnForFilter.type == 'string' ||\n selectedColumnForFilter.type == 'number' ||\n selectedColumnForFilter.type == 'date')\n \"\n (click)=\"$event.stopPropagation()\"\n class=\"shadow rounded-3 bg-white actions-dropdown mt-1 show shadow custom-menu table-layout filter-columns\"\n style=\"width: 280px; right: unset; max-width: 230px\"\n >\n <div class=\"px-3 border-below py-1 pb-2 d-flex ps-1\">\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrow-left.svg'\"\n (click)=\"toggleActions('filter-columns'); isActiveFilterOpen = false\"\n class=\"data-grid-svg-icon me-2 cursor-pointer\"\n ></span\n ><b>{{ selectedColumnForFilter?.header }}</b>\n </div>\n <div class=\"col-12 position-relative p-2 text-filter\">\n <div class=\"mb-2\">\n <select\n class=\"form-select form-select-sm custom-select\"\n [(ngModel)]=\"firstCondition\"\n >\n <ng-container *ngIf=\"selectedColumnForFilter.type === 'date' || selectedColumnForFilter.type === 'time'; else textOptions\">\n <option value=\"equal\">Equal to</option>\n <option value=\"not_equal\">Not Equal</option>\n <option value=\"after\">After</option>\n <option value=\"before\">Before</option>\n </ng-container>\n <ng-template #textOptions>\n <option value=\"equal\">Equals</option>\n <!-- <option value=\"not_equal\">Not Equals</option> -->\n <option value=\"contain\">Contains</option>\n <option value=\"before\">Begins With</option>\n <option value=\"after\">Ends With</option>\n </ng-template>\n </select>\n </div>\n <div class=\"mb-2\">\n <input\n class=\"form-control form-control-sm\"\n placeholder=\"Enter first value\"\n [type]=\"\n selectedColumnForFilter.type == 'string'\n ? 'text'\n : selectedColumnForFilter.type\n \"\n [(ngModel)]=\"firstValue\"\n [min]=\"selectedColumnForFilter.type == 'number' ? 0 : null\"\n [class.number-input]=\"selectedColumnForFilter.type == 'number'\"\n (input)=\"selectedColumnForFilter.type == 'number' && $any($event.target).value < 0 ? $any($event.target).value = 0 : null\"\n (ngModelChange)=\"!firstValue ? condition = 'none' : null\"\n (keydown)=\"selectedColumnForFilter.type == 'number' && $event.key === '-' ? $event.preventDefault() : null\"\n />\n </div>\n <div class=\"d-flex my-3\">\n <div class=\"form-check form-check-inline\">\n <input\n class=\"form-check-input\"\n type=\"radio\"\n id=\"logicalAnd\"\n name=\"logicalOperator\"\n value=\"and\"\n [(ngModel)]=\"condition\"\n />\n <label class=\"form-check-label\" for=\"logicalAnd\">AND</label>\n </div>\n\n <div class=\"form-check form-check-inline\">\n <input\n class=\"form-check-input\"\n type=\"radio\"\n id=\"logicalOr\"\n name=\"logicalOperator\"\n value=\"or\"\n [(ngModel)]=\"condition\"\n />\n <label class=\"form-check-label\" for=\"logicalOr\">OR</label>\n </div>\n\n <div class=\"form-check form-check-inline\">\n <input\n class=\"form-check-input\"\n type=\"radio\"\n id=\"logicalNone\"\n name=\"logicalOperator\"\n value=\"none\"\n [(ngModel)]=\"condition\"\n />\n <label class=\"form-check-label\" for=\"logicalNone\">None</label>\n </div>\n </div>\n\n <div *ngIf=\"firstValue && condition !== 'none'\">\n <div class=\"my-3\">\n <!-- Second condition select -->\n <select\n class=\"form-select form-select-sm\"\n [(ngModel)]=\"secondCondition\"\n >\n <ng-container *ngIf=\"selectedColumnForFilter.type === 'date' || selectedColumnForFilter.type === 'time'; else textOptionsSecond\">\n <option value=\"equal\">Equal to</option>\n <option value=\"not_equal\">Not Equal</option>\n <option value=\"after\">After</option>\n <option value=\"before\">Before</option>\n </ng-container>\n <ng-template #textOptionsSecond>\n <option value=\"equal\">Equals</option>\n <!-- <option value=\"not_equal\">Not Equals</option> -->\n <option value=\"contain\">Contains</option>\n <option value=\"before\">Begins With</option>\n <option value=\"after\">Ends With</option>\n </ng-template>\n </select>\n </div>\n\n <div class=\"mb-2\">\n <!-- Second value input -->\n <input\n [type]=\"\n selectedColumnForFilter.type == 'string'\n ? 'text'\n : selectedColumnForFilter.type\n \"\n class=\"form-control form-control-sm\"\n placeholder=\"Enter second value\"\n [(ngModel)]=\"secondValue\"\n [min]=\"selectedColumnForFilter.type == 'number' ? 0 : null\"\n [class.number-input]=\"selectedColumnForFilter.type == 'number'\"\n (input)=\"selectedColumnForFilter.type == 'number' && $any($event.target).value < 0 ? $any($event.target).value = 0 : null\"\n (keydown)=\"selectedColumnForFilter.type == 'number' && $event.key === '-' ? $event.preventDefault() : null\"\n />\n </div>\n </div>\n </div>\n\n <div\n class=\"d-flex justify-content-center gap-2 px-2 border-top\"\n style=\"height: 38px\"\n >\n <button\n type=\"button\"\n style=\"height: 32px\"\n class=\"btn btn-outline-secondary btn-light border w-100 d-flex align-items-center justify-content-center mt-1 btn-light\"\n (click)=\"$event.stopPropagation(); resetTextFilterChanges()\"\n >\n <span>Cancel</span>\n </button>\n <button\n type=\"button\"\n style=\"height: 32px\"\n class=\"btn btn-primary w-100 d-flex align-items-center justify-content-center mt-1\"\n (click)=\"applyDropdownFilter()\"\n >\n <span style=\"margin-top: -2px\">Save</span>\n </button>\n </div>\n </div>\n</ng-template>\n\n<!-- Detail Filter Menu -->\n <div\n *ngIf=\"activeAccordionFilterMenu && detailFilterMenuPosition\"\n class=\"detail-filter-menu\"\n [style.backgroundColor]=\"dropdownsBackgroundColor\"\n [style.left.px]=\"detailFilterMenuPosition.x\"\n [style.top.px]=\"detailFilterMenuPosition.y\"\n (click)=\"$event.stopPropagation()\"\n >\n <div class=\"px-3 border-below py-1 pb-2 d-flex ps-1\">\n <span\n (click)=\"closeDetailFilterMenu()\"\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrow-left.svg'\"\n class=\"data-grid-svg-icon me-2 cursor-pointer\"\n ></span\n ><b>{{ activeDetailFilterCol?.header }}</b>\n </div>\n\n <!-- Text Filter -->\n <div *ngIf=\"detailFilterType === 'string'\" class=\"col-12 position-relative p-2 text-filter\">\n <div class=\"mb-2\">\n <select\n class=\"form-select form-select-sm custom-select\"\n [(ngModel)]=\"detailFilterCondition\"\n >\n <option value=\"contain\">Contains</option>\n <option value=\"equal\">Equals</option>\n <option value=\"before\">Begins With</option>\n <option value=\"after\">Ends With</option>\n </select>\n </div>\n <div class=\"mb-2\">\n <input\n class=\"form-control form-control-sm\"\n placeholder=\"Enter value\"\n [(ngModel)]=\"detailFilterValue\"\n (keydown.enter)=\"applyDetailFilter()\"\n />\n </div>\n </div>\n\n <!-- Date Filter -->\n <div *ngIf=\"detailFilterType === 'date'\" class=\"col-12 position-relative p-2 text-filter\">\n <div class=\"mb-2\">\n <select\n class=\"form-select form-select-sm custom-select\"\n [(ngModel)]=\"detailFilterCondition\"\n >\n <option value=\"equal\">Equal to</option>\n <option value=\"before\">Before</option>\n <option value=\"after\">After</option>\n </select>\n </div>\n <div class=\"mb-2\">\n <input\n type=\"date\"\n class=\"form-control form-control-sm\"\n placeholder=\"Select date\"\n [(ngModel)]=\"detailFilterDateValue\"\n (keydown.enter)=\"applyDetailFilter()\"\n />\n <small class=\"text-muted d-block mt-1\">{{ detailFilterDateValue | timezoneFormat:prefs:'date' }}</small>\n </div>\n </div>\n\n <!-- Time Filter -->\n <div *ngIf=\"detailFilterType === 'time'\" class=\"col-12 position-relative p-2 text-filter\">\n <div class=\"mb-2\">\n <select\n class=\"form-select form-select-sm custom-select\"\n [(ngModel)]=\"detailFilterCondition\"\n >\n <option value=\"equal\">Equal to</option>\n <option value=\"before\">Before</option>\n <option value=\"after\">After</option>\n </select>\n </div>\n <div class=\"mb-2\">\n <input\n type=\"time\"\n class=\"form-control form-control-sm\"\n placeholder=\"Select time\"\n [(ngModel)]=\"detailFilterTimeValue\"\n (keydown.enter)=\"applyDetailFilter()\"\n />\n </div>\n </div>\n\n <!-- Dropdown Filter -->\n <div *ngIf=\"detailFilterType === 'dropdown'\" class=\"col-12 position-relative p-2 text-filter\">\n <div class=\"mb-2\">\n <input\n type=\"text\"\n class=\"form-control form-control-sm\"\n placeholder=\"Search options...\"\n [(ngModel)]=\"detailFilterSearch\"\n (input)=\"filterDetailDropdownOptions()\"\n />\n </div>\n <div class=\"dropdown-options\" style=\"max-height: 150px; overflow-y: auto;\">\n <div\n *ngFor=\"let option of filteredDetailDropdownOptions; let i = index\"\n class=\"form-check mb-1 ms-1\"\n >\n <input\n class=\"form-check-input\"\n type=\"checkbox\"\n [id]=\"'detail-filter-option-' + i\"\n [checked]=\"detailSelectedFilterOptions.includes(option._id || option.id || option.value)\"\n (change)=\"toggleDetailFilterOption(option)\"\n />\n <label\n class=\"form-check-label\"\n [for]=\"'detail-filter-option-' + i\"\n >\n {{ option.value || option.name || option }}\n </label>\n </div>\n </div>\n </div>\n\n <!-- <div class=\"d-flex gap-2\">\n <button\n type=\"button\"\n class=\"btn btn-primary w-100 d-flex align-items-center justify-content-center mt-1\"\n (click)=\"applyDetailFilter()\"\n >\n <span>Apply</span>\n </button>\n <button\n type=\"button\"\n class=\"btn btn-danger w-100 d-flex align-items-center justify-content-center mt-1\"\n (click)=\"resetDetailFilter()\"\n >\n <span>Reset</span>\n </button>\n \n</div> -->\n\n <div class=\"d-flex gap-2 mt-2\">\n <div\n class=\"btn btn-sm btn-primary d-flex justify-content-center align-items-center w-100\"\n style=\"height: 22px\"\n (click)=\"applyDetailFilter()\"\n >\n Apply\n </div>\n <div\n class=\"btn btn-sm btn-secondary d-flex justify-content-center align-items-center w-100\"\n style=\"height: 22px\"\n (click)=\"resetDetailFilter()\"\n >\n Reset\n </div>\n </div>\n</div>\n\n<!-- Edit dropdown here -->\n<ng-template let-col>\n <div class=\"drop-down-edit\"></div>\n</ng-template>\n\n<ng-template\n #fullTextTemplate\n let-row=\"row\"\n let-col=\"col\"\n let-isArray=\"isArray\"\n>\n <div\n class=\"full-text-box\"\n (dblclick)=\"$event.stopPropagation(); $event.preventDefault();\"\n (click)=\"$event.stopPropagation(); $event.preventDefault()\"\n >\n <ng-container *ngIf=\"!isEditing(row, col)\">\n <div\n *ngIf=\"!isArray\"\n class=\"full-text-content\"\n (dblclick)=\"$event.stopPropagation(); $event.preventDefault(); enableEdit(row, col)\"\n (click)=\"$event.stopPropagation(); $event.preventDefault()\"\n >\n {{\n getNestedValue(row, col.field)?.value ||\n getNestedValue(row, col.field)?.name ||\n getNestedValue(row, col.field)\n }}\n </div>\n <div *ngIf=\"isArray\">\n <ul>\n <ng-container\n *ngFor=\"let item of getNestedValue(row, col.field); let i = index\"\n >\n <li *ngIf=\"i !== 0\">\n <ng-container>\n {{ item?.department_name || item?.roleName || \"-\" }}\n </ng-container>\n </li>\n </ng-container>\n </ul>\n </div>\n </ng-container>\n <ng-container *ngIf=\"isEditing(row, col)\">\n <textarea\n #textModel=\"ngModel\"\n rows=\"4\"\n #textAreadInput\n [(ngModel)]=\"row[col.field]\"\n name=\"{{ col.field }}\"\n required\n (blur)=\"disableEdit(row, col, textModel)\"\n (keydown.enter)=\"textAreadInput.blur()\"\n autofocus\n class=\"form-control\"\n [ngClass]=\"{\n 'is-invalid': textModel.invalid\n }\"\n (mousedown)=\"$event.stopPropagation()\"\n ></textarea>\n\n </ng-container>\n </div>\n</ng-template>\n\n<ng-template #defaultImagePlaceholder let-row=\"row\" let-col=\"col\">\n <span\n class=\"px-2 d-flex align-items-center w-100 cell-content image-placeholder cursor-pointer position-relative\"\n \n (click)=\"onEmployeeClick(row)\"\n >\n <!-- Blue dot for manual logs -->\n <span\n *ngIf=\"row?.manually_logs && row.manually_logs.length > 0\"\n class=\"manual-logs-indicator\"\n (mouseenter)=\"openManualLogsModal($event, row)\"\n (mouseleave)=\"closeManualLogsModal()\"\n ></span>\n <ng-container\n *ngIf=\"\n row?.User?.logo || row?.User?.profile_pictures?.length || row?.logo || row?.profile_pictures?.length || row?.assetImage || row?.invoice?.invoice_image;\n else placeholder\n \"\n >\n <span class=\"pic\">\n <img\n [width]=\"rowHeight - 12\"\n [height]=\"rowHeight - 12\"\n [src]=\"row?.User?.profile_pictures?.[4]?.path || row?.User?.logo || row?.profile_pictures?.[4]?.path || row?.logo || row?.assetImage || row?.invoice?.invoice_image\"\n alt=\"icon\"\n />\n </span>\n </ng-container>\n\n <ng-template #placeholder>\n <span\n [ngClass]=\"getDynamicClass(row?.User?.full_name || row?.full_name || row?.name)\"\n class=\"pic d-flex align-items-center rounded-circle\"\n [style.width.px]=\"rowHeight - 12\"\n [style.height.px]=\"rowHeight - 12\"\n [style.fontSize.px]=\"rowHeight / 3\"\n >\n {{ getInitials(row?.User?.full_name || row?.full_name) }}\n </span>\n </ng-template>\n </span>\n</ng-template>\n\n<!-- Cell Content Template for Card View -->\n<ng-template #cellContent let-row=\"row\" let-parentRow=\"parentRow\" let-col=\"col\">\n <ng-container [ngSwitch]=\"col.type\">\n <!-- String/Text -->\n <ng-container *ngSwitchCase=\"'string'\">\n {{ getNestedValue(row, col.field) || getNestedValue(parentRow, col.field) || '-' }}\n </ng-container>\n\n <!-- Number -->\n <ng-container *ngSwitchCase=\"'number'\">\n {{ getNestedValue(row, col.field) || getNestedValue(parentRow, col.field) || '-' }}\n </ng-container>\n\n <!-- Date -->\n <ng-container *ngSwitchCase=\"'date'\">\n {{ getNestedValue(row, col.field) || getNestedValue(parentRow, col.field) ? (getNestedValue(row, col.field) || getNestedValue(parentRow, col.field) | timezoneFormat:prefs:'date') : '-' }}\n </ng-container>\n\n <!-- Time -->\n <ng-container *ngSwitchCase=\"'time'\">\n {{ (getNestedValue(row, col.field) || getNestedValue(parentRow, col.field)) !== null && (getNestedValue(row, col.field) || getNestedValue(parentRow, col.field)) !== undefined ? ((getTimeValue(getNestedValue(row, col.field) || getNestedValue(parentRow, col.field)) | timezoneFormat:prefs:'time')) : '-' }}\n </ng-container>\n\n <!-- Boolean -->\n <ng-container *ngSwitchCase=\"'boolean'\">\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'\">\n {{ (getNestedValue(row, col.field) || getNestedValue(parentRow, col.field) === true || getNestedValue(row, col.field) || getNestedValue(parentRow, col.field) === 'true') ? 'Yes' : 'No' }}\n </span>\n </ng-container>\n\n <!-- <div *ngSwitchCase=\"'is_payroll_processed'\" class=\"d-flex justify-content-start flex-column pointer position-relative\" >\n <span class=\"popover__wrapper\" >none\n {{ row.is_payroll_processed ? 'Yes' : 'No' }}\n </span>\n </div> -->\n\n <!-- Status -->\n <ng-container *ngSwitchCase=\"'status'\">\n <span class=\"badge\" [class]=\"getStatusBadgeClass(getNestedValue(row, col.field) || getNestedValue(parentRow, col.field))\">\n {{ transformStatus(getNestedValue(row, col.field) || getNestedValue(parentRow, col.field)) || '-' }}\n </span>\n </ng-container>\n\n <!-- Array -->\n <ng-container *ngSwitchCase=\"'array'\">\n <ng-container *ngIf=\"isArray(getNestedValue(row, col.field) || getNestedValue(parentRow, col.field))\">\n <ng-container *ngIf=\"col.field === 'breaks' || col.header?.toLowerCase().includes('break')\">\n <app-badge-overflow\n [badges]=\"getBreakBadges(getNestedValue(row, col.field) || getNestedValue(parentRow, col.field) || [])\"\n [maxWidth]=\"col.width || 200\"\n (badgeMouseEnter)=\"showBreakTooltip($event.event, $event.badge.data)\"\n (badgeMouseLeave)=\"hideBreakTooltip()\"\n (overflowCountClick)=\"onBadgeOverflowCountClick(col)\">\n </app-badge-overflow>\n </ng-container>\n <ng-container *ngIf=\"!(col.field === 'breaks' || col.header?.toLowerCase().includes('break'))\">\n {{ (getNestedValue(row, col.field) || getNestedValue(parentRow, col.field) || []).length }} items\n </ng-container>\n </ng-container>\n <ng-container *ngIf=\"!isArray(getNestedValue(row, col.field) || getNestedValue(parentRow, col.field))\">\n {{ getNestedValue(row, col.field) || getNestedValue(parentRow, col.field) || '-' }}\n </ng-container>\n </ng-container>\n\n <!-- Default -->\n <ng-container *ngSwitchDefault>\n {{ getNestedValue(row, col.field) || getNestedValue(parentRow, col.field) || '-' }}\n </ng-container>\n \n </ng-container>\n</ng-template>\n\n<!-- Right Click Menue -->\n<div\n [class.invisible]=\"!positionedYet\"\n class=\"context-menu p-2\"\n *ngIf=\"actionHide && actions?.length\"\n [ngStyle]=\"{ 'top.px': yPos, 'left.px': xPos }\"\n [class.show]=\"isVisible\"\n appendTo=\"body\"\n>\n <ul>\n <li\n *ngFor=\"let action of actions\"\n class=\"rounded d-flex align-items-center\"\n (click)=\"onActionClick(action)\"\n >\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/' + action + '.svg'\"\n class=\"data-grid-svg-icon me-2\"\n ></span>\n <span class=\"text-capitalize fw-500\">{{ action }}</span>\n </li>\n </ul>\n</div>\n\n<!-- Details Toggle from bottom -->\n <div\n [style.bottom.px]=\"footerRowHeight + 50\"\n *ngIf=\"selectedRows.size > 0 && showTaskbar\"\n class=\"taskbar\"\n >\n <div class=\"selected-rows-action-bar\" [@slideUp]>\n <span class=\"selected-count\">\n {{ selectedRows.size }} selected of\n {{\n paginationConfig.totalResults ||\n config?.paginationParams?.totalItems\n }}\n Total\n </span>\n <div class=\"action-buttons\">\n <ng-container *ngFor=\"let action of computedTaskbarActions; let i = index\">\n <span\n class=\"action-btn verified btn {{ action }}\"\n (click)=\"action === 'Export' ? onExportClick() : action === 'Delete' ? onDeleteClick() : onVerifyClick(action)\"\n >{{ action }}</span\n >\n <span\n *ngIf=\"computedTaskbarActions.length > 1 && i !== computedTaskbarActions.length - 1\"\n class=\"separator\"\n >|</span\n >\n </ng-container>\n </div>\n </div>\n </div>\n\n<!-- Detail Row Choose Columns Modal -->\n<div *ngIf=\"showDetailColumnPanel\" class=\"custom-modal-overlay\" (click)=\"closeDetailColumnPanel()\">\n <div\n class=\"custom-modal-content\"\n [style.backgroundColor]=\"dropdownsBackgroundColor\"\n (click)=\"$event.stopPropagation()\"\n >\n <ng-container *ngTemplateOutlet=\"detailModalColumnPannel\"></ng-container>\n </div>\n</div>\n\n<!-- Paste Confirmation Modal -->\n<div *ngIf=\"showPasteConfirmationModal\" class=\"custom-modal-overlay\" (click)=\"cancelPaste()\">\n <div class=\"custom-modal-content\" [style.backgroundColor]=\"dropdownsBackgroundColor\" (click)=\"$event.stopPropagation()\">\n <div class=\"column-panel-header\">\n <div class=\"d-flex justify-content-between align-items-center px-2 ps-3 rounded-top-2 moda-header\" style=\"height: 48px;\">\n Confirm Paste Operation\n <span class=\"filter-icon-wrapper\" (click)=\"cancelPaste()\">\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/x.svg'\" class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"></span>\n </span>\n </div>\n <hr class=\"my-0\" />\n <div class=\"p-3\">\n <div class=\"mb-3\">\n <h6 class=\"mb-3\">You are about to paste the following data:</h6>\n <div class=\"border rounded p-3 bg-light\">\n <pre class=\"mb-0 text-dark small\">{{ pastePreviewData }}</pre>\n </div>\n </div>\n <div class=\"alert alert-warning\" role=\"alert\">\n <strong>Warning:</strong> This action will overwrite existing data in the selected cells. This cannot be undone.\n </div>\n <div class=\"d-flex justify-content-end gap-2 mt-4\">\n <button type=\"button\" class=\"btn btn-secondary\" (click)=\"cancelPaste()\">Cancel</button>\n <button type=\"button\" class=\"btn btn-primary\" (click)=\"confirmPaste()\">Confirm Paste</button>\n </div>\n </div>\n </div>\n </div>\n</div>\n\n<!-- Short Leave Tooltip Modal -->\n<div *ngIf=\"showShortLeaveTooltipModal\"\n class=\"custom-break-tooltips\"\n @tooltipAnimationBottom\n [style.--tooltip-x.px]=\"shortLeaveTooltipPosition.x\"\n [style.--tooltip-y.px]=\"shortLeaveTooltipPosition.y\"\n (mouseenter)=\"preventShortLeaveTooltipHide()\"\n (mouseleave)=\"hideShortLeaveTooltip()\">\n <div class=\"modal-body\">\n <div class=\"table-responsive\">\n <table class=\"table table-striped text-dark\">\n <thead>\n <tr>\n <th>Leave Type</th>\n <th>Start Time</th>\n <th>End Time</th>\n <th>Duration (min)</th>\n </tr>\n </thead>\n <tbody>\n <tr *ngFor=\"let item of currentShortLeaveData\">\n <td>{{ item.leave_type || 'N/A' }}</td>\n\n <!-- Start Time -->\n <td>\n {{\n item.star_time\n ? (getTimeValue(item.star_time) | timezoneFormat:prefs:'time')\n : 'N/A'\n }}\n </td>\n\n <!-- End Time -->\n <td>\n {{\n item.end_time\n ? (getTimeValue(item.end_time) | timezoneFormat:prefs:'time')\n : 'N/A'\n }}\n </td>\n\n <td>{{ item.minutes || 'N/A' }}</td>\n</tr>\n\n </tbody>\n </table>\n </div>\n </div>\n </div>\n\n<!-- Paste Confirmation Modal -->\n<div *ngIf=\"showPasteConfirmationModal\" class=\"custom-modal-overlay\" (click)=\"cancelPaste()\">\n <div class=\"custom-modal-content\" [style.backgroundColor]=\"dropdownsBackgroundColor\" (click)=\"$event.stopPropagation()\">\n <div class=\"column-panel-header\">\n <div class=\"d-flex justify-content-between align-items-center px-2 ps-3 rounded-top-2 moda-header\" style=\"height: 48px;\">\n <span class=\"fw-bold\">Confirm Paste</span>\n <span class=\"filter-icon-wrapper\" (click)=\"cancelPaste()\">\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/x.svg'\" class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"></span>\n </span>\n </div>\n <hr class=\"my-0\" />\n <div class=\"p-3\">\n <div class=\"mb-3\">\n <p class=\"mb-2\">Are you sure you want to paste the following data?</p>\n <div class=\"border rounded p-2 bg-light\">\n <small class=\"text-muted\">{{ pastePreviewData }}</small>\n </div>\n </div>\n <div class=\"d-flex gap-2 justify-content-end\">\n <button type=\"button\" class=\"btn btn-secondary\" (click)=\"cancelPaste()\">Cancel</button>\n <button type=\"button\" class=\"btn btn-primary\" (click)=\"confirmPaste()\">Confirm Paste</button>\n </div>\n </div>\n </div>\n </div>\n</div>\n\n<!-- Paste Confirmation Modal -->\n<div *ngIf=\"showPasteConfirmationModal\" class=\"custom-modal-overlay\" (click)=\"cancelPaste()\">\n <div class=\"custom-modal-content\" [style.backgroundColor]=\"dropdownsBackgroundColor\" (click)=\"$event.stopPropagation()\">\n <div class=\"modal-header d-flex justify-content-between align-items-center p-3\">\n <h5 class=\"modal-title mb-0\">Confirm Paste</h5>\n <button type=\"button\" class=\"btn-close\" (click)=\"cancelPaste()\"></button>\n </div>\n <div class=\"modal-body p-3\">\n <p class=\"mb-3\">Are you sure you want to paste the clipboard data into the selected cells?</p>\n <div class=\"alert alert-info\" *ngIf=\"pastePreviewData\">\n <strong>Paste Preview:</strong>\n <pre class=\"mt-2\">{{ pastePreviewData }}</pre>\n </div>\n </div>\n <div class=\"modal-footer p-3\">\n <button type=\"button\" class=\"btn btn-secondary\" (click)=\"cancelPaste()\">Cancel</button>\n <button type=\"button\" class=\"btn btn-primary\" (click)=\"confirmPaste()\">Paste</button>\n </div>\n </div>\n</div>\n\n<!-- Tooltip for accordion manual logs -->\n<!-- Tooltip for accordion manual logs -->\n<div *ngIf=\"showManualLogsTooltipModal\" class=\"custom-break-tooltips\"\n [style.--tooltip-x.px]=\"manualLogsTooltipPosition.x\"\n [style.--tooltip-y.px]=\"manualLogsTooltipPosition.y\"\n \n (mouseenter)=\"preventManualLogsTooltipHide()\"\n (mouseleave)=\"hideManualLogsTooltip()\">\n\n <div class=\"modal-body\">\n <div class=\"table-responsive\">\n <table class=\"table table-striped text-dark\">\n <thead>\n <tr>\n <th>Name</th>\n <th>Date/Time</th>\n <th>Previous</th>\n <th>Updated</th>\n <th>Status</th>\n <th>Remarks</th>\n </tr>\n </thead>\n <tbody>\n <ng-container *ngFor=\"let item of selectedManualLogs; let i = index\">\n <tr>\n <td>{{ item?.updated_by?.full_name || selectedManualLogsRow?.User?.full_name }}</td>\n <td>{{ item?.log_date && item.log_date !== '--' ? (item.log_date | timezoneFormat:prefs:'datetime') : (selectedManualLogsRow?.attendanceDate && selectedManualLogsRow?.attendanceDate !== '--' ? (selectedManualLogsRow?.attendanceDate | timezoneFormat:prefs:'datetime') : '-') }}</td>\n <td>\n <ng-container [ngSwitch]=\"isDate(item?.log_details?.previous_state)\">\n \n <!-- If it is a date -->\n <span *ngSwitchCase=\"true\">\n {{ formatLogState(item?.log_details?.previous_state) | timezoneFormat:prefs:'time' }}\n </span>\n\n <!-- If it is NOT a date -->\n <span *ngSwitchDefault>\n {{ item?.log_details?.previous_state || '-' }}\n </span>\n\n </ng-container>\n</td>\n\n\n<td>\n <ng-container [ngSwitch]=\"isDate(item?.log_details?.updated_state)\">\n \n <!-- If it is a date -->\n <span *ngSwitchCase=\"true\">\n {{ formatLogState(item?.log_details?.updated_state) | timezoneFormat:prefs:'time' }}\n </span>\n\n <!-- If it is NOT a date -->\n <span *ngSwitchDefault>\n {{ item?.log_details?.updated_state || '-' }}\n </span>\n\n </ng-container>\n</td>\n\n <td>{{ item?.log_details?.status ? transformStatus(item.log_details.status) : (item.log_details?.status || '-') }}</td>\n <td>{{ item?.log_details?.remarks || item?.remarks || selectedManualLogsRow?.message || '-' }}</td>\n </tr>\n </ng-container>\n\n <!-- Fallback for empty manual logs -->\n <tr *ngIf=\"!selectedManualLogs || selectedManualLogs.length === 0\">\n <td colspan=\"6\" class=\"text-center\">No manual logs available</td>\n </tr>\n </tbody>\n </table>\n </div>\n </div>\n </div>\n<!-- </div> -->\n\n<ng-template #detailModalColumnPannel>\n <div class=\"column-panel-header detail-column-modal\">\n <div\n class=\"d-flex justify-content-between align-items-center px-2 ps-3 rounded-top-2 moda-header\"\n [style.height.px]=\"48\"\n >\n Choose Detail Columns\n <span class=\"filter-icon-wrapper\" (click)=\"closeDetailColumnPanel()\">\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/x.svg'\"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n </span>\n </div>\n <hr class=\"my-0\" />\n <div>\n <div class=\"d-flex align-items-center px-2 pe-3\" [style.height.px]=\"48\">\n <input\n type=\"checkbox\"\n class=\"form-check-input me-2\"\n [checked]=\"allDetailColumnsSelected()\"\n (change)=\"toggleAllDetailColumnsVisibility()\"\n />\n <input\n type=\"text\"\n class=\"form-control form-control-sm\"\n placeholder=\"Search detail columns...\"\n [(ngModel)]=\"choseColumnsSearch\"\n />\n </div>\n <hr class=\"mt-0 mb-1\" />\n <div class=\"px-2 overlay-scrollable\">\n <ng-container\n *ngFor=\"\n let col of (currentDetailRowForColumnSelection?.details?.columns || [])\n | filter : choseColumnsSearch : 'header';\n trackBy: trackByField\n \"\n >\n <div class=\"d-flex align-items-center mb-2\">\n <input\n type=\"checkbox\"\n class=\"form-check-input me-2\"\n [checked]=\"col.is_visible !== false\"\n (change)=\"toggleDetailColumnVisibility(col, !col.is_visible)\"\n [id]=\"'detail_col_' + col.field\"\n />\n <label\n class=\"d-flex align-items-center mb-0 w-100\"\n [for]=\"'detail_col_' + col.field\"\n style=\"cursor: pointer\"\n >\n <span class=\"text-truncate\">{{ col.header }}</span>\n </label>\n </div>\n </ng-container>\n </div>\n </div>\n <!-- <div class=\"px-3 py-2 border-top d-flex justify-content-end\">\n <button class=\"btn btn-sm btn-link\" (click)=\"resetDetailColumnsInModal()\">Reset</button>\n </div> -->\n </div>\n</ng-template>\n\n\n\n\n\n\n\n\n\n\n\n", styles: ["@charset \"UTF-8\";@keyframes fadeInUp{0%{opacity:0;transform:translateY(8px)}to{opacity:1;transform:translateY(0)}}@keyframes fadeInScale{0%{opacity:0;transform:scale(.95)}to{opacity:1;transform:scale(1)}}@keyframes slideInRight{0%{opacity:0;transform:translate(16px)}to{opacity:1;transform:translate(0)}}@keyframes pulse{0%{transform:scale(1)}50%{transform:scale(1.02)}to{transform:scale(1)}}@keyframes shimmer{0%{background-position:-200px 0}to{background-position:calc(200px + 100%) 0}}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.loading-overlay{animation:fadeInScale .25s cubic-bezier(.4,0,.2,1);transform:translateZ(0)}.loading-overlay .spinner-border{animation:spin 1s linear infinite}.data-grid-table-wrapper{height:100%;width:100%;border:1px solid #d9d9db;border-radius:12px;box-shadow:none!important;position:relative;animation:fadeInScale .35s cubic-bezier(.4,0,.2,1);transform:translateZ(0)}.data-grid-table-wrapper[data-theme=white]{border-color:#d9d9db;background-color:#f6f8ff;color:#000}.data-grid-table-wrapper[data-theme=white] *,.data-grid-table-wrapper[data-theme=white] *:before,.data-grid-table-wrapper[data-theme=white] *:after{color:#000!important}.data-grid-table-wrapper[data-theme=white] ::selection{background-color:#007bff!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=white] ::-moz-selection{background-color:#007bff!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=white] .data-grid-header-wrapper{background-color:#f8f9fa;color:#000!important}.data-grid-table-wrapper[data-theme=white] .data-grid-body-wrapper{background-color:#f6f8ff;box-shadow:none!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .data-grid-row{border-bottom-color:#d9d9db;box-shadow:none!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .data-grid-row:nth-child(2n){background-color:#f8f9fa!important}.data-grid-table-wrapper[data-theme=white] .data-grid-row:nth-child(odd){background-color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=white] .data-grid-row:hover{background-color:#007bff1a!important}.data-grid-table-wrapper[data-theme=white] .selected-cell,.data-grid-table-wrapper[data-theme=white] .row-selected{background-color:#e3f2fd!important}.data-grid-table-wrapper[data-theme=white] .cell,.data-grid-table-wrapper[data-theme=white] .header-cell,.data-grid-table-wrapper[data-theme=white] .data-grid-row,.data-grid-table-wrapper[data-theme=white] .data-grid-header,.data-grid-table-wrapper[data-theme=white] .cell-content,.data-grid-table-wrapper[data-theme=white] .full-text-content,.data-grid-table-wrapper[data-theme=white] .circle-value,.data-grid-table-wrapper[data-theme=white] .pic,.data-grid-table-wrapper[data-theme=white] .image-placeholder,.data-grid-table-wrapper[data-theme=white] .s-no,.data-grid-table-wrapper[data-theme=white] .fw-500{color:#000!important}.data-grid-table-wrapper[data-theme=white] span,.data-grid-table-wrapper[data-theme=white] div,.data-grid-table-wrapper[data-theme=white] p,.data-grid-table-wrapper[data-theme=white] td,.data-grid-table-wrapper[data-theme=white] th,.data-grid-table-wrapper[data-theme=white] label,.data-grid-table-wrapper[data-theme=white] a:not(.text-primary){color:#000!important}.data-grid-table-wrapper[data-theme=white] svg,.data-grid-table-wrapper[data-theme=white] svg path,.data-grid-table-wrapper[data-theme=white] svg circle,.data-grid-table-wrapper[data-theme=white] svg rect,.data-grid-table-wrapper[data-theme=white] svg polygon{color:#000!important;fill:#000!important;stroke:#000!important}.data-grid-table-wrapper[data-theme=white] .data-grid-svg-icon{color:#000!important}.data-grid-table-wrapper[data-theme=white] .data-grid-svg-icon path{stroke:#000!important;fill:#000!important}.data-grid-table-wrapper[data-theme=white] .badge.badge-danger{background-color:#ea5353!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=white] .badge.badge-success{background-color:#84ca81!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=white] .badge.badge-warning{background-color:#fff3dc!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .badge.badge-info{background-color:#e8fbfd!important;color:#00bad1!important}.data-grid-table-wrapper[data-theme=white] .context-menu{background:#f6f8ff;border-color:#d9d9db;color:#000!important}.data-grid-table-wrapper[data-theme=white] .context-menu li{color:#000!important}.data-grid-table-wrapper[data-theme=white] .context-menu li:hover{background-color:#007bff1a!important}.data-grid-table-wrapper[data-theme=white] .custom-tooltip,.data-grid-table-wrapper[data-theme=white] .popover__content,.data-grid-table-wrapper[data-theme=white] .custom-break-tooltip{background:#f6f8ff!important;border-color:#d9d9db!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .actions-dropdown,.data-grid-table-wrapper[data-theme=white] .custom-menu{background-color:#f6f8ff!important;border-color:#d9d9db!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .actions-dropdown .dropdown-item,.data-grid-table-wrapper[data-theme=white] .custom-menu .dropdown-item{color:#000!important}.data-grid-table-wrapper[data-theme=white] .actions-dropdown .dropdown-item:hover,.data-grid-table-wrapper[data-theme=white] .custom-menu .dropdown-item:hover{background-color:#007bff1a!important}.data-grid-table-wrapper[data-theme=white] .taskbar .selected-rows-action-bar{background-color:#343a40!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=white] .taskbar .selected-rows-action-bar .action-btn{color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=white] .manual-logs-modal .modal-header{background:linear-gradient(135deg,#343a40,#495057)!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=white] .manual-logs-modal .modal-header .modal-title{color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=white] .manual-logs-modal .modal-body{background-color:#f6f8ff!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .manual-logs-modal .modal-body .table{color:#000!important}.data-grid-table-wrapper[data-theme=white] .manual-logs-modal .modal-body .table thead th{background:linear-gradient(135deg,#f8f9fa,#e9ecef)!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .manual-logs-modal .modal-body .table tbody tr{color:#000!important}.data-grid-table-wrapper[data-theme=white] .manual-logs-modal .modal-body .table tbody tr:nth-child(2n){background-color:#f8f9fa!important}.data-grid-table-wrapper[data-theme=white] .manual-logs-modal .modal-body .table tbody tr:hover{background-color:#007bff1a!important}.data-grid-table-wrapper[data-theme=white] .manual-logs-modal .modal-body .table tbody tr td{color:#000!important;border-color:#d9d9db!important}.data-grid-table-wrapper[data-theme=white] .form-control,.data-grid-table-wrapper[data-theme=white] .form-select{background-color:#f6f8ff!important;border-color:#d9d9db!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .form-control::placeholder,.data-grid-table-wrapper[data-theme=white] .form-select::placeholder{color:#6c757d!important}.data-grid-table-wrapper[data-theme=white] .form-control option,.data-grid-table-wrapper[data-theme=white] .form-select option{background-color:#f6f8ff!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .filter-serach-inpt{background-color:#f6f8ff!important;border-color:#d9d9db!important}.data-grid-table-wrapper[data-theme=white] .filter-serach-inpt input{background-color:#f6f8ff!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .active-filters{background-color:#f8f9fa!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .custom-modal-overlay .custom-modal-content{background-color:#f6f8ff!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .circle-value{background-color:#f8f9fa!important;border-color:#d9d9db!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .pagination-container,.data-grid-table-wrapper[data-theme=white] .page-size,.data-grid-table-wrapper[data-theme=white] .page-info,.data-grid-table-wrapper[data-theme=white] .page-buttons{color:#000!important}.data-grid-table-wrapper[data-theme=white] .pagination-container select,.data-grid-table-wrapper[data-theme=white] .pagination-container button,.data-grid-table-wrapper[data-theme=white] .pagination-container span,.data-grid-table-wrapper[data-theme=white] .page-size select,.data-grid-table-wrapper[data-theme=white] .page-size button,.data-grid-table-wrapper[data-theme=white] .page-size span,.data-grid-table-wrapper[data-theme=white] .page-info select,.data-grid-table-wrapper[data-theme=white] .page-info button,.data-grid-table-wrapper[data-theme=white] .page-info span,.data-grid-table-wrapper[data-theme=white] .page-buttons select,.data-grid-table-wrapper[data-theme=white] .page-buttons button,.data-grid-table-wrapper[data-theme=white] .page-buttons span{background-color:#f6f8ff!important;border-color:#d9d9db!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .pagination-container button.active,.data-grid-table-wrapper[data-theme=white] .page-size button.active,.data-grid-table-wrapper[data-theme=white] .page-info button.active,.data-grid-table-wrapper[data-theme=white] .page-buttons button.active{background-color:#e3f2fd!important}.data-grid-table-wrapper[data-theme=white] .footer-row{background-color:#f8f9fa!important;border-top-color:#d9d9db!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] ::-webkit-scrollbar{background-color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=white] ::-webkit-scrollbar-thumb{background-color:#d9d9db!important}.data-grid-table-wrapper[data-theme=white] ::-webkit-scrollbar-thumb:hover{background-color:#adb5bd!important}.data-grid-table-wrapper[data-theme=white] ::-webkit-scrollbar-track{background-color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker{background-color:#f6f8ff!important;color:#000!important;border-color:#d9d9db!important}.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker .bs-datepicker-head{background:linear-gradient(135deg,#343a40,#495057)!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker .bs-datepicker-body{background-color:#f6f8ff!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker table td,.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker table th{color:#000!important}.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker table td.is-other-month,.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker table th.is-other-month{color:#6c757d!important}.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker table td.active,.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker table th.active{background-color:#e3f2fd!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker table td span.in-range,.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker table th span.in-range{background-color:#e3f2fd!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker table td:hover:not(.active),.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker table th:hover:not(.active){background-color:#007bff1a!important}.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker .bs-datepicker-buttons{background-color:#f8f9fa!important;border-top-color:#d9d9db!important}.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker .bs-datepicker-buttons .btn-primary{background:linear-gradient(135deg,#007bff,#0056b3)!important;color:#f6f8ff!important;border-color:#007bff!important}.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker .bs-datepicker-buttons .btn-secondary{background-color:#f6f8ff!important;color:#000!important;border-color:#d9d9db!important}.data-grid-table-wrapper[data-theme=white] button,.data-grid-table-wrapper[data-theme=white] .btn,.data-grid-table-wrapper[data-theme=white] .button{background-color:#f6f8ff!important;border-color:#d9d9db!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] button:hover,.data-grid-table-wrapper[data-theme=white] .btn:hover,.data-grid-table-wrapper[data-theme=white] .button:hover{background-color:#007bff1a!important}.data-grid-table-wrapper[data-theme=white] button.btn-primary,.data-grid-table-wrapper[data-theme=white] .btn.btn-primary,.data-grid-table-wrapper[data-theme=white] .button.btn-primary{background-color:#007bff!important;border-color:#007bff!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=white] button.btn-outline-primary,.data-grid-table-wrapper[data-theme=white] .btn.btn-outline-primary,.data-grid-table-wrapper[data-theme=white] .button.btn-outline-primary{border-color:#007bff!important;color:#007bff!important;background-color:transparent!important}.data-grid-table-wrapper[data-theme=white] a:not(.text-primary){color:#007bff!important}.data-grid-table-wrapper[data-theme=white] a:not(.text-primary):hover{color:#0056b3!important}.data-grid-table-wrapper[data-theme=white] .text-primary{color:#007bff!important}.data-grid-table-wrapper[data-theme=white] .text-danger{color:#dc3545!important}.data-grid-table-wrapper[data-theme=white] .text-success{color:#28a745!important}.data-grid-table-wrapper[data-theme=white] .text-warning{color:#ffc107!important}.data-grid-table-wrapper[data-theme=white] .text-info{color:#17a2b8!important}.data-grid-table-wrapper[data-theme=white] .text-muted,.data-grid-table-wrapper[data-theme=white] .muted-text{color:#6c757d!important}.data-grid-table-wrapper[data-theme=white] .border,.data-grid-table-wrapper[data-theme=white] .border-top,.data-grid-table-wrapper[data-theme=white] .border-bottom,.data-grid-table-wrapper[data-theme=white] .border-left,.data-grid-table-wrapper[data-theme=white] .border-right,.data-grid-table-wrapper[data-theme=white] .border-below,.data-grid-table-wrapper[data-theme=white] .border-start,.data-grid-table-wrapper[data-theme=white] .border-end{border-color:#d9d9db!important}.data-grid-table-wrapper[data-theme=white] .accordion-details,.data-grid-table-wrapper[data-theme=white] .nested-table,.data-grid-table-wrapper[data-theme=white] .detail-virtual-scroll{background-color:#f6f8ff!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .accordion-details td,.data-grid-table-wrapper[data-theme=white] .accordion-details th,.data-grid-table-wrapper[data-theme=white] .nested-table td,.data-grid-table-wrapper[data-theme=white] .nested-table th,.data-grid-table-wrapper[data-theme=white] .detail-virtual-scroll td,.data-grid-table-wrapper[data-theme=white] .detail-virtual-scroll th{color:#000!important;border-color:#d9d9db!important}.data-grid-table-wrapper[data-theme=blue]{border-color:#b3d9ff;background-color:#f0f8ff;color:#1e3a5f}.data-grid-table-wrapper[data-theme=blue] *,.data-grid-table-wrapper[data-theme=blue] *:before,.data-grid-table-wrapper[data-theme=blue] *:after{color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] ::selection{background-color:#007cf5!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=blue] ::-moz-selection{background-color:#007cf5!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=blue] .data-grid-header-wrapper{background-color:#e6f3ff;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .data-grid-body-wrapper{background-color:#f0f8ff;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .data-grid-row{border-bottom-color:#b3d9ff;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .data-grid-row:nth-child(2n){background-color:#f0f8ff!important}.data-grid-table-wrapper[data-theme=blue] .data-grid-row:nth-child(odd){background-color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=blue] .data-grid-row:hover{background-color:#1e3a5f1a!important}.data-grid-table-wrapper[data-theme=blue] .selected-cell,.data-grid-table-wrapper[data-theme=blue] .row-selected{background-color:#cce5ff!important}.data-grid-table-wrapper[data-theme=blue] .cell,.data-grid-table-wrapper[data-theme=blue] .header-cell,.data-grid-table-wrapper[data-theme=blue] .data-grid-row,.data-grid-table-wrapper[data-theme=blue] .data-grid-header,.data-grid-table-wrapper[data-theme=blue] .cell-content,.data-grid-table-wrapper[data-theme=blue] .full-text-content,.data-grid-table-wrapper[data-theme=blue] .circle-value,.data-grid-table-wrapper[data-theme=blue] .pic,.data-grid-table-wrapper[data-theme=blue] .image-placeholder,.data-grid-table-wrapper[data-theme=blue] .s-no,.data-grid-table-wrapper[data-theme=blue] .fw-500{color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] span,.data-grid-table-wrapper[data-theme=blue] div,.data-grid-table-wrapper[data-theme=blue] p,.data-grid-table-wrapper[data-theme=blue] td,.data-grid-table-wrapper[data-theme=blue] th,.data-grid-table-wrapper[data-theme=blue] label,.data-grid-table-wrapper[data-theme=blue] a:not(.text-primary){color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] svg,.data-grid-table-wrapper[data-theme=blue] svg path,.data-grid-table-wrapper[data-theme=blue] svg circle,.data-grid-table-wrapper[data-theme=blue] svg rect,.data-grid-table-wrapper[data-theme=blue] svg polygon{color:#1e3a5f!important;fill:#1e3a5f!important;stroke:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .data-grid-svg-icon{color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .data-grid-svg-icon path{stroke:#1e3a5f!important;fill:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .badge.badge-danger{background-color:#ff8787!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=blue] .badge.badge-success{background-color:#69db7c!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=blue] .badge.badge-warning{background-color:#ffd43b!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .badge.badge-info{background-color:#74c0fc!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=blue] .context-menu{background:#e6f3ff;border-color:#b3d9ff;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .context-menu li{color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .context-menu li:hover{background-color:#1e3a5f1a!important}.data-grid-table-wrapper[data-theme=blue] .custom-tooltip,.data-grid-table-wrapper[data-theme=blue] .popover__content,.data-grid-table-wrapper[data-theme=blue] .custom-break-tooltip{background:#e6f3ff!important;border-color:#b3d9ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .actions-dropdown,.data-grid-table-wrapper[data-theme=blue] .custom-menu{background-color:#e6f3ff!important;border-color:#b3d9ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .actions-dropdown .dropdown-item,.data-grid-table-wrapper[data-theme=blue] .custom-menu .dropdown-item{color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .actions-dropdown .dropdown-item:hover,.data-grid-table-wrapper[data-theme=blue] .custom-menu .dropdown-item:hover{background-color:#1e3a5f1a!important}.data-grid-table-wrapper[data-theme=blue] .taskbar .selected-rows-action-bar{background-color:#1e3a5f!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=blue] .taskbar .selected-rows-action-bar .action-btn{color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=blue] .manual-logs-modal .modal-header{background:linear-gradient(135deg,#1e3a5f,#2d4a6b)!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=blue] .manual-logs-modal .modal-header .modal-title{color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=blue] .manual-logs-modal .modal-body{background-color:#f0f8ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .manual-logs-modal .modal-body .table{color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .manual-logs-modal .modal-body .table thead th{background:linear-gradient(135deg,#e6f3ff,#cce5ff)!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .manual-logs-modal .modal-body .table tbody tr{color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .manual-logs-modal .modal-body .table tbody tr:nth-child(2n){background-color:#f0f8ff!important}.data-grid-table-wrapper[data-theme=blue] .manual-logs-modal .modal-body .table tbody tr:hover{background-color:#1e3a5f1a!important}.data-grid-table-wrapper[data-theme=blue] .manual-logs-modal .modal-body .table tbody tr td{color:#1e3a5f!important;border-color:#b3d9ff!important}.data-grid-table-wrapper[data-theme=blue] .form-control,.data-grid-table-wrapper[data-theme=blue] .form-select{background-color:#f6f8ff!important;border-color:#b3d9ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .form-control::placeholder,.data-grid-table-wrapper[data-theme=blue] .form-select::placeholder{color:#888!important}.data-grid-table-wrapper[data-theme=blue] .form-control option,.data-grid-table-wrapper[data-theme=blue] .form-select option{background-color:#f6f8ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .filter-serach-inpt{background-color:#f6f8ff!important;border-color:#b3d9ff!important}.data-grid-table-wrapper[data-theme=blue] .filter-serach-inpt input{background-color:#f6f8ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .active-filters,.data-grid-table-wrapper[data-theme=blue] .custom-modal-overlay .custom-modal-content{background-color:#e6f3ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .circle-value{background-color:#f6f8ff!important;border-color:#b3d9ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .pagination-container,.data-grid-table-wrapper[data-theme=blue] .page-size,.data-grid-table-wrapper[data-theme=blue] .page-info,.data-grid-table-wrapper[data-theme=blue] .page-buttons{color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .pagination-container select,.data-grid-table-wrapper[data-theme=blue] .pagination-container button,.data-grid-table-wrapper[data-theme=blue] .pagination-container span,.data-grid-table-wrapper[data-theme=blue] .page-size select,.data-grid-table-wrapper[data-theme=blue] .page-size button,.data-grid-table-wrapper[data-theme=blue] .page-size span,.data-grid-table-wrapper[data-theme=blue] .page-info select,.data-grid-table-wrapper[data-theme=blue] .page-info button,.data-grid-table-wrapper[data-theme=blue] .page-info span,.data-grid-table-wrapper[data-theme=blue] .page-buttons select,.data-grid-table-wrapper[data-theme=blue] .page-buttons button,.data-grid-table-wrapper[data-theme=blue] .page-buttons span{background-color:#f6f8ff!important;border-color:#b3d9ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .pagination-container button.active,.data-grid-table-wrapper[data-theme=blue] .page-size button.active,.data-grid-table-wrapper[data-theme=blue] .page-info button.active,.data-grid-table-wrapper[data-theme=blue] .page-buttons button.active{background-color:#cce5ff!important}.data-grid-table-wrapper[data-theme=blue] .footer-row{background-color:#e6f3ff!important;border-top-color:#b3d9ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] ::-webkit-scrollbar{background-color:#f0f8ff!important}.data-grid-table-wrapper[data-theme=blue] ::-webkit-scrollbar-thumb{background-color:#b3d9ff!important}.data-grid-table-wrapper[data-theme=blue] ::-webkit-scrollbar-thumb:hover{background-color:#74c0fc!important}.data-grid-table-wrapper[data-theme=blue] ::-webkit-scrollbar-track{background-color:#f0f8ff!important}.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker{background-color:#e6f3ff!important;color:#1e3a5f!important;border-color:#b3d9ff!important}.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker .bs-datepicker-head{background:linear-gradient(135deg,#1e3a5f,#2d4a6b)!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker .bs-datepicker-body{background-color:#f0f8ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker table td,.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker table th{color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker table td.is-other-month,.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker table th.is-other-month{color:#888!important}.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker table td.active,.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker table th.active{background-color:#cce5ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker table td span.in-range,.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker table th span.in-range{background-color:#cce5ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker table td:hover:not(.active),.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker table th:hover:not(.active){background-color:#1e3a5f1a!important}.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker .bs-datepicker-buttons{background-color:#f6f8ff!important;border-top-color:#b3d9ff!important}.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker .bs-datepicker-buttons .btn-primary{background:linear-gradient(135deg,#1e3a5f,#2d4a6b)!important;color:#f6f8ff!important;border-color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker .bs-datepicker-buttons .btn-secondary{background-color:#f0f8ff!important;color:#1e3a5f!important;border-color:#b3d9ff!important}.data-grid-table-wrapper[data-theme=blue] button,.data-grid-table-wrapper[data-theme=blue] .btn,.data-grid-table-wrapper[data-theme=blue] .button{background-color:#f6f8ff!important;border-color:#b3d9ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] button:hover,.data-grid-table-wrapper[data-theme=blue] .btn:hover,.data-grid-table-wrapper[data-theme=blue] .button:hover{background-color:#1e3a5f1a!important}.data-grid-table-wrapper[data-theme=blue] button.btn-primary,.data-grid-table-wrapper[data-theme=blue] .btn.btn-primary,.data-grid-table-wrapper[data-theme=blue] .button.btn-primary{background-color:#007cf5!important;border-color:#007cf5!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=blue] button.btn-outline-primary,.data-grid-table-wrapper[data-theme=blue] .btn.btn-outline-primary,.data-grid-table-wrapper[data-theme=blue] .button.btn-outline-primary{border-color:#007cf5!important;color:#007cf5!important;background-color:transparent!important}.data-grid-table-wrapper[data-theme=blue] a:not(.text-primary){color:#007cf5!important}.data-grid-table-wrapper[data-theme=blue] a:not(.text-primary):hover{color:#0056b3!important}.data-grid-table-wrapper[data-theme=blue] .text-primary{color:#007cf5!important}.data-grid-table-wrapper[data-theme=blue] .text-danger{color:#dc3545!important}.data-grid-table-wrapper[data-theme=blue] .text-success{color:#28a745!important}.data-grid-table-wrapper[data-theme=blue] .text-warning{color:#ffc107!important}.data-grid-table-wrapper[data-theme=blue] .text-info{color:#17a2b8!important}.data-grid-table-wrapper[data-theme=blue] .text-muted,.data-grid-table-wrapper[data-theme=blue] .muted-text{color:#6c757d!important}.data-grid-table-wrapper[data-theme=blue] .border,.data-grid-table-wrapper[data-theme=blue] .border-top,.data-grid-table-wrapper[data-theme=blue] .border-bottom,.data-grid-table-wrapper[data-theme=blue] .border-left,.data-grid-table-wrapper[data-theme=blue] .border-right,.data-grid-table-wrapper[data-theme=blue] .border-below,.data-grid-table-wrapper[data-theme=blue] .border-start,.data-grid-table-wrapper[data-theme=blue] .border-end{border-color:#b3d9ff!important}.data-grid-table-wrapper[data-theme=blue] .accordion-details,.data-grid-table-wrapper[data-theme=blue] .nested-table,.data-grid-table-wrapper[data-theme=blue] .detail-virtual-scroll{background-color:#f0f8ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .accordion-details td,.data-grid-table-wrapper[data-theme=blue] .accordion-details th,.data-grid-table-wrapper[data-theme=blue] .nested-table td,.data-grid-table-wrapper[data-theme=blue] .nested-table th,.data-grid-table-wrapper[data-theme=blue] .detail-virtual-scroll td,.data-grid-table-wrapper[data-theme=blue] .detail-virtual-scroll th{color:#1e3a5f!important;border-color:#b3d9ff!important}.data-grid-header{position:sticky;top:0}.data-grid-header{display:flex}.header-row{display:grid;width:100%}.header-cell{display:flex;align-items:center;position:relative;width:100%;padding:8px 0 8px 8px;font-weight:700;border-bottom:1px solid #d9d9db;white-space:nowrap;min-width:30px}.header-cell .filter-applied-on-text{color:#5d9cff!important}.filter-cell{padding:4px!important;display:flex;align-items:center;gap:8px;width:100%}.filter-cell .filter-applied{background-color:#bddef9}.border-right{border-right:1px solid #d9d9db}.merged-grid{display:grid;grid-auto-rows:40px;border-bottom:1px solid #ccc}.span-two-rows{grid-row:span 2;display:flex;justify-content:space-between;align-items:center}.group-header{display:flex;justify-content:space-between;position:relative}.group-header-content{position:sticky;left:10px;overflow:hidden;text-overflow:ellipsis}.resize-handle{width:6px;cursor:e-resize;right:0;top:0;color:#00000026;position:relative}.resize-handle.resizing{z-index:9999!important;opacity:1!important;background-color:#007bff1a;border-right:2px solid #007bff;box-shadow:0 0 8px #007bff4d;position:relative!important;pointer-events:none!important}.group-header .resize-handle{top:25%}.h-100{height:100%}.data-grid-body{position:relative;overflow-y:auto;overflow-x:hidden;box-shadow:none!important}.cell{padding:8px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;height:100%;display:flex;align-items:center}.data-grid-row{display:flex;min-width:max-content;align-items:center;border-bottom:1px solid #d9d9db;transition:all .25s cubic-bezier(.4,0,.2,1);transform:translateZ(0);will-change:transform,box-shadow;backface-visibility:hidden}.data-grid-row:hover{transform:translate(2px);box-shadow:2px 0 8px #007bff1a}.hovered-row{background-color:#ccc}.checkbox-row{border-bottom:#d9d9db}.w-100{width:100%}.data-grid-header-wrapper{display:flex;position:relative;overflow:hidden;-webkit-user-select:none;user-select:none}.data-grid-header{display:flex;position:relative;z-index:1}.left-pinned,.right-pinned{position:sticky;top:0;background:#f6f8ff}.right-pinned-header{position:absolute;right:0;border-left:1px solid #d9d9db;z-index:unset}.left-pinned{left:0;border-right:1px solid #d9d9db}.right-pinned{right:0;border-left:1px solid #d9d9db}.center-scrollable{z-index:unset!important;overflow-x:auto;overflow-y:visible;white-space:nowrap;scrollbar-width:none;-ms-overflow-style:none}.center-scrollable::-webkit-scrollbar{display:none}.data-grid-body-wrapper{display:flex}.data-grid-body-wrapper{scrollbar-width:none;-ms-overflow-style:none}.data-grid-body-wrapper::-webkit-scrollbar{display:none}.center-scrollable-body{overflow-x:auto;scrollbar-width:none;-ms-overflow-style:none}.center-scrollable-body::-webkit-scrollbar{display:none}.left-pinned-body,.right-pinned-body{position:sticky;top:0;z-index:unset;background:#f6f8ff;scrollbar-width:none;-ms-overflow-style:none}.left-pinned-body::-webkit-scrollbar,.right-pinned-body::-webkit-scrollbar{display:none}.left-pinned-body{left:0}.border-end{border-right:1px solid #d9d9db!important}.right-pinned-body{right:-15px;border-left:1px solid #d9d9db}.fake-scroll-bar{height:14px;overflow:scroll;margin-bottom:10px}.text-ellipsis{overflow:hidden;text-overflow:ellipsis}.select-all-checkbox-cell{width:50px;display:flex;justify-content:center;align-items:center;height:100%;border-right:1px solid #d9d9db}.select-all-checkbox-cell input{width:16px;height:16px}.border-below{border-bottom:1px solid #d9d9db!important}.three-dots{width:22px;height:22px;display:flex;justify-content:center;align-items:center;border-radius:6px;margin-right:8px;cursor:pointer;transition:all .25s cubic-bezier(.4,0,.2,1);transform:translateZ(0);position:relative}.three-dots:before{content:\"\";position:absolute;top:50%;left:50%;width:0;height:0;background:#007bff1a;border-radius:50%;transform:translate(-50%,-50%);transition:width .25s,height .25s}.three-dots:hover{background-color:#007bff1a;transform:rotate(90deg)}.three-dots:hover:before{width:28px;height:28px}.three-dots:active{transform:rotate(90deg) scale(.95);transition-duration:.15s}.filter-icon-wrapper{min-height:22px;max-height:22px;min-width:22px;max-width:22px;display:flex;justify-content:center;align-items:center;border-radius:6px;cursor:pointer;transition:all .25s cubic-bezier(.4,0,.2,1);transform:translateZ(0);position:relative}.filter-icon-wrapper:before{content:\"\";position:absolute;top:50%;left:50%;width:0;height:0;background:#007bff1a;border-radius:50%;transform:translate(-50%,-50%);transition:width .25s,height .25s}.filter-icon-wrapper:hover{background-color:#007bff1a;transform:scale(1.05)}.filter-icon-wrapper:hover:before{width:32px;height:32px}.filter-icon-wrapper:active{transform:scale(.95);transition-duration:.15s}.column-panel-item{font-size:.875rem;color:#333;transition:all .25s cubic-bezier(.4,0,.2,1);transform:translateZ(0)}.column-panel-item:hover{background-color:#007bff0d;color:#007bff;transform:translate(2px)}.column-menu,.filter-menu{box-shadow:0 0 16px #00000026;border-radius:4px}.column-menu{background:#fff;width:100%;width:240px;border:1px solid #ddd;box-shadow:0 0 16px #00000026;border:1px solid #d9d9db;padding:4px 0;font-size:14px;position:fixed}.column-menu-item{padding:8px 12px;cursor:pointer;display:flex;align-items:center;transition:background-color .2s ease}.column-menu-item:hover{background-color:#deebf7}.pin-parent{position:relative;width:100%!important}.column-submenu{position:absolute;top:0;left:100%;background:#fff;border:1px solid #ddd;width:130px;box-shadow:0 0 16px #00000026;border:1px solid #d9d9db;display:none;padding:4px 0;z-index:10;border-radius:4px}.pin-parent:hover .column-submenu{display:block}.filter-menu-container{position:fixed;width:210px;background:#fff;border:1px solid #ddd;border-radius:4px;padding:12px;box-shadow:0 0 16px #00000026;border:1px solid #d9d9db;z-index:1000;font-size:14px}.filter-menu-header{font-weight:600;margin-bottom:10px}.filter-dropdown-section{max-height:350px;overflow-y:auto}.dropdown-options{overflow-y:auto;scrollbar-width:thin;height:100%}.filter-text-section select,.filter-text-section input{width:100%}.filter-radio-inputs{width:14px!important;height:14px!important}.right-menu{border-left:1px solid #d9d9db;font-size:14px}.border-start{border-left:1px solid #d9d9db!important}.column-panel-item{font-size:.875rem;color:#333}.toggle-icon{cursor:pointer;transition:all .25s cubic-bezier(.4,0,.2,1);transform:translateZ(0);border-radius:4px;padding:2px}.toggle-icon:hover{background-color:#007bff1a;transform:scale(1.1)}.toggle-icon:active{transform:scale(.95)}.grab-icon{cursor:grab;color:#6c757d;transition:all .25s cubic-bezier(.4,0,.2,1);transform:translateZ(0)}.grab-icon:hover{color:#007bff;transform:scale(1.1)}.grab-icon:active{cursor:grabbing;transform:scale(.95)}.text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:100%}.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:-3px}.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:20px;left:50%;transform:translate(-50%);display:flex;justify-content:center;z-index:1000;padding:0;width:auto;max-width:90vw}.taskbar .action-btn{transition:all .3s ease;font-weight:500;font-size:14px;padding:8px 16px;border-radius:6px;cursor:pointer;display:inline-flex;align-items:center;gap:6px}.taskbar .action-btn:hover{transform:translateY(-1px);box-shadow:0 4px 12px #00000026}.taskbar .action-btn:active{transform:translateY(0)}.taskbar .delete{background-color:#dc3545;color:#fff;border:1px solid #dc3545}.taskbar .delete:hover{background-color:#c82333;border-color:#bd2130}.taskbar .export{background-color:#28a745;color:#fff;border:1px solid #28a745}.taskbar .export:hover{background-color:#218838;border-color:#1e7e34}.taskbar .verify{background-color:#007bff;color:#fff;border:1px solid #007bff}.taskbar .verify:hover{background-color:#0056b3;border-color:#004085}.selected-count,.action-btn,.dropdown-content a{font-weight:500;font-size:14px}.selected-rows-action-bar{background:linear-gradient(135deg,#667eea,#764ba2);color:#fff;padding:12px 24px;border-radius:12px;display:flex;align-items:center;justify-content:space-between;gap:16px;box-shadow:0 8px 32px #0003;backdrop-filter:blur(10px);border:1px solid rgba(255,255,255,.1);min-width:300px}.selected-rows-action-bar .selected-count{font-weight:600;font-size:14px;flex:1;text-align:center}.selected-rows-action-bar .action-buttons{display:flex;align-items:center;gap:8px}.selected-rows-action-bar .action-buttons .separator{color:#ffffff80;font-weight:700;font-size:16px}.selected-rows-action-bar .action-buttons .action-btn{background:#fff3;color:#fff!important;border:1px solid rgba(255,255,255,.3);padding:8px 16px;border-radius:8px;font-weight:500;font-size:13px;transition:all .3s ease;cursor:pointer;display:inline-flex;align-items:center;gap:6px}.selected-rows-action-bar .action-buttons .action-btn:hover{background:#ffffff4d;transform:translateY(-1px);box-shadow:0 4px 12px #0003}.selected-rows-action-bar .action-buttons .action-btn:active{transform:translateY(0)}.selected-rows-action-bar .action-buttons .action-btn.Export{background:#28a745cc;border-color:#28a745e6}.selected-rows-action-bar .action-buttons .action-btn.Export:hover{background:#218838e6}.selected-rows-action-bar .action-buttons .action-btn.Delete{background:#dc3545cc;border-color:#dc3545e6}.selected-rows-action-bar .action-buttons .action-btn.Delete:hover{background:#c82333e6}.selected-rows-action-bar .action-buttons .action-btn.Verify{background:#007bffcc;border-color:#007bffe6}.selected-rows-action-bar .action-buttons .action-btn.Verify:hover{background:#0056b3e6}.selected-rows-action-bar .btn:active,.selected-rows-action-bar .btn:focus{outline:0!important;border:0!important;border-color:transparent!important}@media (max-width: 768px){.taskbar{bottom:10px;max-width:95vw}.taskbar .selected-rows-action-bar{padding:8px 16px;min-width:280px;flex-direction:column;gap:12px}.taskbar .selected-rows-action-bar .selected-count{font-size:13px;text-align:center}.taskbar .selected-rows-action-bar .action-buttons{justify-content:center;flex-wrap:wrap;gap:6px}.taskbar .selected-rows-action-bar .action-buttons .action-btn{padding:6px 12px;font-size:12px;min-width:80px}.taskbar .selected-rows-action-bar .action-buttons .separator{display:none}}@media (max-width: 480px){.taskbar .selected-rows-action-bar{min-width:250px;padding:6px 12px}.taskbar .selected-rows-action-bar .action-buttons .action-btn{padding:5px 10px;font-size:11px;min-width:70px}}.cell .dropdown-menu,.cell .form-select,.cell input{color:#000!important}.cell input::placeholder{color:#727272!important}.cell .badge{font-size:14px;padding:6px 12px;border-radius:6px;text-align:center;height:auto;min-height:28px;display:inline-flex;align-items:center;justify-content:center;font-weight:500;line-height:1.5;white-space:nowrap;transition:all .2s cubic-bezier(.4,0,.2,1);will-change:transform,opacity;backface-visibility:hidden;transform:translateZ(0)}.cell .badge-danger{color:#ea5353!important;border:1px solid #ea5353!important;background-color:#ff00000d!important}.cell .badge-success{background-color:#84ca8130!important;border:1.5px solid rgb(70,227,114)!important;color:#46e372!important}.cell .badge-warning{background-color:#fff3dc!important;color:orange!important;border:1px solid #ffa000!important}.cell .badge-info{color:#00bad1;background-color:#e8fbfd;border:1px solid #00bad1}.header-tag ::ng-deep svg path{stroke:#727272!important}.cross-secondary:hover ::ng-deep svg path{stroke:#000!important}.disable-sorting{pointer-events:none;opacity:.5}.rows-grouping-top-container ::ng-deep .cdk-drag-placeholder{background-color:transparent!important}input.is-invalid:focus{border:2.5px solid red!important;outline:none}.table-cell input.is-invalid:focus{border:2.5px solid red!important;outline-color:red!important;outline:none!important;box-shadow:none!important}.active-for-editing:has(input.is-invalid:focus){outline:none!important;box-shadow:none!important;border:0!important}.selected-cell,.row-selected{background-color:#c2e0fe;animation:pulse .25s cubic-bezier(.4,0,.2,1);transform:translateZ(0);position:relative}.selected-cell:before,.row-selected:before{content:\"\";position:absolute;inset:0;background:linear-gradient(45deg,transparent,rgba(255,255,255,.1),transparent);animation:shimmer 1.5s ease-in-out infinite}.first-row-selected{border-top:2px solid #2196f3!important}.last-row-selected{border-bottom:2px solid #2196f3!important}.left-selection-border{border-left:2px solid #2196f3!important}.s-no{font-size:14px;font-weight:500}.top-border{border-top:2px solid #2196f3!important}.bottom-border{border-bottom:2px solid #2196f3!important}.left-border{border-left:2px solid #2196f3!important}.right-border{border-right:2px solid #2196f3!important}.top-left-corner{border-top-left-radius:4px}.top-right-corner{border-top-right-radius:4px}.bottom-left-corner{border-bottom-left-radius:4px}.bottom-right-corner{border-bottom-right-radius:4px}.flash-bg{animation:flashAnim 1000s ease}@keyframes flashAnim{0%{background-color:#48a2fc}50%{background-color:#c2e0fe}to{background-color:#c2e0fe}}.cut-flash-bg{animation:cut-flash .8s ease}@keyframes cut-flash{0%{background-color:#f006}50%{background-color:#f00c}to{background-color:#c2e0fe}}.accordion-details.dragging th,.accordion-details.dragging td{pointer-events:none}.accordion-details.dragging th{z-index:2}.drag-handle{cursor:move;opacity:.5;transition:opacity .2s}.drag-handle:hover{opacity:1}.detail-edit-input{z-index:100;position:relative}.detail-filter-menu{position:fixed;width:210px;background:#fff;border:1px solid #ddd;border-radius:4px;padding:12px;box-shadow:0 0 16px #00000026;border:1px solid #d9d9db;z-index:1000;font-size:14px}.detail-filter-menu-positioned{width:280px;right:unset;max-width:230px;z-index:99;left:375px;top:225px}.resize-handle{cursor:col-resize;opacity:.5;width:8px;display:flex;align-items:center;justify-content:center}.resize-handle:hover{opacity:1;background-color:#f0f0f0}.detail-header-row{transition:all .3s ease}.detail-header-row.dragging{opacity:.7;transform:translate(5px)}.detail-cell{transition:background-color .2s ease,transform .3s ease}.detail-cell.active-drag{background-color:#f0f0f0;transform:scale(1.02)}.break-color-paid{background-color:#4caf50!important}.break-color-unpaid{background-color:#f44336!important}.break-color-lunch{background-color:#2196f3!important}.break-color-default{background-color:#f44336!important}.circle-value{display:flex;align-items:center;justify-content:center;width:32px;height:32px;border-radius:50%;background-color:#f8f9fa;border:2px solid #d9d9db;font-size:12px;font-weight:600;color:#fff;text-align:center;line-height:1;vertical-align:middle;box-sizing:border-box;white-space:nowrap;overflow:hidden;cursor:pointer;transition:all .3s cubic-bezier(.4,0,.2,1);transform:translateZ(0);will-change:transform,box-shadow,background-color;backface-visibility:hidden}.circle-value:hover{background-color:#e9ecef;box-shadow:0 6px 16px #007bff40;transform:scale(1.15) translateY(-2px);border-color:#007bff}.circle-value:active{transform:scale(1.08) translateY(-1px);transition-duration:.15s}.break-tooltip-wrapper{position:relative;display:inline-block}.break-tooltip-wrapper:hover .custom-break-tooltip{opacity:1;visibility:visible}.circle-value[title]{position:relative}.circle-value[title]:after{content:attr(title);position:absolute;bottom:100%;left:50%;transform:translate(-50%);background-color:#333;color:#fff;padding:4px 8px;border-radius:4px;font-size:12px;white-space:nowrap;opacity:0;transition:opacity .2s ease;pointer-events:none}.circle-value[title]:hover:after{opacity:1}.custom-tooltip{position:fixed;background:#fff;border:1px solid #dcdcdc;border-radius:8px;padding:12px 16px;max-width:300px;z-index:9999;font-size:13px;animation:fadeIn .2s ease-in-out}.tooltip-title{font-size:14px;font-weight:600;margin-bottom:8px;color:#333}.tooltip-list{margin:0;padding-left:16px;list-style-type:disc}.tooltip-list li{margin-bottom:4px;line-height:1.4;color:#444}.tooltip-total{font-weight:700;margin-top:8px;color:#222}@keyframes fadeIn{0%{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:translateY(0)}}.restriction-indicator{position:absolute;display:inline-block;padding-right:10px}.restriction-indicator:after{content:\"\";position:absolute;top:0;right:0;width:8px;height:8px;background-color:#0d6efd;border-radius:50%}.manual-logs-indicator{position:absolute;top:2px;right:2px;width:8px;height:8px;background-color:#0d6efd;border-radius:50%;border:1px solid #fff;box-shadow:0 0 2px #0d6efd80;cursor:pointer;z-index:10;transition:all .2s ease}.manual-logs-indicator:hover{transform:scale(1.2);box-shadow:0 0 4px #0d6efdcc}.manual-logs-table-tooltip{background:#fff!important;border:1px solid #dcdcdc!important;border-radius:8px!important;box-shadow:0 4px 12px #00000026!important;font-size:13px!important;animation:fadeIn .2s ease-in-out!important;display:block!important;visibility:visible!important;opacity:1!important}.manual-logs-table-tooltip .popover__content,.manual-logs-table-tooltip .modal-area{padding:0!important;display:block!important;visibility:visible!important}.manual-logs-table-tooltip .table-responsive{max-height:300px;overflow-y:auto;display:block!important;visibility:visible!important}.manual-logs-table-tooltip table{margin:0!important;border-collapse:collapse!important;display:table!important;visibility:visible!important}.manual-logs-table-tooltip table th,.manual-logs-table-tooltip table td{padding:6px 8px!important;border:1px solid #f1f1f1!important;text-align:center!important;vertical-align:middle!important;display:table-cell!important;visibility:visible!important}.manual-logs-table-tooltip table th{background-color:#f8f9fa!important;font-weight:600!important;color:#495057!important;position:sticky!important;top:0!important;z-index:1!important}.manual-logs-table-tooltip table tbody tr:nth-child(2n){background-color:#f8f9fa!important}.manual-logs-table-tooltip table tbody tr:hover{background-color:#e3f2fd!important}.manual-logs-table-tooltip table .text-primary{color:#0d6efd!important;text-decoration:none!important}.manual-logs-table-tooltip table .capitalize{text-transform:capitalize!important}@keyframes fadeIn{0%{opacity:0;transform:translate(-50%) translateY(-110%)}to{opacity:1;transform:translate(-50%) translateY(-100%)}}.detail-column-menu{max-height:250px;overflow-y:auto;overflow-x:auto;white-space:nowrap;padding:8px 0;border-radius:6px;scrollbar-width:thin}.detail-column-menu-wrapper{z-index:1001;position:absolute}.accordion-details{position:relative;z-index:999}.detail-column-menu .column-menu-item{padding:8px 12px;cursor:pointer;display:flex;align-items:center;transition:all .25s cubic-bezier(.4,0,.2,1);font-size:14px;transform:translateZ(0);border-radius:4px}.detail-column-menu .column-menu-item:hover{background-color:#007bff1a;transform:translate(2px);color:#007bff}.detail-column-menu .column-menu-item:active{transform:translate(0) scale(.98)}.detail-column-menu .column-menu-item:hover{background-color:#deebf7}.nested-table th[pinned=left],.nested-table td[pinned=left]{border-right:2px solid #ccc;border-left:none;border-bottom:2px solid #ccc}.nested-table th[pinned=right],.nested-table td[pinned=right]{border-left:2px solid #ccc;border-right:none;border-bottom:2px solid #ccc}.data-grid-accordion-table.show-borders{border:1px solid #d9d9db;border-collapse:collapse}.data-grid-accordion-table.show-borders th,.data-grid-accordion-table.show-borders td{border:1px solid #d9d9db}.data-grid-accordion-table.show-shadow tbody tr:hover{box-shadow:0 4px 8px #0000001a;transition:box-shadow .3s ease}.data-grid-accordion-table tbody tr:hover{background-color:#deebf7;transition:background-color .3s ease}.data-grid-pin-icon{display:inline-block;vertical-align:middle;margin-left:4px}.accordion-details.center-section{position:relative;display:flex}.detail-side-menu-wrapper{display:flex;flex-shrink:0;position:sticky;right:0;top:0;height:100%;max-height:275px}.detail-side-menu-content{width:250px;box-shadow:-2px 0 5px #0000001a;display:flex;flex-direction:column}.side-menu-scrollable{flex:1;overflow-y:auto;padding:0 12px 12px;max-height:calc(100% - 40px)}.filter-input-container{padding:8px;background:#f9f9f9;border-radius:4px}.toggle-icon.rotate{transform:rotate(90deg)}.resize-handle{top:0;right:3px;bottom:0;width:8px;cursor:col-resize;z-index:10;display:flex;align-items:center;justify-content:center;opacity:1.4;transition:all .25s cubic-bezier(.4,0,.2,1);background:transparent;transform:translateZ(0)}.resize-handle:hover{opacity:1;background:#007bff1a}.resize-handle:active{opacity:1;background:#007bff33;transform:scaleX(1.2)}th:hover .resize-handle{opacity:40}.resize-handles{top:0;right:3px;bottom:0;width:8px;cursor:col-resize;z-index:10;display:flex;align-items:center;justify-content:center;position:absolute;opacity:1.4;transition:all .25s cubic-bezier(.4,0,.2,1);background:transparent;transform:translateZ(0)}.resize-handles:hover{opacity:1;background:#007bff1a}.resize-handles:active{opacity:1;background:#007bff33;transform:scaleX(1.2)}.resize-handles.resizing{z-index:9999!important;opacity:1!important;background-color:#007bff1a;border-right:2px solid #007bff;box-shadow:0 0 8px #007bff4d;pointer-events:none!important}th:hover .resize-handles{opacity:40}.resizing-highlight{background-color:#007bff1a!important}.accordion-details-wrapper{display:flex;width:100%;max-height:350px;overflow:hidden}.accordion-details.show-borders,.accordion-details-wrapper.show-borders{border:1px solid #d9d9db;border-radius:4px}.accordion-left-section,.accordion-right-section,.detail-side-menu-wrapper{flex-shrink:0;max-height:350px;overflow:hidden;height:fit-content}.accordion-center-section{flex:1;min-width:0;overflow:auto;max-height:350px}.detail-virtual-scroll{display:block;width:100%;height:250px;overflow:auto}.detail-virtual-scroll table{table-layout:fixed;width:100%}.detail-virtual-scroll td,.detail-virtual-scroll th{overflow:hidden!important;text-overflow:ellipsis!important;white-space:nowrap!important}.nested-table th{overflow:hidden!important}.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:10;background-color:#f6f8ff!important}.data-pin-body-wrapper{-webkit-user-select:none;user-select:none;display:flex}.data-pin-body-wrapper{scrollbar-width:none;-ms-overflow-style:none}.data-pin-body-wrapper::-webkit-scrollbar{display:none}.detail-virtual-scroll .selected-cell,.accordion-left-section .selected-cell,.accordion-right-section .selected-cell{background-color:#cce5ff!important}.custom-datepicker-buttons button{height:28px;padding:0 10px;font-size:12px}.manual-logs-modal{max-width:800px;max-height:80vh;overflow:hidden;border-radius:12px;box-shadow:0 10px 40px #0003}.manual-logs-modal .modal-header{background:linear-gradient(135deg,#4361ee,#3a0ca3);color:#fff;padding:16px 20px;border-bottom:none;border-radius:12px 12px 0 0}.manual-logs-modal .modal-header .modal-title{font-weight:600;font-size:18px;margin:0}.manual-logs-modal .modal-header .btn-close{background:#fff3;border:none;border-radius:50%;width:32px;height:32px;display:flex;align-items:center;justify-content:center;color:#fff;opacity:.8;transition:all .25s cubic-bezier(.4,0,.2,1);transform:translateZ(0)}.manual-logs-modal .modal-header .btn-close:hover{background:#ffffff4d;opacity:1;transform:scale(1.1) rotate(90deg)}.manual-logs-modal .modal-header .btn-close:active{transform:scale(.95) rotate(90deg)}.manual-logs-modal .modal-body{padding:20px;max-height:calc(80vh - 80px);overflow-y:auto}.manual-logs-modal .modal-body .table-responsive{border-radius:8px;overflow:hidden;box-shadow:0 2px 8px #0000001a}.manual-logs-modal .modal-body .table-responsive .table{margin-bottom:0;font-size:14px}.manual-logs-modal .modal-body .table-responsive .table thead th{background:linear-gradient(135deg,#f8f9fa,#e9ecef);border-bottom:2px solid #dee2e6;font-weight:600;color:#495057;padding:12px 16px;position:sticky;top:0;z-index:10}.manual-logs-modal .modal-body .table-responsive .table tbody tr{transition:background-color .2s ease}.manual-logs-modal .modal-body .table-responsive .table tbody tr:hover{background-color:#f8f9fa}.manual-logs-modal .modal-body .table-responsive .table tbody tr:nth-child(2n){background-color:#f8f9fa}.manual-logs-modal .modal-body .table-responsive .table tbody tr td{padding:10px 16px;vertical-align:middle;border-color:#e9ecef}.manual-logs-modal .modal-body .table-responsive .table tbody tr td .text-primary{color:#0d6efd!important;font-weight:500;text-decoration:none}.manual-logs-modal .modal-body .table-responsive .table tbody tr td .text-primary:hover{text-decoration:underline}.manual-logs-modal .modal-body .table-responsive .table tbody tr td .capitalize{text-transform:capitalize}::ng-deep bs-daterangepicker-container .bs-datepicker{border-radius:4px!important;box-shadow:0 2px 8px #0000001a!important;font-size:14px!important;display:flex!important;align-items:flex-start!important;left:142px!important}::ng-deep .bs-datepicker-head{background:#f8f9fa!important;color:#495057!important;border-bottom:1px solid #dee2e6!important;padding:8px 12px!important;border-radius:4px 4px 0 0!important}::ng-deep .bs-datepicker-head .current{font-weight:600!important;color:#495057!important;font-size:13px!important}::ng-deep .bs-datepicker-head .previous,::ng-deep .bs-datepicker-head .next{background:#fff!important;color:#495057!important;border:1px solid #dee2e6!important;width:24px!important;border-radius:4px!important;font-size:12px!important}::ng-deep .bs-datepicker-head .previous:hover,::ng-deep .bs-datepicker-head .next:hover{background:#e9ecef!important}::ng-deep .bs-datepicker .bs-datepicker-buttons{padding:8px!important;background:#f8f9fa!important;border-top:1px solid #dee2e6!important;border-radius:0 0 4px 4px!important}::ng-deep .bs-datepicker .bs-datepicker-buttons .btn-primary{background:#007bff!important;color:#fff!important;border:1px solid #007bff!important;font-weight:500!important;padding:4px 8px!important;border-radius:4px!important;font-size:12px!important}::ng-deep .bs-datepicker .bs-datepicker-buttons .btn-primary:hover{background:#0056b3!important;border-color:#0056b3!important}::ng-deep .bs-datepicker .bs-datepicker-buttons .btn-secondary{background:#fff!important;color:#495057!important;border:1px solid #dee2e6!important;font-weight:500!important;padding:4px 8px!important;border-radius:4px!important;font-size:12px!important}::ng-deep .bs-datepicker .bs-datepicker-buttons .btn-secondary:hover{background:#e9ecef!important}::ng-deep .bs-datepicker-body{background:#fff!important;padding:6px!important}::ng-deep .bs-datepicker-body table{background:#fff!important;border-collapse:separate!important;border-spacing:1px!important}::ng-deep .bs-datepicker-body table th,::ng-deep .bs-datepicker-body table td{border:1px solid #dee2e6!important;border-radius:4px!important;text-align:center!important;font-weight:500!important;color:#495057!important;cursor:pointer!important;transition:all .2s ease!important;font-size:12px!important;width:32px!important;height:32px!important;line-height:24px!important}::ng-deep .bs-datepicker-body table th{background:#f8f9fa!important;font-weight:600!important;font-size:11px!important;padding:2px!important;height:24px!important;line-height:20px!important}::ng-deep .bs-datepicker-body table td:hover:not(.disabled){background:#e9ecef!important}::ng-deep .bs-datepicker-body table td.active{background:#007bff!important;color:#fff!important;border-color:#007bff!important}::ng-deep .bs-datepicker-body table td.is-other-month{color:#6c757d!important;background:#f8f9fa!important}::ng-deep .bs-datepicker-body table td.disabled{color:#adb5bd!important;background:#e9ecef!important;cursor:not-allowed!important}::ng-deep .bs-datepicker-custom-range{background:transparent!important;border-right:1px solid #dee2e6!important;padding:6px!important;width:130px!important;margin-right:8px!important;align-self:flex-start!important}::ng-deep .bs-datepicker-predefined-btns{display:flex!important;flex-direction:column!important;gap:2px!important}::ng-deep .bs-datepicker-predefined-btns button{background:transparent!important;color:#495057!important;border:1px solid #dee2e6!important;border-radius:4px!important;padding:4px 6px!important;font-size:11px!important;font-weight:500!important;text-align:left!important;cursor:pointer!important;transition:all .2s ease!important;width:100%!important;margin:0!important}::ng-deep .bs-datepicker-predefined-btns button:hover{background:#e9ecef!important;border-color:#adb5bd!important}::ng-deep .bs-datepicker-predefined-btns button:active,::ng-deep .bs-datepicker-predefined-btns button:focus{outline:none!important;box-shadow:0 0 0 2px #007bff40!important;background:#007bff!important;color:#fff!important;border-color:#007bff!important}.manual-logs-modal-overlay{position:fixed;top:0;left:0;width:100%;height:100%;background-color:#00000080;display:flex;justify-content:center;align-items:center;z-index:9999}.manual-logs-modal-content{background:#fff;border-radius:8px;max-width:800px;max-height:80vh;overflow:auto;box-shadow:0 4px 8px #0000001a}.popover__wrapper{position:relative;display:inline-block}.popover__content{position:absolute;bottom:100%;left:50%;transform:translate(-50%);background:#fff;border:1px solid #ccc;border-radius:8px;padding:12px;box-shadow:0 4px 12px #00000026;z-index:1000;opacity:0;visibility:hidden;transition:opacity .3s ease,visibility .3s ease;min-width:250px;max-width:400px;font-size:14px}.popover__wrapper:hover .popover__content{opacity:1;visibility:visible}.popover__content .modal-area{padding:0}.popover__content h4{margin:0 0 8px;font-size:16px;font-weight:600;color:#333}.popover__content .break-status{font-size:12px;color:#666;margin-bottom:8px}.popover__content .d-flex{gap:12px}.popover__content p{margin:0 0 4px;font-size:12px;color:#666}.popover__content h5{margin:0;font-size:14px;font-weight:500;color:#333}.popover__content .break-footer{border-top:1px solid #eee;margin-top:8px;padding-top:8px}.popover__content .break-footer p{font-size:12px;color:#666;margin:0}.custom-break-tooltip{position:fixed;z-index:1000;background:#fff;border:1px solid #ddd;border-radius:8px;box-shadow:0 4px 12px #00000026;padding:12px;font-size:13px;max-width:220px;pointer-events:none;top:0;left:0;transform:translate(var(--tooltip-x, 0px),var(--tooltip-y, 0px))}.custom-break-tooltips{position:fixed;z-index:1000;background:#fff;border:1px solid #ddd;border-radius:8px;box-shadow:0 4px 12px #00000026;padding:8px;font-size:12px;max-width:500px;max-height:300px;top:0;left:0;transform:translate(var(--tooltip-x, 0px),var(--tooltip-y, 0px))}.custom-break-tooltips .modal-body{max-height:250px!important;overflow-y:auto;padding:0}.custom-break-tooltips .table-responsive{max-height:250px}.custom-break-tooltips thead th{position:sticky;top:0;background:#f8f9fa;z-index:10;border-bottom:2px solid #dee2e6;font-size:11px;padding:4px 8px;font-weight:600}.custom-break-tooltips table{font-size:11px;margin-bottom:0}.custom-break-tooltips table td{padding:4px 8px;white-space:nowrap}.custom-break-tooltips .table-striped tbody tr:nth-of-type(odd){background-color:#00000005}.popver_content_progress_bar{visibility:hidden}.badge-overflow-container{display:flex;flex-wrap:nowrap;gap:4px;align-items:center;min-width:0;overflow:hidden;width:100%}.badge-overflow-container .badge{flex-shrink:0;white-space:nowrap;font-size:12px;padding:4px 8px;border-radius:50%;display:inline-flex;align-items:center;justify-content:center;font-weight:600;line-height:1;text-transform:uppercase;letter-spacing:.5px;transition:all .3s cubic-bezier(.4,0,.2,1);border:2px solid transparent;width:32px;height:32px;box-sizing:border-box;cursor:pointer;transform:translateZ(0);will-change:transform,box-shadow,background-color;backface-visibility:hidden}.badge-overflow-container .badge:hover{transform:scale(1.15) translateY(-2px);box-shadow:0 6px 16px #007bff40}.badge-overflow-container .badge:active{transform:scale(1.08) translateY(-1px);transition-duration:.15s}.badge-overflow-container .badge-overflow-count{background-color:#6c757d!important;color:#fff!important;cursor:pointer;border:2px solid #6c757d!important;flex-shrink:0;border-radius:50%;width:32px;height:32px;display:inline-flex;align-items:center;justify-content:center;font-weight:600;transition:all .3s cubic-bezier(.4,0,.2,1);transform:translateZ(0);will-change:transform,box-shadow,background-color;backface-visibility:hidden}.badge-overflow-container .badge-overflow-count:hover{background-color:#5a6268!important;border-color:#5a6268!important;transform:scale(1.15) translateY(-2px);box-shadow:0 6px 16px #007bff40}.badge-overflow-container .badge-overflow-count:active{transform:scale(1.08) translateY(-1px);transition-duration:.15s}.timeline-view-container{padding:1rem;background-color:#f8f9fa}.timeline-view-container .timeline-header{margin-bottom:2rem}.timeline-view-container .timeline-header h5{color:#495057;font-weight:600;margin-bottom:1rem}.timeline-view-container .timeline-header .timeline-hours{display:flex;justify-content:space-between;padding:.5rem 0;border-bottom:1px solid #dee2e6;margin-bottom:1rem;background:#fff;border-radius:8px;padding:1rem}.timeline-view-container .timeline-header .timeline-hours .timeline-hour{font-size:.8rem;color:#6c757d;font-weight:500;min-width:40px;text-align:center;padding:.5rem;border-radius:4px;background:#f8f9fa}.timeline-view-container .timeline-body .timeline-row{background:#fff;border:1px solid #dee2e6;border-radius:8px;margin-bottom:1rem;padding:1rem;box-shadow:0 2px 4px #0000001a;transition:box-shadow .2s ease}.timeline-view-container .timeline-body .timeline-row:hover{box-shadow:0 4px 8px #00000026}.timeline-view-container .timeline-body .timeline-row .timeline-employee{margin-bottom:1rem}.timeline-view-container .timeline-body .timeline-row .timeline-employee .employee-name{font-weight:600;color:#495057;font-size:1.1rem}.timeline-view-container .timeline-body .timeline-row .timeline-track{position:relative;height:40px;background:#f8f9fa;border-radius:4px;border:1px solid #e9ecef}.timeline-view-container .timeline-body .timeline-row .timeline-track .work-duration-bar{position:absolute;height:100%;background:linear-gradient(135deg,#28a745,#20c997);border-radius:4px;box-shadow:0 2px 4px #28a7454d;transition:opacity .2s ease}.timeline-view-container .timeline-body .timeline-row .timeline-track .work-duration-bar:hover{opacity:.8}.timeline-view-container .timeline-body .timeline-row .timeline-track .break-bar{position:absolute;height:100%;border-radius:4px;box-shadow:0 2px 4px #0003;border:1px solid rgba(255,255,255,.5);transition:opacity .2s ease}.timeline-view-container .timeline-body .timeline-row .timeline-track .break-bar:hover{opacity:.8}.calendar-view-container .calendar-header{margin-bottom:2rem}.calendar-view-container .calendar-header h5{color:#495057;font-weight:600}.calendar-view-container .calendar-header .calendar-nav button{border:1px solid #dee2e6;background:#fff;color:#495057;padding:.375rem .75rem;border-radius:.375rem;transition:all .2s ease}.calendar-view-container .calendar-header .calendar-nav button:hover{background-color:#f8f9fa;border-color:#adb5bd}.calendar-view-container .calendar-header .calendar-nav button:first-child{border-top-right-radius:0;border-bottom-right-radius:0;border-right:none}.calendar-view-container .calendar-header .calendar-nav button:last-child{border-top-left-radius:0;border-bottom-left-radius:0}.calendar-view-container .calendar-grid .calendar-week-header{display:flex;background-color:#f8f9fa;border:1px solid #dee2e6;border-bottom:none}.calendar-view-container .calendar-grid .calendar-week-header .calendar-day-header{flex:1;padding:.75rem;text-align:center;font-weight:600;color:#495057;border-right:1px solid #dee2e6}.calendar-view-container .calendar-grid .calendar-week-header .calendar-day-header:last-child{border-right:none}.calendar-view-container .calendar-grid .calendar-weeks{border:1px solid #dee2e6;border-top:none}.calendar-view-container .calendar-grid .calendar-weeks .calendar-week{display:flex;border-bottom:1px solid #dee2e6}.calendar-view-container .calendar-grid .calendar-weeks .calendar-week:last-child{border-bottom:none}.calendar-view-container .calendar-grid .calendar-weeks .calendar-week .calendar-day{flex:1;min-height:100px;padding:.5rem;border-right:1px solid #dee2e6;background:#fff}.calendar-view-container .calendar-grid .calendar-weeks .calendar-week .calendar-day:last-child{border-right:none}.calendar-view-container .calendar-grid .calendar-weeks .calendar-week .calendar-day.current-month{background:#fff}.calendar-view-container .calendar-grid .calendar-weeks .calendar-week .calendar-day.today{background-color:#fff3cd;border:2px solid #ffc107}.calendar-view-container .calendar-grid .calendar-weeks .calendar-week .calendar-day .day-number{font-weight:600;color:#495057;margin-bottom:.25rem}.calendar-view-container .calendar-grid .calendar-weeks .calendar-week .calendar-day .day-entries .entry-dot{width:8px;height:8px;border-radius:50%;display:inline-block;margin-right:2px;margin-bottom:2px}.heatmap-view-container .heatmap-header{margin-bottom:2rem}.heatmap-view-container .heatmap-header h5{color:#495057;font-weight:600}.heatmap-view-container .heatmap-header .heatmap-legend .legend-colors{display:flex;margin:0 1rem}.heatmap-view-container .heatmap-header .heatmap-legend .legend-colors .legend-color{width:12px;height:12px;margin-right:2px;border-radius:2px}.heatmap-view-container .heatmap-header .heatmap-legend span{font-size:.875rem;color:#6c757d}.heatmap-view-container .heatmap-grid .heatmap-months{display:flex;margin-bottom:.5rem}.heatmap-view-container .heatmap-grid .heatmap-months .month-label{flex:1;text-align:center;font-size:.8rem;font-weight:600;color:#495057}.heatmap-view-container .heatmap-grid .heatmap-weeks .heatmap-week{display:flex;margin-bottom:2px}.heatmap-view-container .heatmap-grid .heatmap-weeks .heatmap-week .heatmap-day{flex:1;aspect-ratio:1;border-radius:2px;margin-right:2px;transition:opacity .2s ease}.heatmap-view-container .heatmap-grid .heatmap-weeks .heatmap-week .heatmap-day:hover{opacity:.8}.heatmap-view-container .heatmap-grid .heatmap-weeks .heatmap-week .heatmap-day:last-child{margin-right:0}.card-view-container{padding:1rem;height:100%;overflow-y:auto;overflow-x:hidden}.card-view-container[data-theme=white]{background-color:#f6f8ff;color:#000}.card-view-container[data-theme=white] .attendance-card{background-color:#f6f8ff;border-color:#d9d9db;color:#000}.card-view-container[data-theme=white] .attendance-card:hover{background-color:#007bff1a}.card-view-container[data-theme=white] .attendance-card .card-header{background-color:#f8f9fa;color:#000;border-bottom-color:#d9d9db}.card-view-container[data-theme=white] .attendance-card .card-body{background-color:#f6f8ff;color:#000}.card-view-container[data-theme=white] .attendance-card .badge.bg-success{background-color:#84ca81;color:#f6f8ff}.card-view-container[data-theme=white] .attendance-card .badge.bg-danger{background-color:#ea5353;color:#f6f8ff}.card-view-container[data-theme=white] .attendance-card .badge.bg-warning{background-color:#fff3dc;color:#000}.card-view-container[data-theme=white] .attendance-card .badge.bg-info{background-color:#e8fbfd;color:#00bad1}.card-view-container[data-theme=blue]{background-color:#f0f8ff;color:#1e3a5f}.card-view-container[data-theme=blue] .attendance-card{background-color:#f6f8ff;border-color:#b3d9ff;color:#1e3a5f}.card-view-container[data-theme=blue] .attendance-card:hover{background-color:#1e3a5f1a}.card-view-container[data-theme=blue] .attendance-card .card-header{background-color:#e6f3ff;color:#1e3a5f;border-bottom-color:#b3d9ff}.card-view-container[data-theme=blue] .attendance-card .card-body{background-color:#f6f8ff;color:#1e3a5f}.card-view-container[data-theme=blue] .attendance-card .badge.bg-success{background-color:#69db7c;color:#f6f8ff}.card-view-container[data-theme=blue] .attendance-card .badge.bg-danger{background-color:#ff8787;color:#f6f8ff}.card-view-container[data-theme=blue] .attendance-card .badge.bg-warning{background-color:#ffd43b;color:#1e3a5f}.card-view-container[data-theme=blue] .attendance-card .badge.bg-info{background-color:#74c0fc;color:#f6f8ff}.card-view-container .row{margin:0}.card-view-container .row .col-xl-4,.card-view-container .row .col-lg-6,.card-view-container .row .col-md-6,.card-view-container .row .col-sm-12{padding:.5rem}.card-view-container .attendance-card{transition:background-color .2s ease;border:1px solid #d9d9db;border-radius:4px;overflow:hidden;height:100%;display:flex;flex-direction:column;font-family:sans-serif;font-size:16px}.card-view-container .attendance-card:hover{box-shadow:0 2px 4px #0000001a}.card-view-container .attendance-card.expanded .card-body{max-height:none}.card-view-container .attendance-card .card-header{padding:8px;border-bottom:1px solid #d9d9db;flex-shrink:0;font-weight:500}.card-view-container .attendance-card .card-header .employee-avatar{margin-right:.75rem;flex-shrink:0}.card-view-container .attendance-card .card-header .employee-avatar img,.card-view-container .attendance-card .card-header .employee-avatar .avatar-placeholder{border:1px solid #d9d9db;width:40px;height:40px;border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:16px;font-weight:400}.card-view-container .attendance-card .card-header .flex-grow-1{min-width:0}.card-view-container .attendance-card .card-header h6{margin:0;font-weight:500;font-size:16px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.card-view-container .attendance-card .card-header small{opacity:.9;font-weight:400;font-size:16px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.card-view-container .attendance-card .card-header .card-actions{flex-shrink:0}.card-view-container .attendance-card .card-header .card-actions .btn{background-color:transparent;border:1px solid #d9d9db;color:inherit;padding:.25rem .5rem}.card-view-container .attendance-card .card-header .card-actions .btn:hover{background-color:#007bff1a}.card-view-container .attendance-card .card-header .card-actions .btn i{font-size:.8rem}.card-view-container .attendance-card .card-body{padding:8px;flex:1;display:flex;flex-direction:column}.card-view-container .attendance-card .card-body .info-item{text-align:center;margin-bottom:.5rem}.card-view-container .attendance-card .card-body .info-item small{display:block;font-weight:400;color:#6c757d;text-transform:uppercase;font-size:12px;letter-spacing:.5px;margin-bottom:.25rem}.card-view-container .attendance-card .card-body .info-item span{font-size:16px;font-weight:400;color:inherit}.card-view-container .attendance-card .card-body .badge{font-size:12px;padding:.25rem .5rem;border-radius:4px;font-weight:400;text-transform:uppercase;letter-spacing:.5px;border:none}.card-view-container .attendance-card .card-body .badge.bg-success,.card-view-container .attendance-card .card-body .badge.bg-danger{color:#f6f8ff}.card-view-container .attendance-card .card-body .badge.bg-warning{color:#000}.card-view-container .attendance-card .card-body .badge.bg-secondary{color:#f6f8ff}.card-view-container .attendance-card .card-body .card-details{margin-top:1rem}.card-view-container .attendance-card .card-body .card-details .section-title{font-size:14px;font-weight:500;color:inherit;margin-bottom:.75rem;display:flex;align-items:center}.card-view-container .attendance-card .card-body .card-details .section-title i{margin-right:.5rem;opacity:.8}.card-view-container .attendance-card .card-body .card-details .breaks-list .break-item,.card-view-container .attendance-card .card-body .card-details .breaks-list .leave-item,.card-view-container .attendance-card .card-body .card-details .short-leave-list .break-item,.card-view-container .attendance-card .card-body .card-details .short-leave-list .leave-item{background-color:inherit;border:1px solid #d9d9db;border-radius:4px;padding:8px;margin-bottom:.5rem;cursor:pointer;transition:all .25s cubic-bezier(.4,0,.2,1);transform:translateZ(0)}.card-view-container .attendance-card .card-body .card-details .breaks-list .break-item .d-flex,.card-view-container .attendance-card .card-body .card-details .breaks-list .leave-item .d-flex,.card-view-container .attendance-card .card-body .card-details .short-leave-list .break-item .d-flex,.card-view-container .attendance-card .card-body .card-details .short-leave-list .leave-item .d-flex{gap:.75rem;align-items:center}.card-view-container .attendance-card .card-body .card-details .breaks-list .break-item .d-flex small,.card-view-container .attendance-card .card-body .card-details .breaks-list .leave-item .d-flex small,.card-view-container .attendance-card .card-body .card-details .short-leave-list .break-item .d-flex small,.card-view-container .attendance-card .card-body .card-details .short-leave-list .leave-item .d-flex small{font-weight:500;color:inherit;margin-bottom:.25rem}.card-view-container .attendance-card .card-body .card-details .breaks-list .break-item .d-flex .text-muted,.card-view-container .attendance-card .card-body .card-details .breaks-list .leave-item .d-flex .text-muted,.card-view-container .attendance-card .card-body .card-details .short-leave-list .break-item .d-flex .text-muted,.card-view-container .attendance-card .card-body .card-details .short-leave-list .leave-item .d-flex .text-muted{font-size:12px;color:#6c757d}.card-view-container .attendance-card .card-body .card-details .breaks-list .break-item .d-flex .badge,.card-view-container .attendance-card .card-body .card-details .breaks-list .leave-item .d-flex .badge,.card-view-container .attendance-card .card-body .card-details .short-leave-list .break-item .d-flex .badge,.card-view-container .attendance-card .card-body .card-details .short-leave-list .leave-item .d-flex .badge{font-size:10px;padding:.2rem .4rem}.card-view-container .attendance-card .card-body .card-details .additional-details .row .col-6{margin-bottom:.5rem}.card-view-container .attendance-card .card-body .card-details .additional-details .row .col-6 small{font-weight:400;color:#6c757d;text-transform:uppercase;font-size:12px;letter-spacing:.5px;margin-bottom:.25rem}.card-view-container .attendance-card .card-body .card-details .additional-details .row .col-6 span{font-weight:400;color:inherit;font-size:14px}@media (max-width: 1200px){.card-view-container .row .col-xl-4{flex:0 0 50%;max-width:50%}}@media (max-width: 768px){.card-view-container .row .col-xl-4,.card-view-container .col-lg-6,.card-view-container .col-md-6{flex:0 0 100%;max-width:100%}.card-view-container .attendance-card .card-body{padding:8px}.card-view-container .attendance-card .card-body .info-item small{font-size:10px}.card-view-container .attendance-card .card-body .info-item span{font-size:14px}}@media (max-width: 576px){.card-view-container{padding:.5rem}.card-view-container .row .col-sm-12{padding:.25rem}.card-view-container .attendance-card .card-header{padding:8px}.card-view-container .attendance-card .card-header h6,.card-view-container .attendance-card .card-header small{font-size:14px}.card-view-container .attendance-card .card-body{padding:8px}}.btn-xs{padding:.125rem .3rem!important;font-size:.9rem!important;border-radius:.2rem!important;line-height:1.5!important}.form-select.form-select-sm:invalid{border-color:#d9d9db!important}.form-select.form-select-sm:valid{border-color:#d9d9db!important}.date-range-container{gap:8px;flex-wrap:nowrap;align-items:center}.date-range-btn{padding:6px 12px;font-size:14px;font-weight:500;border-radius:6px;transition:all .25s cubic-bezier(.4,0,.2,1);white-space:nowrap;display:inline-flex;align-items:center;justify-content:center;min-height:36px;transform:translateZ(0);position:relative;overflow:hidden}.date-range-btn:before{content:\"\";position:absolute;top:50%;left:50%;width:0;height:0;background:#fff3;border-radius:50%;transform:translate(-50%,-50%);transition:width .25s,height .25s}.date-range-btn:active:before{width:300px;height:300px}.calendar-btn{border-color:#0d6efd;color:#0d6efd;background-color:transparent}.calendar-btn:hover{background-color:#0d6efd;color:#fff;transform:translateY(-1px);box-shadow:0 4px 12px #0d6efd4d}.clear-btn{border-color:#dc3545;color:#dc3545;background-color:transparent}.clear-btn:hover{background-color:#dc3545;color:#fff;transform:translateY(-1px);box-shadow:0 4px 12px #dc35454d}.date-range-label{font-size:14px;font-weight:500;padding:4px 8px;min-width:180px;text-align:center;white-space:nowrap;cursor:pointer}.date-range-btn .bi{font-size:14px;transition:transform .2s ease}.date-range-btn:hover .bi{transform:scale(1.1)}@media (max-width: 768px){.date-range-container{flex-wrap:wrap;justify-content:flex-start}.date-range-label{min-width:100%;margin-top:8px;order:3}}.date-range-btn:focus{outline:none;box-shadow:0 0 0 3px #0d6efd40}.clear-btn:focus{box-shadow:0 0 0 3px #dc354540}.action-buttons-row .button{display:inline-flex;align-items:center;justify-content:center;overflow:hidden;color:#fff;border-radius:6px;height:34px;padding:0 10px;white-space:nowrap;transition:max-width .4s ease,background-color .3s ease;max-width:40px;background-color:transparent;border:1px solid #6F61CF}.action-buttons-row .button .label-hidden{opacity:0;margin-left:8px;transition:opacity .3s ease;pointer-events:none;display:none}.action-buttons-row .button:hover{max-width:200px;background-color:#6f61cf}.action-buttons-row .button:hover .label-hidden{opacity:1;pointer-events:auto;margin-left:8px!important;display:block}.action-buttons-row ::ng-deep .button .svg-icon svg path{stroke:#6f61cf;transition:fill .3s ease,stroke .3s ease}.action-buttons-row ::ng-deep .button:hover .svg-icon svg path{stroke:#fff!important}.action-buttons-row ::ng-deep .button:active .svg-icon svg path{stroke:#6f61cf!important}.action-buttons-row ::ng-deep .button:focus .svg-icon svg path{stroke:#6f61cf!important}.badge-overflow-wrapper{width:100%;min-width:0;display:flex;align-items:center}.custom-overlay-wrapper{position:fixed;top:0;left:0;width:100%;height:100%;background-color:#00000080;display:flex;justify-content:center;align-items:center;z-index:9999}.custom-overlay{background:#fff;border-radius:8px;box-shadow:0 4px 12px #00000026;min-width:300px;max-width:400px}.custom-modal-body{padding:20px;text-align:center}.custom-modal-body .modal-message{font-size:16px;margin-bottom:20px;color:#333}.custom-modal-body .modal-actions{display:flex;gap:10px;justify-content:center}.custom-modal-body .modal-actions button{padding:8px 16px;border:none;border-radius:4px;cursor:pointer;font-size:14px;transition:background-color .2s ease}.custom-modal-body .modal-actions button.btn-confirm{background-color:#007bff;color:#fff}.custom-modal-body .modal-actions button.btn-confirm:hover{background-color:#0056b3}.custom-modal-body .modal-actions button.btn-cancel{background-color:#6c757d;color:#fff}.custom-modal-body .modal-actions button.btn-cancel:hover{background-color:#545b62}.custom-break-tooltip .short-break-table{width:100%;border-collapse:collapse;font-size:12px}.custom-break-tooltip .short-break-table th,.custom-break-tooltip .short-break-table td{padding:4px 6px;text-align:center;border:1px solid #ddd}.custom-break-tooltip .short-break-table th{background-color:#f8f9fa;font-weight:600}.custom-break-tooltip .short-break-table tbody tr:nth-child(2n){background-color:#fafafa}.text-truncate{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;display:flex;align-items:center;min-width:0}\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: "ngmodule", type: FormsModule }, { kind: "directive", type: i3.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i3.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i3.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i3.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i3.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i3.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i3.RadioControlValueAccessor, selector: "input[type=radio][formControlName],input[type=radio][formControl],input[type=radio][ngModel]", inputs: ["name", "formControlName", "value"] }, { kind: "directive", type: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i3.PatternValidator, selector: "[pattern][formControlName],[pattern][formControl],[pattern][ngModel]", inputs: ["pattern"] }, { kind: "directive", type: i3.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: InlineSVGModule }, { kind: "directive", type: i4.InlineSVGDirective, selector: "[inlineSVG]", inputs: ["inlineSVG", "resolveSVGUrl", "replaceContents", "prepend", "injectComponent", "cacheSVG", "setSVGAttributes", "removeSVGAttributes", "forceEvalStyles", "evalScripts", "fallbackImgUrl", "fallbackSVG", "onSVGLoaded"], outputs: ["onSVGInserted", "onSVGFailed"] }, { kind: "pipe", type: FilterPipe, name: "filter" }, { kind: "pipe", type: PinnedColumnsPipe, name: "pinnedColumns" }, { kind: "ngmodule", type: DragDropModule }, { kind: "directive", type: i5.CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: i5.CdkDropListGroup, selector: "[cdkDropListGroup]", inputs: ["cdkDropListGroupDisabled"], exportAs: ["cdkDropListGroup"] }, { kind: "directive", type: i5.CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "directive", type: i5.CdkDragHandle, selector: "[cdkDragHandle]", inputs: ["cdkDragHandleDisabled"] }, { kind: "directive", type: i5.CdkDragPreview, selector: "ng-template[cdkDragPreview]", inputs: ["data", "matchSize"] }, { kind: "directive", type: i5.CdkDragPlaceholder, selector: "ng-template[cdkDragPlaceholder]", inputs: ["data"] }, { kind: "ngmodule", type: BsDatepickerModule }, { kind: "directive", type: i6.BsDaterangepickerDirective, selector: "[bsDaterangepicker]", inputs: ["placement", "triggers", "outsideClick", "container", "outsideEsc", "isOpen", "bsValue", "bsConfig", "isDisabled", "minDate", "maxDate", "dateCustomClasses", "daysDisabled", "datesDisabled", "datesEnabled"], outputs: ["onShown", "onHidden", "bsValueChange"], exportAs: ["bsDaterangepicker"] }, { kind: "directive", type: i6.BsDaterangepickerInputDirective, selector: "input[bsDaterangepicker]" }, { kind: "ngmodule", type: ScrollingModule }, { kind: "directive", type: i7.CdkFixedSizeVirtualScroll, selector: "cdk-virtual-scroll-viewport[itemSize]", inputs: ["itemSize", "minBufferPx", "maxBufferPx"] }, { kind: "directive", type: i7.CdkVirtualForOf, selector: "[cdkVirtualFor][cdkVirtualForOf]", inputs: ["cdkVirtualForOf", "cdkVirtualForTrackBy", "cdkVirtualForTemplate", "cdkVirtualForTemplateCacheSize"] }, { kind: "component", type: i7.CdkVirtualScrollViewport, selector: "cdk-virtual-scroll-viewport", inputs: ["orientation", "appendOnly"], outputs: ["scrolledIndexChange"] }, { kind: "component", type: BadgeOverflowComponent, selector: "app-badge-overflow", inputs: ["badges", "maxWidth"], outputs: ["badgeMouseEnter", "badgeMouseLeave", "overflowCountClick"] }, { kind: "pipe", type: TimezoneFormatPipe, name: "timezoneFormat" }], animations: [
9454
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: TimeSheetComponent, isStandalone: true, selector: "time-sheet", inputs: { rowAnimation: "rowAnimation", paginationConfig: "paginationConfig", dataSet: "dataSet", columns: "columns", rowHeight: "rowHeight", headerRowHeight: "headerRowHeight", showVerticalBorder: "showVerticalBorder", evenRowsBackgroundColor: "evenRowsBackgroundColor", oddRowsBackgroundColor: "oddRowsBackgroundColor", headerBackgroundColor: "headerBackgroundColor", checkboxesBackgroundColor: "checkboxesBackgroundColor", showColumnsGrouping: "showColumnsGrouping", rowHoverColor: "rowHoverColor", leftPinnedBackgroundColor: "leftPinnedBackgroundColor", bodyBackgroundColor: "bodyBackgroundColor", rightPinnedBackgroundColor: "rightPinnedBackgroundColor", sidemenuBackgroundColor: "sidemenuBackgroundColor", bodyTextColor: "bodyTextColor", headerTextColor: "headerTextColor", headerTextFontsSize: "headerTextFontsSize", bodyTextFontsSize: "bodyTextFontsSize", headerFontWeight: "headerFontWeight", bodyFontWeight: "bodyFontWeight", checkedRowBackgroundColor: "checkedRowBackgroundColor", dropdownsBackgroundColor: "dropdownsBackgroundColor", footerRowHeight: "footerRowHeight", topGroupedBadgesBackgroundColor: "topGroupedBadgesBackgroundColor", showRowsGrouping: "showRowsGrouping", showFilterRow: "showFilterRow", fontFaimly: "fontFaimly", showSideMenu: "showSideMenu", footerPadding: "footerPadding", topFilterRowHeight: "topFilterRowHeight", rowShadingEnabled: "rowShadingEnabled", showSerialNumber: "showSerialNumber", enableExport: "enableExport", singleSpaAssetsPath: "singleSpaAssetsPath", filtersConfig: "filtersConfig", loading: "loading", dataSetLoading: "dataSetLoading", verticalScrollbarWidth: "verticalScrollbarWidth", horizintalScrollbarWidth: "horizintalScrollbarWidth", showCellDetailsBox: "showCellDetailsBox", dateFormat: "dateFormat", tableSearch: "tableSearch", actions: "actions", config: "config", showTaskbar: "showTaskbar", tableName: "tableName", listingType: "listingType", checkboxState: "checkboxState", taskbarActions: "taskbarActions", sortingConfig: "sortingConfig", tableFilterViewId: "tableFilterViewId", selectedTableLayout: "selectedTableLayout", selectedPresetId: "selectedPresetId", closeDropdown: "closeDropdown", globalSearchText: "globalSearchText", nestedTablerowFontsize: "nestedTablerowFontsize", nestedTableHeaderRowHeight: "nestedTableHeaderRowHeight", nestedTablerowHeight: "nestedTablerowHeight", gridType: "gridType", isSingleDay: "isSingleDay", leftPinnedBoxshadow: "leftPinnedBoxshadow", rightPinnedBoxshadow: "rightPinnedBoxshadow", enableAccordionShadow: "enableAccordionShadow", enableAccordionSeparators: "enableAccordionSeparators", enableRowShading: "enableRowShading", selectedRowsBackgroundColor: "selectedRowsBackgroundColor", nestedTableHeaderBAckgroundColor: "nestedTableHeaderBAckgroundColor", tableView: "tableView", columnThreedotsMunuConfig: "columnThreedotsMunuConfig", timezonePrefs: "timezonePrefs", enableProgressiveLoading: "enableProgressiveLoading", progressiveChunkSize: "progressiveChunkSize", progressiveDelay: "progressiveDelay", detailsIconPosition: "detailsIconPosition", detailsPosition: "detailsPosition", singleOpen: "singleOpen", buttons: "buttons", isStartDateNotEqualToEndDate: "isStartDateNotEqualToEndDate" }, outputs: { onShortBreakClick: "onShortBreakClick", searchEvent: "searchEvent", changeLayout: "changeLayout", filterOptions: "filterOptions", filterCleared: "filterCleared", genericEvent: "genericEvent", tablePresetConfig: "tablePresetConfig", sortingOrderOptions: "sortingOrderOptions", createUpdateConfigListing: "createUpdateConfigListing", loadMore: "loadMore", emailClicked: "emailClicked", addAttendanceClicked: "addAttendanceClicked", backPayClicked: "backPayClicked", grandTotalClicked: "grandTotalClicked", printClicked: "printClicked", exportClicked: "exportClicked", exportDailyClicked: "exportDailyClicked", deleteClicked: "deleteClicked", closeTaskbar: "closeTaskbar" }, 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: "searchInput", first: true, predicate: ["searchInput"], 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\">\n <!-- <h1>abu </h1> -->\n <div\n class=\"d-flex justify-content-between mb-3 align-items-center position-relative\"\n >\n <div class=\"col-4 global-search position-relative\">\n\n <span\n\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/search.svg'\"\n class=\"data-grid-svg-icon mx-2 position-absolute icon\"\n ></span>\n <input\n #searchInput\n style=\"height: 36px\"\n class=\"form-control\"\n placeholder=\"Search all columns and press Enter\"\n [(ngModel)]=\"tableSearch\"\n (keydown.enter)=\"onGlobalSearch()\"\n\n />\n <span\n *ngIf=\"tableSearch\"\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/x.svg'\"\n class=\"data-grid-svg-icon position-absolute end-0 top-50 translate-middle-y me-2 cursor-pointer\"\n (click)=\"onSearchReset()\"\n title=\"Clear search\"\n ></span>\n\n </div>\n\n <!-- Date Picker Buttons -->\n <!-- Date Picker Section - Improved Version -->\n<div class=\"position-relative d-flex justify-content-center align-items-center ms-2 date-range-container\">\n\n <!-- Hidden Date Picker Input -->\n <input\n type=\"text\"\n class=\"form-control\"\n bsDaterangepicker\n #picker=\"bsDaterangepicker\"\n [(ngModel)]=\"bsRangeValue\"\n [bsConfig]=\"bsConfig\"\n (bsValueChange)=\"onRangeSelected($event, picker)\"\n style=\"opacity: 0; width: 0; height: 0; position: absolute;\"\n />\n\n <!-- Left Arrow Button -->\n <span\n class=\"text-primary cursor-pointer me-2 date-range-btn arrow-btn\"\n (click)=\"navigateDate('left')\"\n title=\"Previous Date Range\"\n *ngIf=\"bsRangeValue && bsRangeValue.length > 0\"\n >\n <span class=\"bi bi-chevron-left\"></span>\n </span>\n\n <!-- Date Range Label -->\n <span\n *ngIf=\"bsRangeValue && bsRangeValue.length > 0\"\n class=\"text-primary date-range-label cursor-pointer\"\n (click)=\"togglePicker(picker)\"\n title=\"Click to open calendar\"\n >\n {{ bsRangeValue[0] | timezoneFormat:prefs:'date' }} - {{ bsRangeValue[1] | timezoneFormat:prefs:'date' }}\n </span>\n\n <!-- Right Arrow Button -->\n <span\n class=\"text-primary cursor-pointer ms-2 date-range-btn arrow-btn\"\n (click)=\"navigateDate('right')\"\n title=\"Next Date Range\"\n *ngIf=\"bsRangeValue && bsRangeValue.length > 0\"\n >\n <span class=\"bi bi-chevron-right\"></span>\n </span>\n\n\n\n</div>\n\n <div class=\"d-flex gap-2 align-items-center table-right-top-actions\">\n\n <!-- Pivot Mode Button -->\n <!-- <a\n href=\"JavaScript:void(0)\"\n class=\"button button-small btn btn-active-primary border border-primary me-2 header-icon\"\n (click)=\"togglePivotMode()\"\n [class.active]=\"pivotMode\"\n title=\"Toggle Pivot Mode\"\n >\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/pivot.svg'\"\n class=\"svg-icon svg-icon-2\"\n ></span>\n </a> -->\n\n <div class=\"action-buttons-row d-flex gap-2 align-items-center\">\n <a\n href=\"JavaScript:void(0)\"\n class=\"button button-small btn btn-active-primary border border-primary p-0 d-flex align-items-center justify-content-center px-3\"\n (click)=\"togglePicker(picker)\"\n title=\"Select Date Range\"\n >\n <span class=\"bi bi-calendar3 text-primary\"></span>\n <span class=\"label-hidden text-white\">Calendar</span>\n </a>\n <button\n *ngIf=\"bsRangeValue && bsRangeValue.length > 0 && !isDefaultDateRange\"\n type=\"button\"\n class=\"button button-small btn btn-active-danger border border-danger p-0 d-flex align-items-center justify-content-center px-3\"\n (click)=\"clearDateRange()\"\n title=\"Clear Date Range\"\n >\n <span class=\"bi bi-x-circle text-danger\"></span>\n <span class=\"label-hidden text-white\">Clear</span>\n </button>\n</div>\n<ng-container *ngFor=\"let button of buttons\">\n <div\n class=\"action-buttons-row d-flex align-items-center\"\n *ngIf=\"getButtonPermission(button) && (!button.condition || (button.condition === '!isSingleDay' && !isSingleDay) || (button.condition === 'isSingleDay' && isSingleDay))\"\n >\n <a\n href=\"JavaScript:void(0)\"\n (click)=\"onActionButtonClick(button.name)\"\n class=\"button\"\n [title]=\"button.name\"\n >\n <span\n *ngIf=\"button.is_showIcon\"\n [inlineSVG]=\"button.iconPath\"\n class=\"svg-icon\"\n ></span>\n <span\n class=\"label-hidden\"\n >{{ button.name }}</span\n >\n </a>\n </div>\n</ng-container>\n\n<!-- Calendar Button -->\n\n\n<!-- Existing filter, settings, etc. -->\n <div\n *ngIf=\"!showFilterRow\"\n class=\"cursor-pointer position-relative action-buttons-row d-flex align-items-center\"\n (click)=\"toggleOpenFilter()\"\n [class.active]=\"showFilters\"\n >\n <a\n href=\"JavaScript:void(0)\"\n class=\"button button-small btn btn-active-primary border border-primary p-0 d-flex align-items-center justify-content-center px-3\"\n >\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\"\n class=\"svg-icon svg-icon-2\"\n ></span>\n <span class=\"label-hidden text-white\">Filters</span>\n </a>\n <span\n *ngIf=\"activeFilteredColumns?.length\"\n style=\"\n width: 7px;\n height: 7px;\n box-shadow: 0px 0px 3px #0022ff;\n background-color: rgb(0, 60, 255);\n position: absolute;\n right: 16px;\n top: 10px;\n \"\n class=\"rounded-circle d-block\"\n ></span>\n </div>\n <div\n class=\"cursor-pointer d-none\"\n (click)=\"toggleActions('advance-filter')\"\n [class.active]=\"activeTopButton === 'advance-filter'\"\n >\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/zoom-charge.svg'\"\n class=\"data-grid-svg-icon top-icon me-2\"\n ></span>\n </div>\n <div\n class=\"cursor-pointer action-buttons-row\"\n (click)=\"toggleActions('setting')\"\n [class.active]=\"\n activeTopButton === 'setting' ||\n activeTopButton === 'table-layout' ||\n activeTopButton === 'table-presets' ||\n activeTopButton === 'show-hide-columns'\n \"\n >\n <!-- <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/settings-2.svg'\"\n class=\"data-grid-svg-icon top-icon me-2\"\n ></span> -->\n <a\n href=\"JavaScript:void(0)\"\n class=\"button button-small btn btn-active-primary border border-primary p-0 d-flex align-items-center justify-content-center px-3\"\n >\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/settings-2.svg'\"\n class=\"svg-icon svg-icon-2\"\n ></span>\n <span class=\"label-hidden text-white\">Setting</span>\n </a>\n\n <div\n *ngIf=\"activeTopButton === 'setting'\"\n class=\"actions-dropdown mt-1 actions-dropdown-setting\"\n style=\"position: absolute\"\n >\n <div class=\"dropdown-menu show shadow custom-menu\">\n <!-- Table Layout -->\n <a\n class=\"dropdown-item d-flex justify-content-between align-items-center cursor-pointer\"\n (click)=\"$event.stopPropagation(); toggleActions('table-layout')\"\n >\n <span\n ><span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/table-2.svg'\n \"\n class=\"data-grid-svg-icon me-2\"\n ></span>\n Table Layout</span\n >\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\n \"\n class=\"data-grid-svg-icon me-2\"\n ></span>\n </a>\n <!-- Table Presets -->\n <a\n (click)=\"$event.stopPropagation(); toggleActions('table-presets')\"\n class=\"dropdown-item d-flex justify-content-between align-items-center cursor-pointer\"\n >\n <span\n ><span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/list-details.svg'\n \"\n class=\"data-grid-svg-icon me-2\"\n ></span>\n Table Presets</span\n >\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\n \"\n class=\"data-grid-svg-icon me-2\"\n ></span>\n </a>\n\n <!-- Columns -->\n <a\n *ngIf=\"!showSideMenu\"\n (click)=\"\n $event.stopPropagation(); toggleActions('show-hide-columns')\n \"\n class=\"dropdown-item d-flex justify-content-between align-items-center cursor-pointer\"\n >\n <span\n ><span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/eye.svg'\"\n class=\"data-grid-svg-icon me-2\"\n ></span>\n Columns</span\n >\n <div class=\"d-flex gap-2\">\n <span class=\"muted-text\">{{ columnsCount }}</span>\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\n \"\n class=\"data-grid-svg-icon me-2\"\n ></span>\n </div>\n </a>\n\n <div class=\"dropdown-divider\"></div>\n\n <!-- Filter -->\n <a\n class=\"dropdown-item cursor-pointer\"\n (click)=\"toggleOpenFilter(); activeTopButton = ''\"\n *ngIf=\"!showFilterRow\"\n >\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\n \"\n class=\"data-grid-svg-icon me-2 mt-1 cursor-pointer\"\n ></span>\n Filter\n </a>\n\n <!-- Download -->\n <!-- <a\n class=\"dropdown-item cursor-pointer\"\n (click)=\"downloadCsv('csv')\"\n >\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/download.svg'\n \"\n class=\"data-grid-svg-icon me-2 cursor-pointer\"\n ></span>\n CSV Export\n </a> -->\n <!-- <a\n *ngIf=\"enableExport\"\n class=\"dropdown-item cursor-pointer\"\n (click)=\"downloadCsv('xlsx')\"\n >\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/download.svg'\n \"\n class=\"data-grid-svg-icon me-2 cursor-pointer\"\n ></span>\n Excel Export\n </a> -->\n <!-- Font Family & Font Size -->\n <div class=\"px-2 pb-2 pt-2\">\n <div class=\"d-flex gap-2\">\n <!-- Font Family -->\n <select\n class=\"form-select form-select-sm\"\n [(ngModel)]=\"fontFaimly\"\n (change)=\"onFontChange()\"\n >\n <option *ngFor=\"let font of fontFamilies\" [value]=\"font\">\n {{ font }}\n </option>\n </select>\n\n <!-- Font Size -->\n <select\n class=\"form-select form-select-sm\"\n (change)=\"onFontChange()\"\n [(ngModel)]=\"bodyTextFontsSize\"\n >\n <option *ngFor=\"let size of fontSizes\" [value]=\"size\">\n {{ size }}\n </option>\n </select>\n </div>\n </div>\n </div>\n </div>\n\n <!-- Table Layout -->\n\n <ng-container *ngIf=\"activeTopButton === 'table-layout'\">\n <div\n *ngTemplateOutlet=\"tableLayout\"\n class=\"actions-dropdown mt-1\"\n style=\"position: absolute\"\n ></div>\n </ng-container>\n\n <!-- Table Presets -->\n <ng-container *ngIf=\"activeTopButton === 'table-presets'\">\n <div\n *ngTemplateOutlet=\"tablePreset\"\n class=\"actions-dropdown mt-1\"\n style=\"position: absolute\"\n ></div>\n </ng-container>\n\n <!-- Table Presets -->\n <ng-container *ngIf=\"activeTopButton === 'show-hide-columns'\">\n <div\n *ngTemplateOutlet=\"showHideColumns\"\n class=\"actions-dropdown mt-1\"\n style=\"position: absolute\"\n ></div>\n </ng-container>\n </div>\n <div>\n <!-- Example single danger button -->\n\n <!-- <button\n type=\"button\"\n class=\"btn btn-primary btn-sm d-flex gap-2 action-button\"\n (click)=\"toggleActions('actions')\"\n >\n Action\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/Vector.svg'\"\n class=\"data-grid-svg-icon\"\n ></span>\n </button>\n <div\n *ngIf=\"activeTopButton === 'actions'\"\n class=\"actions-dropdown mt-1\"\n >\n <div class=\"dropdown-menu show\">\n <a class=\"dropdown-item\" href=\"#\">Action</a>\n <a class=\"dropdown-item\" href=\"#\">Another action</a>\n <a class=\"dropdown-item\" href=\"#\">Something else here</a>\n <div class=\"dropdown-divider\"></div>\n <a class=\"dropdown-item\" href=\"#\">Separated link</a>\n </div>\n </div> -->\n </div>\n </div>\n </div>\n\n <div\n *ngIf=\"showFilters && !showFilterRow\"\n class=\"top-filter-row border-top py-2 d-flex justify-content-between align-items-center\"\n [style.height.px]=\"topFilterRowHeight\"\n >\n <!-- LEFT SIDE (Filter tags + Filter button) -->\n <div class=\"d-flex gap-2 align-items-center\">\n <ng-container *ngIf=\"activeFilteredColumns?.length\">\n <div\n *ngFor=\"let col of activeFilteredColumns; trackBy: trackByField\"\n class=\"filter-tags\"\n >\n <div\n (click)=\"\n isActiveFilterOpen = true;\n activeTopButton = 'filter-columns';\n openFilter(col)\n \"\n class=\"d-flex justify-content-center align-items-center muted-text add-filter-button active-filters\"\n style=\"white-space: nowrap\"\n [class.active]=\"\n col?.field == selectedColumnForFilter?.field &&\n isActiveFilterOpen &&\n activeTopButton == 'filter-columns'\n \"\n >\n <span class=\"header-tag mt-0 d-flex align-items-center\">\n <span\n *ngIf=\"col?.pinned\"\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/pin.svg'\"\n class=\"data-grid-svg-icon me-2\"\n ></span>\n {{ col.header }}\n <span\n (click)=\"\n $event.stopPropagation(); removeColumnFilterFromColumn(col)\n \"\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/cross-primary.svg'\n \"\n class=\"data-grid-svg-icon cross-secondary ms-2 mb-1\"\n ></span>\n </span>\n </div>\n\n <ng-container\n *ngIf=\"\n activeTopButton === 'filter-columns' &&\n col?.field == selectedColumnForFilter?.field &&\n isActiveFilterOpen\n \"\n >\n <div\n *ngTemplateOutlet=\"filterColumns; context: { column: col }\"\n class=\"actions-dropdown mt-1\"\n ></div>\n </ng-container>\n </div>\n </ng-container>\n\n <!-- Filter Button -->\n <div class=\"add-filter-button-menu\">\n <div\n (click)=\"toggleActions('filter-columns'); isActiveFilterOpen = false\"\n class=\"d-flex justify-content-center align-items-center muted-text add-filter-button button-filter\"\n style=\"width: 70px\"\n >\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/plus.svg'\"\n class=\"me-2 data-grid-svg-icon\"\n ></span>\n Filter\n </div>\n\n <ng-container\n *ngIf=\"activeTopButton === 'filter-columns' && !isActiveFilterOpen\"\n >\n <div\n *ngTemplateOutlet=\"filterColumns\"\n class=\"actions-dropdown mt-1\"\n ></div>\n </ng-container>\n </div>\n </div>\n\n <!-- RIGHT SIDE (Update + Reset) -->\n <div class=\"d-flex gap-3 align-items-center\">\n <div\n (click)=\"savePreset()\"\n class=\"text-primary cursor-pointer all-filters-reset-button\"\n *ngIf=\"!checkFilterChangesEffect()\"\n >\n Update View\n </div>\n\n <div\n class=\"text-primary cursor-pointer all-filters-reset-button\"\n *ngIf=\"!tableFilterViewId && activeFilteredColumns?.length\"\n (click)=\"clearAllFilters()\"\n >\n Reset\n </div>\n </div>\n </div>\n\n <div\n [style.height]=\"\n showFilters ? 'calc(100% - ' + topFilterRowHeight + 'px)' : '100%'\n \"\n cdkDropListGroup\n class=\"data-grid-table-wrapper overflow-hidden\"\n #dataGridContainer\n [style.fontFamily]=\"fontFaimly\"\n >\n <div\n *ngIf=\"showRowsGrouping\"\n [style.height.px]=\"headerRowHeight\"\n [cdkDropListData]=\"columns\"\n [style.backgroundColor]=\"\n topGroupedBadgesBackgroundColor || headerBackgroundColor\n \"\n cdkDropList\n (cdkDropListEntered)=\"enterToTopRowGrouping($event)\"\n (cdkDropListExited)=\"exitedFromTheTopRow($event)\"\n (cdkDropListDropped)=\"onDropTopGroup($event)\"\n [cdkDropListEnterPredicate]=\"canEnterToRowsGrouping\"\n id=\"rows-grouping-top-container\"\n class=\"border-below d-flex px-4 align-items-center\"\n >\n <div class=\"d-flex gap-2 align-items-center me-5\">\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/justify.svg'\"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n <div *ngIf=\"!draggingInGroupArea && !groupedColumns?.length\">\n Drag here to set row groups\n </div>\n <ng-container\n *ngFor=\"\n let child of groupedColumns;\n let i = index;\n trackBy: trackByField\n \"\n >\n <ng-container\n *ngTemplateOutlet=\"\n topGroupingRowPlaceholder;\n context: {\n $implicit: child,\n showChevron:\n groupedColumns.length > 1 && i != groupedColumns.length - 1\n }\n \"\n ></ng-container>\n </ng-container>\n </div>\n\n\n\n\n</div>\n<div\n class=\"d-flex overflow-hidden\"\n [style.height]=\"\n 'calc(100% - ' +\n (showRowsGrouping\n ? headerRowHeight + footerRowHeight\n : footerRowHeight) +\n 'px)'\n \"\n>\n <div\n class=\"h-100\"\n [style.width]=\"\n !showSideMenu\n ? '100%'\n : sideMenuVisible\n ? 'calc(100% - 280px)'\n : 'calc(100% - 30px)'\n \"\n >\n <div class=\"h-100 transition position-relative w-100\">\n <!-- ##################################################################################################################################################################################### -->\n <!-- ##################################################################################################################################################################################### -->\n <!-- Data Grid Header starts here -->\n <!-- ##################################################################################################################################################################################### -->\n <!-- ##################################################################################################################################################################################### -->\n\n <div\n class=\"data-grid-header-wrapper w-100\"\n [style.color]=\"headerTextColor\"\n [style.fontSize.px]=\"headerTextFontsSize\"\n [style.backgroundColor]=\"headerBackgroundColor\"\n [class.border-below]=\"!hasAnyVisibleColumn\"\n [style.height.px]=\"\n showColumnsGrouping && showFilterRow\n ? headerRowHeight * 3\n : showColumnsGrouping || showFilterRow\n ? headerRowHeight * 2\n : headerRowHeight\n \"\n >\n <!-- ********************************************************************************* -->\n <!-- ********************************************************************************* -->\n <!-- Data Grid Left Pinned Header starts here -->\n <!-- ********************************************************************************* -->\n <!-- ********************************************************************************* -->\n <div class=\"data-grid-header left-pinned\" #leftPinnedHeader>\n <div\n *ngIf=\"showSerialNumber\"\n [style.backgroundColor]=\"checkboxesBackgroundColor\"\n class=\"select-all-checkbox-cell border-below\"\n [style.width.px]=\"65\"\n [style.height.px]=\"\n showColumnsGrouping && showFilterRow\n ? headerRowHeight * 3\n : showColumnsGrouping || showFilterRow\n ? headerRowHeight * 2\n : headerRowHeight\n \"\n >\n S.No</div>\n <div\n [style.backgroundColor]=\"checkboxesBackgroundColor\"\n class=\"select-all-checkbox-cell border-below\"\n [style.height.px]=\"\n showColumnsGrouping && showFilterRow\n ? headerRowHeight * 3\n : showColumnsGrouping || showFilterRow\n ? headerRowHeight * 2\n : headerRowHeight\n \"\n >\n <input\n *ngIf=\"hasAnyVisibleColumn\"\n type=\"checkbox\"\n [indeterminate]=\"isIndeterminateState(dataSet)\"\n [checked]=\"isAllSelected(dataSet)\"\n (change)=\"toggleSelectAll(dataSet)\"\n />\n </div>\n <div\n class=\"d-flex\"\n cdkDropList\n id=\"left-pinned-header\"\n cdkDropListOrientation=\"horizontal\"\n [cdkDropListData]=\"leftPinnedColumns\"\n (cdkDropListEntered)=\"onDropListEnter($event, 'left')\"\n (cdkDropListSorted)=\"\n onSortGroup($event, 'previewLeftPinnedColumns')\n \"\n (cdkDropListDropped)=\"onDropGroup()\"\n style=\"min-width: 0.2px\"\n [style.background-color]=\"headerBackgroundColor\"\n >\n <div\n class=\"dragable-header\"\n cdkDrag\n [cdkDragData]=\"col\"\n *ngFor=\"\n let col of leftPinnedColumns;\n let i = index;\n trackBy: trackByField\n \"\n >\n <ng-container\n *ngTemplateOutlet=\"\n headerCell;\n context: {\n $implicit: col,\n index: i,\n section: 'previewLeftPinnedColumns'\n }\n \"\n ></ng-container>\n <ng-template cdkDragPreview\n ><div class=\"p-2 border d-flex gap-2\">\n <div>\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath +\n 'data-grid/icons/arrows-move.svg'\n \"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n </div>\n <div>{{ col.header }}</div>\n </div>\n </ng-template>\n <ng-template cdkDragPlaceholder>\n <div *ngIf=\"!draggingInGroupArea\">\n <div\n *ngTemplateOutlet=\"\n headerCell;\n context: {\n $implicit: col,\n index: i,\n section: ''\n }\n \"\n ></div>\n </div>\n <div\n *ngIf=\"draggingInGroupArea\"\n class=\"d-flex gap-2 ms-2\"\n style=\"opacity: 0.6\"\n >\n <ng-container\n *ngIf=\"col?.children?.length; else singleCol\"\n >\n <ng-container\n *ngFor=\"\n let child of col.children;\n let i = index;\n trackBy: trackByField\n \"\n >\n <ng-container\n *ngTemplateOutlet=\"\n topGroupingRowPlaceholder;\n context: {\n $implicit: child,\n showChevron:\n col.children.length > 1 &&\n i != col.children.length - 1\n }\n \"\n ></ng-container>\n </ng-container>\n </ng-container>\n\n <ng-template #singleCol>\n <ng-container\n *ngTemplateOutlet=\"\n topGroupingRowPlaceholder;\n context: {\n $implicit: col,\n showChevron: col?.children?.length > 1\n }\n \"\n ></ng-container>\n </ng-template>\n </div>\n </ng-template>\n </div>\n </div>\n </div>\n\n <!-- ********************************************************************************* -->\n <!-- ********************************************************************************* -->\n <!-- Data Grid Center Pinned Header starts here -->\n <!-- ********************************************************************************* -->\n <!-- ********************************************************************************* -->\n <div\n class=\"data-grid-header center-scrollable\"\n #centerPinnedHeader\n (scroll)=\"onCenterHeaderScroll($event)\"\n id=\"center-pinned-header\"\n cdkDropList\n [cdkDropListConnectedTo]=\"\n showRowsGrouping ? ['rows-grouping-top-container'] : []\n \"\n [cdkDropListData]=\"centerColumns\"\n cdkDropListOrientation=\"horizontal\"\n [cdkDropListSortingDisabled]=\"\n isDisableColumnGrouping && draggingInGroupArea\n \"\n (cdkDropListEntered)=\"onDropListEnter($event, 'center')\"\n (cdkDropListSorted)=\"onSortGroup($event, 'previewCenterColumns')\"\n (cdkDropListDropped)=\"onDropGroup()\"\n [style.maxWidth]=\"\n 'calc(100% - ' +\n (rightPinnedHeader.offsetWidth + leftPinnedHeader.offsetWidth) +\n 'px)'\n \"\n >\n <div\n *ngIf=\"groupedColumns?.length\"\n style=\"min-width: 200px\"\n class=\"h-100 align-items-center\"\n #columnsGroupedBox\n id=\"groupBoxHeaderDiv\"\n >\n <div\n class=\"d-flex w-100 justify-content-between align-items-center border-below\"\n [style.height.px]=\"\n showFilterRow ? headerRowHeight * 2 : headerRowHeight\n \"\n >\n <div class=\"ps-3\">Group</div>\n <div class=\"d-flex\">\n <div\n class=\"three-dots cursor-pointer\"\n (click)=\"openThreeDotsMenu($event, 'group')\"\n >\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath +\n 'data-grid/icons/three-dots-vertical.svg'\n \"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n </div>\n <div\n (mousedown)=\"onResizeGroupBox($event)\"\n class=\"resize-handle\"\n style=\"margin-right: -2px\"\n >\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath +\n 'data-grid/icons/resize-handle.svg'\n \"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n </div>\n </div>\n </div>\n\n <div\n [style.height.px]=\"headerRowHeight\"\n class=\"border-below\"\n ></div>\n </div>\n <!-- <span\n class=\"d-flex align-items-center justify-content-center cursor-pointer border-below\"\n style=\"min-width: 30px; height: 100%;\"\n *ngIf=\"gridType === 'TimeSheet' && !areDatesSelectedAndEqual\"\n >\n </span> -->\n <div\n class=\"dragable-header\"\n (cdkDragStarted)=\"\n checkColumnGroupingStatus(col); dragStartOnGroup(col)\n \"\n cdkDrag\n [cdkDragData]=\"col\"\n *ngFor=\"\n let col of centerColumns;\n let i = index;\n trackBy: trackById\n \"\n >\n <ng-container\n *ngTemplateOutlet=\"\n headerCell;\n context: {\n $implicit: col,\n index: i,\n section: 'previewCenterColumns'\n }\n \"\n >\n </ng-container>\n <ng-template cdkDragPreview\n ><div class=\"p-2 border d-flex gap-2\">\n <div>\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath +\n 'data-grid/icons/arrows-move.svg'\n \"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n </div>\n <div>{{ col.header }}</div>\n </div>\n </ng-template>\n <ng-template cdkDragPlaceholder>\n <div *ngIf=\"!draggingInGroupArea\">\n <div\n *ngTemplateOutlet=\"\n headerCell;\n context: {\n $implicit: col,\n index: i,\n section: 'centerColumns'\n }\n \"\n ></div>\n </div>\n <div\n *ngIf=\"draggingInGroupArea\"\n class=\"d-flex gap-2 ms-2\"\n style=\"opacity: 0.6\"\n >\n <ng-container *ngIf=\"col?.children?.length; else singleCol\">\n <ng-container\n *ngFor=\"\n let child of col.children;\n let i = index;\n trackBy: trackById\n \"\n >\n <ng-container *ngIf=\"child?.is_groupable\">\n <ng-container\n *ngTemplateOutlet=\"\n topGroupingRowPlaceholder;\n context: {\n $implicit: child,\n showChevron:\n col.children.length > 1 &&\n i != col.children.length - 1\n }\n \"\n ></ng-container>\n </ng-container>\n </ng-container>\n </ng-container>\n\n <ng-template #singleCol>\n <ng-container *ngIf=\"col?.is_groupable\">\n <ng-container\n *ngTemplateOutlet=\"\n topGroupingRowPlaceholder;\n context: {\n $implicit: col,\n showChevron: col?.children?.length > 1\n }\n \"\n ></ng-container>\n </ng-container>\n </ng-template>\n </div>\n </ng-template>\n </div>\n <div *ngIf=\"!areDatesSelectedAndEqual\" class=\"header-cell border-below\" [style.width.px]=\"30\" [style.height.px]=\"headerRowHeight\" [style.backgroundColor]=\"headerBackgroundColor\"></div>\n </div>\n\n <!-- ********************************************************************************* -->\n <!-- ********************************************************************************* -->\n <!-- Data Grid Right Pinned Header starts here -->\n <!-- ********************************************************************************* -->\n <!-- ********************************************************************************* -->\n <div\n cdkDropList\n id=\"right-pinned-header\"\n [cdkDropListConnectedTo]=\"\n showRowsGrouping ? ['rows-grouping-top-container'] : []\n \"\n cdkDropListOrientation=\"horizontal\"\n class=\"data-grid-header right-pinned\"\n (cdkDropListSorted)=\"\n onSortGroup($event, 'previewRightPinnedColumns')\n \"\n (cdkDropListEntered)=\"onDropListEnter($event, 'right')\"\n (cdkDropListDropped)=\"onDropGroup()\"\n #rightPinnedHeader\n class=\"right-pinned-header d-flex\"\n style=\"min-width: 0.2px\"\n >\n <div\n class=\"dragable-header\"\n cdkDrag\n [cdkDragData]=\"col\"\n *ngFor=\"\n let col of rightPinnedColumns;\n let i = index;\n trackBy: trackById\n \"\n >\n <ng-container\n *ngTemplateOutlet=\"\n headerCell;\n context: {\n $implicit: col,\n pinnedRight: true,\n index: i,\n section: 'previewRightPinnedColumns'\n }\n \"\n ></ng-container>\n <ng-template cdkDragPreview\n ><div class=\"p-2 border d-flex gap-2\">\n <div>\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath +\n 'data-grid/icons/arrows-move.svg'\n \"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n </div>\n <div>{{ col.header }}</div>\n </div>\n </ng-template>\n <ng-template cdkDragPlaceholder>\n <div *ngIf=\"!draggingInGroupArea\">\n <div\n *ngTemplateOutlet=\"\n headerCell;\n context: {\n $implicit: col,\n index: i,\n section: 'centerColumns'\n }\n \"\n ></div>\n </div>\n <div\n *ngIf=\"draggingInGroupArea\"\n class=\"d-flex gap-2 ms-2\"\n style=\"opacity: 0.6\"\n >\n <ng-container *ngIf=\"col?.children?.length; else singleCol\">\n <ng-container\n *ngFor=\"\n let child of col.children;\n let i = index;\n trackBy: trackById\n \"\n >\n <ng-container\n *ngTemplateOutlet=\"\n topGroupingRowPlaceholder;\n context: {\n $implicit: child,\n showChevron:\n col.children.length > 1 &&\n i != col.children.length - 1\n }\n \"\n ></ng-container>\n </ng-container>\n </ng-container>\n\n <ng-template #singleCol>\n <ng-container\n *ngTemplateOutlet=\"\n topGroupingRowPlaceholder;\n context: {\n $implicit: col,\n showChevron: col?.children?.length > 1\n }\n \"\n ></ng-container>\n </ng-template>\n </div>\n </ng-template>\n </div>\n </div>\n </div>\n\n <!--########################################################################################################################################################################################################################### -->\n <!--########################################################################################################################################################################################################################### -->\n <!-- Data Grid Body starts here -->\n <!--########################################################################################################################################################################################################################### -->\n <!--########################################################################################################################################################################################################################### -->\n <div\n class=\"h-100 d-flex justify-content-center align-items-center\"\n *ngIf=\"!dataSet.length && !loading\"\n >\n No Record Found\n </div>\n\n <div\n class=\"position-absolute w-100 h-100 d-flex justify-content-center align-items-center loading-overlay\"\n *ngIf=\"loading\"\n style=\"\n z-index: 999;\n background: rgba(255, 255, 255, 0.8);\n backdrop-filter: blur(1px);\n \"\n >\n <div class=\"text-center p-2\">\n <div class=\"spinner-border text-primary\" role=\"status\"></div> Loading...\n</div>\n </div>\n\n <!-- Card View -->\n \n\n <!-- Table View -->\n <div\n class=\"data-grid-body-wrapper position-relative d-flex\"\n [style.height]=\"bodyWrapperHeight\"\n style=\"overflow-y: auto; overflow-x: hidden\"\n #mainScroll\n (scroll)=\"onMainScroll($event)\"\n *ngIf=\"dataSet.length\"\n >\n <!-- LEFT PINNED -->\n <div [style.height.px]=\"!groupedColumns.length ? originalDataSet.length * rowHeight: 0\"></div>\n <div [class.h-100]=\"originalDataSet.length <= 10\">\n <div\n class=\"data-grid-body left-pinned-body w-100\"\n style=\"overflow-y: hidden\"\n [class.border-right]=\"hasLeftPinnedColumns\"\n [class.transparent-border-right]=\"!hasLeftPinnedColumns\"\n *ngIf=\"!loading && !dataSetLoading\"\n [@rowDynamic]=\"rowAnimation\"\n [style.transform]=\"\n 'translateY(' + startIndex * rowHeight + 'px)'\n \"\n >\n <ng-container\n *ngFor=\"\n let row of visibleRows;\n let i = index;\n trackBy: trackById\n \"\n >\n <ng-container\n *ngTemplateOutlet=\"\n rowCell;\n context: {\n $implicit: row,\n columns: previewLeftPinnedColumns,\n isEven: (startIndex + i) % 2 === 0,\n isOdd: (startIndex + i) % 2 !== 0,\n isLeft: true,\n section: 'left'\n }\n \"\n ></ng-container>\n </ng-container>\n </div>\n </div>\n\n <!-- CENTER -->\n <div\n class=\"\"\n [style.width.px]=\"centerPinnedHeader.clientWidth\"\n >\n <div\n class=\"data-grid-body center-scrollable\"\n [@rowDynamic]=\"rowAnimation\" *ngIf=\"!loading && !dataSetLoading\"\n style=\"overflow-y: hidden; overflow-x: auto\"\n [style.transform]=\"\n 'translateY(' + startIndex * rowHeight + 'px)'\n \"\n [style.backgroundColor]=\"bodyBackgroundColor\"\n #centerScrollableBody\n (scroll)=\"onCenterBodyScroll($event)\"\n [style.boxShadow]=\"leftPinnedBoxshadow\"\n\n >\n <ng-container \n *ngFor=\"\n let row of visibleRows;\n let i = index;\n trackBy: trackById\n \"\n >\n <ng-container\n *ngTemplateOutlet=\"\n rowCell;\n context: {\n $implicit: row,\n columns: previewCenterColumns,\n isEven: (startIndex + i) % 2 === 0,\n isOdd: (startIndex + i) % 2 !== 0,\n section: 'center'\n }\n \"\n ></ng-container>\n </ng-container>\n </div>\n </div>\n\n <!-- RIGHT PINNED -->\n <div\n class=\"right-pinned-body-wrapper\"\n *ngIf=\"hasRightPinnedColumns\"\n [class.h-100]=\"originalDataSet.length <= 10\"\n [style.max-width.px]=\"isScrollbarVisible ? rightPinnedHeader.offsetWidth - 15: rightPinnedHeader.offsetWidth\"\n >\n <div\n class=\"data-grid-body right-pinned-body w-100\"\n style=\"overflow-y: hidden\"\n [style.transform]=\"\n 'translateY(' + startIndex * rowHeight + 'px)'\n \"\n [style.boxShadow]=\"rightPinnedBoxshadow\"\n *ngIf=\"!loading && !dataSetLoading\"\n [@rowDynamic]=\"rowAnimation\"\n >\n <ng-container\n *ngFor=\"\n let row of visibleRows;\n let i = index;\n trackBy: trackById\n \"\n >\n <ng-container\n *ngTemplateOutlet=\"\n rowCell;\n context: {\n $implicit: row,\n columns: previewRightPinnedColumns,\n isEven: (startIndex + i) % 2 === 0,\n isOdd: (startIndex + i) % 2 !== 0,\n section: 'right'\n }\n \"\n ></ng-container>\n </ng-container>\n </div>\n </div>\n </div>\n <!-- Vertical Fake scroll Bar -->\n <div\n (scroll)=\"onMainFakeScroll($event)\"\n class=\"fake-scrollbar fake-scrollbar-vertical d-none\"\n [style.scrollbarWidth]=\"verticalScrollbarWidth\"\n [style.top.px]=\"\n showColumnsGrouping && showFilterRow\n ? headerRowHeight * 3\n : showColumnsGrouping || showFilterRow\n ? headerRowHeight * 2\n : headerRowHeight\n \"\n #fakeScroll\n [style.height]=\"bodyWrapperHeight\"\n style=\"\n overflow-y: auto;\n overflow-x: hidden;\n width: 17px;\n position: absolute;\n right: 0;\n background-color: f1f2f3;\n z-index: 10;\n \"\n >\n <div [style.height.px]=\"rowHeight * (paginationConfig.totalResults || flattenedData.length)\"></div>\n </div>\n </div>\n\n <!-- Horizintal Fake Scrollbars -->\n <div class=\"d-flex justify-content-between\" *ngIf=\"dataSet.length\">\n <div\n [style.scrollbarWidth]=\"horizintalScrollbarWidth\"\n class=\"fake-horizintal-scrollbar\"\n #fakeScroll\n [style.width.px]=\"leftPinnedHeader.offsetWidth\"\n style=\"overflow-x: scroll\"\n ></div>\n <div\n [style.scrollbarWidth]=\"horizintalScrollbarWidth\"\n (scroll)=\"onHorizintalFakeScroll($event)\"\n class=\"fake-horizintal-scrollbar\"\n #horizintalFakeScroll\n [style.width.px]=\"centerPinnedHeader.offsetWidth\"\n >\n <div [style.width.px]=\"centerPinnedHeader.scrollWidth\"></div>\n </div>\n <div\n [style.scrollbarWidth]=\"horizintalScrollbarWidth\"\n class=\"fake-horizintal-scrollbar\"\n #fakeScroll\n [style.width.px]=\"rightPinnedHeader.offsetWidth\"\n style=\"overflow-x: scroll\"\n ></div>\n </div>\n </div>\n\n <!-- Side Menu Implemented Here -->\n <div\n *ngIf=\"showSideMenu && !hasOpenAccordion\"\n [style.width.px]=\"sideMenuVisible ? 280 : 30\"\n class=\"right-menu h-100\"\n [style.backgroundColor]=\"sidemenuBackgroundColor\"\n >\n <div class=\"h-100 d-flex flex-row-reverse\">\n <div\n style=\"width: 30px\"\n class=\"d-flex flex-column align-items-center cursor-pointer\"\n [class.border-start]=\"sideMenuVisible\"\n >\n <div\n (click)=\"toggleSideMenu('cols')\"\n [class.bg-white]=\"\n currentOpenedSideMenue == 'cols' && sideMenuVisible\n \"\n [class.border-below]=\"sideMenuVisible\"\n class=\"columns-button d-flex flex-column align-items-center\"\n >\n <div>\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/ui-checks-grid.svg'\n \"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n </div>\n <div class=\"side-menue-text\">Columns</div>\n </div>\n\n <div\n (click)=\"toggleSideMenu('filtrs')\"\n [class.bg-white]=\"\n currentOpenedSideMenue == 'filtrs' && sideMenuVisible\n \"\n [class.border-below]=\"\n sideMenuVisible && currentOpenedSideMenue == 'filtrs'\n \"\n class=\"columns-button d-flex flex-column align-items-center\"\n >\n <div>\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\n \"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n </div>\n <div class=\"side-menue-text\">Filter</div>\n </div>\n </div>\n <div\n class=\"h-100\"\n *ngIf=\"sideMenuVisible\"\n [ngStyle]=\"{ width: sideMenuVisible ? '250px' : '' }\"\n >\n <div class=\"h-100\">\n <ng-container\n *ngIf=\"currentOpenedSideMenue == 'cols' && sideMenuVisible\"\n >\n <ng-container *ngTemplateOutlet=\"columnPannel\"></ng-container>\n <!-- Column Items -->\n <div class=\"column-panel-body px-3\">\n <ng-container\n *ngFor=\"let col of columns; trackBy: trackByField\"\n >\n <ng-container\n *ngTemplateOutlet=\"columnPanelItem; context: { col: col }\"\n ></ng-container>\n </ng-container>\n </div>\n <hr />\n\n <div class=\"side-menu-row-groups\" style=\"height: 30%\">\n <ng-container\n *ngTemplateOutlet=\"sideMenuRowGroups\"\n ></ng-container>\n </div>\n </ng-container>\n <ng-container\n *ngIf=\"currentOpenedSideMenue == 'filtrs' && sideMenuVisible\"\n >\n <ng-container *ngTemplateOutlet=\"sideFilters\"></ng-container>\n </ng-container>\n </div>\n </div>\n </div>\n </div>\n </div>\n <div [style.height.px]=\"footerRowHeight\" class=\"border-top\">\n <!-- Rows: <span class=\"fw-500 ms-1\">{{ dataSet.length }}</span> -->\n <div\n class=\"pagination-container\"\n [style.height.px]=\"footerRowHeight\"\n [style.padding.px]=\"footerPadding\"\n >\n <div class=\"page-size\">\n <select\n [(ngModel)]=\"paginationConfig.selectedPageSize\"\n (change)=\"onPageSizeChange()\"\n >\n <option *ngFor=\"let size of pageSizeOptions\" [value]=\"size\">\n {{ size }}\n </option>\n </select>\n <span class=\"\"> per page </span>\n </div>\n\n <div class=\"page-info\">\n Results: {{ startPageIndex }}-{{ endPageIndex }}\n of\n {{ paginationConfig.totalResults }}\n </div>\n\n <div class=\"page-buttons\">\n <button\n (click)=\"goToPage(paginationConfig.page - 1)\"\n [disabled]=\"paginationConfig.page === 1\"\n >\n \u2039\n </button>\n\n <ng-container *ngFor=\"let page of visiblePages\">\n <button\n *ngIf=\"page !== '...'\"\n (click)=\"goToPage(page)\"\n [class.active]=\"page === paginationConfig.page\"\n >\n {{ page }}\n </button>\n <span *ngIf=\"page === '...'\">...</span>\n </ng-container>\n\n <button\n (click)=\"goToPage(paginationConfig.page + 1)\"\n [disabled]=\"paginationConfig.page === paginationConfig.totalResults\"\n >\n \u203A\n </button>\n </div>\n </div>\n </div>\n </div>\n</div>\n\n<!-- ------------------------------------------------------------------------------------------------------------------------ -->\n<!-- ------------------------------------------------------------------------------------------------------------------------ -->\n<!-- Header Cell Template -->\n<!-- ------------------------------------------------------------------------------------------------------------------------ -->\n<!-- ------------------------------------------------------------------------------------------------------------------------ -->\n\n<ng-template\n #headerCell\n let-col\n let-pinnedRight=\"pinnedRight\"\n let-i=\"index\"\n let-sections=\"section\"\n let-calledFromNestedPlaceholder=\"calledFromNestedPlaceholder\"\n>\n <div>\n <!-- Group Header -->\n <ng-container *ngIf=\"col.children?.length > 0; else flatHeader\">\n <div cdkDroplistGroup class=\"group-column-wrapper\">\n <!-- Parent Header -->\n <div\n *ngIf=\"shouldTheGroupHeaderShow(col)\"\n class=\"header-cell group-header\"\n [style.height.px]=\"headerRowHeight\"\n [style.min-height.px]=\"headerRowHeight\"\n [style.max-height.px]=\"headerRowHeight\"\n [class.border-right]=\"showVerticalBorder\"\n [style.gridColumn]=\"'span ' + col.children.length\"\n [style.fontWeight]=\"headerFontWeight\"\n [class.flex-row-reverse]=\"pinnedRight\"\n [class.justify-content-end]=\"pinnedRight\"\n style=\"grid-row: 1\"\n >\n <div\n class=\"group-header-content\"\n [title]=\"col.header\"\n [class.ms-2]=\"pinnedRight\"\n >\n {{ col.header }}\n </div>\n <div\n class=\"resize-handle\"\n (dblclick)=\"autosizeColumn(col.children)\"\n (mousedown)=\"onResizeGroup($event, col, pinnedRight)\"\n >\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/resize-handle.svg'\n \"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n </div>\n </div>\n\n <!-- Child Headers and Filters -->\n\n <div\n class=\"d-flex\"\n cdkDropList\n cdkDropListOrientation=\"horizontal\"\n [cdkDropListData]=\"col.children\"\n (cdkDropListSorted)=\"onChildDroplistSorted($event, sections)\"\n (cdkDropListDropped)=\"onChildDroplistDroped($event)\"\n [cdkDropListSortingDisabled]=\"false\"\n [cdkDropListConnectedTo]=\"\n showRowsGrouping ? ['rows-grouping-top-container'] : []\n \"\n >\n <div\n cdkDrag\n [cdkDragData]=\"child\"\n *ngFor=\"let child of col.children; let i = index\"\n >\n <!-- Child Header -->\n <ng-container *ngIf=\"child.is_visible && !child['isRowGrouped']\">\n <div\n cdkDragHandle\n class=\"header-cell one-row-header-cells cursor-pointer\"\n [class.border-right]=\"showVerticalBorder\"\n [attr.field]=\"child.field\"\n [style.width.px]=\"child.width\"\n [style.min-width.px]=\"child.width\"\n [style.min-height.px]=\"headerRowHeight\"\n [style.max-height.px]=\"headerRowHeight\"\n [style.fontWeight]=\"headerFontWeight\"\n style=\"grid-row: 2\"\n [class.filter-applied-on-text]=\"isFilterAppliedOnColumn(child)\"\n >\n <div\n class=\"d-flex justify-content-between h-100 align-items-center w-100\"\n >\n <div\n class=\"d-flex justify-content-between w-100\"\n [class.flex-row-reverse]=\"pinnedRight\"\n >\n <div\n class=\"text-ellipsis h-100 d-flex align-items-center w-100\"\n [title]=\"col.header\"\n [class.w-100]=\"pinnedRight\"\n >\n <div\n class=\"text-ellipsis h-100\"\n [class.editable-header]=\"child?.is_editable\"\n (click)=\"openThreeDotsMenu($event, child); openFilteronThreeDotsClick(child)\"\n >\n {{ child.header }}\n </div>\n </div>\n\n <div\n class=\"position-relative d-flex\"\n [class.flex-row-reverse]=\"pinnedRight\"\n >\n <div\n [class.me-2]=\"pinnedRight\"\n class=\"d-flex align-items-center\"\n *ngIf=\"child.pinned\"\n >\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/pin-blue.svg'\n \"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n </div>\n <div\n class=\"three-dots p-1\"\n (click)=\"openThreeDotsMenu($event, child)\"\n style=\"cursor: pointer\"\n >\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath +\n 'data-grid/icons/three-dots-vertical.svg'\n \"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n </div>\n\n <!-- Only show menu if this column is active -->\n <div\n class=\"position-absolute\"\n *ngIf=\"activeCol === child\"\n style=\"top: -50%; z-index: 21\"\n [style.left.px]=\"\n -(!child?.pinned ? centerPinnedHeader.scrollLeft : 0)\n \"\n >\n <ng-container\n *ngTemplateOutlet=\"\n columnMenu;\n context: { col: child }\n \"\n ></ng-container>\n </div>\n\n <div\n class=\"resize-handle\"\n (dblclick)=\"autosizeColumn(child)\"\n (mousedown)=\"onResizeColumn($event, child)\"\n >\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath +\n 'data-grid/icons/resize-handle.svg'\n \"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n </div>\n </div>\n </div>\n </div>\n </div>\n\n <!-- Filter Cell -->\n <div\n *ngIf=\"showFilterRow\"\n [style.backgroundColor]=\"headerBackgroundColor\"\n class=\"header-cell filter-cell\"\n [class.border-right]=\"showVerticalBorder\"\n [attr.field]=\"child.field\"\n [style.width.px]=\"child.width\"\n [style.min-width.px]=\"child.width\"\n [style.height.px]=\"headerRowHeight\"\n [style.min-height.px]=\"headerRowHeight\"\n [style.max-height.px]=\"headerRowHeight\"\n [class.border-right]=\"showVerticalBorder\"\n style=\"grid-row: 3\"\n >\n <div\n class=\"header-cell filter-cell\"\n [attr.field]=\"col.field\"\n [style.width.px]=\"col.width\"\n [style.min-width.px]=\"col.width\"\n [style.height.px]=\"headerRowHeight\"\n [style.min-height.px]=\"headerRowHeight\"\n [style.max-height.px]=\"headerRowHeight\"\n >\n <input\n type=\"text\"\n class=\"form-control form-control-sm\"\n placeholder=\"Filter\"\n [(ngModel)]=\"col.filterValue\"\n (ngModelChange)=\"onFilterChange(col)\"\n />\n <span\n class=\"filter-icon-wrapper\"\n (click)=\"$event.stopPropagation(); openFilter(child)\"\n [class.filter-applied]=\"isFilterAppliedOnColumn(child)\"\n ><span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\n \"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n <span\n *ngIf=\"isFilterAppliedOnColumn(child)\"\n style=\"\n width: 7px;\n height: 7px;\n box-shadow: 0px 0px 3px #7486ff;\n background-color: rgb(0 163 233);\n position: absolute;\n right: 4px;\n top: 12px;\n \"\n class=\"rounded-circle d-block\"\n ></span\n ></span>\n\n <div\n class=\"position-absolute filter-row-filter-wrapper\"\n *ngIf=\"activeFilterCell?.field == child?.field\"\n style=\"top: 100%; right: 0; z-index: 99\"\n [style.left.px]=\"\n child?.pinned ? 0 : -centerPinnedHeader.scrollLeft\n \"\n >\n <ng-container\n *ngTemplateOutlet=\"filterMenu; context: { col: child }\"\n ></ng-container>\n </div>\n </div>\n </div>\n </ng-container>\n <ng-template cdkDragPreview\n ><div class=\"p-2 border d-flex gap-2\">\n <div\n *ngIf=\"\n !draggingInGroupArea ||\n (child.is_groupable && draggingInGroupArea)\n \"\n >\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/arrows-move.svg'\n \"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n </div>\n <div *ngIf=\"draggingInGroupArea && !child.is_groupable\">\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/ban.svg'\n \"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n </div>\n <div>{{ child.header }}</div>\n </div>\n </ng-template>\n <ng-template cdkDragPlaceholder>\n <div *ngIf=\"!draggingInGroupArea\" class=\"position-relative\">\n <div\n *ngTemplateOutlet=\"\n childHeaderPlaceholder;\n context: {\n $implicit: child,\n index: i,\n sections: sections,\n calledFromNestedPlaceholder: true,\n }\n \"\n ></div>\n </div>\n <div\n *ngIf=\"draggingInGroupArea && child?.is_groupable\"\n class=\"d-flex gap-2 ms-2\"\n style=\"opacity: 0.6\"\n >\n <ng-container\n *ngTemplateOutlet=\"\n topGroupingRowPlaceholder;\n context: {\n $implicit: child,\n showChevron: false,\n pinnedRight: pinnedRight,\n sections: sections,\n index: i\n }\n \"\n ></ng-container>\n </div>\n </ng-template>\n </div>\n </div>\n </div>\n </ng-container>\n\n <!-- Flat Header || Single Header Cell-->\n <ng-template #flatHeader>\n <div class=\"group-column-wrapper\">\n <!-- Full-height Header Cell (spans 2 rows visually) -->\n <div\n class=\"header-cell one-row-header-cells\"\n [attr.field]=\"col.field\"\n [style.width.px]=\"col.width\"\n [style.min-width.px]=\"col.width\"\n [class.border-right]=\"showVerticalBorder\"\n [style.min-height.px]=\"\n showColumnsGrouping ? headerRowHeight * 2 : headerRowHeight\n \"\n [style.height.px]=\"\n showColumnsGrouping ? headerRowHeight * 2 : headerRowHeight\n \"\n [style.fontWeight]=\"headerFontWeight\"\n style=\"grid-row: 1 / span 2\"\n >\n <div\n class=\"d-flex justify-content-between h-100 align-items-center w-100\"\n >\n <div\n class=\"d-flex justify-content-between w-100\"\n [class.flex-row-reverse]=\"pinnedRight\"\n >\n <div\n class=\"text-ellipsis h-100 d-flex align-items-center w-100\"\n [title]=\"col.header\"\n >\n <div\n class=\"text-ellipsis h-100 cursor-pointer\"\n [class.editable-header]=\"col?.is_editable\"\n [class.filter-applied-on-text]=\"isFilterAppliedOnColumn(col)\"\n (click)=\"openThreeDotsMenu($event, col); openFilteronThreeDotsClick(col)\"\n >\n {{ col.header }}\n </div>\n </div>\n\n <div\n class=\"position-relative d-flex\"\n [class.flex-row-reverse]=\"pinnedRight\"\n >\n <div\n [class.me-2]=\"pinnedRight\"\n class=\"d-flex align-items-center\"\n *ngIf=\"col?.pinned\"\n >\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/pin-blue.svg'\n \"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n </div>\n <div\n [class.me-2]=\"col.order_by\"\n class=\"d-flex align-items-center\"\n *ngIf=\"sortingConfig?.field == col.field\"\n >\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath +\n (sortingConfig?.order_by == 'desc'\n ? 'data-grid/icons/sort-desc.svg'\n : 'data-grid/icons/sort-asc.svg')\n \"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center mt-1\"\n ></span>\n </div>\n <div\n class=\"three-dots p-1\"\n (click)=\"openThreeDotsMenu($event, col)\"\n style=\"cursor: pointer\"\n >\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath +\n 'data-grid/icons/three-dots-vertical.svg'\n \"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n </div>\n\n <!-- Only show menu if this column is active -->\n <div\n class=\"position-absolute\"\n *ngIf=\"activeCol === col\"\n style=\"top: -50%; z-index: 21\"\n [style.left.px]=\"\n -(!col?.pinned ? centerPinnedHeader.scrollLeft : 0)\n \"\n >\n <ng-container\n *ngTemplateOutlet=\"columnMenu; context: { col: col }\"\n ></ng-container>\n </div>\n\n <div\n class=\"resize-handle\"\n [class.w-100]=\"col.pinned == 'right'\"\n (dblclick)=\"autosizeColumn(col)\"\n (mousedown)=\"onResizeColumn($event, col)\"\n >\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/resize-handle.svg'\n \"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n </div>\n </div>\n </div>\n </div>\n </div>\n\n <!-- Filter Cell -->\n <div\n *ngIf=\"showFilterRow\"\n [style.backgroundColor]=\"headerBackgroundColor\"\n class=\"header-cell filter-cell\"\n [class.border-right]=\"showVerticalBorder\"\n [attr.field]=\"col.field\"\n [style.width.px]=\"col.width\"\n [style.min-width.px]=\"col.width\"\n [style.height.px]=\"headerRowHeight\"\n [style.min-height.px]=\"headerRowHeight\"\n [style.max-height.px]=\"headerRowHeight\"\n >\n <input\n type=\"text\"\n class=\"form-control form-control-sm\"\n placeholder=\"Filter\"\n [(ngModel)]=\"col.filterValue\"\n (ngModelChange)=\"onFilterChange(col)\"\n />\n <span\n class=\"filter-icon-wrapper\"\n (click)=\"$event.stopPropagation(); openFilter(col)\"\n [class.filter-applied]=\"isFilterAppliedOnColumn(col)\"\n ><span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n <span\n *ngIf=\"isFilterAppliedOnColumn(col)\"\n style=\"\n width: 7px;\n height: 7px;\n box-shadow: 0px 0px 3px #7486ff;\n background-color: rgb(0 163 233);\n position: absolute;\n right: 4px;\n top: 12px;\n \"\n class=\"rounded-circle d-block\"\n ></span\n ></span>\n\n <div\n class=\"position-absolute filter-row-filter-wrapper\"\n *ngIf=\"activeFilterCell === col\"\n style=\"top: 100%; right: 0; z-index: 99\"\n [style.left.px]=\"col?.pinned ? 0 : -centerPinnedHeader.scrollLeft\"\n >\n <ng-container\n *ngTemplateOutlet=\"filterMenu; context: { col: col }\"\n ></ng-container>\n </div>\n </div>\n </div>\n </ng-template>\n </div>\n</ng-template>\n\n<!-- -------------------------------------------------------------------------------------------------------------------------------------------------------------------- -->\n<!-- -------------------------------------------------------------------------------------------------------------------------------------------------------------------- -->\n<!-- Body Cell Template -->\n<!-- -------------------------------------------------------------------------------------------------------------------------------------------------------------------- -->\n<!-- -------------------------------------------------------------------------------------------------------------------------------------------------------------------- -->\n\n<ng-template\n #rowCell\n let-row\n let-columns=\"columns\"\n let-isEven=\"isEven\"\n let-isOdd=\"isOdd\"\n let-isLeftSection=\"isLeft\"\n let-section=\"section\"\n let-rowIndex=\"rowIndex\"\n>\n <!-- Check if row is a group -->\n <ng-container\n *ngTemplateOutlet=\"groupRowTemplate; context: { $implicit: row, depth: 0 }\"\n ></ng-container>\n <ng-template #groupRowTemplate let-row let-depth=\"depth\">\n <ng-container *ngIf=\"row.isGroup; else regularRow\">\n <!-- Group Header -->\n <div\n class=\"group-header-row border-below d-flex align-items-center\"\n [style.height.px]=\"rowHeight\"\n [style.width]=\"\n section == 'center'\n ? centerScrollableBody?.nativeElement?.scrollWidth + 'px'\n : '100%'\n \"\n >\n <div\n *ngIf=\"section == 'left'\"\n class=\"h-100 d-flex\"\n [style.width.px]=\"leftPinnedHeader.offsetWidth - 1\"\n [class.row-selected]=\"rowSelectedIndexes.has(row.__virtualIndex)\"\n >\n <div\n *ngIf=\"showSerialNumber\"\n style=\"width: 50px\"\n class=\"d-flex align-items-center h-100 border-right justify-content-end pe-2 s-no\"\n [style.backgroundColor]=\"checkboxesBackgroundColor\"\n [style.width.px]=\"65\"\n [style.cursor]=\"\n 'url(' +\n singleSpaAssetsPath +\n 'data-grid/icons/arrow-right.svg), auto'\n \"\n (mousedown)=\"onRowMouseDown(row.__virtualIndex, $event)\"\n (mouseover)=\"onRowMouseOver(row.__virtualIndex, $event)\"\n >\n {{ row.__virtualIndex }}\n </div>\n <div\n style=\"width: 50px\"\n class=\"d-flex align-items-center justify-content-center h-100 border-right\"\n [style.backgroundColor]=\"checkboxesBackgroundColor\"\n [class.row-selected]=\"rowSelectedIndexes.has(row.__virtualIndex)\"\n [class.left-selection-border]=\"\n rowSelectedIndexes.has(row.__virtualIndex)\n \"\n [class.first-row-selected]=\"firstSelectedRow == row.__virtualIndex\"\n [class.last-row-selected]=\"lastSelectedRow == row.__virtualIndex\"\n >\n <input style=\"width: 16px; height: 16px\" type=\"checkbox\" />\n </div>\n </div>\n\n <div\n *ngIf=\"section == 'center'\"\n [style.width.px]=\"centerPinnedHeader.scrollWidth\"\n class=\"d-flex align-items-center ps-2 h-100\"\n [class.row-selected]=\"rowSelectedIndexes.has(row.__virtualIndex)\"\n [class.first-row-selected]=\"firstSelectedRow == row.__virtualIndex\"\n [class.last-row-selected]=\"lastSelectedRow == row.__virtualIndex\"\n >\n <div\n class=\"d-flex align-items-center justify-content-between\"\n [style.paddingLeft.px]=\"depth > 0 ? depth * 16 : 0\"\n >\n <span class=\"me-2 filter-icon-wrapper\" (click)=\"toggleExpand(row)\">\n <span\n class=\"data-grid-svg-icon\"\n [inlineSVG]=\"\n row.isExpand\n ? singleSpaAssetsPath + 'data-grid/icons/chevron-down.svg'\n : singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\n \"\n ></span>\n </span>\n <strong (click)=\"toggleExpand(row)\" class=\"cursor-pointer\">\n {{ row.groupValue }} ({{ countLeafRows(row) }})\n </strong>\n </div>\n </div>\n\n <div\n *ngIf=\"section == 'right'\"\n [style.width.px]=\"rightPinnedHeader.offsetWidth\"\n [class.row-selected]=\"rowSelectedIndexes.has(row.__virtualIndex)\"\n [class.first-row-selected]=\"firstSelectedRow == row.__virtualIndex\"\n [class.last-row-selected]=\"lastSelectedRow == row.__virtualIndex\"\n ></div>\n </div>\n\n <!-- Recursive Children -->\n <div class=\"group-children\" *ngIf=\"row.isExpand\">\n <ng-container\n *ngFor=\"let child of row.children; let i = index; trackBy: trackById\"\n >\n <ng-container *ngIf=\"child.isGroup; else dataRow\">\n <!-- Recursive call for nested group -->\n <ng-container\n *ngTemplateOutlet=\"\n groupRowTemplate;\n context: { $implicit: child, depth: depth + 1 }\n \"\n ></ng-container>\n </ng-container>\n\n <ng-template #dataRow>\n <!-- Regular data row -->\n <ng-container\n *ngTemplateOutlet=\"\n rowCell;\n context: {\n $implicit: child,\n columns: columns,\n isEven: i % 2 === 0,\n isOdd: i % 2 !== 0,\n isLeft: isLeftSection,\n section: section\n }\n \"\n ></ng-container>\n </ng-template>\n </ng-container>\n </div>\n </ng-container>\n </ng-template>\n\n <!-- Regular row (not a group) -->\n <ng-template #regularRow>\n <div class=\"d-flex\" [style.height.px]=\"rowHeight\">\n <span\n class=\"d-flex align-items-center justify-content-center cursor-pointer border-below\"\n style=\"min-width: 30px; height: 100%;\"\n *ngIf=\"section == 'center' && gridType === 'TimeSheet' && detailsIconPosition === 'start' && !areDatesSelectedAndEqual\"\n [ngStyle]=\"{\n 'background-color':\n hoveredRowId === (row._id || row.id)\n ? rowHoverColor\n : isRowSelected(row)\n ? checkedRowBackgroundColor\n : isEven\n ? evenRowsBackgroundColor\n : oddRowsBackgroundColor\n }\"\n (click)=\"toggleExpand(row)\"\n >\n <span\n class=\"data-grid-svg-icon\"\n [inlineSVG]=\"\n row.isDetailsExpand\n ? singleSpaAssetsPath + 'data-grid/icons/chevron-down.svg'\n : singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\n \"\n ></span>\n </span>\n <div\n [style.min-width.px]=\"\n section == 'center' && groupedColumns!.length ? groupBoxPadding : 0\n \"\n [class.row-selected]=\"rowSelectedIndexes.has(row.__virtualIndex)\"\n [class.first-row-selected]=\"firstSelectedRow == row.__virtualIndex\"\n [class.last-row-selected]=\"lastSelectedRow == row.__virtualIndex\"\n (contextmenu)=\"onRightClick($event, row, row?.details?.data?.length ? 'accordion-parent' : 'main')\"\n [style.height.px]=\"rowHeight\"\n class=\"data-grid-row h-100\"\n [class.even-row]=\"isEven\"\n [class.odd-row]=\"isOdd\"\n [class.hovered-row]=\"hoveredRowId === (row._id || row.id)\"\n (mouseenter)=\"onRowHover(row)\"\n (mouseleave)=\"onRowLeave()\"\n [ngStyle]=\"{\n 'background-color':\n hoveredRowId === (row._id || row.id)\n ? rowHoverColor\n : isRowSelected(row)\n ? checkedRowBackgroundColor\n : isEven\n ? evenRowsBackgroundColor\n : oddRowsBackgroundColor\n }\"\n ></div>\n <div\n (contextmenu)=\"onRightClick($event, row, row?.details?.data?.length ? 'accordion-parent' : 'main')\"\n [style.height.px]=\"rowHeight\"\n class=\"data-grid-row\"\n [class.even-row]=\"isEven\"\n [class.odd-row]=\"isOdd\"\n [class.hovered-row]=\"hoveredRowId === (row._id || row.id)\"\n (mouseenter)=\"onRowHover(row)\"\n (mouseleave)=\"onRowLeave()\"\n [ngStyle]=\"{\n 'background-color':\n hoveredRowId === (row._id || row.id)\n ? rowHoverColor\n : isRowSelected(row)\n ? checkedRowBackgroundColor\n : isEven\n ? evenRowsBackgroundColor\n : oddRowsBackgroundColor\n }\"\n >\n <div\n [style.backgroundColor]=\"checkboxesBackgroundColor\"\n class=\"select-all-checkbox-cell justify-content-end pe-2 s-no\"\n [style.width.px]=\"65\"\n *ngIf=\"isLeftSection && showSerialNumber\"\n [style.cursor]=\"\n 'url(' +\n singleSpaAssetsPath +\n 'data-grid/icons/arrow-right.svg), auto'\n \"\n (mousedown)=\"onRowMouseDown(row.__virtualIndex, $event)\"\n (mouseover)=\"onRowMouseOver(row.__virtualIndex, $event)\"\n >\n {{ row.__virtualIndex }}\n </div>\n <div\n [style.backgroundColor]=\"\n rowSelectedIndexes.has(row.__virtualIndex)\n ? selectedRowsBackgroundColor\n : checkboxesBackgroundColor\n \"\n class=\"select-all-checkbox-cell\"\n *ngIf=\"isLeftSection\"\n [class.left-selection-border]=\"\n rowSelectedIndexes.has(row.__virtualIndex)\n \"\n [class.first-row-selected]=\"firstSelectedRow == row.__virtualIndex\"\n [class.last-row-selected]=\"lastSelectedRow == row.__virtualIndex\"\n >\n <input\n *ngIf=\"hasAnyVisibleColumn\"\n type=\"checkbox\"\n [checked]=\"isRowSelected(row)\"\n (change)=\"toggleRowSelection(row)\"\n />\n </div>\n\n <!-- Render all columns -->\n <ng-container\n *ngFor=\"\n let col of columns;\n trackBy: trackByField;\n let colIndex = index\n \"\n >\n <ng-container *ngIf=\"col.children?.length > 0; else flatColumn\">\n <ng-container\n *ngFor=\"\n let child of col.children;\n trackBy: trackByField;\n let subColIndex = index\n \"\n >\n <ng-container *ngIf=\"child?.is_visible && !child?.isRowGrouped\">\n <ng-container\n *ngTemplateOutlet=\"\n cellTemplate;\n context: {\n col: child,\n row: row,\n rowIndex: rowIndex,\n colIndex: colIndex,\n subColIndex: subColIndex,\n section: section\n }\n \"\n ></ng-container>\n </ng-container>\n </ng-container>\n </ng-container>\n\n <ng-template #flatColumn>\n <ng-container\n *ngTemplateOutlet=\"\n cellTemplate;\n context: {\n col: col,\n row: row,\n rowIndex: rowIndex,\n colIndex: colIndex,\n subColIndex: null,\n section: section\n }\n \"\n ></ng-container>\n </ng-template>\n </ng-container>\n </div>\n\n <span\n class=\"d-flex align-items-center justify-content-center cursor-pointer border-below\"\n style=\"min-width: 30px; height: 100%;\"\n *ngIf=\"section == 'center' && gridType === 'TimeSheet' && detailsIconPosition === 'end' && !areDatesSelectedAndEqual\"\n [ngStyle]=\"{\n 'background-color':\n hoveredRowId === (row._id || row.id)\n ? rowHoverColor\n : isRowSelected(row)\n ? checkedRowBackgroundColor\n : isEven\n ? evenRowsBackgroundColor\n : oddRowsBackgroundColor\n }\"\n (click)=\"toggleExpand(row)\"\n >\n <span\n class=\"data-grid-svg-icon\"\n [inlineSVG]=\"\n row.isDetailsExpand\n ? singleSpaAssetsPath + 'data-grid/icons/chevron-down.svg'\n : singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\n \"\n ></span>\n </span>\n </div>\n <!-- LEFT PINNED: Empty table to keep alignment -->\n <div *ngIf=\"section === 'left' && row.isDetailsExpand && !isSingleDay\" class=\"accordion-details data-grid-accordion-section\" [style.color]=\"headerTextColor\" style=\"max-height: 350px; min-height: 150px ; overflow: hidden;\">\n <table class=\"nested-table table table-sm w-100 mb-0 data-grid-accordion-table\" [class.show-shadow]=\"rowShadingEnabled\">\n <thead>\n <tr [style.height.px]=\"nestedTableHeaderRowHeight\" [style.backgroundColor]=\"headerBackgroundColor\" [style.color]=\"headerTextColor\" [style.fontSize.px]=\"headerTextFontsSize\" [style.fontWeight]=\"headerFontWeight\">\n <th *ngFor=\"let _ of [1, 2, 3, 4, 5]\"></th>\n </tr>\n </thead>\n <tbody>\n <tr [style.height.px]=\"nestedTablerowHeight\" *ngFor=\"let _ of row.details.data\" [style.backgroundColor]=\"headerBackgroundColor\">\n <td *ngFor=\"let __ of [1, 2, 3, 4, 5]\"></td>\n </tr>\n </tbody>\n </table>\n </div>\n\n<!-- CENTER SECTION: Actual details table -->\n\n<div *ngIf=\"section === 'center' && row.isDetailsExpand && !isSingleDay\" class=\"accordion-details-wrapper data-grid-accordion\" [style.fontFamily]=\"fontFaimly\" [style.fontSize.px]=\"bodyTextFontsSize\" style=\"display: flex; width: 100%; max-height: 350px; min-height: 150px ; overflow: hidden ; \">\n <!-- LEFT SECTION OF ACCORDION -->\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;\">\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;\">\n <thead>\n <tr [style.height.px]=\"nestedTableHeaderRowHeight\" [style.backgroundColor]=\"headerBackgroundColor\" [style.color]=\"headerTextColor\" [style.fontSize.px]=\"headerTextFontsSize\" [style.fontWeight]=\"headerFontWeight\">\n <ng-container *ngFor=\"let col of row.details.columns | pinnedColumns:'left'; trackBy: trackByField\">\n <th *ngIf=\"col.is_visible !== false\"\n class=\"px-4\"\n [class.filter-applied]=\"isAccordionColumnFiltered(row, col)\"\n [style.color]=\"isAccordionColumnFiltered(row, col) ? '#007bff' : headerTextColor\"\n [attr.field]=\"col.field\"\n [attr.pinned]=\"col.pinned\"\n [style.width.px]=\"col.width || 200\"\n [style.min-width.px]=\"col.width || 200\">\n <div class=\"d-flex justify-content-between align-items-center\" style=\"width: 100%;\">\n <span class=\"d-flex align-items-center gap-1\" style=\"overflow: hidden; width: 100%;\">\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>\n <span class=\"text-truncate\" style=\"flex: 1; min-width: 0;\" title=\"{{ col.header }}\">{{ col.header }}</span>\n <span *ngIf=\"isAccordionColumnFiltered(row, col)\"\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\"\n class=\"data-grid-svg-icon text-primary ms-1\"\n style=\"font-size: 12px;\"></span>\n </span>\n <span class=\"three-dots p-1\"\n (click)=\"openDetailThreeDotsMenus($event, col, row, $any($event.currentTarget))\">\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/three-dots-vertical.svg'\" class=\"data-grid-svg-icon\"></span>\n </span>\n </div>\n <!-- <div class=\"resize-handles\" (mousedown)=\"onResizeDetailColumn($event, row, col)\">\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/resize-handle.svg'\" class=\"data-grid-svg-icon text-primary\"></span>\n </div> -->\n <ng-container *ngIf=\"activeDetailCol?.field == col.field && activeDetailRow === row\">\n <div class=\"position-absolute detail-column-menu-wrapper\"\n [style.top.px]=\"nestedTableHeaderRowHeight\"\n [style.left.px]=\"0\">\n <ng-container *ngTemplateOutlet=\"detailColumnMenu; context: { col: col, row: row }\"></ng-container>\n </div>\n </ng-container>\n </th>\n </ng-container>\n </tr>\n </thead>\n <tbody>\n <tr [style.height.px]=\"nestedTablerowHeight\" *ngFor=\"let d of row.details.data; let j = index; trackBy: trackById\" [ngStyle]=\"getAccordionRowStyle(j, row)\">\n <ng-container *ngFor=\"let col of row.details.columns | pinnedColumns:'left'; let localK = index; trackBy: trackByField\">\n <td *ngIf=\"col.is_visible !== false\"\n class=\"px-4\"\n (mousedown)=\"startDetailSelection(row, j, localK, col.field, $event, 'left')\"\n (mouseenter)=\"extendDetailSelection(row, j, localK, col.field, $event, 'left')\"\n [class.selected-cell]=\"isDetailCellSelected(row, j, localK, col.field, 'left')\"\n [attr.field]=\"col.field\"\n [attr.pinned]=\"col.pinned\"\n [style.fontSize.px]=\"bodyTextFontsSize\"\n (dblclick)=\"enableDetailEdits(row, d, col)\"\n [class.active-cell-detail]=\"isActiveDetailCell(row, d, col)\">\n <!-- Use the same rendering logic as center section -->\n <ng-container [ngSwitch]=\"col.field\">\n\n <ng-container *ngSwitchCase=\"'manually_logs'\" class=\"d-flex justify-content-start align-items-center pointer position-relative\">\n <ng-container *ngIf=\"d.manually_logs?.length > 0; else noManualLogsIcon\">\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/eye.svg'\"\n class=\"data-grid-svg-icon text-primary\"\n style=\"cursor: pointer; font-size: 16px;\"\n (mouseenter)=\"showManualLogsTooltip($event, row, d)\"\n (mouseleave)=\"hideManualLogsTooltip()\">\n </span>\n </ng-container>\n <ng-template #noManualLogsIcon>\u2013</ng-template>\n</ng-container>\n <!-- Breaks -->\n <ng-container *ngSwitchCase=\"'breaks'\">\n <ng-container *ngIf=\"d[col.field]?.length; else noBreaksLeft\">\n <app-badge-overflow\n [badges]=\"getBreakBadges(d[col.field])\"\n [maxWidth]=\"col.width || 200\"\n (badgeMouseEnter)=\"showBreakTooltip($event.event, $event.badge.data)\"\n (badgeMouseLeave)=\"hideBreakTooltip()\"\n (overflowCountClick)=\"onDetailBadgeOverflowCountClick(col, d)\">\n</app-badge-overflow>\n </ng-container>\n <ng-template #noBreaksLeft>\n <div >\n -\n </div>\n </ng-template>\n </ng-container>\n\n <!-- Short Breaks -->\n <ng-container *ngSwitchCase=\"'short_breaks'\">\n <ng-container *ngIf=\"d[col.field]?.short_break_duration; else noShortBreakLeft\">\n <div (dblclick)=\"onShortBreakClick.emit(d)\">\n <app-badge-overflow\n [badges]=\"getShortBreakBadges(d[col.field])\"\n [maxWidth]=\"col.width || 200\"\n (badgeMouseEnter)=\"showShortBreakTooltip($event.event, d)\"\n (badgeMouseLeave)=\"hideShortBreakTooltip()\"\n (badgeClick)=\"handleShortBreakClick(d, $event)\"\n (overflowCountClick)=\"onDetailBadgeOverflowCountClick(col, d)\">\n </app-badge-overflow>\n </div>\n </ng-container>\n <ng-template #noShortBreakLeft>\n <div >-</div>\n </ng-template>\n </ng-container>\n\n <!-- Short Leave -->\n <!-- Short Leave -->\n<ng-container *ngSwitchCase=\"'short_leave'\">\n <ng-container *ngIf=\"row.short_leave && row.short_leave.length > 0; else noShortLeaveMain\">\n <div class=\"w-100 d-flex main-progress-bar justify-content-center align-items-center\" \n style=\"background-color: rgb(111, 97, 207); height: 20px; border-radius: 4px; position: relative;\"\n (mouseenter)=\"showShortLeaveTooltip($event, row)\"\n (mouseleave)=\"hideShortLeaveTooltip()\">\n <span class=\"d-block\" [style.min-width.%]=\"row.short_leave[0].short_leave_time_percentage\" \n style=\"background-color: rgb(238, 99, 82); height: 100%; border-radius: 4px;\"></span>\n <span style=\"position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); color: white; font-size: 12px; font-weight: bold;\">\n {{ row.short_leave[0].short_leave_time_percentage }}%\n </span>\n </div>\n </ng-container>\n <ng-template #noShortLeaveMain>-</ng-template>\n</ng-container>\n\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()\">\n <div style=\"overflow: hidden; text-overflow: ellipsis; white-space: nowrap; width: 100%;\" [class.restriction-indicator]=\"row.attendance_log_detail?.length > 0\" title=\"{{ d.is_un_restricted ? 'Yes' : 'No' }}\">\n {{ d.is_un_restricted ? 'Yes' : 'No' }}\n </div>\n</div>\n\n <div *ngSwitchCase=\"'is_payroll_processed'\" class=\"d-flex justify-content-start flex-column pointer position-relative\" >\n <div style=\"overflow: hidden; text-overflow: ellipsis; white-space: nowrap; width: 100%;\">\n {{ d.is_payroll_processed ? 'Yes' : 'No' }}\n </div>\n </div>\n\n\n <!-- Status -->\n <ng-container *ngSwitchCase=\"'status'\">\n <ng-container *ngIf=\"getNestedValue(d, col.field); else noStatus\">\n <span class=\"badge\" [class]=\"getStatusBadgeClass(getNestedValue(d, col.field))\">\n {{ transformStatus(getNestedValue(d, col.field)) }}\n </span>\n </ng-container>\n <ng-template #noStatus>-</ng-template>\n</ng-container>\n\n<!-- Attendance Status -->\n<ng-container *ngSwitchCase=\"'attendanceStatus'\">\n <ng-container *ngIf=\"getNestedValue(d, col.field); else noAttendanceStatus\">\n <span class=\"badge\" [class]=\"getAttendanceStatusBadgeClass(getNestedValue(d, col.field))\">\n {{ transformStatus(getNestedValue(d, col.field)) }}\n </span>\n </ng-container>\n <ng-template #noAttendanceStatus>-</ng-template>\n</ng-container>\n\n <!-- Default fallback -->\n <ng-container *ngSwitchDefault>\n <div style=\"overflow: hidden; text-overflow: ellipsis; white-space: nowrap; width: 100%;\" title=\"{{\n col.type === 'date'\n ? (getNestedValue(d, col.field) ? (getNestedValue(d, col.field) | timezoneFormat:prefs:'date') : '-')\n : col.type === 'time'\n ? ((getTimeValue(getNestedValue(d, col.field)) | timezoneFormat:prefs:'time'))\n : (getNestedValue(d, col.field)?.value || getNestedValue(d, col.field)?.name || getNestedValue(d, col.field) || '-')\n }}\">{{ col.type === 'date'\n ? (getNestedValue(d, col.field) ? (getNestedValue(d, col.field) | timezoneFormat:prefs:'date') : '-')\n : col.type === 'time'\n ? ((getTimeValue(getNestedValue(d, col.field)) | timezoneFormat:prefs:'time'))\n : (getNestedValue(d, col.field)?.value || getNestedValue(d, col.field)?.name || getNestedValue(d, col.field) || '-')\n }}</div>\n </ng-container>\n </ng-container>\n </td>\n </ng-container>\n </tr>\n</tbody>\n </table>\n </div>\n\n <!-- CENTER SECTION OF ACCORDION (WITH VIRTUAL SCROLL) -->\n\n<div class=\"accordion-center-section data-grid-accordion-section\" style=\"flex: 1; min-width: 0; display: flex; flex-direction: column; overflow: hidden;\">\n <!-- Header Section -->\n <div class=\"header-container\" style=\"overflow-x: auto; scrollbar-width: none; -ms-overflow-style: none;\" #headerContainer (scroll)=\"syncScroll($event)\">\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%;\">\n <thead>\n <tr\n [style.height.px]=\"nestedTableHeaderRowHeight\"\n cdkDropList\n [cdkDropListData]=\"row?.details.columns\"\n cdkDropListOrientation=\"horizontal\"\n (cdkDropListDropped)=\"dropColumn($event, row)\"\n >\n <ng-container *ngFor=\"let col of row.details.columns; let i = index\">\n <th\n *ngIf=\"col.is_visible !== false && !col.pinned\"\n class=\"px-4\"\n cdkDrag\n [attr.field]=\"col.field\"\n [class.filter-applied]=\"isAccordionColumnFiltered(row, col)\"\n [style.width.px]=\"col.width || 200\"\n [style.min-width.px]=\"col.width || 200\"\n [style.backgroundColor]=\"headerBackgroundColor\"\n [style.color]=\"isAccordionColumnFiltered(row, col) ? '#007bff' : headerTextColor\"\n [style.fontSize.px]=\"headerTextFontsSize\"\n [style.fontWeight]=\"headerFontWeight\"\n style=\"cursor: move; position: relative;\">\n <div class=\"d-flex justify-content-between align-items-center\" style=\"width: 100%;\">\n <span class=\"d-flex align-items-center gap-1\" style=\"overflow: hidden; width: 100%;\">\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>\n <span class=\"text-truncate\" style=\"flex: 1; min-width: 0;\" title=\"{{ col.header }}\">{{ col.header }}</span>\n <span *ngIf=\"isAccordionColumnFiltered(row, col)\"\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\"\n class=\"data-grid-svg-icon text-primary ms-1\"\n style=\"font-size: 12px;\"></span>\n </span>\n <span class=\"three-dots p-1\"\n (click)=\"openDetailThreeDotsMenus($event, col, row, $any($event.currentTarget))\">\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/three-dots-vertical.svg'\" class=\"data-grid-svg-icon\"></span>\n </span>\n </div>\n <!-- <div class=\"resize-handles\" (mousedown)=\"onResizeDetailColumn($event, row, col)\">\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/resize-handle.svg'\" class=\"data-grid-svg-icon text-primary\"></span>\n </div> -->\n <ng-container *ngIf=\"activeDetailCol?.field == col.field && activeDetailRow === row\">\n <div class=\"position-absolute detail-column-menu-wrapper\" [style.top.px]=\"nestedTableHeaderRowHeight\" [style.left.px]=\"0\">\n <ng-container *ngTemplateOutlet=\"detailColumnMenu; context: { col: col, row: row }\"></ng-container>\n </div>\n </ng-container>\n </th>\n </ng-container>\n </tr>\n </thead>\n </table>\n </div>\n\n <!-- Group Badges (if any) -->\n <div *ngIf=\"row.details?.groupedColumns?.length\" class=\"detail-group-badges\">\n <span *ngFor=\"let g of row.details.groupedColumns; trackBy: trackByField\" class=\"badge bg-light text-dark me-1\">\n {{ g.header }}\n <span class=\"ms-1 cursor-pointer\" (click)=\"ungroupDetailColumn(g, row)\" [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/x.svg'\"></span>\n </span>\n </div>\n\n <!-- No Data Message when filtered results are empty -->\n <div *ngIf=\"row.details.data.length === 0\" class=\"d-flex justify-content-center align-items-center\" style=\"flex: 1; min-height: 104px ;\">\n <div class=\"text-center text-muted\">\n <div class=\"mb-2\">\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\" class=\"data-grid-svg-icon text-muted\" style=\"font-size: 24px;\"></span>\n </div>\n <div class=\"fw-bold\">No records found for this filter.</div>\n </div>\n </div>\n\n <!-- Data Table Section with Virtual Scroll -->\n <cdk-virtual-scroll-viewport\n *ngIf=\"row.details.data.length > 0\"\n itemSize=\"{{ nestedTablerowHeight }}\"\n minBufferPx=\"200\"\n maxBufferPx=\"400\"\n class=\"detail-virtual-scroll\"\n [attr.data-detail-row-id]=\"row._id || row.id\"\n style=\"flex: 1; overflow: auto;\"\n #dataContainer\n (scroll)=\"syncVerticalScroll($event)\"\n (scroll)=\"syncScroll($event)\">\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%;\">\n <tbody>\n <tr\n class=\"cursor-pointer data-grid-accordion-row\"\n *cdkVirtualFor=\"let d of row.details.data; trackBy: trackById; let j = index\"\n (contextmenu)=\"onRightClick($event, d, 'accordion-child')\"\n [style.height.px]=\"nestedTablerowHeight\"\n [ngStyle]=\"getAccordionRowStyle(j, row)\">\n <ng-container *ngFor=\"let col of row.details.columns; let k = index\">\n <td\n *ngIf=\"col.is_visible !== false && !col.pinned\"\n class=\"px-4\"\n (mousedown)=\"startDetailSelection(row, j, k, col.field, $event, 'center')\"\n (mouseenter)=\"extendDetailSelection(row, j, k, col.field, $event, 'center')\"\n [class.selected-cell]=\"isDetailCellSelected(row, j, k, col.field, 'center')\"\n [attr.field]=\"col.field\"\n [style.width.px]=\"col.width || 200\"\n [style.min-width.px]=\"col.width || 200\"\n [style.fontSize.px]=\"bodyTextFontsSize\"\n [class.active-cell-detail]=\"isActiveDetailCell(row, d, col)\"\n style=\"cursor: pointer; position: relative; overflow: visible; cursor: cell; \">\n <div class=\"time-sheet-container\" style=\"overflow: visible; display: flex; gap: 4px; align-items: center; height: 100%; \">\n <ng-container *ngIf=\"col.field === 'breaks' || col.field === 'short_breaks'; else defaultDetailCell\">\n <ng-container *ngIf=\"col.field === 'breaks'\">\n <ng-container *ngIf=\"d[col.field]?.length; else noBreaks\">\n <span\n *ngFor=\"let breakItem of d[col.field]; let breakIndex = index\"\n class=\"circle-value badge-outline break-on text-center\"\n [ngClass]=\"(breakItem.break_type?.data_value_name?.toLowerCase() || breakItem.breakType?.toLowerCase()) === 'paid' \n ? 'break-color-paid' \n : (breakItem.break_type?.data_value_name?.toLowerCase() || breakItem.breakType?.toLowerCase()) === 'unpaid' \n ? 'break-color-unpaid' \n : (breakItem.break_type?.data_value_name?.toLowerCase() || breakItem.breakType?.toLowerCase()) === 'lunch' \n ? 'break-color-lunch' \n : 'break-color-default'\"\n (mouseenter)=\"showBreakTooltip($event, breakItem)\"\n (mouseleave)=\"hideBreakTooltip()\"\n >\n <!-- Show total_minutes_logged if available and truthy, else break_duration -->\n {{ (breakItem.total_minutes_logged || breakItem.break_duration) }}m\n </span>\n </ng-container>\n\n <ng-template #noBreaks>\n <div>-</div>\n </ng-template>\n</ng-container>\n <ng-container *ngIf=\"col.field === 'short_breaks' && !isDetailEditing(row, d, col)\">\n <ng-container *ngIf=\"d[col.field]?.short_break_duration; else noShortBreak\">\n <div (dblclick)=\"onShortBreakClick.emit(d)\">\n <app-badge-overflow\n [badges]=\"getShortBreakBadges(d[col.field])\"\n [maxWidth]=\"col.width || 200\"\n (badgeMouseEnter)=\"showShortBreakTooltip($event.event, d)\"\n (badgeMouseLeave)=\"hideShortBreakTooltip()\"\n (badgeClick)=\"handleShortBreakClick(d, $event)\"\n (overflowCountClick)=\"onDetailBadgeOverflowCountClick(col, d)\">\n </app-badge-overflow>\n </div>\n </ng-container>\n <ng-template #noShortBreak>\n <div >-</div>\n </ng-template>\n</ng-container>\n <ng-container *ngIf=\"isDetailEditing(row, d, col)\">\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;\" />\n </ng-container>\n </ng-container>\n <ng-template #defaultDetailCell>\n <span class=\"d-flex align-items-center h-100\">\n <ng-container *ngIf=\"!isDetailEditing(row, d, col)\">\n <ng-container [ngSwitch]=\"col.field\">\n <!-- \u2705 SHORT LEAVE: Progress bar in detail rows -->\n <div *ngSwitchCase=\"'short_leave'\" class=\"position-relative\" style=\"min-width: 100px; width: 200px;\">\n <ng-container *ngIf=\"d.short_leave && d.short_leave.length > 0; else noShortLeaveDetail\">\n <div\n class=\"w-100 d-flex main-progress-bar\"\n style=\"background-color: rgb(111, 97, 207); height: 20px; border-radius: 4px; position: relative;\"\n (mouseenter)=\"showShortLeaveTooltip($event, d)\"\n (mouseleave)=\"hideShortLeaveTooltip()\"\n >\n <span\n class=\"d-block\"\n [style.min-width.%]=\"d.short_leave[0].short_leave_time_percentage\"\n style=\"background-color: rgb(238, 99, 82); height: 100%; border-radius: 4px;\"\n ></span>\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>\n </div>\n </ng-container>\n <ng-template #noShortLeaveDetail>\n <div >-</div>\n </ng-template>\n </div>\n\n <!-- Status -->\n<ng-container *ngSwitchCase=\"'status'\">\n <ng-container *ngIf=\"getNestedValue(d, col.field); else noStatus\">\n <span class=\"badge\" [class]=\"getStatusBadgeClass(getNestedValue(d, col.field))\">\n {{ transformStatus(getNestedValue(d, col.field)) }}\n </span>\n </ng-container>\n <ng-template #noStatus>-</ng-template>\n</ng-container>\n\n<!-- Attendance Status -->\n<ng-container *ngSwitchCase=\"'attendanceStatus'\">\n <ng-container *ngIf=\"getNestedValue(d, col.field); else noAttendanceStatus\">\n <span class=\"badge\" [class]=\"getAttendanceStatusBadgeClass(getNestedValue(d, col.field))\">\n {{ transformStatus(getNestedValue(d, col.field)) }}\n </span>\n </ng-container>\n <ng-template #noAttendanceStatus>-</ng-template>\n</ng-container>\n\n <!-- Existing cases -->\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()\">\n <div class=\"popover__wrapper\" style=\"overflow: hidden; text-overflow: ellipsis; white-space: nowrap; width: 100%;\" [class.restriction-indicator]=\"row.attendance_log_detail?.length > 0\">\n {{ d.is_un_restricted ? 'Yes' : 'No' }}\n </div>\n </div>\n\n <div *ngSwitchCase=\"'is_payroll_processed'\" class=\"d-flex justify-content-start flex-column pointer position-relative\" >\n <div style=\"overflow: hidden; text-overflow: ellipsis; white-space: nowrap; width: 100%;\" title=\"{{ d.is_payroll_processed ? 'Yes' : 'No' }}\">\n {{ d.is_payroll_processed ? 'Yes' : 'No' }}\n </div>\n </div>\n <div *ngSwitchCase=\"'manually_logs'\" class=\"d-flex justify-content-start align-items-center pointer position-relative\">\n <ng-container *ngIf=\"d.manually_logs?.length > 0; else noManualLogsIcon\">\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>\n </ng-container>\n <ng-template #noManualLogsIcon>\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>\n </ng-template>\n </div>\n\n <!-- Default fallback -->\n <div *ngSwitchDefault style=\"overflow: hidden; text-overflow: ellipsis; white-space: nowrap; width: 100%;\" title=\"{{\n col.type === 'date'\n ? (getNestedValue(d, col.field) ? (getNestedValue(d, col.field) | timezoneFormat:prefs:'date') : '-')\n : col.type === 'time'\n ? ((getTimeValue(getNestedValue(d, col.field)) | timezoneFormat:prefs:'time'))\n : (getNestedValue(d, col.field)?.value || getNestedValue(d, col.field)?.name || getNestedValue(d, col.field) || '-')\n }}\">\n {{\n col.type === 'date'\n ? (getNestedValue(d, col.field) ? (getNestedValue(d, col.field) | timezoneFormat:prefs:'date') : '-')\n : col.type === 'time'\n ? ((getTimeValue(getNestedValue(d, col.field)) | timezoneFormat:prefs:'time'))\n : (getNestedValue(d, col.field)?.value || getNestedValue(d, col.field)?.name || getNestedValue(d, col.field) || '-')\n }}\n </div>\n</ng-container>\n </ng-container>\n <ng-container *ngIf=\"isDetailEditing(row, d, col)\">\n <ng-container [ngSwitch]=\"col.type\">\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;\" />\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;\" />\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;\" />\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;\" />\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;\" />\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;\">\n <option *ngFor=\"let option of col.column_dropdown_value\" [ngValue]=\"option?.value || option\">\n {{ option?.label || option?.name || option }}\n </option>\n </select>\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;\" />\n </ng-container>\n </ng-container>\n </span>\n </ng-template>\n </div>\n </td>\n </ng-container>\n </tr>\n </tbody>\n </table>\n </cdk-virtual-scroll-viewport>\n</div>\n\n <!-- RIGHT SECTION OF ACCORDION -->\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;\">\n <table class=\"nested-table table-sm mb-0 data-grid-accordion-table\" [class.show-shadow]=\"rowShadingEnabled\" style=\"table-layout: fixed; width: auto;\">\n <thead>\n <tr [style.height.px]=\"nestedTableHeaderRowHeight\" [style.backgroundColor]=\"headerBackgroundColor\" [style.color]=\"headerTextColor\" [style.fontSize.px]=\"headerTextFontsSize\" [style.fontWeight]=\"headerFontWeight\">\n <ng-container *ngFor=\"let col of row.details.columns | pinnedColumns:'right'; trackBy: trackByField\">\n <th *ngIf=\"col.is_visible !== false\"\n class=\"px-4\"\n [class.filter-applied]=\"isAccordionColumnFiltered(row, col)\"\n [style.width.px]=\"col.width || 200\"\n [style.min-width.px]=\"col.width || 200\"\n [style.color]=\"isAccordionColumnFiltered(row, col) ? '#007bff' : headerTextColor\"\n [attr.field]=\"col.field\"\n [attr.pinned]=\"col.pinned\">\n <div class=\"d-flex justify-content-between align-items-center\" style=\"width: 100%;\">\n <span class=\"d-flex align-items-center gap-1\" style=\"overflow: hidden; width: 100%;\">\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/pin-blue.svg'\"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"></span>\n <span class=\"text-truncate\" style=\"flex: 1; min-width: 0;\" title=\"{{ col.header }}\">{{ col.header }}</span>\n <span *ngIf=\"isAccordionColumnFiltered(row, col)\"\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\"\n class=\"data-grid-svg-icon text-primary ms-1\"\n style=\"font-size: 12px;\"></span>\n </span>\n <span class=\"three-dots p-1\"\n (click)=\"openDetailThreeDotsMenus($event, col, row, $any($event.currentTarget))\">\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/three-dots-vertical.svg'\" class=\"data-grid-svg-icon\"></span>\n </span>\n </div>\n\n <!-- <div class=\"resize-handles\" (mousedown)=\"onResizeDetailColumn($event, row, col)\">\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/resize-handle.svg'\" class=\"data-grid-svg-icon text-primary\"></span>\n </div> -->\n <ng-container *ngIf=\"activeDetailCol?.field == col.field && activeDetailRow === row\">\n <div class=\"position-absolute detail-column-menu-wrapper\"\n [style.top.px]=\"nestedTableHeaderRowHeight\"\n [style.left.px]=\"0\">\n <ng-container *ngTemplateOutlet=\"detailColumnMenu; context: { col: col, row: row }\"></ng-container>\n </div>\n </ng-container>\n </th>\n </ng-container>\n </tr>\n </thead>\n <tbody>\n <tr [style.height.px]=\"nestedTablerowHeight\" *ngFor=\"let d of row.details.data; let j = index; trackBy: trackById\" [ngStyle]=\"getAccordionRowStyle(j, row)\">\n <ng-container *ngFor=\"let col of row.details.columns | pinnedColumns:'right'; let localK = index; trackBy: trackByField\">\n <td *ngIf=\"col.is_visible !== false\"\n class=\"px-4\"\n [attr.field]=\"col.field\"\n [attr.pinned]=\"col.pinned\"\n (mousedown)=\"startDetailSelection(row, j, localK, col.field, $event, 'right')\"\n (mouseenter)=\"extendDetailSelection(row, j, localK, col.field, $event, 'right')\"\n [class.selected-cell]=\"isDetailCellSelected(row, j, localK, col.field, 'right')\"\n [style.fontSize.px]=\"bodyTextFontsSize\"\n [class.active-cell-detail]=\"isActiveDetailCell(row, d, col)\">\n <ng-container [ngSwitch]=\"col.field\">\n\n <ng-container *ngSwitchCase=\"'manually_logs'\" class=\"d-flex justify-content-start align-items-center pointer position-relative\">\n <ng-container *ngIf=\"d.manually_logs?.length > 0; else noManualLogsIcon\">\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/eye.svg'\"\n class=\"data-grid-svg-icon text-primary\"\n style=\"cursor: pointer; font-size: 16px;\"\n (mouseenter)=\"showManualLogsTooltip($event, row, d)\"\n (mouseleave)=\"hideManualLogsTooltip()\">\n </span>\n </ng-container>\n <ng-template #noManualLogsIcon>\u2013</ng-template>\n</ng-container>\n <!-- Breaks -->\n <ng-container *ngSwitchCase=\"'breaks'\">\n <ng-container *ngIf=\"d[col.field]?.length; else noBreaksLeft\">\n <app-badge-overflow\n [badges]=\"getBreakBadges(d[col.field])\"\n [maxWidth]=\"col.width || 200\"\n (badgeMouseEnter)=\"showBreakTooltip($event.event, $event.badge.data)\"\n (badgeMouseLeave)=\"hideBreakTooltip()\"\n (overflowCountClick)=\"onDetailBadgeOverflowCountClick(col, d)\">\n</app-badge-overflow>\n </ng-container>\n <ng-template #noBreaksLeft>\n <div>\n -\n </div>\n </ng-template>\n </ng-container>\n\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()\">\n <div style=\"overflow: hidden; text-overflow: ellipsis; white-space: nowrap; width: 100%;\" [class.restriction-indicator]=\"row.attendance_log_detail?.length > 0\" title=\"{{ d.is_un_restricted ? 'Yes' : 'No' }}\">\n {{ d.is_un_restricted ? 'Yes' : 'No' }}\n </div>\n </div>\n\n <div *ngSwitchCase=\"'is_payroll_processed'\" class=\"d-flex justify-content-start flex-column pointer position-relative\" >\n <div style=\"overflow: hidden; text-overflow: ellipsis; white-space: nowrap; width: 100%;\" title=\"{{ d.is_payroll_processed ? 'Yes' : 'No' }}\">\n {{ d.is_payroll_processed ? 'Yes' : 'No' }}\n </div>\n </div>\n\n <!-- Short Breaks -->\n <ng-container *ngSwitchCase=\"'short_breaks'\">\n <ng-container *ngIf=\"d[col.field]?.short_break_duration; else noShortBreakLeft\">\n <div (dblclick)=\"onShortBreakClick.emit(d)\">\n <app-badge-overflow\n [badges]=\"getShortBreakBadges(d[col.field])\"\n [maxWidth]=\"col.width || 200\"\n (badgeMouseEnter)=\"showShortBreakTooltip($event.event, d)\"\n (badgeMouseLeave)=\"hideShortBreakTooltip()\"\n (badgeClick)=\"handleShortBreakClick(d, $event)\"\n (overflowCountClick)=\"onDetailBadgeOverflowCountClick(col, d)\">\n </app-badge-overflow>\n </div>\n </ng-container>\n <ng-template #noShortBreakLeft>\n <div >-</div>\n </ng-template>\n </ng-container>\n\n <!-- Short Leave -->\n <!-- Short Leave -->\n<ng-container *ngSwitchCase=\"'short_leave'\">\n <ng-container *ngIf=\"row.short_leave && row.short_leave.length > 0; else noShortLeaveMain\">\n <div class=\"w-100 d-flex main-progress-bar justify-content-center align-items-center\" \n style=\"background-color: rgb(111, 97, 207); height: 20px; border-radius: 4px; position: relative;\"\n (mouseenter)=\"showShortLeaveTooltip($event, row)\"\n (mouseleave)=\"hideShortLeaveTooltip()\">\n <span class=\"d-block\" [style.min-width.%]=\"row.short_leave[0].short_leave_time_percentage\" \n style=\"background-color: rgb(238, 99, 82); height: 100%; border-radius: 4px;\"></span>\n <span style=\"position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); color: white; font-size: 12px; font-weight: bold;\">\n {{ row.short_leave[0].short_leave_time_percentage }}%\n </span>\n </div>\n </ng-container>\n <ng-template #noShortLeaveMain>-</ng-template>\n</ng-container>\n\n<ng-container *ngSwitchCase=\"'status'\">\n <ng-container *ngIf=\"getNestedValue(d, col.field); else noStatus\">\n <span class=\"badge\" [class]=\"getStatusBadgeClass(getNestedValue(d, col.field))\">\n {{ transformStatus(getNestedValue(d, col.field)) }}\n </span>\n </ng-container>\n <ng-template #noStatus>-</ng-template>\n</ng-container>\n\n<!-- Attendance Status -->\n<ng-container *ngSwitchCase=\"'attendanceStatus'\">\n <ng-container *ngIf=\"getNestedValue(d, col.field); else noAttendanceStatus\">\n <span class=\"badge\" [class]=\"getAttendanceStatusBadgeClass(getNestedValue(d, col.field))\">\n {{ transformStatus(getNestedValue(d, col.field)) }}\n </span>\n </ng-container>\n <ng-template #noAttendanceStatus>-</ng-template>\n</ng-container>\n\n <!-- Default -->\n <ng-container *ngSwitchDefault>\n<div style=\"overflow: hidden; text-overflow: ellipsis; white-space: nowrap; width: 100%;\" title=\"{{\n col.type === 'date'\n ? (getNestedValue(d, col.field) ? (getNestedValue(d, col.field) | timezoneFormat:prefs:'date') : '-')\n : col.type === 'time'\n ? ((getTimeValue(getNestedValue(d, col.field)) | timezoneFormat:prefs:'time'))\n : (getNestedValue(d, col.field)?.value || getNestedValue(d, col.field)?.name || getNestedValue(d, col.field) || '-')\n}}\">{{ col.type === 'date'\n ? (getNestedValue(d, col.field) ? (getNestedValue(d, col.field) | timezoneFormat:prefs:'date') : '-')\n : col.type === 'time'\n ? ((getTimeValue(getNestedValue(d, col.field)) | timezoneFormat:prefs:'time'))\n : (getNestedValue(d, col.field)?.value || getNestedValue(d, col.field)?.name || getNestedValue(d, col.field) || '-')\n}}</div>\n</ng-container>\n</ng-container>\n </td>\n </ng-container>\n </tr>\n</tbody>\n </table>\n\n </div>\n\n <!-- DETAIL SIDE MENU (Sticky on right end) -->\n <!-- <div class=\"detail-side-menu-wrapper\" >\n <div style=\"width: 30px\" class=\"d-flex flex-column align-items-center \">\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\">\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/ui-checks-grid.svg'\" class=\"data-grid-svg-icon\"></span>\n <div class=\"side-menue-text\">Columns</div>\n </div>\n \n </div>\n\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);\">\n <ng-container *ngIf=\"row.details.sideMenu.currentTab === 'cols'\">\n <div class=\"px-3 py-2 border-bottom d-flex align-items-center\">\n <strong class=\"me-auto\">Columns</strong>\n <input type=\"text\" class=\"form-control form-control-sm\" placeholder=\"Search...\" [(ngModel)]=\"row.details.sideMenu.columnSearch\" style=\"width: 120px; font-size: 12px;\" />\n </div>\n <div class=\"side-menu-scrollable\">\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\">\n <input type=\"checkbox\" class=\"form-check-input me-2\" [(ngModel)]=\"col.is_visible\" (change)=\"onDetailColumnVisibilityChange(row)\" />\n <span>{{ col.header }}</span>\n </div>\n </div>\n </ng-container>\n\n <ng-container *ngIf=\"row.details.sideMenu.currentTab === 'filtrs'\">\n <div class=\"px-3 py-2 border-bottom d-flex align-items-center\">\n <strong class=\"me-auto\">Filters</strong>\n <input type=\"text\" class=\"form-control form-control-sm\" placeholder=\"Search...\" [(ngModel)]=\"row.details.sideMenu.columnSearch\" style=\"width: 120px; font-size: 12px;\" />\n </div>\n <div class=\"side-menu-scrollable\">\n <div *ngFor=\"let col of row.details.columns | filter: row.details.sideMenu.columnSearch:'header'; trackBy: trackByField\" class=\"mb-3\">\n <div class=\"d-flex justify-content-between align-items-center cursor-pointer\" (click)=\"col.expandedFilter = !col.expandedFilter\">\n <label class=\"mb-0 small\">{{ col.header }}</label>\n <span class=\"toggle-icon data-grid-svg-icon\" [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\" [class.rotate]=\"col.expandedFilter\"></span>\n </div>\n <div *ngIf=\"col.expandedFilter\" class=\"mt-2 filter-input-container ps-3 pe-3\">\n <ng-container *ngIf=\"col.type === 'dropdown'; else textFilter\">\n <div class=\"p-1\">\n <input\n type=\"text\"\n class=\"form-control form-control-sm mb-2\"\n placeholder=\"Search...\"\n [(ngModel)]=\"col.searchValue\"\n />\n\n <div class=\"form-check mb-1 ms-1\">\n <input\n class=\"form-check-input\"\n type=\"checkbox\"\n [checked]=\"\n row.details.filters[col.field]?._ids?.length == col.column_dropdown_value?.length\n \"\n (change)=\"toggleSelectAllDetailFilters(col, row, $event)\"\n id=\"detail_selectAll_{{ col.field }}\"\n />\n <label class=\"form-check-label\" for=\"detail_selectAll_{{ col.field }}\">\n Select All\n </label>\n </div>\n\n <div class=\"dropdown-options\">\n <div\n class=\"form-check mb-1 ms-1\"\n *ngFor=\"\n let option of col?.column_dropdown_value\n | filter : col.searchValue : 'value';\n trackBy: trackById\n \"\n >\n <input\n class=\"form-check-input\"\n type=\"checkbox\"\n [value]=\"option\"\n [checked]=\"\n row.details.filters[col.field]?._ids?.includes(option?._id || option?.id || option)\n \"\n (change)=\"onDetailOptionToggle(col, option, row)\"\n id=\"detail_option_{{ col.field }}_{{\n option?.id || option?._id || option\n }}\"\n />\n <label\n class=\"form-check-label\"\n [for]=\"\n 'detail_option_' +\n col.field +\n '_' +\n (option?.id || option?._id || option)\n \"\n >\n {{ option.value || option }}\n </label>\n </div>\n </div>\n </div>\n </ng-container>\n\n <ng-template #textFilter>\n <div class=\"filter-text-section\">\n <div class=\"form-group mb-2\">\n <select\n class=\"form-select form-select-sm\"\n [(ngModel)]=\"row.details.filters[col.field].first_condition\"\n (ngModelChange)=\"applyDetailRowFilter(row)\"\n >\n <option value=\"contain\">Contains</option>\n <option value=\"equal\">Equals</option>\n <option value=\"before\">Begins With</option>\n <option value=\"after\">Ends With</option>\n </select>\n </div>\n\n <input\n [type]=\"col.type == 'date' ? 'date' : 'text'\"\n class=\"form-control form-control-sm mb-3\"\n placeholder=\"Value\"\n [(ngModel)]=\"row.details.filters[col.field].first_value\"\n (ngModelChange)=\"applyDetailRowFilter(row)\"\n />\n\n <ng-container *ngIf=\"row.details.filters[col.field]?.first_value\">\n <div class=\"form-group mb-2\">\n <div class=\"form-check form-check-inline\">\n <input\n class=\"form-check-input filter-radio-inputs\"\n type=\"radio\"\n name=\"detail_condition_{{ col.field }}\"\n [(ngModel)]=\"row.details.filters[col.field].condition\"\n (ngModelChange)=\"applyDetailRowFilter(row)\"\n value=\"and\"\n id=\"detail_and_{{ col.field }}\"\n />\n <label class=\"form-check-label\" for=\"detail_and_{{ col.field }}\"\n >AND</label\n >\n </div>\n <div class=\"form-check form-check-inline\">\n <input\n class=\"form-check-input filter-radio-inputs\"\n type=\"radio\"\n name=\"detail_condition_{{ col.field }}\"\n [(ngModel)]=\"row.details.filters[col.field].condition\"\n (ngModelChange)=\"applyDetailRowFilter(row)\"\n value=\"or\"\n id=\"detail_or_{{ col.field }}\"\n />\n <label class=\"form-check-label\" for=\"detail_or_{{ col.field }}\"\n >OR</label\n >\n </div>\n <div class=\"form-check form-check-inline\">\n <input\n class=\"form-check-input filter-radio-inputs\"\n type=\"radio\"\n name=\"detail_condition_{{ col.field }}\"\n [(ngModel)]=\"row.details.filters[col.field].condition\"\n (ngModelChange)=\"applyDetailRowFilter(row)\"\n value=\"none\"\n id=\"detail_none_{{ col.field }}\"\n />\n <label class=\"form-check-label\" for=\"detail_none_{{ col.field }}\"\n >None</label\n >\n </div>\n </div>\n\n <ng-container *ngIf=\"row.details.filters[col.field].condition !== 'none'\">\n <div class=\"form-group mb-2\">\n <select\n class=\"form-select form-select-sm\"\n [(ngModel)]=\"row.details.filters[col.field].second_condition\"\n (ngModelChange)=\"applyDetailRowFilter(row)\"\n >\n <option value=\"contain\">Contains</option>\n <option value=\"equal\">Equals</option>\n <option value=\"before\">Begins With</option>\n <option value=\"after\">Ends With</option>\n </select>\n </div>\n\n <input\n [type]=\"col.type == 'date' ? 'date' : 'text'\"\n class=\"form-control form-control-sm mb-2\"\n placeholder=\"Second Value\"\n [(ngModel)]=\"row.details.filters[col.field].second_value\"\n (ngModelChange)=\"applyDetailRowFilter(row)\"\n />\n </ng-container>\n </ng-container>\n </div>\n </ng-template>\n </div>\n </div>\n </div>\n </ng-container>\n </div>\n </div> -->\n</div>\n\n<!-- Detail Side Menu -->\n\n\n\n<!-- Popover for Restriction Logs (is_un_restricted) -->\n<!-- <div\n *ngIf=\"restrictionTooltipVisible\"\n class=\"popover__content m-l-10 popoverRestriction position-absolute border rounded bg-white p-3\"\n [style.left.px]=\"restrictionTooltipPosition.x\"\n [style.top.px]=\"restrictionTooltipPosition.y\"\n (mouseenter)=\"preventRestrictionTooltipHide()\"\n (mouseleave)=\"hideRestrictionTooltip()\"\n style=\"z-index: 1000; min-width: 300px; font-size: 12px;\"\n @tooltipAnimation\n>\n <div class=\"modal-area px-0 py-0\">\n <div class=\"table-responsive\">\n <table class=\"table table-row-primary-100 gs-0 gy-2 mb-0\">\n <thead>\n <tr class=\"fw-bolder text-muted bg-light\">\n <th class=\"center ps-2\">Clock in</th>\n <th class=\"center\">Clock out</th>\n <th class=\"center\">Log Hr</th>\n <th class=\"center\">Log Min</th>\n <th class=\"center pe-2\">Status</th>\n </tr>\n </thead>\n <tbody>\n <tr *ngFor=\"let item of currentRestrictionLogs\">\n <td class=\"center ps-2\">\n <span class=\"text-primary\"> {{ item?.clock_in_time | date:'shortTime'}}</span>\n </td>\n <td class=\"center\">\n <span class=\"text-primary\">{{ item?.clock_out_time | date:'shortTime'}}</span>\n </td>\n <td class=\"center\">\n <span class=\"text-primary\">{{ item?.logged_hours }}</span>\n </td>\n <td class=\"center\">\n <span class=\"text-primary\">{{ item?.logged_minutes }}</span>\n </td>\n <td class=\"center\">\n <span class=\"badge bg-light text-dark border\">\n {{ item?.status ? (item.status | titlecase) : 'N/A' }}\n </span>\n </td>\n </tr>\n </tbody>\n </table>\n </div>\n </div>\n</div> -->\n\n<!-- Popover for Manual Logs -->\n<!-- <div\n *ngIf=\"manualLogsTooltipVisible\"\n class=\"popover__content position-absolute border rounded bg-white p-3\"\n [style.left.px]=\"manualLogsTooltipPosition.x\"\n [style.top.px]=\"manualLogsTooltipPosition.y\"\n (mouseenter)=\"preventManualLogsTooltipHide()\"\n (mouseleave)=\"hideManualLogsTooltip()\"\n style=\"z-index: 1000; min-width: 500px; font-size: 12px;\"\n @tooltipAnimation\n>\n <div class=\"modal-area px-0 py-0\">\n <ng-container *ngIf=\"currentManualLogs.length > 0; else noManualLogs\">\n <div class=\"table-responsive\">\n <table class=\"table table-row-primary-100 gs-0 gy-2 mb-0\">\n <thead>\n <tr class=\"fw-bolder text-muted bg-light\">\n <th class=\"center ps-2\" style=\"width: 18%;\">Name</th>\n <th class=\"center\">Date/Time</th>\n <th class=\"center\">Previous Time</th>\n <th class=\"center\">Updated Time</th>\n <th class=\"center\">Status</th>\n <th class=\"center pe-2\">Remarks</th>\n </tr>\n </thead>\n <tbody>\n <tr *ngFor=\"let log of currentManualLogs\">\n <td class=\"center ps-2\">\n <span class=\"text-primary\">{{ log.name }}</span>\n </td>\n <td class=\"center\">\n <span class=\"text-primary\">{{ log.date_time }}</span>\n </td>\n <td class=\"center\">\n <span class=\"text-primary\">{{ log.previous_time }}</span>\n </td>\n <td class=\"center\">\n <span class=\"text-primary\">{{ log.updated_time }}</span>\n </td>\n <td class=\"center\">\n <span class=\"badge bg-light text-dark border\">\n {{ log.log_status ? (log.log_status | titlecase) : 'N/A' }}\n </span>\n </td>\n <td class=\"center pe-2\">\n <span class=\"text-primary\">{{ log.remarks }}</span>\n </td>\n </tr>\n </tbody>\n </table>\n </div>\n </ng-container>\n </div>\n\n <ng-template #noManualLogs>\n <div class=\"text-center p-3\">\n <p class=\"text-muted mb-0\">No manual logs available for this record.</p>\n </div>\n </ng-template>\n</div> -->\n\n\n\n\n<!-- Existing Custom Tooltip for Breaks -->\n\n\n\n\n\n <!-- RIGHT PINNED: Empty table to keep alignment -->\n <div *ngIf=\"section === 'right' && row.isDetailsExpand && !isSingleDay\" class=\"accordion-details data-grid-accordion-section\" style=\"max-height: 350px; min-height: 150px ; overflow: hidden;\">\n <table class=\"nested-table table table-sm w-100 mb-0 data-grid-accordion-table\" [class.show-shadow]=\"rowShadingEnabled\">\n <thead>\n <tr [style.height.px]=\"nestedTableHeaderRowHeight\" [style.backgroundColor]=\"headerBackgroundColor\">\n <th *ngFor=\"let _ of [1, 2, 3, 4, 5]\">&nbsp;</th>\n </tr>\n </thead>\n <tbody>\n <tr [style.height.px]=\"nestedTablerowHeight\" *ngFor=\"let _ of row.details.data\" [style.backgroundColor]=\"headerBackgroundColor\">\n <td *ngFor=\"let __ of [1, 2, 3, 4, 5]\">&nbsp;</td>\n </tr>\n </tbody>\n </table>\n </div>\n\n </ng-template>\n</ng-template>\n\n<!-- Actual Cell is Here -->\n<ng-template\n #cellTemplate\n let-col=\"col\"\n let-row=\"row\"\n let-section=\"section\"\n let-subColIndex=\"subColIndex\"\n let-rowIndex=\"rowIndex\"\n let-colIndex=\"colIndex\"\n>\n <div\n (click)=\"disableEdit(row, col); setActiveCell(row, col)\"\n [style.fontWeight]=\"bodyFontWeight\"\n [class.border-right]=\"showVerticalBorder\"\n class=\"cell overflow-visible position-relative\"\n [attr.field]=\"col.field\"\n [style.width.px]=\"col.width\"\n [style.min-width.px]=\"col.width\"\n [style.fontSize.px]=\"bodyTextFontsSize\"\n [class.active-cell]=\"\n isActiveCell(row, col) && !isEditing(row, col) && selectedKeys.size == 1\n \"\n (dblclick)=\"$event.preventDefault(); enableEdit(row, col)\"\n [class.row-selected]=\"rowSelectedIndexes.has(row.__virtualIndex)\"\n [class.first-row-selected]=\"firstSelectedRow === row.__virtualIndex\"\n [class.last-row-selected]=\"lastSelectedRow === row.__virtualIndex\"\n tabindex=\"0\"\n (keydown.enter)=\"$event.preventDefault(); enableEdit(row, col)\"\n (mousedown)=\"\n startSelection(\n row.__virtualIndex,\n colIndex,\n subColIndex ?? 0,\n col.field,\n $event,\n section\n )\n \"\n (mouseenter)=\"\n extendSelection(\n row.__virtualIndex,\n colIndex,\n subColIndex ?? 0,\n col.field,\n $event,\n section\n )\n \"\n (mouseup)=\"endSelection()\"\n [class.selected-cell]=\"\n isSelected(\n row.__virtualIndex,\n colIndex,\n subColIndex ?? 0,\n col.field,\n section\n )\n \"\n [class.top-border]=\"\n isTopBorder(row.__virtualIndex, colIndex, subColIndex, section)\n \"\n [class.bottom-border]=\"\n isBottomBorder(row.__virtualIndex, colIndex, subColIndex, section)\n \"\n [class.left-border]=\"\n isLeftBorder(row.__virtualIndex, colIndex, subColIndex, section)\n \"\n [class.right-border]=\"\n isRightBorder(row.__virtualIndex, colIndex, subColIndex, section)\n \"\n [class.top-left-corner]=\"\n isTopLeftCorner(row.__virtualIndex, colIndex, subColIndex, section)\n \"\n [class.top-right-corner]=\"\n isTopRightCorner(row.__virtualIndex, colIndex, subColIndex, section)\n \"\n [class.bottom-left-corner]=\"\n isBottomLeftCorner(row.__virtualIndex, colIndex, subColIndex, section)\n \"\n [class.bottom-right-corner]=\"\n isBottomRightCorner(row.__virtualIndex, colIndex, subColIndex, section)\n \"\n >\n <!-- (mousedown)=\"startSelection(row.__virtualIndex, colIndex, subColIndex ?? 0, col.field, $event)\"\n (mouseenter)=\"extendSelection(row.__virtualIndex, colIndex, subColIndex ?? 0, col.field, $event)\"\n (mouseup)=\"endSelection()\"\n [class.selected-cell]=\"isSelected(row.__virtualIndex, colIndex, subColIndex ?? 0, col.field)\" -->\n <div class=\"table-cell\" [class.active-for-editing]=\"isEditing(row, col) && getNestedValue(row, col.field)?.length <= 50\">\n <div\n (click)=\"$event.stopPropagation()\"\n *ngIf=\"isEditing(row, col) && getNestedValue(row, col.field)?.length <= 50; else viewMode\"\n >\n <ng-container [ngSwitch]=\"col.type\">\n <!-- Text Input -->\n <input\n [style.height.px]=\"rowHeight - 10\"\n *ngSwitchCase=\"'input'\"\n type=\"text\"\n [(ngModel)]=\"row[col.field]\"\n (blur)=\"disableEdit(row, col)\"\n autofocus\n class=\"form-control form-control-sm\"\n (mousedown)=\"$event.stopPropagation()\"\n />\n\n <!-- Number Input -->\n <input\n [style.height.px]=\"rowHeight - 8\"\n *ngSwitchCase=\"'number'\"\n #numberInput=\"ngModel\"\n #numberRef\n (keypress)=\"allowOnlyNumbers($event)\"\n type=\"number\"\n required\n [(ngModel)]=\"row[col.field]\"\n (blur)=\"disableEdit(row, col)\"\n autofocus\n (keydown.enter)=\"numberRef.blur()\"\n class=\"form-control form-control-sm\"\n [ngClass]=\"{\n 'is-invalid': numberInput.invalid\n }\"\n (mousedown)=\"$event.stopPropagation()\"\n />\n\n <!-- Date Input -->\n <input\n [style.height.px]=\"rowHeight - 8\"\n *ngSwitchCase=\"'date'\"\n type=\"date\"\n [(ngModel)]=\"row[col.field]\"\n (blur)=\"disableEdit(row, col)\"\n autofocus\n class=\"form-control form-control-sm\"\n #dateInput=\"ngModel\"\n [ngClass]=\"{\n 'is-invalid': dateInput.invalid\n }\"\n (mousedown)=\"$event.stopPropagation()\"\n />\n\n <!-- Dropdown -->\n <!-- ng-select like dropdown -->\n <div\n *ngSwitchCase=\"'dropdown'\"\n class=\"dropdown w-100\"\n (blur)=\"disableEdit(row, col)\"\n >\n <!-- Trigger -->\n <button\n class=\"form-select form-select-sm text-start w-100 text-ellipsis\"\n type=\"button\"\n data-bs-toggle=\"dropdown\"\n aria-expanded=\"false\"\n [style.minHeight.px]=\"rowHeight - 10\"\n data-bs-display=\"static\"\n (mousedown)=\"$event.stopPropagation()\"\n >\n <ng-container>\n {{\n getNestedValue(row, col.field)?.value ||\n getNestedValue(row, col.field)?.name ||\n getNestedValue(row, col.field)\n }}\n </ng-container>\n <ng-template #placeholder> Select options... </ng-template>\n </button>\n\n <!-- Menu -->\n <div\n class=\"dropdown-menu w-100 p-0 cell-editing-dropdown-menu rounded-3\"\n [class.show]=\"isEditing(row, col)\"\n >\n <!-- Search -->\n <div class=\"px-2 py-1\">\n <input\n type=\"text\"\n class=\"form-control form-control-sm\"\n placeholder=\"Search...\"\n [(ngModel)]=\"editinDropdownSearch\"\n />\n </div>\n\n <!-- Options -->\n <div\n class=\"cell-editin-dropdown\"\n style=\"max-height: 200px; overflow: auto\"\n >\n <div\n (click)=\"\n setNestedValue(row, col, option, true);\n disableEdit(row, col)\n \"\n class=\"px-2 py-1 d-flex align-items-center item\"\n *ngFor=\"\n let option of col.column_dropdown_value\n | filter : editinDropdownSearch : 'value'\n \"\n >\n <label\n class=\"form-check-label d-flex align-items-center mb-0\"\n [for]=\"col.field + '-' + option.value || option\"\n >\n {{ option.value || option }}\n </label>\n </div>\n </div>\n </div>\n </div>\n\n <input\n *ngSwitchCase=\"'email'\"\n [style.height.px]=\"rowHeight - 10\"\n [style.maxHeight.px]=\"rowHeight - 10\"\n #emailModel=\"ngModel\"\n #emailInput\n type=\"email\"\n [(ngModel)]=\"row[col.field]\"\n name=\"{{ col.field }}\"\n required\n pattern=\"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$\"\n (blur)=\"disableEdit(row, col, emailModel)\"\n (keydown.enter)=\"\n emailModel.control.markAsTouched(); emailInput.blur()\n \"\n autofocus\n class=\"form-control form-control-sm\"\n [ngClass]=\"{\n 'is-invalid': emailModel.invalid\n }\"\n (mousedown)=\"$event.stopPropagation()\"\n />\n <!-- Default fallback -->\n <input\n *ngSwitchDefault\n [style.height.px]=\"rowHeight - 10\"\n [style.maxHeight.px]=\"rowHeight - 10\"\n #textModel=\"ngModel\"\n #textInput\n type=\"text\"\n [(ngModel)]=\"row[col.field]\"\n name=\"{{ col.field }}\"\n required\n (blur)=\"disableEdit(row, col, textModel)\"\n (keydown.enter)=\"\n textModel.control.markAsTouched(); textInput.blur()\n \"\n autofocus\n class=\"form-control form-control-sm\"\n [ngClass]=\"{\n 'is-invalid': textModel.invalid\n }\"\n (mousedown)=\"$event.stopPropagation()\"\n />\n </ng-container>\n </div>\n\n <!-- Display mode -->\n <ng-template #viewMode>\n <div\n class=\"d-flex justify-between items-center w-100\"\n [ngClass]=\"getCellClasses(col, getNestedValue(row, col.field))\"\n >\n <!-- Text cell -->\n <div class=\"d-flex align-items-center w-100\">\n <div\n #cellText\n class=\"text-ellipsis flex-grow-1\"\n \n >\n <ng-container *ngIf=\"col.type !== 'image'\">\n <ng-container [ngSwitch]=\"col.field\">\n <!-- Breaks -->\n <ng-container *ngSwitchCase=\"'breaks'\">\n <ng-container *ngIf=\"getNestedValue(row, 'breaks')?.length; else noBreaksMain\">\n <app-badge-overflow\n [badges]=\"getBreakBadges(getNestedValue(row, 'breaks'))\"\n [maxWidth]=\"col.width || 200\"\n (badgeMouseEnter)=\"showBreakTooltip($event.event, $event.badge.data)\"\n (badgeMouseLeave)=\"hideBreakTooltip()\"\n (overflowCountClick)=\"onBadgeOverflowCountClick(col)\">\n </app-badge-overflow>\n </ng-container>\n <ng-template #noBreaksMain>\n <div >\n -\n </div>\n </ng-template>\n </ng-container>\n\n <!-- Short Breaks -->\n <ng-container *ngSwitchCase=\"'short_breaks'\">\n <ng-container *ngIf=\"row.short_breaks?.short_break_duration && row.short_breaks.short_break_duration > 0; else noShortBreak\">\n <div (dblclick)=\"onShortBreakClick.emit(row)\"> <app-badge-overflow\n [badges]=\"getShortBreakBadges(row.short_breaks)\"\n [maxWidth]=\"col.width || 200\"\n (badgeMouseEnter)=\"showShortBreakTooltip($event.event, row)\"\n (badgeMouseLeave)=\"hideShortBreakTooltip()\"\n (badgeClick)=\"handleShortBreakClick(row, $event)\"\n (overflowCountClick)=\"onShortBreakOverflowCountClick(col)\">\n </app-badge-overflow> </div>\n \n \n </ng-container>\n <ng-template #noShortBreak>\n <div >-</div>\n </ng-template>\n </ng-container>\n\n <!-- Short Leave -->\n <!-- Short Leave -->\n<ng-container *ngSwitchCase=\"'short_leave'\">\n <ng-container *ngIf=\"row.short_leave && row.short_leave.length > 0; else noShortLeaveMain\">\n <div class=\"w-100 d-flex main-progress-bar justify-content-center align-items-center\" \n style=\"background-color: rgb(111, 97, 207); height: 20px; border-radius: 4px; position: relative;\"\n (mouseenter)=\"showShortLeaveTooltip($event, row)\"\n (mouseleave)=\"hideShortLeaveTooltip()\">\n <span class=\"d-block\" [style.min-width.%]=\"row.short_leave[0].short_leave_time_percentage\" \n style=\"background-color: rgb(238, 99, 82); height: 100%; border-radius: 4px;\"></span>\n <span style=\"position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); color: white; font-size: 12px; font-weight: bold;\">\n {{ row.short_leave[0].short_leave_time_percentage }}%\n </span>\n </div>\n </ng-container>\n <ng-template #noShortLeaveMain>-</ng-template>\n</ng-container>\n\n <!-- Status -->\n <ng-container *ngSwitchCase=\"'status'\">\n <span class=\"badge\" [class]=\"getStatusBadgeClass(getNestedValue(row, col.field))\">\n {{ transformStatus(getNestedValue(row, col.field)) || '-' }}\n </span>\n </ng-container>\n\n <!-- Attendance Status -->\n <ng-container *ngSwitchCase=\"'attendanceStatus'\">\n <span class=\"badge\" [class]=\"getAttendanceStatusBadgeClass(getNestedValue(row, col.field))\">\n {{ transformStatus(getNestedValue(row, col.field)) || '-' }}\n </span>\n </ng-container>\n\n <!-- Payroll Processed -->\n <ng-container *ngSwitchCase=\"'is_payroll_processed'\">\n <span class=\"badge\" [class]=\"getNestedValue(row, col.field) ? 'badge-success' : 'badge-secondary'\">\n {{ getNestedValue(row, col.field) ? 'Yes' : 'No' }}\n </span>\n </ng-container>\n\n <!-- Restriction -->\n <ng-container *ngSwitchCase=\"'is_un_restricted'\">\n <span class=\"badge\" [class]=\"getNestedValue(row, col.field) ? 'badge-success' : 'badge-secondary'\">\n {{ getNestedValue(row, col.field) ? 'Yes' : 'No' }}\n </span>\n </ng-container>\n\n <!-- Default -->\n <ng-container *ngSwitchDefault>\n {{\n !isNestedValueArray(row, col.field)\n ? col.type === 'date'\n ? (isDate(getNestedValue(row, col.field))\n ? ((getNestedValue(row, col.field)) | timezoneFormat:prefs:'date' )\n : (getNestedValue(row, col.field)?.value ||\n getNestedValue(row, col.field)?.name ||\n getNestedValue(row, col.field) ||\n '-'))\n : col.type === 'time'\n ? ((getTimeValue(getNestedValue(row, col.field)) | timezoneFormat:prefs:'time'))\n : (getNestedValue(row, col.field)?.value ||\n getNestedValue(row, col.field)?.name ||\n getNestedValue(row, col.field) ||\n '-')\n : (getNestedValue(row, col.field)?.[0]?.department_name ||\n getNestedValue(row, col.field)?.[0]?.roleName ||\n '-')\n }}\n </ng-container>\n </ng-container>\n </ng-container>\n <ng-container *ngIf=\"col.type == 'image'\">\n <ng-container\n *ngTemplateOutlet=\"\n defaultImagePlaceholder;\n context: {\n row: row,\n col: col,\n }\n \"\n ></ng-container>\n </ng-container>\n </div>\n\n <!-- Active dot and eye icon for employee name -->\n <span *ngIf=\"col.field === 'User' && hasManualLogs(row) && !row.isDetailsExpand\" class=\"badge badge-dot badge-success ms-1\" (mouseenter)=\"showManualLogsTooltip($event, row, row)\"></span>\n <i *ngIf=\"col.field === 'User' && hasManualLogs(row)\" class=\"bi bi-eye ms-1\" (mouseenter)=\"showManualLogsTooltip($event, row, row)\"></i>\n </div>\n\n <!-- Expand / Collapse icon for multiple data showing in one coll-->\n\n <!-- <span\n *ngIf=\"\n (isOverflowing(cellText) &&\n showCellDetailsBox &&\n getNestedValue(row, col.field)?.length > 50) ||\n (isNestedValueArray(row, col.field) &&\n getNestedValue(row, col.field)?.length > 1)\n \"\n class=\"toggle-icon data-grid-svg-icon ms-2 cursor-pointer\"\n [inlineSVG]=\"\n isExpanded(row, col)\n ? singleSpaAssetsPath + 'data-grid/icons/chevron-down.svg'\n : singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\n \"\n (click)=\"\n $event.stopPropagation();\n toggleExpandOfLongCellText(row, col, columns, true)\n \"\n (dblclick)=\"$event.preventDefault(); $event.stopPropagation()\"\n ></span> -->\n </div>\n\n <!-- Expanded text -->\n <div\n class=\"position-absolute w-100\"\n *ngIf=\"isExpanded(row, col)\"\n [style.zIndex]=\"getZIndex(row, col)\"\n style=\"top: 100%; left: 0\"\n >\n <ng-container\n *ngTemplateOutlet=\"\n fullTextTemplate;\n context: {\n row: row,\n col: col,\n isArray: isNestedValueArray(row, col.field)\n }\n \"\n ></ng-container>\n </div>\n </ng-template>\n\n\n \n\n\n\n </div>\n </div>\n</ng-template>\n\n<div\n *ngIf=\"currentBreakTooltip\"\n class=\"custom-break-tooltip\"\n [style.--tooltip-x.px]=\"tooltipPosition.x\"\n [style.--tooltip-y.px]=\"tooltipPosition.y\"\n @tooltipAnimationBottom\n>\n <div class=\"break-tooltip-header\">\n <strong>{{ currentBreakTooltip.break_type?.data_value_name || 'Break' }}</strong>\n <span class=\"text-muted ms-2\">\n {{ currentBreakTooltip.breakInstatus === 'breakOut' ? 'Taken' : 'On Break' }}\n </span>\n </div>\n\n <div class=\"break-tooltip-body\">\n <div>\n <i class=\"bi bi-play-circle\"></i>\n In: {{ currentBreakTooltip.break_in_time | timezoneFormat:prefs:'time' }}\n </div>\n \n <div>\n <i class=\"bi bi-stop-circle\"></i>\n Out: {{ currentBreakTooltip.break_out_time | timezoneFormat:prefs:'time' }}\n </div>\n \n <div>\n <i class=\"bi bi-clock\"></i>\n Duration: {{ (currentBreakTooltip.total_minutes_logged || currentBreakTooltip.break_duration) }} min\n</div>\n </div>\n</div>\n\n\n\n\n\n\n<!-- Short Break Tooltip (Table Format) -->\n<div\n *ngIf=\"currentShortBreakTooltip\"\n class=\"custom-break-tooltip\"\n [style.--tooltip-x.px]=\"tooltipPosition.x\"\n [style.--tooltip-y.px]=\"tooltipPosition.y\"\n @tooltipAnimationBottom\n>\n <div class=\"break-tooltip-header\">\n <strong>{{ currentShortBreakTooltip.name }}</strong>\n </div>\n <div class=\"break-tooltip-body\">\n <table class=\"short-break-table\">\n <thead>\n <tr>\n <th>Start Time</th>\n <th>End Time</th>\n <th>Duration</th>\n </tr>\n </thead>\n <tbody>\n <tr *ngFor=\"let detail of currentShortBreakTooltip.details\">\n <td>\n {{\n detail.start_time\n ? (detail.start_time | timezoneFormat:prefs:'time')\n : 'N/A'\n }}\n </td>\n <td>\n {{\n detail.end_time\n ? (detail.end_time | timezoneFormat:prefs:'time')\n : 'N/A'\n }}\n </td>\n <td>{{ detail.duration }} min</td>\n </tr>\n <tr *ngIf=\"currentShortBreakTooltip.details.length === 0\">\n <td colspan=\"3\" class=\"text-center text-muted\">No timing details</td>\n </tr>\n </tbody>\n </table>\n </div>\n</div>\n\n\n\n\n<!-- Headers Action List On clicking three dots -->\n\n<ng-template #columnMenu let-col=\"col\">\n <div\n class=\"column-menu three-dots-col-menu\"\n [class.visually-hidden]=\"isMenueHidden\"\n *ngIf=\"activeCol && !isThreeDotsFilterOpen && !loading\"\n [style.backgroundColor]=\"dropdownsBackgroundColor\"\n >\n <!-- Sort Ascending -->\n <div class=\"border-below pb-2\" [class.disable-sorting]=\"!col.is_sortable\">\n <span class=\"muted-text fs-7\" style=\"margin-left: 12px\">Sort</span>\n <div\n *ngIf=\"\n columnThreedotsMunuConfig?.showAscending &&\n (sortingConfig?.field != col.field ||\n sortingConfig?.order_by == 'desc')\n \"\n class=\"column-menu-item\"\n (click)=\"sortAsc(activeCol)\"\n >\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrow-up.svg'\"\n class=\"data-grid-svg-icon me-2\"\n ></span>\n Sort Ascending\n </div>\n\n <!-- Sort Descending -->\n <div\n *ngIf=\"\n columnThreedotsMunuConfig?.showDescending &&\n (sortingConfig?.field != col.field ||\n sortingConfig?.order_by == 'asc')\n \"\n class=\"column-menu-item\"\n (click)=\"sortDesc(activeCol)\"\n >\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrow-down.svg'\"\n class=\"data-grid-svg-icon me-2\"\n ></span>\n Sort Descending\n </div>\n\n <div\n *ngIf=\"\n sortingConfig?.field === col.field &&\n (sortingConfig?.order_by === 'asc' ||\n sortingConfig?.order_by === 'desc')\n \"\n class=\"column-menu-item\"\n (click)=\"resetSort(activeCol)\"\n >\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/arrow-counterclockwise.svg'\n \"\n class=\"data-grid-svg-icon me-2\"\n ></span>\n Reset Sort\n </div>\n </div>\n <div class=\"py-2 border-below three-dots-filter\">\n <div\n *ngIf=\"columnThreedotsMunuConfig?.showFilter && !(col.is_search_able === false )\"\n class=\"column-menu-item three-dots-filter\"\n (click)=\"openFilteronThreeDotsClick(col)\"\n >\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\"\n class=\"data-grid-svg-icon me-2\"\n ></span>\n Filter\n </div>\n </div>\n\n <div class=\"py-2 border-below\">\n <span class=\"muted-text fs-7\" style=\"margin-left: 12px\">Pin</span>\n <div\n *ngIf=\"columnThreedotsMunuConfig?.showPinleft && col?.pinned !== 'left'\"\n class=\"column-menu-item\"\n (click)=\"updateColumnPinInSourceByField(activeCol, 'left')\"\n >\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/pin-left.svg'\"\n class=\"data-grid-svg-icon me-2\"\n ></span\n >Pin Left\n </div>\n\n <div\n *ngIf=\"\n columnThreedotsMunuConfig?.showPinright && col?.pinned !== 'right'\n \"\n class=\"column-menu-item\"\n (click)=\"updateColumnPinInSourceByField(activeCol, 'right')\"\n >\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/pin-right.svg'\"\n class=\"data-grid-svg-icon data-grid-svg-icon me-2\"\n ></span\n >Pin Right\n </div>\n\n <div\n *ngIf=\"col?.pinned\"\n class=\"column-menu-item\"\n (click)=\"updateColumnPinInSourceByField(activeCol, null)\"\n >\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/layout-three-columns.svg'\n \"\n class=\"data-grid-svg-icon me-2\"\n ></span\n >Unpin\n </div>\n </div>\n\n <div\n *ngIf=\"columnThreedotsMunuConfig?.showAutosizeThisColumn\"\n class=\"column-menu-item\"\n (click)=\"autosizeColumn(activeCol)\"\n >\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/arrows-expand-vertical.svg'\n \"\n class=\"me-2\"\n ></span>\n Autosize This Column\n </div>\n\n <!-- Autosize All Columns -->\n <div\n *ngIf=\"columnThreedotsMunuConfig?.showAutosizeAllColumns\"\n class=\"column-menu-item\"\n (click)=\"autosizeAllColumns()\"\n >\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/arrows-angle-expand.svg'\n \"\n class=\"data-grid-svg-icon me-2\"\n ></span\n >Autosize All Columns\n </div>\n\n <!-- Group By -->\n <div\n *ngIf=\"showRowsGrouping && !(col.is_groupable === false)\"\n class=\"column-menu-item\"\n (click)=\"groupBy(activeCol)\"\n >\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/diagram-3.svg'\"\n class=\"data-grid-svg-icon me-2\"\n ></span>\n Group by {{ col.header }}\n </div>\n\n <!-- Choose Columns -->\n <!-- <div\n *ngIf=\"columnThreedotsMunuConfig?.showChoseColumns\"\n class=\"column-menu-item\"\n (click)=\"chooseColumns()\"\n >\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/ui-checks-grid.svg'\"\n class=\"data-grid-svg-icon me-2\"\n ></span>\n Choose Columns\n </div> -->\n\n <!-- Reset Columns -->\n <!-- <div\n *ngIf=\"columnThreedotsMunuConfig?.showResetColumns\"\n class=\"column-menu-item\"\n (click)=\"resetColumns()\"\n >\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/arrow-counterclockwise.svg'\n \"\n class=\"data-grid-svg-icon me-2\"\n ></span\n >Reset Columns\n </div> -->\n </div>\n <div *ngIf=\"isThreeDotsFilterOpen\" class=\"three-dots-col-menu position-relative\" [style.left.px]=\"-140\" >\n <ng-container\n *ngTemplateOutlet=\"filterMenu; context: { col: col }\"\n ></ng-container>\n </div>\n</ng-template>\n\n\n\n<!-- Filter Menue -->\n<ng-template #filterMenu let-col=\"col\">\n <div\n class=\"filter-menu-container filter-menu\"\n [style.backgroundColor]=\"dropdownsBackgroundColor\"\n >\n <!-- Dropdown Type -->\n <ng-container *ngIf=\"col.type === 'dropdown'; else textFilter\">\n <div class=\"filter-dropdown-section p-1\">\n <input\n type=\"text\"\n class=\"form-control form-control-sm mb-2\"\n placeholder=\"Search...\"\n [(ngModel)]=\"addFilterDropdownSearch\"\n #filterMenueSearchInput\n />\n\n <div class=\"form-check mb-1\">\n <input\n class=\"form-check-input\"\n type=\"checkbox\"\n [checked]=\"isAllSideFilterOptionsSelected(col)\"\n (change)=\"toggleSelectAllSideFilters(col, $event)\"\n id=\"selectAll_{{ col.field }}\"\n />\n <label class=\"form-check-label\" for=\"selectAll_{{ col.field }}\">\n Select All\n </label>\n </div>\n\n <div class=\"dropdown-options\">\n <div class=\"form-check mb-1\"\n *ngFor=\"\n let option of getColumnOptions(col)\n | filter : addFilterDropdownSearch : 'value';\n trackBy: trackById\n\">\n <input\n class=\"form-check-input\"\n type=\"checkbox\"\n [checked]=\"isOptionSelected(col, option)\"\n [value]=\"option\"\n (change)=\"onOptionToggle(col, option)\"\n />\n <label class=\"form-check-label\">\n {{ option.value || option }}\n </label>\n </div>\n</div>\n </div>\n </ng-container>\n\n <!-- Text Filter Section -->\n <ng-template #textFilter>\n <div class=\"filter-text-section\">\n <div class=\"form-group mb-2\">\n <select\n class=\"form-select form-select-sm\"\n [ngModel]=\"col.query.first_condition || (col.type === 'date' || col.type === 'time' ? 'equal' : 'contain')\"\n (ngModelChange)=\"col.query.first_condition = $event\"\n >\n <ng-container *ngIf=\"col.type === 'date' || col.type === 'time'; else textOptions\">\n <option value=\"equal\">Equal to</option>\n <option value=\"not_equal\">Not Equal</option>\n <option value=\"after\">After</option>\n <option value=\"before\">Before</option>\n </ng-container>\n <ng-template #textOptions>\n <option value=\"contain\">Contains</option>\n <option value=\"equal\">Equals</option>\n <option value=\"before\">Begins With</option>\n <option value=\"after\">Ends With</option>\n </ng-template>\n </select>\n </div>\n\n <input\n [type]=\"col.type == 'string' ? 'text' : col.type\"\n class=\"form-control form-control-sm mb-3\"\n placeholder=\"Value\"\n [(ngModel)]=\"col.query.first_value\"\n [min]=\"col.type == 'number' ? 0 : null\"\n (input)=\"col.type == 'number' && $any($event.target).value < 0 ? $any($event.target).value = 0 : null\"\n (keydown)=\"col.type == 'number' && $event.key === '-' ? $event.preventDefault() : null\"\n [class.number-input]=\"col.type == 'number'\"\n #filterMenueTextchInput\n />\n\n <ng-container >\n <div class=\"form-group mb-2\">\n <div class=\"form-check form-check-inline\">\n <input\n class=\"form-check-input filter-radio-inputs\"\n type=\"radio\"\n name=\"condition\"\n [(ngModel)]=\"condition\"\n value=\"and\"\n id=\"and_{{ col.field }}\"\n />\n <label class=\"form-check-label\" for=\"and_{{ col.field }}\"\n >AND</label\n >\n </div>\n <div class=\"form-check form-check-inline\">\n <input\n class=\"form-check-input filter-radio-inputs\"\n type=\"radio\"\n name=\"condition\"\n [(ngModel)]=\"condition\"\n value=\"or\"\n id=\"or_{{ col.field }}\"\n />\n <label class=\"form-check-label\" for=\"or_{{ col.field }}\"\n >OR</label\n >\n </div>\n <div class=\"form-check form-check-inline\">\n <input\n class=\"form-check-input filter-radio-inputs\"\n type=\"radio\"\n name=\"condition\"\n [(ngModel)]=\"condition\"\n value=\"none\"\n id=\"none_{{ col.field }}\"\n />\n <label class=\"form-check-label\" for=\"none_{{ col.field }}\"\n >None</label\n >\n </div>\n </div>\n\n <ng-container *ngIf=\"col.query?.first_value && condition !== 'none'\">\n <div class=\"form-group mb-2\">\n <select\n class=\"form-select form-select-sm\"\n [ngModel]=\"col.query.second_condition || (col.type === 'date' || col.type === 'time' ? 'equal' : 'contain')\"\n (ngModelChange)=\"col.query.second_condition = $event\"\n >\n <ng-container *ngIf=\"col.type === 'date' || col.type === 'time'; else textOptionsSecond\">\n <option value=\"equal\">Equal to</option>\n <option value=\"not_equal\">Not Equal</option>\n <option value=\"after\">After</option>\n <option value=\"before\">Before</option>\n </ng-container>\n <ng-template #textOptionsSecond>\n <option value=\"contain\">Contains</option>\n <option value=\"equal\">Equals</option>\n <option value=\"before\">Begins With</option>\n <option value=\"after\">Ends With</option>\n </ng-template>\n </select>\n </div>\n\n <input\n [type]=\"col.type == 'string' ? 'text' : col.type\"\n class=\"form-control form-control-sm mb-2\"\n placeholder=\"Second Value\"\n [(ngModel)]=\"col.query.second_value\"\n [min]=\"col.type == 'number' ? 0 : null\"\n (input)=\"col.type == 'number' && $any($event.target).value < 0 ? $any($event.target).value = 0 : null\"\n (keydown)=\"col.type == 'number' && $event.key === '-' ? $event.preventDefault() : null\"\n [class.number-input]=\"col.type == 'number'\"\n />\n </ng-container>\n </ng-container>\n </div>\n </ng-template>\n\n <!-- Actions -->\n <div class=\"d-flex gap-2 mt-2\">\n <div\n class=\"btn btn-sm btn-primary d-flex justify-content-center align-items-center w-100\"\n style=\"height: 22px\"\n (click)=\"applyFilterFromFilterRow(col)\"\n >\n Apply\n </div>\n <div\n class=\"btn btn-sm btn-secondary d-flex justify-content-center align-items-center w-100\"\n style=\"height: 22px\"\n (click)=\"resetSideFilter(col)\"\n >\n Reset\n </div>\n </div>\n </div>\n</ng-template>\n\n<!-- Side Menue -->\n\n<!-- Add this new template for accordion detail column menu -->\n<ng-template #detailColumnMenu let-col=\"col\" let-row=\"row\">\n <div\n class=\"column-menu three-dots-col-menu detail-column-menu\"\n [class.visually-hidden]=\"isDetailMenueHidden\"\n *ngIf=\"activeDetailCol\"\n [style.backgroundColor]=\"dropdownsBackgroundColor\"\n >\n <!-- Sort Ascending -->\n <!-- <div class=\"border-below pb-2\" [class.disable-sorting]=\"!col.is_sortable\">\n <span class=\"muted-text fs-7\" style=\"margin-left: 12px\">Sort</span> -->\n <!-- <div\n *ngIf=\"columnThreedotsMunuConfig?.showAscending\"\n class=\"column-menu-item\"\n (click)=\"sortDetailAsc(activeDetailCol, row)\"\n >\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrow-up.svg'\"\n class=\"data-grid-svg-icon me-2\"\n ></span>\n Sort Ascending\n </div> -->\n\n <!-- Sort Descending -->\n <!-- <div\n *ngIf=\"columnThreedotsMunuConfig?.showDescending\"\n class=\"column-menu-item\"\n (click)=\"sortDetailDesc(activeDetailCol, row)\"\n >\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrow-down.svg'\"\n class=\"data-grid-svg-icon me-2\"\n ></span>\n Sort Descending\n </div> -->\n\n <!-- <div\n *ngIf=\"col?.sortOrder\"\n class=\"column-menu-item\"\n (click)=\"resetDetailSort(activeDetailCol, row)\"\n >\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/arrow-counterclockwise.svg'\n \"\n class=\"data-grid-svg-icon me-2\"\n ></span>\n Reset Sort\n </div> -->\n <!-- </div> -->\n\n <div class=\"py-2 border-below\" *ngIf=\"isColumnFilterable(col)\">\n <span class=\"muted-text fs-7\" style=\"margin-left: 12px\">Filter</span>\n <div\n *ngIf=\"columnThreedotsMunuConfig?.showFilter\"\n class=\"column-menu-item\"\n (click)=\"openDetailFilterMenu($event, col, row)\"\n >\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\"\n class=\"data-grid-svg-icon me-2\"\n ></span>\n Filter\n </div>\n </div>\n\n <div class=\"py-2 border-below\">\n <span class=\"muted-text fs-7\" style=\"margin-left: 12px\">Pin</span>\n <div\n *ngIf=\"columnThreedotsMunuConfig?.showPinleft && col?.pinned !== 'left'\"\n class=\"column-menu-item\"\n (click)=\"updateDetailColumnPin(activeDetailCol, row, 'left')\"\n >\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/pin-left.svg'\"\n class=\"data-grid-svg-icon me-2\"\n ></span\n >Pin Left\n </div>\n\n <div\n *ngIf=\"\n columnThreedotsMunuConfig?.showPinright && col?.pinned !== 'right'\n \"\n class=\"column-menu-item\"\n (click)=\"updateDetailColumnPin(activeDetailCol, row, 'right')\"\n >\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/pin-right.svg'\"\n class=\"data-grid-svg-icon data-grid-svg-icon me-2\"\n ></span\n >Pin Right\n </div>\n\n <div\n *ngIf=\"col?.pinned\"\n class=\"column-menu-item\"\n (click)=\"updateDetailColumnPin(activeDetailCol, row, null)\"\n >\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/layout-three-columns.svg'\n \"\n class=\"data-grid-svg-icon me-2\"\n ></span\n >Unpin\n </div>\n </div>\n\n <div\n *ngIf=\"columnThreedotsMunuConfig?.showAutosizeThisColumn\"\n class=\"column-menu-item\"\n (click)=\"autosizeDetailColumn(activeDetailCol, row)\"\n >\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/arrows-expand-vertical.svg'\n \"\n class=\"me-2\"\n ></span>\n Autosize This Column\n </div>\n\n <!-- Autosize All Columns -->\n <div\n *ngIf=\"columnThreedotsMunuConfig?.showAutosizeAllColumns\"\n class=\"column-menu-item\"\n (click)=\"autosizeAllDetailColumns(row)\"\n >\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/arrows-angle-expand.svg'\n \"\n class=\"data-grid-svg-icon me-2\"\n ></span\n >Autosize All Columns\n </div>\n\n\n <!-- Choose Columns -->\n <div\n *ngIf=\"columnThreedotsMunuConfig?.showChoseColumns\"\n class=\"column-menu-item\"\n (click)=\"openDetailChooseColumns(row)\"\n>\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/ui-checks-grid.svg'\"\n class=\"data-grid-svg-icon me-2\"\n ></span>\n Choose Columns\n</div>\n\n <!-- Reset Columns -->\n <!-- <div\n *ngIf=\"columnThreedotsMunuConfig?.showResetColumns\"\n class=\"column-menu-item\"\n (click)=\"resetDetailColumns(row)\"\n >\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/arrow-counterclockwise.svg'\n \"\n class=\"data-grid-svg-icon me-2\"\n ></span\n >Reset Columns\n </div> -->\n </div>\n</ng-template>\n\n<!-- Column Pannel / Pivot Mode / Searching -->\n\n<ng-template #columnPannel>\n <div class=\"column-panel-header\">\n <!-- Pivot Toggle -->\n <div\n class=\"form-check form-switch d-flex align-items-center mb-2 pivot-mode px-5 ms-2\"\n >\n <input\n class=\"form-check-input me-2\"\n type=\"checkbox\"\n id=\"pivotToggle\"\n [(ngModel)]=\"pivotMode\"\n />\n <label class=\"form-check-label\" for=\"pivotToggle\">Pivot Mode</label>\n </div>\n\n <!-- Select All & Search -->\n <div class=\"d-flex align-items-center mb-2 px-3\">\n <span class=\"filter-icon-wrapper me-2\" *ngIf=\"showColumnsGrouping\">\n <span\n class=\"toggle-icon data-grid-svg-icon\"\n [inlineSVG]=\"\n accordionState === 'all'\n ? singleSpaAssetsPath + 'data-grid/icons/chevron-down.svg'\n : accordionState === 'some'\n ? singleSpaAssetsPath + 'data-grid/icons/dash.svg'\n : singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\n \"\n (click)=\"toggleAllAccordions()\"\n ></span>\n </span>\n <input\n type=\"checkbox\"\n class=\"form-check-input me-2\"\n [checked]=\"allColumnsSelected()\"\n (change)=\"toggleAllColumnsVisibility()\"\n />\n <input\n type=\"text\"\n class=\"form-control form-control-sm\"\n placeholder=\"Search columns...\"\n [(ngModel)]=\"columnSearch\"\n />\n </div>\n\n <!-- Separator -->\n <hr class=\"my-2\" />\n </div>\n</ng-template>\n\n<!-- Right Columns Menue -->\n\n<!-- Column Panel Item Template -->\n<ng-template #columnPanelItem let-col=\"col\">\n <!-- Group Column -->\n <ng-container *ngIf=\"col.children?.length\">\n <div class=\"column-group d-flex align-items-center mb-2\">\n <span class=\"filter-icon-wrapper me-2\">\n <span\n class=\"toggle-icon data-grid-svg-icon\"\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\n \"\n [class.rotate]=\"col.expanded\"\n (click)=\"col.expanded = !col.expanded\"\n ></span>\n </span>\n <input\n type=\"checkbox\"\n class=\"form-check-input me-2\"\n [id]=\"'group_' + col.header\"\n [checked]=\"isColumnVisible(col)\"\n (change)=\"toggleGroupVisibility(col)\"\n />\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/grid-3x2-gap.svg'\"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center me-2\"\n ></span>\n <label\n class=\"d-flex align-items-center mb-0 w-100\"\n [for]=\"'group_' + col.header\"\n style=\"cursor: pointer\"\n >\n <span class=\"text-truncate\">{{ col.header }}</span>\n </label>\n </div>\n <div *ngIf=\"col.expanded\" class=\"ps-4\">\n <ng-container *ngFor=\"let child of col.children; trackBy: trackByField\">\n <ng-container\n *ngTemplateOutlet=\"columnPanelItem; context: { col: child }\"\n ></ng-container>\n </ng-container>\n </div>\n </ng-container>\n\n <!-- Leaf Column -->\n <ng-container *ngIf=\"!col.children?.length\">\n <div class=\"d-flex align-items-center mb-2\">\n <span class=\"me-2\" style=\"width: 1.5rem\"></span>\n <input\n type=\"checkbox\"\n class=\"form-check-input me-2\"\n [(ngModel)]=\"col.is_visible\"\n [id]=\"'col_' + col.field\"\n (change)=\"onSideMenuColumnsVisibilityChange()\"\n />\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/grid-3x2-gap.svg'\"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center me-2\"\n ></span>\n <label\n class=\"d-flex align-items-center mb-0 w-100\"\n [for]=\"'col_' + col.field\"\n style=\"cursor: pointer\"\n >\n <span class=\"text-truncate\">{{ col.header }}</span>\n </label>\n </div>\n </ng-container>\n</ng-template>\n<!-- Columns Side Filter -->\n<ng-template #sideFilters>\n <div class=\"py-3 px-2 pe-3 h-100\">\n <div class=\"d-flex align-items-center mb-2\">\n <span class=\"filter-icon-wrapper me-2\">\n <span\n class=\"toggle-icon data-grid-svg-icon\"\n [inlineSVG]=\"\n filterAccordionState === 'all'\n ? singleSpaAssetsPath + 'data-grid/icons/chevron-down.svg'\n : filterAccordionState === 'some'\n ? singleSpaAssetsPath + 'data-grid/icons/dash.svg'\n : singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\n \"\n (click)=\"toggleAllFilterAccordions()\"\n ></span>\n </span>\n\n <input\n type=\"text\"\n class=\"form-control form-control-sm\"\n placeholder=\"Search...\"\n [(ngModel)]=\"columnSearch\"\n />\n </div>\n <div\n class=\"overflow-auto side-filter-columns-wrapper\"\n style=\"height: calc(100% - 120px); scrollbar-width: thin\"\n >\n <ng-container\n *ngFor=\"\n let col of columns | filter : columnSearch : 'header';\n trackBy: trackByField\n \"\n >\n <ng-container\n *ngTemplateOutlet=\"filterPannelItem; context: { col: col }\"\n ></ng-container>\n </ng-container>\n </div>\n <!-- Apply and Reset Buttons -->\n <!-- <div class=\"d-flex gap-2 mt-3 px-2\">\n <button\n class=\"btn btn-sm btn-primary d-flex justify-content-center align-items-center flex-fill\"\n style=\"height: 32px;\"\n (click)=\"applySideMenuFilters()\"\n >\n Apply\n </button>\n <button\n class=\"btn btn-sm btn-secondary d-flex justify-content-center align-items-center flex-fill\"\n style=\"height: 32px;\"\n (click)=\"resetSideMenuFilters()\"\n >\n Reset\n </button>\n </div> -->\n </div>\n</ng-template>\n\n<ng-template #filterPannelItem let-col=\"col\">\n <!-- Group Column -->\n <ng-container *ngIf=\"col.children?.length\">\n <div class=\"column-group d-flex align-items-center mb-2\">\n <!-- Chevron toggle -->\n <span class=\"filter-icon-wrapper me-2\">\n <span\n class=\"toggle-icon data-grid-svg-icon\"\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\n \"\n [class.rotate]=\"col.expandedFilter\"\n (click)=\"col.expandedFilter = !col.expandedFilter\"\n ></span>\n </span>\n\n <!-- Group label toggle -->\n <label\n class=\"d-flex align-items-center mb-0 w-100\"\n style=\"cursor: pointer\"\n (click)=\"col.expandedFilter = !col.expandedFilter\"\n >\n <span class=\"fw-bold text-truncate\"\n >{{ col.header }}\n <span\n class=\"text-primary ms-1\"\n *ngIf=\"col?.query?._ids?.length || col?.query?._first_value\"\n >*</span\n >\n </span>\n </label>\n </div>\n\n <!-- Children columns -->\n <div *ngIf=\"col.expandedFilter\" class=\"ps-4\">\n <ng-container *ngFor=\"let child of col.children; trackBy: trackByField\">\n <ng-container\n *ngTemplateOutlet=\"filterPannelItem; context: { col: child }\"\n ></ng-container>\n </ng-container>\n </div>\n </ng-container>\n\n <!-- Leaf Column -->\n <ng-container *ngIf=\"!col.children?.length\">\n <div class=\"d-flex align-items-center mb-2\">\n <span\n class=\"me-2 filter-icon-wrapper me-2\"\n (click)=\"col.expandedFilter = !col.expandedFilter\"\n >\n <span\n class=\"toggle-icon data-grid-svg-icon\"\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\n \"\n [class.rotate]=\"col.expandedFilter\"\n ></span>\n </span>\n\n <label\n class=\"d-flex align-items-center mb-0 w-100\"\n style=\"cursor: pointer\"\n (click)=\"col.expandedFilter = !col.expandedFilter\"\n >\n <span class=\"text-truncate fw-bold\">{{ col.header }}</span>\n </label>\n </div>\n\n <!-- Show filter when expanded -->\n <div *ngIf=\"col.expandedFilter\" class=\"ps-4 pe-3\">\n <ng-container\n *ngTemplateOutlet=\"sideNestedFilter; context: { col: col }\"\n ></ng-container>\n </div>\n </ng-container>\n</ng-template>\n\n<!-- Side Nested Filters -->\n<ng-template #sideNestedFilter let-col=\"col\">\n <div class=\"\">\n <!-- Dropdown Type -->\n <ng-container *ngIf=\"col.type === 'dropdown'; else textFilter\">\n <div class=\"p-1\">\n <!-- Search -->\n <input\n type=\"text\"\n class=\"form-control form-control-sm mb-2\"\n placeholder=\"Search...\"\n [(ngModel)]=\"col.searchValue\"\n />\n\n <!-- Select All -->\n <div class=\"form-check mb-1 ms-1\">\n <input\n class=\"form-check-input\"\n type=\"checkbox\"\n [checked]=\"\n col.query?._ids?.length == col?.column_dropdown_value?.length\n \"\n (change)=\"toggleSelectAllSideFilters(col, $event)\"\n id=\"selectAll_{{ col.field }}\"\n />\n <label class=\"form-check-label\" for=\"selectAll_{{ col.field }}\">\n Select All\n </label>\n </div>\n\n <!-- Options -->\n <div class=\"dropdown-options\">\n <div\n class=\"form-check mb-1 ms-1\"\n *ngFor=\"\n let option of col?.column_dropdown_value\n | filter : addFilterDropdownSearch : 'header'\n \"\n >\n <input\n class=\"form-check-input\"\n type=\"checkbox\"\n [value]=\"option\"\n [checked]=\"isOptionSelected(col, option)\"\n (change)=\"onOptionToggle(col, option)\"\n id=\"option_{{ col.field }}_{{\n option?.id || option?._id || option\n }}\"\n />\n <label\n class=\"form-check-label\"\n [for]=\"\n 'option_' +\n col.field +\n '_' +\n (option?.id || option?._id || option)\n \"\n >\n {{ option.value || option }}\n </label>\n </div>\n </div>\n\n <!-- Actions -->\n <!-- <div class=\"d-flex gap-2 mt-2\">\n <div\n class=\"btn btn-sm btn-primary d-flex justify-content-center align-items-center\"\n style=\"height: 22px;\"\n (click)=\"applySideMenuFilters()\"\n >\n Apply\n </div>\n <div\n class=\"btn btn-sm btn-secondary d-flex justify-content-center align-items-center\"\n style=\"height: 22px;\"\n (click)=\"resetSideMenuFilters()\"\n >\n Reset\n </div>\n </div> -->\n </div>\n </ng-container>\n\n <!-- Text Filter Section -->\n <ng-template #textFilter>\n <div class=\"filter-text-section\">\n <div class=\"form-group mb-2\">\n <select\n class=\"form-select form-select-sm\"\n [ngModel]=\"col!.query!.first_condition || (col.type === 'date' || col.type === 'time' ? 'equal' : 'contain')\"\n (ngModelChange)=\"col!.query!.first_condition = $event\"\n >\n <ng-container *ngIf=\"col.type === 'date' || col.type === 'time'; else textOptions\">\n <option value=\"equal\">Equal to</option>\n <option value=\"not_equal\">Not Equal</option>\n <option value=\"after\">After</option>\n <option value=\"before\">Before</option>\n </ng-container>\n <ng-template #textOptions>\n <option value=\"contain\">Contains</option>\n <option value=\"equal\">Equals</option>\n <option value=\"before\">Begins With</option>\n <option value=\"after\">Ends With</option>\n </ng-template>\n </select>\n </div>\n\n <input\n [type]=\"col.type == 'date' ? 'date' : col.type == 'number' ? 'number' : 'text'\"\n class=\"form-control form-control-sm mb-3\"\n placeholder=\"Value\"\n [(ngModel)]=\"col!.query!.first_value\"\n [min]=\"col.type == 'number' ? 0 : null\"\n (input)=\"col.type == 'number' && $any($event.target).value < 0 ? $any($event.target).value = 0 : null\"\n (keydown)=\"col.type == 'number' && $event.key === '-' ? $event.preventDefault() : null\"\n [class.number-input]=\"col.type == 'number'\"\n />\n\n <ng-container *ngIf=\"col?.query?.first_value && col?.query?.condition !== 'none'\">\n <div class=\"form-group mb-2\">\n <div class=\"form-check form-check-inline\">\n <input\n class=\"form-check-input filter-radio-inputs\"\n type=\"radio\"\n name=\"condition\"\n [(ngModel)]=\"col!.query.condition\"\n value=\"and\"\n id=\"and_{{ col.field }}\"\n />\n <label class=\"form-check-label\" for=\"and_{{ col.field }}\"\n >AND</label\n >\n </div>\n <div class=\"form-check form-check-inline\">\n <input\n class=\"form-check-input filter-radio-inputs\"\n type=\"radio\"\n name=\"condition\"\n [(ngModel)]=\"col!.query.condition\"\n value=\"or\"\n id=\"or_{{ col.field }}\"\n />\n <label class=\"form-check-label\" for=\"or_{{ col.field }}\"\n >OR</label\n >\n </div>\n <div class=\"form-check form-check-inline\">\n <input\n class=\"form-check-input filter-radio-inputs\"\n type=\"radio\"\n name=\"condition\"\n [(ngModel)]=\"col!.query.condition\"\n value=\"none\"\n id=\"none_{{ col.field }}\"\n />\n <label class=\"form-check-label\" for=\"none_{{ col.field }}\"\n >None</label\n >\n </div>\n </div>\n\n <div class=\"form-group mb-2\">\n <select\n class=\"form-select form-select-sm\"\n [ngModel]=\"col!.query.second_condition || (col.type === 'date' || col.type === 'time' ? 'equal' : 'contain')\"\n (ngModelChange)=\"col!.query.second_condition = $event\"\n >\n <ng-container *ngIf=\"col.type === 'date' || col.type === 'time'; else textOptionsSecond\">\n <option value=\"equal\">Equal to</option>\n <option value=\"not_equal\">Not Equal</option>\n <option value=\"after\">After</option>\n <option value=\"before\">Before</option>\n </ng-container>\n <ng-template #textOptionsSecond>\n <option value=\"contain\">Contains</option>\n <option value=\"equal\">Equals</option>\n <option value=\"before\">Begins With</option>\n <option value=\"after\">Ends With</option>\n </ng-template>\n </select>\n </div>\n\n <input\n [type]=\"col.type == 'date' ? 'date' : col.type == 'number' ? 'number' : 'text'\"\n class=\"form-control form-control-sm mb-2\"\n placeholder=\"Second Value\"\n [(ngModel)]=\"col!.query.second_value\"\n [min]=\"col.type == 'number' ? 0 : null\"\n (input)=\"col.type == 'number' && $any($event.target).value < 0 ? $any($event.target).value = 0 : null\"\n (keydown)=\"col.type == 'number' && $event.key === '-' ? $event.preventDefault() : null\"\n [class.number-input]=\"col.type == 'number'\"\n />\n </ng-container>\n\n <!-- Apply and Reset Buttons -->\n <div class=\"d-flex gap-2 mt-2\">\n <div\n class=\"btn btn-sm btn-primary d-flex justify-content-center align-items-center w-100\"\n style=\"height: 22px\"\n (click)=\"applyFilterFromFilterRow(col)\"\n >\n Apply\n </div>\n <div\n class=\"btn btn-sm btn-secondary d-flex justify-content-center align-items-center w-100\"\n style=\"height: 22px\"\n (click)=\"resetSideFilter(col)\"\n >\n Reset\n </div>\n </div>\n </div>\n </ng-template>\n </div>\n</ng-template>\n\n<!-- Centr Overlay for showing the chose columns -->\n\n<div *ngIf=\"showColumnPanel\" class=\"custom-modal-overlay\" (click)=\"closeModalColumnPanel()\">\n <div\n class=\"custom-modal-content\"\n [style.backgroundColor]=\"dropdownsBackgroundColor\"\n (click)=\"$event.stopPropagation()\"\n >\n <ng-container *ngTemplateOutlet=\"modalColumnPannel\"></ng-container>\n </div>\n</div>\n\n<!-- The existing ng-template you provided -->\n<ng-template #modalColumnPannel>\n <div class=\"column-panel-header\">\n <div\n class=\"d-flex justify-content-between align-items-center px-2 ps-3 rounded-top-2 moda-header\"\n [style.height.px]=\"48\"\n >\n Choose Columns\n <span class=\"filter-icon-wrapper\" (click)=\"closeModalColumnPanel()\"\n ><span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/x.svg'\"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span\n ></span>\n </div>\n <hr class=\"my-0\" />\n <div>\n <div class=\"d-flex align-items-center px-2 pe-3\" [style.height.px]=\"48\">\n <span class=\"filter-icon-wrapper me-2\" *ngIf=\"showColumnsGrouping\">\n <span\n class=\"toggle-icon data-grid-svg-icon\"\n [inlineSVG]=\"\n accordionState === 'all'\n ? singleSpaAssetsPath + 'data-grid/icons/chevron-down.svg'\n : accordionState === 'some'\n ? singleSpaAssetsPath + 'data-grid/icons/dash.svg'\n : singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\n \"\n (click)=\"toggleAllAccordions()\"\n ></span>\n </span>\n <input\n type=\"checkbox\"\n class=\"form-check-input me-2\"\n [checked]=\"allColumnsSelected()\"\n (change)=\"toggleAllColumnsVisibility()\"\n />\n <input\n type=\"text\"\n class=\"form-control form-control-sm\"\n placeholder=\"Search columns...\"\n [(ngModel)]=\"choseColumnsSearch\"\n />\n </div>\n\n <hr class=\"mt-0 mb-1\" />\n <div class=\"px-2 overlay-scrollable\">\n <ng-container\n *ngFor=\"\n let col of columns | filter : choseColumnsSearch : 'header';\n trackBy: trackByField\n \"\n >\n <ng-container\n *ngTemplateOutlet=\"columnPanelItem; context: { col: col }\"\n ></ng-container>\n </ng-container>\n </div>\n </div>\n </div>\n</ng-template>\n\n<ng-template #sideMenuRowGroups>\n <div class=\"d-flex flex-column h-100\">\n <div class=\"px-3 h-100\">\n <div class=\"d-flex gap-3 mb-4\">\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/justify.svg'\"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n <span>Row Groups</span>\n </div>\n <div class=\"h-50\">\n <div\n class=\"px-3 py-2 border-dashed h-100 d-flex justify-content-center align-items-center\"\n style=\"font-size: 14px\"\n >\n Drag here to set row Groups\n </div>\n </div>\n </div>\n\n <hr class=\"mt-4\" />\n\n <div class=\"px-3 h-100\">\n <div class=\"d-flex gap-3 mb-4\">\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/justify.svg'\"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n <span>Values</span>\n </div>\n <div class=\"h-50 d-flex\">\n <div\n class=\"px-3 py-2 border-dashed h-100 d-flex justify-content-center align-items-center\"\n style=\"font-size: 14px\"\n >\n Drag here aggregate\n </div>\n </div>\n </div>\n </div>\n</ng-template>\n\n<!-- *************************************************** -->\n<!-- *************************************************** -->\n<!-- *************************************************** -->\n<!-- Drag Preview Template -->\n<!-- *************************************************** -->\n<!-- *************************************************** -->\n<ng-template #dragPreview let-col>\n <div class=\"p-2 border d-flex gap-2\">\n <div>\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrows-move.svg'\"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n </div>\n <div>{{ col.header }}</div>\n </div>\n</ng-template>\n\n<!-- Drag Placeholder Template -->\n<ng-template\n #dragPlaceholder\n let-col\n let-i=\"index\"\n let-section=\"section\"\n let-draggingInGroupArea=\"draggingInGroupArea\"\n>\n <div *ngIf=\"!draggingInGroupArea\">\n <div\n *ngTemplateOutlet=\"\n headerCell;\n context: { $implicit: col, index: i, section: section }\n \"\n ></div>\n </div>\n <div *ngIf=\"draggingInGroupArea\">New Placeholder</div>\n</ng-template>\n\n<!-- Top Group Row Placeholder -->\n<ng-template #topGroupingRowPlaceholder let-col let-showChevron=\"showChevron\">\n <div class=\"d-flex gap-2\">\n <div\n class=\"d-flex gap-2 top-row-grouping-placeholder\"\n [style.backgroundColor]=\"topGroupedBadgesBackgroundColor\"\n >\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/grid-3x2-gap.svg'\"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n <span>{{ col.header }}</span>\n <span\n (click)=\"ungroupColumn(col)\"\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/x.svg'\"\n class=\"cursor-pointer data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n </div>\n </div>\n <div *ngIf=\"showChevron\" style=\"opacity: 0.6; font-size: 14px\">\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n </div>\n</ng-template>\n\n<ng-template\n #childHeaderPlaceholder\n let-col\n let-pinnedRight=\"pinnedRight\"\n let-i=\"index\"\n let-sections=\"sections\"\n>\n <div\n class=\"header-cell one-row-header-cells\"\n [class.border-right]=\"showVerticalBorder\"\n [style.width.px]=\"col.width\"\n [style.min-width.px]=\"col.width\"\n [style.min-height.px]=\"headerRowHeight\"\n [style.max-height.px]=\"headerRowHeight\"\n [class.border-right]=\"showVerticalBorder\"\n [style.fontWeight]=\"headerFontWeight\"\n >\n <div class=\"d-flex justify-content-between h-100 align-items-center w-100\">\n <div\n class=\"d-flex justify-content-between w-100\"\n [class.flex-row-reverse]=\"pinnedRight\"\n >\n <div\n class=\"text-ellipsis h-100 d-flex align-items-center\"\n [title]=\"col.header\"\n [class.w-100]=\"pinnedRight\"\n >\n {{ col.header }}\n </div>\n\n <div\n class=\"position-relative d-flex\"\n [class.flex-row-reverse]=\"pinnedRight\"\n >\n <div class=\"three-dots p-1\" style=\"cursor: pointer\">\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/three-dots-vertical.svg'\n \"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n </div>\n\n <div class=\"resize-handle\">\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/resize-handle.svg'\n \"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n </div>\n </div>\n </div>\n </div>\n </div>\n <div\n *ngIf=\"showFilterRow\"\n [style.backgroundColor]=\"headerBackgroundColor\"\n class=\"header-cell filter-cell\"\n [class.border-right]=\"showVerticalBorder\"\n [style.width.px]=\"col.width\"\n [style.min-width.px]=\"col.width\"\n [style.height.px]=\"headerRowHeight\"\n [style.min-height.px]=\"headerRowHeight\"\n [style.max-height.px]=\"headerRowHeight\"\n [class.border-right]=\"showVerticalBorder\"\n style=\"grid-row: 3\"\n >\n <div\n class=\"header-cell filter-cell\"\n [style.backgroundColor]=\"headerBackgroundColor\"\n [style.width.px]=\"col.width\"\n [style.min-width.px]=\"col.width\"\n [style.height.px]=\"headerRowHeight\"\n [style.min-height.px]=\"headerRowHeight\"\n [style.max-height.px]=\"headerRowHeight\"\n >\n <input\n type=\"text\"\n class=\"form-control form-control-sm\"\n placeholder=\"Filter\"\n [(ngModel)]=\"col.filterValue\"\n />\n <span\n class=\"filter-icon-wrapper\"\n (click)=\"activeFilterCell = col; activeCol = null\"\n ><span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span\n ></span>\n\n <div\n class=\"position-absolute\"\n *ngIf=\"activeFilterCell === col\"\n style=\"top: 100%; right: 0; z-index: 10; left: 0\"\n ></div>\n </div>\n </div>\n</ng-template>\n\n<ng-template #tableLayout>\n <div\n (click)=\"$event.stopPropagation()\"\n class=\"p-3 shadow rounded-3 bg-white actions-dropdown mt-1 dropdown-menu show shadow custom-menu table-layout\"\n style=\"width: 320px\"\n >\n <div class=\"d-flex align-items-center mb-3\">\n <button\n class=\"btn btn-link p-0\"\n style=\"margin-left: -10px\"\n (click)=\"toggleActions('setting')\"\n >\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrow-left.svg'\"\n class=\"data-grid-svg-icon me-2\"\n ></span>\n </button>\n <h6 class=\"mb-0 ms-2\" style=\"font-weight: 500\">Table Layout</h6>\n </div>\n <hr class=\"my-2\" />\n <div class=\"w-100 mb-3 d-flex\" role=\"group\">\n <input\n type=\"radio\"\n class=\"btn-check layout-button-check\"\n name=\"layoutSize\"\n id=\"small\"\n autocomplete=\"off\"\n (change)=\"changeTableLayout($event, 'small')\"\n [checked]=\"selectedTableLayout == 'small'\"\n />\n <label\n class=\"border d-flex flex-column align-items-center layout-button\"\n for=\"small\"\n [ngStyle]=\"{\n color: selectedTableLayout == 'small' ? '#000' : '#727272'\n }\"\n >\n <div class=\"preview-box border mb-1\" style=\"height: 8px\"></div>\n Small\n </label>\n\n <input\n type=\"radio\"\n class=\"btn-check layout-button-check\"\n name=\"layoutSize\"\n id=\"medium\"\n autocomplete=\"off\"\n [checked]=\"selectedTableLayout == 'medium'\"\n (change)=\"changeTableLayout($event, 'medium')\"\n />\n <label\n class=\"border mx-3 d-flex flex-column align-items-center layout-button\"\n for=\"medium\"\n [ngStyle]=\"{\n color: selectedTableLayout == 'medium' ? '#000' : '#727272'\n }\"\n >\n <div class=\"preview-box border mb-1\" style=\"height: 12px\"></div>\n Medium\n </label>\n\n <input\n type=\"radio\"\n class=\"btn-check layout-button-check\"\n name=\"layoutSize\"\n id=\"large\"\n autocomplete=\"off\"\n (change)=\"changeTableLayout($event, 'large')\"\n [checked]=\"selectedTableLayout == 'large'\"\n />\n <label\n class=\"border d-flex flex-column align-items-center layout-button\"\n for=\"large\"\n [ngStyle]=\"{\n color: selectedTableLayout == 'large' ? '#000' : '#727272'\n }\"\n >\n <div class=\"preview-box border mb-1\" style=\"height: 16px\"></div>\n Large\n </label>\n </div>\n\n <hr class=\"my-2\" />\n <div class=\"d-flex justify-content-between align-items-center mb-2\">\n <span>Show separators</span>\n <div class=\"form-check form-switch m-0\">\n <input\n class=\"form-check-input\"\n type=\"checkbox\"\n id=\"separators\"\n [(ngModel)]=\"showVerticalBorder\"\n (change)=\"emitConfigUpdate()\"\n />\n </div>\n </div>\n <div class=\"d-flex justify-content-between align-items-center\">\n <span>Row shading</span>\n <div class=\"form-check form-switch m-0\">\n <input\n class=\"form-check-input\"\n [(ngModel)]=\"rowShadingEnabled\"\n (change)=\"toggleRowShading()\"\n type=\"checkbox\"\n id=\"rowShading\"\n />\n </div>\n </div>\n </div>\n</ng-template>\n\n<ng-template #tablePreset>\n <div\n *ngIf=\"activeSubButton !== 'save-preset'\"\n (click)=\"$event.stopPropagation();\"\n class=\"p-3 shadow rounded-3 bg-white actions-dropdown mt-1 dropdown-menu show shadow custom-menu table-layout\"\n style=\"width: 280px\"\n >\n <!-- Header -->\n <div class=\"d-flex justify-content-between align-items-center mb-3\">\n <div class=\"d-flex align-items-center\">\n <button\n class=\"btn btn-link p-0\"\n style=\"margin-left: -10px\"\n (click)=\"toggleActions('setting')\"\n >\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrow-left.svg'\"\n class=\"data-grid-svg-icon\"\n ></span>\n </button>\n <h6 class=\"mb-0 ms-2\" style=\"font-weight: 500\">Table Presets</h6>\n </div>\n <!-- Save/Update Preset Button -->\n <div>\n <a\n class=\"text-decoration-none btn btn-link\"\n type=\"button\"\n id=\"savePresetDropdown\"\n (click)=\"$event.stopPropagation(); toggleSubActions('save-preset')\"\n >\n {{ tableFilterViewId && tableFilterViewId !== 'default' ? 'Update Preset' : 'Save Preset' }}\n </a>\n </div>\n </div>\n\n <!-- Search -->\n <div class=\"mb-3\">\n <div class=\"col-12 global-search\">\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/search.svg'\"\n class=\"data-grid-svg-icon mx-2 position-absolute icon\"\n ></span>\n <input\n class=\"form-control form-control-sm\"\n placeholder=\"Search...\"\n [(ngModel)]=\"searchTextPresetTable\"\n type=\"search\"\n />\n </div>\n </div>\n\n <!-- Preset List -->\n <ng-container\n *ngIf=\"\n tableView | filter : searchTextPresetTable : 'name' as filteredList\n \"\n >\n <!-- If filteredList exists and none is default -> show fallback -->\n <div class=\"\" (click)=\"selectDefault()\">\n <div class=\"fw-semibold\">Default View\n <span\n *ngIf=\"tableFilterViewId === 'default'\"\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/check-blue.svg'\"\n class=\"me-2\"\n ></span>\n </div>\n </div>\n <div class=\"d-flex justify-content-between\">\n <small class=\"text-dark\">Created by system</small>\n <span\n *ngIf=\"tableFilterViewId === 'default'\"\n class=\"badge bg-light text-primary ms-2\"\n >Default</span\n >\n <div\n class=\"dropdown d-flex justify-content-end\"\n *ngIf=\"tableFilterViewId\"\n >\n <a\n href=\"javascript:void(0)\"\n class=\"muted-text\"\n data-bs-toggle=\"dropdown\"\n >\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/horizontal-dots.svg'\n \"\n class=\"me-2\"\n ></span>\n </a>\n <ul class=\"dropdown-menu dropdown-menu-end\">\n <a\n (click)=\"actionPreset({ id: 'default' }, 'setPreset')\"\n class=\"dropdown-item d-flex align-items-center\"\n >\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/star.svg'\"\n class=\"me-2\"\n ></span>\n Set as default\n </a>\n </ul>\n </div>\n </div>\n\n <!-- The list: render each table from filteredList -->\n <div\n class=\"list-group list-group-flush\"\n *ngFor=\"let table of filteredList; trackBy: trackByTable\"\n >\n <!-- Item -->\n <div\n class=\"list-group-item px-0 d-flex justify-content-between align-items-center\"\n >\n <div (click)=\"selectFilter(table)\">\n <div class=\"fw-semibold\" style=\"cursor: pointer;\">\n {{ table?.name }}\n <!-- {{table?.is_temp}} -->\n <span\n *ngIf=\"table?.is_temp\"\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/check-blue.svg'\n \"\n class=\"me-2\"\n ></span>\n <span\n *ngIf=\"table?.is_default\"\n class=\"badge bg-light text-primary ms-2\"\n >Default</span\n >\n </div>\n <small class=\"text-dark\"\n >Created {{ table?.createdAt | timezoneFormat:prefs:'date' }}</small\n >\n </div>\n\n <div class=\"d-flex align-items-center\">\n <span\n *ngIf=\"table?.is_default\"\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/check-blue.svg'\n \"\n class=\"me-2\"\n ></span>\n\n <div class=\"dropdown position-relative\" *ngIf=\"!table?.is_default\">\n <a href=\"javascript:void(0)\" class=\"muted-text\" (click)=\"togglePresetDropdown(table.id)\">\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/horizontal-dots.svg'\" class=\"me-2\"></span>\n </a>\n\n <div\n *ngIf=\"activePresetDropdownId === table.id\"\n class=\"dropdown-menu dropdown-menu-end show position-absolute\"\n style=\"z-index: 1000; top: 100%; right: 0; min-width: 180px\"\n (click)=\"$event.stopPropagation()\"\n >\n <a\n [class.d-none]=\"confirmDeletePresetId === table.id\"\n (click)=\"setPresetAsDefault(table); activePresetDropdownId = null;\"\n class=\"dropdown-item d-flex align-items-center\"\n >\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/star.svg'\" class=\"me-2\"></span>\n Set as default\n </a>\n\n <ng-container *ngIf=\"confirmDeletePresetId !== table.id; else confirmBlock\">\n <a\n (click)=\"confirmDeletePresetId = table.id\"\n class=\"dropdown-item d-flex align-items-center text-danger\"\n >\n <span style=\"margin-top: -4px\" [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/trash-red.svg'\" class=\"me-2\"></span>\n Delete\n </a>\n </ng-container>\n\n <ng-template #confirmBlock>\n <div class=\"dropdown-item\"><b>Delete preset</b></div>\n <div class=\"dropdown-item text-center\">\n <div class=\"mb-2\">\n Are you sure you want to delete the <br />\n <b>\u201C{{ table?.name }}\u201D</b> preset?\n </div>\n <button\n class=\"btn btn-sm btn-light me-2\"\n (click)=\"confirmDeletePresetId = null\"\n >\n Cancel\n </button>\n <button\n class=\"btn btn-sm btn-danger delete-preset\"\n (click)=\"actionPreset(table, 'deletePreset'); confirmDeletePresetId = null; activePresetDropdownId = null;\"\n >\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/trash-red.svg'\" class=\"confirm-preset-delete\"></span>\n Delete\n </button>\n </div>\n </ng-template>\n </div>\n</div>\n </div>\n </div>\n <!-- Item End Here -->\n </div>\n\n </ng-container>\n </div>\n\n <div\n (click)=\"$event.stopPropagation()\"\n *ngIf=\"activeSubButton == 'save-preset'\"\n class=\"dropdown-menu p-3 badge mt-4 save-preset-dropdown mt-1\"\n aria-labelledby=\"savePresetDropdown\"\n style=\"min-width: 250px\"\n >\n <div class=\"fw-bold fs-14px mb-2\">Save preset</div>\n <div class=\"fs-14px mb-2\" style=\"line-height: 20px\">\n This will save the current table adjustments as a preset.\n </div>\n <!-- Input -->\n <div class=\"mb-2\">\n <label for=\"presetName\" class=\"form-label fs-12px fw-bold\"\n >Preset Name</label\n >\n <div class=\"col-12 global-search\">\n <input\n #presetNameCtrl=\"ngModel\"\n required\n [(ngModel)]=\"presetName\"\n [ngClass]=\"{\n 'is-invalid':\n presetNameCtrl.invalid &&\n (presetNameCtrl.dirty || presetNameCtrl.touched)\n }\"\n class=\"form-control form-control-sm ps-2\"\n placeholder=\"Enter preset name\"\n type=\"text\"\n />\n </div>\n </div>\n\n <!-- Checkbox -->\n <div class=\"form-check mb-2\">\n <input\n class=\"form-check-input\"\n [(ngModel)]=\"presetFilter\"\n type=\"checkbox\"\n id=\"saveFilters\"\n />\n <label class=\"form-check-label mt-1\" for=\"saveFilters\">\n Save active filters\n </label>\n </div>\n\n <!-- Save Button -->\n <div class=\"d-flex justify-content-center gap-2\" style=\"height: 32px\">\n <button\n type=\"button\"\n style=\"height: 32px\"\n class=\"btn border w-100 d-flex align-items-center justify-content-center btn-light\"\n (click)=\"$event.stopPropagation(); toggleActions('table-presets')\"\n style=\"margin-top: -2px\"\n >\n <span>Cancel</span>\n </button>\n <button\n [disabled]=\"closeDropdown.preset.loading\"\n (click)=\"savePreset(presetNameCtrl)\"\n type=\"button\"\n style=\"height: 32px\"\n class=\"btn btn-primary w-100 d-flex align-items-center justify-content-center\"\n >\n <span style=\"margin-top: -2px\">\n <ng-container *ngIf=\"!closeDropdown.preset.loading && (!tableFilterViewId || tableFilterViewId === 'default')\"\n >Save</ng-container\n >\n <ng-container *ngIf=\"!closeDropdown.preset.loading && tableFilterViewId && tableFilterViewId !== 'default'\"\n >Update</ng-container\n >\n <ng-container *ngIf=\"closeDropdown.preset.loading\"\n ><span class=\"spinner-border spinner-border-sm\"></span\n ></ng-container>\n </span>\n </button>\n </div>\n </div>\n</ng-template>\n\n<ng-template #showHideColumns>\n <div\n (click)=\"$event.stopPropagation()\"\n class=\"p-3 shadow rounded-3 bg-white actions-dropdown mt-1 dropdown-menu show shadow custom-menu table-layout\"\n style=\"width: 280px\"\n >\n <!-- Header -->\n <div class=\"d-flex justify-content-between align-items-center mb-3\">\n <div class=\"d-flex align-items-center\">\n <button\n class=\"btn btn-link p-0\"\n style=\"margin-left: -10px\"\n (click)=\"toggleActions('setting')\"\n >\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrow-left.svg'\"\n class=\"data-grid-svg-icon\"\n ></span>\n </button>\n <h6 class=\"mb-0 ms-2\" style=\"font-weight: 500\">Columns</h6>\n </div>\n <a\n (click)=\"resetColumns()\"\n href=\"javascript:void(0)\"\n class=\"text-primary text-decoration-none\"\n >Reset</a\n >\n </div>\n\n <!-- Search -->\n <div class=\"mb-3\">\n <div class=\"col-12 global-search\">\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/search.svg'\"\n class=\"mx-2 position-absolute icon data-grid-svg-icon\"\n ></span>\n <input\n class=\"form-control form-control-sm\"\n placeholder=\"Search column\"\n type=\"search\"\n [(ngModel)]=\"topShowHideColumns\"\n />\n </div>\n </div>\n <!-- Preset List -->\n <div\n class=\"list-group list-group-flush\"\n style=\"\n max-height: calc(100vh - 300px);\n overflow: auto;\n scrollbar-width: thin;\n \"\n >\n <div class=\"muted-text show-hide-table-label d-flex justify-content-between\" *ngIf=\"hasAnyVisibleColumn\">\n Show in table\n <div class=\"form-check\">\n <input\n type=\"checkbox\"\n id=\"show_hide_all\"\n class=\"form-check-input\"\n [checked]=\"areAllNonMandatoryVisible()\"\n (change)=\"toggleAllVisibleColumns()\"\n />\n <label for=\"show_hide_all\" class=\"form-check-label fw-semibold\">Show/Hide All</label>\n </div>\n </div>\n <!-- <div class=\"d-flex align-items-center mb-2\" *ngIf=\"hasAnyVisibleColumn\">\n <input\n type=\"checkbox\"\n class=\"form-check-input me-2\"\n [checked]=\"areAllNonMandatoryVisible()\"\n (change)=\"toggleAllVisibleColumns()\"\n />\n <label class=\"form-check-label fw-semibold\">Show All</label>\n </div> -->\n <!-- Item -->\n <ng-container\n *ngFor=\"\n let col of columns | filter : topShowHideColumns : 'header';\n trackBy: trackByField\n \"\n >\n <div\n *ngIf=\"col.is_visible\"\n class=\"list-group-item border-0 px-0 d-flex justify-content-between align-items-center\"\n >\n <div class=\"d-flex gap-1\">\n <div>\n <span\n *ngIf=\"!col?.pinned\"\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/grip-vertical.svg'\n \"\n class=\"cursor-grap data-grid-svg-icon\"\n (mousedown)=\"$event.preventDefault()\"\n ></span>\n <span\n *ngIf=\"col?.pinned\"\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/pin-blue.svg'\n \"\n class=\"cursor-grap data-grid-svg-icon\"\n (mousedown)=\"$event.preventDefault()\"\n ></span>\n </div>\n <div class=\"fw-semibold\">\n {{ col.header }}\n </div>\n </div>\n <div\n *ngIf=\"!col?.query?.first_value && !col?.query?._ids?.length && !isMandatory(col)\"\n class=\"d-flex align-items-center cursor-pointer\"\n (click)=\"toggleColumnVisibility(col, false)\"\n >\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/eye.svg'\"\n class=\"data-grid-svg-icon me-2\"\n ></span>\n </div>\n <div\n *ngIf=\"(!col?.query?.first_value && !col?.query?._ids?.length && isMandatory(col)) || (col?.query?.first_value || col?.query?._ids?.length)\"\n class=\"d-flex align-items-center\"\n style=\"opacity: 0.5\"\n >\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/eye.svg'\"\n class=\"data-grid-svg-icon me-2\"\n ></span>\n </div>\n </div>\n </ng-container>\n\n <!-- Item End Here -->\n\n <div\n class=\"dropdown-divider\"\n *ngIf=\"hasAnyVisibleColumn && hasAnyInVisibleColumn\"\n ></div>\n\n <!-- <div\n class=\"muted-text show-hide-table-label\"\n *ngIf=\"hasAnyInVisibleColumn\"\n >\n Hide in table\n </div>\n <div class=\"d-flex align-items-center mb-2\" *ngIf=\"hasAnyInVisibleColumn\">\n <input\n type=\"checkbox\"\n id=\"hide_show_all\"\n class=\"form-check-input me-2\"\n [checked]=\"areAllNonMandatoryHidden()\"\n (change)=\"toggleAllInvisibleColumns()\"\n />\n <label class=\"form-check-label fw-semibold\">Hide All</label>\n </div> -->\n\n \n\n\n\n <div class=\"muted-text show-hide-table-label d-flex justify-content-between\" *ngIf=\"hasAnyInVisibleColumn\">\n Hide in table\n <div class=\"form-check\">\n <input\n type=\"checkbox\"\n id=\"hide_show_all\"\n class=\"form-check-input\"\n [checked]=\"areAllNonMandatoryHidden()\"\n (change)=\"toggleAllInvisibleColumns()\"\n />\n <label for=\"hide_show_all\" class=\"form-check-label fw-semibold\">Hide/Show All</label>\n </div>\n </div>\n <div class=\"list-group list-group-flush\">\n <ng-container *ngFor=\"let col of columns; trackBy: trackByField\">\n <div\n *ngIf=\"!col.is_visible\"\n class=\"list-group-item border-0 px-0 d-flex justify-content-between align-items-center\"\n >\n <div class=\"d-flex gap-1\">\n <div>\n <span\n *ngIf=\"!col?.pinned\"\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/grip-vertical.svg'\n \"\n class=\"data-grid-svg-icon cursor-grap\"\n (mousedown)=\"$event.preventDefault()\"\n ></span>\n <span\n *ngIf=\"col?.pinned\"\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/pin-blue.svg'\n \"\n class=\"data-grid-svg-icon cursor-grap\"\n (mousedown)=\"$event.preventDefault()\"\n ></span>\n </div>\n <div class=\"fw-semibold\">\n {{ col.header }}\n </div>\n </div>\n <div\n class=\"d-flex align-items-center cursor-pointer\"\n (click)=\"toggleColumnVisibility(col, true)\"\n >\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/eye-cross.svg'\n \"\n class=\"data-grid-svg-icon me-2\"\n ></span>\n </div>\n </div>\n </ng-container>\n </div>\n\n <!-- Item End Here -->\n </div>\n </div>\n</ng-template>\n\n<ng-template #filterColumns let-col=\"column\">\n <div\n @slideToggle\n *ngIf=\"!isFilterOpen && activeTopButton == 'filter-columns'\"\n (click)=\"$event.stopPropagation()\"\n class=\"shadow rounded-3 bg-white actions-dropdown mt-1 show shadow custom-menu table-layout filter-columns\"\n style=\"width: 280px; right: unset; max-width: 230px\"\n >\n <div class=\"mb-2 px-3\">\n <div class=\"col-12 global-search\">\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/search.svg'\"\n class=\"data-grid-svg-icon mx-2 position-absolute icon\"\n ></span>\n <input\n class=\"form-control form-control-sm\"\n placeholder=\"Filter by\"\n type=\"search\"\n [(ngModel)]=\"addFilterColumnInput\"\n />\n </div>\n </div>\n <div\n class=\"list-group list-group-flush\"\n style=\"max-height: calc(100vh - 500px); overflow: auto\"\n >\n <ng-container\n *ngFor=\"\n let col of columns | filter : addFilterColumnInput : 'header';\n trackBy: trackByField\n \"\n >\n <div\n (click)=\"openFilter(col)\"\n *ngIf=\"\n col.is_visible &&\n !col?.query?.first_value &&\n !col?.query?._ids?.length\n \"\n class=\"list-group-item border-0 px-0 d-flex justify-content-between align-items-center dropdown-item cursor-pointer\"\n >\n <div class=\"d-flex gap-1\">\n <div style=\"margin-top: -3px\"></div>\n <div class=\"fw-semibold\">\n {{ col.header }}\n </div>\n </div>\n </div>\n </ng-container>\n </div>\n </div>\n\n <!-- Dropdown -->\n <div\n @slideToggle\n *ngIf=\"isFilterOpen && selectedColumnForFilter.type == 'dropdown'\"\n (click)=\"$event.stopPropagation()\"\n class=\"shadow rounded-3 bg-white actions-dropdown mt-1 show shadow custom-menu table-layout filter-columns\"\n style=\"width: 280px; right: unset; max-width: 230px\"\n >\n <div class=\"px-3 my-2 border-below py-1 pb-2 mb-3 d-flex ps-1\">\n <span\n (click)=\"toggleActions('filter-columns'); isActiveFilterOpen = false\"\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrow-left.svg'\"\n class=\"data-grid-svg-icon me-2 cursor-pointer\"\n ></span\n ><b>{{ selectedColumnForFilter?.header }}</b>\n </div>\n <div class=\"mb-2 px-3\">\n <div\n class=\"col-12 global-search position-relative border rounded d-flex align-items-center flex-wrap px-2 filter-serach-inpt\"\n >\n <span\n *ngFor=\"let selected of selectedFilterOptions\"\n class=\"badge d-flex align-items-center gap-1 me-1 mb-1\"\n >\n {{ selected?.value ? selected.value : selected }}\n <span\n (click)=\"toggleSelectionInFilter(selected)\"\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/cross-primary.svg'\n \"\n class=\"me-2\"\n ></span>\n </span>\n <input\n class=\"form-control form-control-sm border-0 flex-grow-1\"\n style=\"padding: 0\"\n [placeholder]=\"selectedFilterOptions!.length ? '' : 'Filter by'\"\n type=\"search\"\n [(ngModel)]=\"searchTextForFilterDropDown\"\n (keydown.backspace)=\"handleBackspace($event)\"\n (ngModelChange)=\"selectedFilterOptions.length === 0 ? condition = 'none' : null\"\n />\n </div>\n </div>\n <div\n class=\"list-group list-group-flush\"\n style=\"max-height: calc(100vh - 600px); overflow: auto\"\n >\n <ng-container\n *ngFor=\"\n let col of selectedColumnForFilter.column_dropdown_value\n | filter : searchTextForFilterDropDown : 'value';\n let i = index\n \"\n >\n <div\n class=\"list-group-item border-0 px-2 d-flex justify-content-between align-items-center dropdown-item cursor-pointer\"\n >\n <div class=\"form-check\">\n <input\n class=\"form-check-input\"\n type=\"checkbox\"\n [id]=\"i\"\n [checked]=\"currentFilterSelectedIds.has(col.id || col._id || col)\"\n (change)=\"toggleSelectionInFilter(col)\"\n />\n <label class=\"form-check-label fw-semibold\" [for]=\"i\">\n {{ col?.value || col?.name || col }}\n </label>\n </div>\n </div>\n </ng-container>\n </div>\n <div\n class=\"d-flex justify-content-center gap-2 px-2 border-top\"\n style=\"height: 38px\"\n >\n <button\n type=\"button\"\n style=\"height: 32px\"\n class=\"btn btn-outline-secondary btn-light border w-100 d-flex align-items-center justify-content-center mt-1 btn-light\"\n (click)=\"$event.stopPropagation(); resetFilterChanges()\"\n >\n <span>Cancel</span>\n </button>\n <button\n type=\"button\"\n style=\"height: 32px\"\n class=\"btn btn-primary w-100 d-flex align-items-center justify-content-center mt-1\"\n (click)=\"applyDropdownFilter()\"\n >\n <span style=\"margin-top: -2px\">Save</span>\n </button>\n </div>\n </div>\n\n <!-- For Text fields and number fields-->\n\n <div\n @slideToggle\n *ngIf=\"\n isFilterOpen &&\n (selectedColumnForFilter.type == 'string' ||\n selectedColumnForFilter.type == 'number' ||\n selectedColumnForFilter.type == 'date')\n \"\n (click)=\"$event.stopPropagation()\"\n class=\"shadow rounded-3 bg-white actions-dropdown mt-1 show shadow custom-menu table-layout filter-columns\"\n style=\"width: 280px; right: unset; max-width: 230px\"\n >\n <div class=\"px-3 border-below py-1 pb-2 d-flex ps-1\">\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrow-left.svg'\"\n (click)=\"toggleActions('filter-columns'); isActiveFilterOpen = false\"\n class=\"data-grid-svg-icon me-2 cursor-pointer\"\n ></span\n ><b>{{ selectedColumnForFilter?.header }}</b>\n </div>\n <div class=\"col-12 position-relative p-2 text-filter\">\n <div class=\"mb-2\">\n <select\n class=\"form-select form-select-sm custom-select\"\n [(ngModel)]=\"firstCondition\"\n >\n <ng-container *ngIf=\"selectedColumnForFilter.type === 'date' || selectedColumnForFilter.type === 'time'; else textOptions\">\n <option value=\"equal\">Equal to</option>\n <option value=\"not_equal\">Not Equal</option>\n <option value=\"after\">After</option>\n <option value=\"before\">Before</option>\n </ng-container>\n <ng-template #textOptions>\n <option value=\"equal\">Equals</option>\n <!-- <option value=\"not_equal\">Not Equals</option> -->\n <option value=\"contain\">Contains</option>\n <option value=\"before\">Begins With</option>\n <option value=\"after\">Ends With</option>\n </ng-template>\n </select>\n </div>\n <div class=\"mb-2\">\n <input\n class=\"form-control form-control-sm\"\n placeholder=\"Enter first value\"\n [type]=\"\n selectedColumnForFilter.type == 'string'\n ? 'text'\n : selectedColumnForFilter.type\n \"\n [(ngModel)]=\"firstValue\"\n [min]=\"selectedColumnForFilter.type == 'number' ? 0 : null\"\n [class.number-input]=\"selectedColumnForFilter.type == 'number'\"\n (input)=\"selectedColumnForFilter.type == 'number' && $any($event.target).value < 0 ? $any($event.target).value = 0 : null\"\n (ngModelChange)=\"!firstValue ? condition = 'none' : null\"\n (keydown)=\"selectedColumnForFilter.type == 'number' && $event.key === '-' ? $event.preventDefault() : null\"\n />\n </div>\n <div class=\"d-flex my-3\">\n <div class=\"form-check form-check-inline\">\n <input\n class=\"form-check-input\"\n type=\"radio\"\n id=\"logicalAnd\"\n name=\"logicalOperator\"\n value=\"and\"\n [(ngModel)]=\"condition\"\n />\n <label class=\"form-check-label\" for=\"logicalAnd\">AND</label>\n </div>\n\n <div class=\"form-check form-check-inline\">\n <input\n class=\"form-check-input\"\n type=\"radio\"\n id=\"logicalOr\"\n name=\"logicalOperator\"\n value=\"or\"\n [(ngModel)]=\"condition\"\n />\n <label class=\"form-check-label\" for=\"logicalOr\">OR</label>\n </div>\n\n <div class=\"form-check form-check-inline\">\n <input\n class=\"form-check-input\"\n type=\"radio\"\n id=\"logicalNone\"\n name=\"logicalOperator\"\n value=\"none\"\n [(ngModel)]=\"condition\"\n />\n <label class=\"form-check-label\" for=\"logicalNone\">None</label>\n </div>\n </div>\n\n <div *ngIf=\"firstValue && condition !== 'none'\">\n <div class=\"my-3\">\n <!-- Second condition select -->\n <select\n class=\"form-select form-select-sm\"\n [(ngModel)]=\"secondCondition\"\n >\n <ng-container *ngIf=\"selectedColumnForFilter.type === 'date' || selectedColumnForFilter.type === 'time'; else textOptionsSecond\">\n <option value=\"equal\">Equal to</option>\n <option value=\"not_equal\">Not Equal</option>\n <option value=\"after\">After</option>\n <option value=\"before\">Before</option>\n </ng-container>\n <ng-template #textOptionsSecond>\n <option value=\"equal\">Equals</option>\n <!-- <option value=\"not_equal\">Not Equals</option> -->\n <option value=\"contain\">Contains</option>\n <option value=\"before\">Begins With</option>\n <option value=\"after\">Ends With</option>\n </ng-template>\n </select>\n </div>\n\n <div class=\"mb-2\">\n <!-- Second value input -->\n <input\n [type]=\"\n selectedColumnForFilter.type == 'string'\n ? 'text'\n : selectedColumnForFilter.type\n \"\n class=\"form-control form-control-sm\"\n placeholder=\"Enter second value\"\n [(ngModel)]=\"secondValue\"\n [min]=\"selectedColumnForFilter.type == 'number' ? 0 : null\"\n [class.number-input]=\"selectedColumnForFilter.type == 'number'\"\n (input)=\"selectedColumnForFilter.type == 'number' && $any($event.target).value < 0 ? $any($event.target).value = 0 : null\"\n (keydown)=\"selectedColumnForFilter.type == 'number' && $event.key === '-' ? $event.preventDefault() : null\"\n />\n </div>\n </div>\n </div>\n\n <div\n class=\"d-flex justify-content-center gap-2 px-2 border-top\"\n style=\"height: 38px\"\n >\n <button\n type=\"button\"\n style=\"height: 32px\"\n class=\"btn btn-outline-secondary btn-light border w-100 d-flex align-items-center justify-content-center mt-1 btn-light\"\n (click)=\"$event.stopPropagation(); resetTextFilterChanges()\"\n >\n <span>Cancel</span>\n </button>\n <button\n type=\"button\"\n style=\"height: 32px\"\n class=\"btn btn-primary w-100 d-flex align-items-center justify-content-center mt-1\"\n (click)=\"applyDropdownFilter()\"\n >\n <span style=\"margin-top: -2px\">Save</span>\n </button>\n </div>\n </div>\n</ng-template>\n\n<!-- Detail Filter Menu -->\n <div\n *ngIf=\"activeAccordionFilterMenu && detailFilterMenuPosition\"\n class=\"detail-filter-menu\"\n [style.backgroundColor]=\"dropdownsBackgroundColor\"\n [style.left.px]=\"detailFilterMenuPosition.x\"\n [style.top.px]=\"detailFilterMenuPosition.y\"\n (click)=\"$event.stopPropagation()\"\n >\n <div class=\"px-3 border-below py-1 pb-2 d-flex ps-1\">\n <span\n (click)=\"closeDetailFilterMenu()\"\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrow-left.svg'\"\n class=\"data-grid-svg-icon me-2 cursor-pointer\"\n ></span\n ><b>{{ activeDetailFilterCol?.header }}</b>\n </div>\n\n <!-- Text Filter -->\n <div *ngIf=\"detailFilterType === 'string'\" class=\"col-12 position-relative p-2 text-filter\">\n <div class=\"mb-2\">\n <select\n class=\"form-select form-select-sm custom-select\"\n [(ngModel)]=\"detailFilterCondition\"\n >\n <option value=\"contain\">Contains</option>\n <option value=\"equal\">Equals</option>\n <option value=\"before\">Begins With</option>\n <option value=\"after\">Ends With</option>\n </select>\n </div>\n <div class=\"mb-2\">\n <input\n class=\"form-control form-control-sm\"\n placeholder=\"Enter value\"\n [(ngModel)]=\"detailFilterValue\"\n (keydown.enter)=\"applyDetailFilter()\"\n />\n </div>\n </div>\n\n <!-- Date Filter -->\n <div *ngIf=\"detailFilterType === 'date'\" class=\"col-12 position-relative p-2 text-filter\">\n <div class=\"mb-2\">\n <select\n class=\"form-select form-select-sm custom-select\"\n [(ngModel)]=\"detailFilterCondition\"\n >\n <option value=\"equal\">Equal to</option>\n <option value=\"before\">Before</option>\n <option value=\"after\">After</option>\n </select>\n </div>\n <div class=\"mb-2\">\n <input\n type=\"date\"\n class=\"form-control form-control-sm\"\n placeholder=\"Select date\"\n [(ngModel)]=\"detailFilterDateValue\"\n (keydown.enter)=\"applyDetailFilter()\"\n />\n <small class=\"text-muted d-block mt-1\">{{ detailFilterDateValue | timezoneFormat:prefs:'date' }}</small>\n </div>\n </div>\n\n <!-- Time Filter -->\n <div *ngIf=\"detailFilterType === 'time'\" class=\"col-12 position-relative p-2 text-filter\">\n <div class=\"mb-2\">\n <select\n class=\"form-select form-select-sm custom-select\"\n [(ngModel)]=\"detailFilterCondition\"\n >\n <option value=\"equal\">Equal to</option>\n <option value=\"before\">Before</option>\n <option value=\"after\">After</option>\n </select>\n </div>\n <div class=\"mb-2\">\n <input\n type=\"time\"\n class=\"form-control form-control-sm\"\n placeholder=\"Select time\"\n [(ngModel)]=\"detailFilterTimeValue\"\n (keydown.enter)=\"applyDetailFilter()\"\n />\n </div>\n </div>\n\n <!-- Dropdown Filter -->\n <div *ngIf=\"detailFilterType === 'dropdown'\" class=\"col-12 position-relative p-2 text-filter\">\n <div class=\"mb-2\">\n <input\n type=\"text\"\n class=\"form-control form-control-sm\"\n placeholder=\"Search options...\"\n [(ngModel)]=\"detailFilterSearch\"\n (input)=\"filterDetailDropdownOptions()\"\n />\n </div>\n <div class=\"dropdown-options\" style=\"max-height: 150px; overflow-y: auto;\">\n <div\n *ngFor=\"let option of filteredDetailDropdownOptions; let i = index\"\n class=\"form-check mb-1 ms-1\"\n >\n <input\n class=\"form-check-input\"\n type=\"checkbox\"\n [id]=\"'detail-filter-option-' + i\"\n [checked]=\"detailSelectedFilterOptions.includes(option._id || option.id || option.value)\"\n (change)=\"toggleDetailFilterOption(option)\"\n />\n <label\n class=\"form-check-label\"\n [for]=\"'detail-filter-option-' + i\"\n >\n {{ option.value || option.name || option }}\n </label>\n </div>\n </div>\n </div>\n\n <!-- <div class=\"d-flex gap-2\">\n <button\n type=\"button\"\n class=\"btn btn-primary w-100 d-flex align-items-center justify-content-center mt-1\"\n (click)=\"applyDetailFilter()\"\n >\n <span>Apply</span>\n </button>\n <button\n type=\"button\"\n class=\"btn btn-danger w-100 d-flex align-items-center justify-content-center mt-1\"\n (click)=\"resetDetailFilter()\"\n >\n <span>Reset</span>\n </button>\n \n</div> -->\n\n <div class=\"d-flex gap-2 mt-2\">\n <div\n class=\"btn btn-sm btn-primary d-flex justify-content-center align-items-center w-100\"\n style=\"height: 22px\"\n (click)=\"applyDetailFilter()\"\n >\n Apply\n </div>\n <div\n class=\"btn btn-sm btn-secondary d-flex justify-content-center align-items-center w-100\"\n style=\"height: 22px\"\n (click)=\"resetDetailFilter()\"\n >\n Reset\n </div>\n </div>\n</div>\n\n<!-- Edit dropdown here -->\n<ng-template let-col>\n <div class=\"drop-down-edit\"></div>\n</ng-template>\n\n<ng-template\n #fullTextTemplate\n let-row=\"row\"\n let-col=\"col\"\n let-isArray=\"isArray\"\n>\n <div\n class=\"full-text-box\"\n (dblclick)=\"$event.stopPropagation(); $event.preventDefault();\"\n (click)=\"$event.stopPropagation(); $event.preventDefault()\"\n >\n <ng-container *ngIf=\"!isEditing(row, col)\">\n <div\n *ngIf=\"!isArray\"\n class=\"full-text-content\"\n (dblclick)=\"$event.stopPropagation(); $event.preventDefault(); enableEdit(row, col)\"\n (click)=\"$event.stopPropagation(); $event.preventDefault()\"\n >\n {{\n getNestedValue(row, col.field)?.value ||\n getNestedValue(row, col.field)?.name ||\n getNestedValue(row, col.field)\n }}\n </div>\n <div *ngIf=\"isArray\">\n <ul>\n <ng-container\n *ngFor=\"let item of getNestedValue(row, col.field); let i = index\"\n >\n <li *ngIf=\"i !== 0\">\n <ng-container>\n {{ item?.department_name || item?.roleName || \"-\" }}\n </ng-container>\n </li>\n </ng-container>\n </ul>\n </div>\n </ng-container>\n <ng-container *ngIf=\"isEditing(row, col)\">\n <textarea\n #textModel=\"ngModel\"\n rows=\"4\"\n #textAreadInput\n [(ngModel)]=\"row[col.field]\"\n name=\"{{ col.field }}\"\n required\n (blur)=\"disableEdit(row, col, textModel)\"\n (keydown.enter)=\"textAreadInput.blur()\"\n autofocus\n class=\"form-control\"\n [ngClass]=\"{\n 'is-invalid': textModel.invalid\n }\"\n (mousedown)=\"$event.stopPropagation()\"\n ></textarea>\n\n </ng-container>\n </div>\n</ng-template>\n\n<ng-template #defaultImagePlaceholder let-row=\"row\" let-col=\"col\">\n <span\n class=\"px-2 d-flex align-items-center w-100 cell-content image-placeholder cursor-pointer position-relative\"\n \n (click)=\"onEmployeeClick(row)\"\n >\n <!-- Blue dot for manual logs -->\n <span\n *ngIf=\"row?.manually_logs && row.manually_logs.length > 0\"\n class=\"manual-logs-indicator\"\n (mouseenter)=\"openManualLogsModal($event, row)\"\n (mouseleave)=\"closeManualLogsModal()\"\n ></span>\n <ng-container\n *ngIf=\"\n row?.User?.logo || row?.User?.profile_pictures?.length || row?.logo || row?.profile_pictures?.length || row?.assetImage || row?.invoice?.invoice_image;\n else placeholder\n \"\n >\n <span class=\"pic\">\n <img\n [width]=\"rowHeight - 12\"\n [height]=\"rowHeight - 12\"\n [src]=\"row?.User?.profile_pictures?.[4]?.path || row?.User?.logo || row?.profile_pictures?.[4]?.path || row?.logo || row?.assetImage || row?.invoice?.invoice_image\"\n alt=\"icon\"\n />\n </span>\n </ng-container>\n\n <ng-template #placeholder>\n <span\n [ngClass]=\"getDynamicClass(row?.User?.full_name || row?.full_name || row?.name)\"\n class=\"pic d-flex align-items-center rounded-circle\"\n [style.width.px]=\"rowHeight - 12\"\n [style.height.px]=\"rowHeight - 12\"\n [style.fontSize.px]=\"rowHeight / 3\"\n >\n {{ getInitials(row?.User?.full_name || row?.full_name) }}\n </span>\n </ng-template>\n </span>\n</ng-template>\n\n<!-- Cell Content Template for Card View -->\n<ng-template #cellContent let-row=\"row\" let-parentRow=\"parentRow\" let-col=\"col\">\n <ng-container [ngSwitch]=\"col.type\">\n <!-- String/Text -->\n <ng-container *ngSwitchCase=\"'string'\">\n {{ getNestedValue(row, col.field) || getNestedValue(parentRow, col.field) || '-' }}\n </ng-container>\n\n <!-- Number -->\n <ng-container *ngSwitchCase=\"'number'\">\n {{ getNestedValue(row, col.field) || getNestedValue(parentRow, col.field) || '-' }}\n </ng-container>\n\n <!-- Date -->\n <ng-container *ngSwitchCase=\"'date'\">\n {{ getNestedValue(row, col.field) || getNestedValue(parentRow, col.field) ? (getNestedValue(row, col.field) || getNestedValue(parentRow, col.field) | timezoneFormat:prefs:'date') : '-' }}\n </ng-container>\n\n <!-- Time -->\n <ng-container *ngSwitchCase=\"'time'\">\n {{ (getNestedValue(row, col.field) || getNestedValue(parentRow, col.field)) !== null && (getNestedValue(row, col.field) || getNestedValue(parentRow, col.field)) !== undefined ? ((getTimeValue(getNestedValue(row, col.field) || getNestedValue(parentRow, col.field)) | timezoneFormat:prefs:'time')) : '-' }}\n </ng-container>\n\n <!-- Boolean -->\n <ng-container *ngSwitchCase=\"'boolean'\">\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'\">\n {{ (getNestedValue(row, col.field) || getNestedValue(parentRow, col.field) === true || getNestedValue(row, col.field) || getNestedValue(parentRow, col.field) === 'true') ? 'Yes' : 'No' }}\n </span>\n </ng-container>\n\n <!-- <div *ngSwitchCase=\"'is_payroll_processed'\" class=\"d-flex justify-content-start flex-column pointer position-relative\" >\n <span class=\"popover__wrapper\" >none\n {{ row.is_payroll_processed ? 'Yes' : 'No' }}\n </span>\n </div> -->\n\n <!-- Status -->\n <ng-container *ngSwitchCase=\"'status'\">\n <span class=\"badge\" [class]=\"getStatusBadgeClass(getNestedValue(row, col.field) || getNestedValue(parentRow, col.field))\">\n {{ transformStatus(getNestedValue(row, col.field) || getNestedValue(parentRow, col.field)) || '-' }}\n </span>\n </ng-container>\n\n <!-- Array -->\n <ng-container *ngSwitchCase=\"'array'\">\n <ng-container *ngIf=\"isArray(getNestedValue(row, col.field) || getNestedValue(parentRow, col.field))\">\n <ng-container *ngIf=\"col.field === 'breaks' || col.header?.toLowerCase().includes('break')\">\n <app-badge-overflow\n [badges]=\"getBreakBadges(getNestedValue(row, col.field) || getNestedValue(parentRow, col.field) || [])\"\n [maxWidth]=\"col.width || 200\"\n (badgeMouseEnter)=\"showBreakTooltip($event.event, $event.badge.data)\"\n (badgeMouseLeave)=\"hideBreakTooltip()\"\n (overflowCountClick)=\"onBadgeOverflowCountClick(col)\">\n </app-badge-overflow>\n </ng-container>\n <ng-container *ngIf=\"!(col.field === 'breaks' || col.header?.toLowerCase().includes('break'))\">\n {{ (getNestedValue(row, col.field) || getNestedValue(parentRow, col.field) || []).length }} items\n </ng-container>\n </ng-container>\n <ng-container *ngIf=\"!isArray(getNestedValue(row, col.field) || getNestedValue(parentRow, col.field))\">\n {{ getNestedValue(row, col.field) || getNestedValue(parentRow, col.field) || '-' }}\n </ng-container>\n </ng-container>\n\n <!-- Default -->\n <ng-container *ngSwitchDefault>\n {{ getNestedValue(row, col.field) || getNestedValue(parentRow, col.field) || '-' }}\n </ng-container>\n \n </ng-container>\n</ng-template>\n\n<!-- Right Click Menue -->\n<div\n [class.invisible]=\"!positionedYet\"\n class=\"context-menu p-2\"\n *ngIf=\"actionHide && actions?.length\"\n [ngStyle]=\"{ 'top.px': yPos, 'left.px': xPos }\"\n [class.show]=\"isVisible\"\n appendTo=\"body\"\n>\n <ul>\n <li\n *ngFor=\"let action of actions\"\n class=\"rounded d-flex align-items-center\"\n (click)=\"onActionClick(action)\"\n >\n <ng-container *ngIf=\"action === 'add Leave'\">\n <i class=\"fas fa-clock me-2\"></i>\n </ng-container>\n <ng-container *ngIf=\"action !== 'add Leave'\">\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/' + action + '.svg'\"\n class=\"data-grid-svg-icon me-2\"\n ></span>\n </ng-container>\n <span class=\"text-capitalize fw-500\">{{ action }}</span>\n </li>\n </ul>\n</div>\n\n<!-- Details Toggle from bottom -->\n <div\n [style.bottom.px]=\"footerRowHeight + 50\"\n *ngIf=\"selectedRows.size > 0 && showTaskbar\"\n class=\"taskbar\"\n >\n <div class=\"selected-rows-action-bar\" [@slideUp]>\n <span class=\"selected-count\">\n {{ selectedRows.size }} selected of\n {{\n paginationConfig.totalResults ||\n config?.paginationParams?.totalItems\n }}\n Total\n </span>\n <div class=\"action-buttons\">\n <ng-container *ngFor=\"let action of computedTaskbarActions; let i = index\">\n <span\n class=\"action-btn verified btn {{ action }}\"\n (click)=\"action === 'Export' ? onExportClick() : action === 'Delete' ? onDeleteClick() : onVerifyClick(action)\"\n >{{ action }}</span\n >\n <span\n *ngIf=\"computedTaskbarActions.length > 1 && i !== computedTaskbarActions.length - 1\"\n class=\"separator\"\n >|</span\n >\n </ng-container>\n </div>\n </div>\n </div>\n\n<!-- Detail Row Choose Columns Modal -->\n<div *ngIf=\"showDetailColumnPanel\" class=\"custom-modal-overlay\" (click)=\"closeDetailColumnPanel()\">\n <div\n class=\"custom-modal-content\"\n [style.backgroundColor]=\"dropdownsBackgroundColor\"\n (click)=\"$event.stopPropagation()\"\n >\n <ng-container *ngTemplateOutlet=\"detailModalColumnPannel\"></ng-container>\n </div>\n</div>\n\n<!-- Paste Confirmation Modal -->\n<div *ngIf=\"showPasteConfirmationModal\" class=\"custom-modal-overlay\" (click)=\"cancelPaste()\">\n <div class=\"custom-modal-content\" [style.backgroundColor]=\"dropdownsBackgroundColor\" (click)=\"$event.stopPropagation()\">\n <div class=\"column-panel-header\">\n <div class=\"d-flex justify-content-between align-items-center px-2 ps-3 rounded-top-2 moda-header\" style=\"height: 48px;\">\n Confirm Paste Operation\n <span class=\"filter-icon-wrapper\" (click)=\"cancelPaste()\">\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/x.svg'\" class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"></span>\n </span>\n </div>\n <hr class=\"my-0\" />\n <div class=\"p-3\">\n <div class=\"mb-3\">\n <h6 class=\"mb-3\">You are about to paste the following data:</h6>\n <div class=\"border rounded p-3 bg-light\">\n <pre class=\"mb-0 text-dark small\">{{ pastePreviewData }}</pre>\n </div>\n </div>\n <div class=\"alert alert-warning\" role=\"alert\">\n <strong>Warning:</strong> This action will overwrite existing data in the selected cells. This cannot be undone.\n </div>\n <div class=\"d-flex justify-content-end gap-2 mt-4\">\n <button type=\"button\" class=\"btn btn-secondary\" (click)=\"cancelPaste()\">Cancel</button>\n <button type=\"button\" class=\"btn btn-primary\" (click)=\"confirmPaste()\">Confirm Paste</button>\n </div>\n </div>\n </div>\n </div>\n</div>\n\n<!-- Short Leave Tooltip Modal -->\n<div *ngIf=\"showShortLeaveTooltipModal\"\n class=\"custom-break-tooltips\"\n @tooltipAnimationBottom\n [style.--tooltip-x.px]=\"shortLeaveTooltipPosition.x\"\n [style.--tooltip-y.px]=\"shortLeaveTooltipPosition.y\"\n (mouseenter)=\"preventShortLeaveTooltipHide()\"\n (mouseleave)=\"hideShortLeaveTooltip()\">\n <div class=\"modal-body\">\n <div class=\"table-responsive\">\n <table class=\"table table-striped text-dark\">\n <thead>\n <tr>\n <th>Leave Type</th>\n <th>Start Time</th>\n <th>End Time</th>\n <th>Duration (min)</th>\n </tr>\n </thead>\n <tbody>\n <tr *ngFor=\"let item of currentShortLeaveData\">\n <td>{{ item.leave_type || 'N/A' }}</td>\n\n <!-- Start Time -->\n <td>\n {{\n item.star_time\n ? (getTimeValue(item.star_time) | timezoneFormat:prefs:'time')\n : 'N/A'\n }}\n </td>\n\n <!-- End Time -->\n <td>\n {{\n item.end_time\n ? (getTimeValue(item.end_time) | timezoneFormat:prefs:'time')\n : 'N/A'\n }}\n </td>\n\n <td>{{ item.minutes || 'N/A' }}</td>\n</tr>\n\n </tbody>\n </table>\n </div>\n </div>\n </div>\n\n<!-- Paste Confirmation Modal -->\n<div *ngIf=\"showPasteConfirmationModal\" class=\"custom-modal-overlay\" (click)=\"cancelPaste()\">\n <div class=\"custom-modal-content\" [style.backgroundColor]=\"dropdownsBackgroundColor\" (click)=\"$event.stopPropagation()\">\n <div class=\"column-panel-header\">\n <div class=\"d-flex justify-content-between align-items-center px-2 ps-3 rounded-top-2 moda-header\" style=\"height: 48px;\">\n <span class=\"fw-bold\">Confirm Paste</span>\n <span class=\"filter-icon-wrapper\" (click)=\"cancelPaste()\">\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/x.svg'\" class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"></span>\n </span>\n </div>\n <hr class=\"my-0\" />\n <div class=\"p-3\">\n <div class=\"mb-3\">\n <p class=\"mb-2\">Are you sure you want to paste the following data?</p>\n <div class=\"border rounded p-2 bg-light\">\n <small class=\"text-muted\">{{ pastePreviewData }}</small>\n </div>\n </div>\n <div class=\"d-flex gap-2 justify-content-end\">\n <button type=\"button\" class=\"btn btn-secondary\" (click)=\"cancelPaste()\">Cancel</button>\n <button type=\"button\" class=\"btn btn-primary\" (click)=\"confirmPaste()\">Confirm Paste</button>\n </div>\n </div>\n </div>\n </div>\n</div>\n\n<!-- Paste Confirmation Modal -->\n<div *ngIf=\"showPasteConfirmationModal\" class=\"custom-modal-overlay\" (click)=\"cancelPaste()\">\n <div class=\"custom-modal-content\" [style.backgroundColor]=\"dropdownsBackgroundColor\" (click)=\"$event.stopPropagation()\">\n <div class=\"modal-header d-flex justify-content-between align-items-center p-3\">\n <h5 class=\"modal-title mb-0\">Confirm Paste</h5>\n <button type=\"button\" class=\"btn-close\" (click)=\"cancelPaste()\"></button>\n </div>\n <div class=\"modal-body p-3\">\n <p class=\"mb-3\">Are you sure you want to paste the clipboard data into the selected cells?</p>\n <div class=\"alert alert-info\" *ngIf=\"pastePreviewData\">\n <strong>Paste Preview:</strong>\n <pre class=\"mt-2\">{{ pastePreviewData }}</pre>\n </div>\n </div>\n <div class=\"modal-footer p-3\">\n <button type=\"button\" class=\"btn btn-secondary\" (click)=\"cancelPaste()\">Cancel</button>\n <button type=\"button\" class=\"btn btn-primary\" (click)=\"confirmPaste()\">Paste</button>\n </div>\n </div>\n</div>\n\n<!-- Tooltip for accordion manual logs -->\n<!-- Tooltip for accordion manual logs -->\n<div *ngIf=\"showManualLogsTooltipModal\" class=\"custom-break-tooltips\"\n [style.--tooltip-x.px]=\"manualLogsTooltipPosition.x\"\n [style.--tooltip-y.px]=\"manualLogsTooltipPosition.y\"\n \n (mouseenter)=\"preventManualLogsTooltipHide()\"\n (mouseleave)=\"hideManualLogsTooltip()\">\n\n <div class=\"modal-body\">\n <div class=\"table-responsive\">\n <table class=\"table table-striped text-dark\">\n <thead>\n <tr>\n <th>Name</th>\n <th>Date/Time</th>\n <th>Previous</th>\n <th>Updated</th>\n <th>Status</th>\n <th>Remarks</th>\n </tr>\n </thead>\n <tbody>\n <ng-container *ngFor=\"let item of selectedManualLogs; let i = index\">\n <tr>\n <td>{{ item?.updated_by?.full_name || selectedManualLogsRow?.User?.full_name }}</td>\n <td>{{ item?.log_date && item.log_date !== '--' ? (item.log_date | timezoneFormat:prefs:'datetime') : (selectedManualLogsRow?.attendanceDate && selectedManualLogsRow?.attendanceDate !== '--' ? (selectedManualLogsRow?.attendanceDate | timezoneFormat:prefs:'datetime') : '-') }}</td>\n <td>\n <ng-container [ngSwitch]=\"isDate(item?.log_details?.previous_state)\">\n \n <!-- If it is a date -->\n <span *ngSwitchCase=\"true\">\n {{ formatLogState(item?.log_details?.previous_state) | timezoneFormat:prefs:'time' }}\n </span>\n\n <!-- If it is NOT a date -->\n <span *ngSwitchDefault>\n {{ item?.log_details?.previous_state || '-' }}\n </span>\n\n </ng-container>\n</td>\n\n\n<td>\n <ng-container [ngSwitch]=\"isDate(item?.log_details?.updated_state)\">\n \n <!-- If it is a date -->\n <span *ngSwitchCase=\"true\">\n {{ formatLogState(item?.log_details?.updated_state) | timezoneFormat:prefs:'time' }}\n </span>\n\n <!-- If it is NOT a date -->\n <span *ngSwitchDefault>\n {{ item?.log_details?.updated_state || '-' }}\n </span>\n\n </ng-container>\n</td>\n\n <td>{{ item?.log_details?.status ? transformStatus(item.log_details.status) : (item.log_details?.status || '-') }}</td>\n <td>{{ item?.log_details?.remarks || item?.remarks || selectedManualLogsRow?.message || '-' }}</td>\n </tr>\n </ng-container>\n\n <!-- Fallback for empty manual logs -->\n <tr *ngIf=\"!selectedManualLogs || selectedManualLogs.length === 0\">\n <td colspan=\"6\" class=\"text-center\">No manual logs available</td>\n </tr>\n </tbody>\n </table>\n </div>\n </div>\n </div>\n<!-- </div> -->\n\n<ng-template #detailModalColumnPannel>\n <div class=\"column-panel-header detail-column-modal\">\n <div\n class=\"d-flex justify-content-between align-items-center px-2 ps-3 rounded-top-2 moda-header\"\n [style.height.px]=\"48\"\n >\n Choose Detail Columns\n <span class=\"filter-icon-wrapper\" (click)=\"closeDetailColumnPanel()\">\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/x.svg'\"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n </span>\n </div>\n <hr class=\"my-0\" />\n <div>\n <div class=\"d-flex align-items-center px-2 pe-3\" [style.height.px]=\"48\">\n <input\n type=\"checkbox\"\n class=\"form-check-input me-2\"\n [checked]=\"allDetailColumnsSelected()\"\n (change)=\"toggleAllDetailColumnsVisibility()\"\n />\n <input\n type=\"text\"\n class=\"form-control form-control-sm\"\n placeholder=\"Search detail columns...\"\n [(ngModel)]=\"choseColumnsSearch\"\n />\n </div>\n <hr class=\"mt-0 mb-1\" />\n <div class=\"px-2 overlay-scrollable\">\n <ng-container\n *ngFor=\"\n let col of (currentDetailRowForColumnSelection?.details?.columns || [])\n | filter : choseColumnsSearch : 'header';\n trackBy: trackByField\n \"\n >\n <div class=\"d-flex align-items-center mb-2\">\n <input\n type=\"checkbox\"\n class=\"form-check-input me-2\"\n [checked]=\"col.is_visible !== false\"\n (change)=\"toggleDetailColumnVisibility(col, !col.is_visible)\"\n [id]=\"'detail_col_' + col.field\"\n />\n <label\n class=\"d-flex align-items-center mb-0 w-100\"\n [for]=\"'detail_col_' + col.field\"\n style=\"cursor: pointer\"\n >\n <span class=\"text-truncate\">{{ col.header }}</span>\n </label>\n </div>\n </ng-container>\n </div>\n </div>\n <!-- <div class=\"px-3 py-2 border-top d-flex justify-content-end\">\n <button class=\"btn btn-sm btn-link\" (click)=\"resetDetailColumnsInModal()\">Reset</button>\n </div> -->\n </div>\n</ng-template>\n\n\n\n\n\n\n\n\n\n\n\n", styles: ["@charset \"UTF-8\";@keyframes fadeInUp{0%{opacity:0;transform:translateY(8px)}to{opacity:1;transform:translateY(0)}}@keyframes fadeInScale{0%{opacity:0;transform:scale(.95)}to{opacity:1;transform:scale(1)}}@keyframes slideInRight{0%{opacity:0;transform:translate(16px)}to{opacity:1;transform:translate(0)}}@keyframes pulse{0%{transform:scale(1)}50%{transform:scale(1.02)}to{transform:scale(1)}}@keyframes shimmer{0%{background-position:-200px 0}to{background-position:calc(200px + 100%) 0}}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.loading-overlay{animation:fadeInScale .25s cubic-bezier(.4,0,.2,1);transform:translateZ(0)}.loading-overlay .spinner-border{animation:spin 1s linear infinite}.data-grid-table-wrapper{height:100%;width:100%;border:1px solid #d9d9db;border-radius:12px;box-shadow:none!important;position:relative;animation:fadeInScale .35s cubic-bezier(.4,0,.2,1);transform:translateZ(0)}.data-grid-table-wrapper[data-theme=white]{border-color:#d9d9db;background-color:#f6f8ff;color:#000}.data-grid-table-wrapper[data-theme=white] *,.data-grid-table-wrapper[data-theme=white] *:before,.data-grid-table-wrapper[data-theme=white] *:after{color:#000!important}.data-grid-table-wrapper[data-theme=white] ::selection{background-color:#007bff!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=white] ::-moz-selection{background-color:#007bff!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=white] .data-grid-header-wrapper{background-color:#f8f9fa;color:#000!important}.data-grid-table-wrapper[data-theme=white] .data-grid-body-wrapper{background-color:#f6f8ff;box-shadow:none!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .data-grid-row{border-bottom-color:#d9d9db;box-shadow:none!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .data-grid-row:nth-child(2n){background-color:#f8f9fa!important}.data-grid-table-wrapper[data-theme=white] .data-grid-row:nth-child(odd){background-color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=white] .data-grid-row:hover{background-color:#007bff1a!important}.data-grid-table-wrapper[data-theme=white] .selected-cell,.data-grid-table-wrapper[data-theme=white] .row-selected{background-color:#e3f2fd!important}.data-grid-table-wrapper[data-theme=white] .cell,.data-grid-table-wrapper[data-theme=white] .header-cell,.data-grid-table-wrapper[data-theme=white] .data-grid-row,.data-grid-table-wrapper[data-theme=white] .data-grid-header,.data-grid-table-wrapper[data-theme=white] .cell-content,.data-grid-table-wrapper[data-theme=white] .full-text-content,.data-grid-table-wrapper[data-theme=white] .circle-value,.data-grid-table-wrapper[data-theme=white] .pic,.data-grid-table-wrapper[data-theme=white] .image-placeholder,.data-grid-table-wrapper[data-theme=white] .s-no,.data-grid-table-wrapper[data-theme=white] .fw-500{color:#000!important}.data-grid-table-wrapper[data-theme=white] span,.data-grid-table-wrapper[data-theme=white] div,.data-grid-table-wrapper[data-theme=white] p,.data-grid-table-wrapper[data-theme=white] td,.data-grid-table-wrapper[data-theme=white] th,.data-grid-table-wrapper[data-theme=white] label,.data-grid-table-wrapper[data-theme=white] a:not(.text-primary){color:#000!important}.data-grid-table-wrapper[data-theme=white] svg,.data-grid-table-wrapper[data-theme=white] svg path,.data-grid-table-wrapper[data-theme=white] svg circle,.data-grid-table-wrapper[data-theme=white] svg rect,.data-grid-table-wrapper[data-theme=white] svg polygon{color:#000!important;fill:#000!important;stroke:#000!important}.data-grid-table-wrapper[data-theme=white] .data-grid-svg-icon{color:#000!important}.data-grid-table-wrapper[data-theme=white] .data-grid-svg-icon path{stroke:#000!important;fill:#000!important}.data-grid-table-wrapper[data-theme=white] .badge.badge-danger{background-color:#ea5353!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=white] .badge.badge-success{background-color:#84ca81!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=white] .badge.badge-warning{background-color:#fff3dc!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .badge.badge-info{background-color:#e8fbfd!important;color:#00bad1!important}.data-grid-table-wrapper[data-theme=white] .context-menu{background:#f6f8ff;border-color:#d9d9db;color:#000!important}.data-grid-table-wrapper[data-theme=white] .context-menu li{color:#000!important}.data-grid-table-wrapper[data-theme=white] .context-menu li:hover{background-color:#007bff1a!important}.data-grid-table-wrapper[data-theme=white] .custom-tooltip,.data-grid-table-wrapper[data-theme=white] .popover__content,.data-grid-table-wrapper[data-theme=white] .custom-break-tooltip{background:#f6f8ff!important;border-color:#d9d9db!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .actions-dropdown,.data-grid-table-wrapper[data-theme=white] .custom-menu{background-color:#f6f8ff!important;border-color:#d9d9db!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .actions-dropdown .dropdown-item,.data-grid-table-wrapper[data-theme=white] .custom-menu .dropdown-item{color:#000!important}.data-grid-table-wrapper[data-theme=white] .actions-dropdown .dropdown-item:hover,.data-grid-table-wrapper[data-theme=white] .custom-menu .dropdown-item:hover{background-color:#007bff1a!important}.data-grid-table-wrapper[data-theme=white] .taskbar .selected-rows-action-bar{background-color:#343a40!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=white] .taskbar .selected-rows-action-bar .action-btn{color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=white] .manual-logs-modal .modal-header{background:linear-gradient(135deg,#343a40,#495057)!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=white] .manual-logs-modal .modal-header .modal-title{color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=white] .manual-logs-modal .modal-body{background-color:#f6f8ff!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .manual-logs-modal .modal-body .table{color:#000!important}.data-grid-table-wrapper[data-theme=white] .manual-logs-modal .modal-body .table thead th{background:linear-gradient(135deg,#f8f9fa,#e9ecef)!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .manual-logs-modal .modal-body .table tbody tr{color:#000!important}.data-grid-table-wrapper[data-theme=white] .manual-logs-modal .modal-body .table tbody tr:nth-child(2n){background-color:#f8f9fa!important}.data-grid-table-wrapper[data-theme=white] .manual-logs-modal .modal-body .table tbody tr:hover{background-color:#007bff1a!important}.data-grid-table-wrapper[data-theme=white] .manual-logs-modal .modal-body .table tbody tr td{color:#000!important;border-color:#d9d9db!important}.data-grid-table-wrapper[data-theme=white] .form-control,.data-grid-table-wrapper[data-theme=white] .form-select{background-color:#f6f8ff!important;border-color:#d9d9db!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .form-control::placeholder,.data-grid-table-wrapper[data-theme=white] .form-select::placeholder{color:#6c757d!important}.data-grid-table-wrapper[data-theme=white] .form-control option,.data-grid-table-wrapper[data-theme=white] .form-select option{background-color:#f6f8ff!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .filter-serach-inpt{background-color:#f6f8ff!important;border-color:#d9d9db!important}.data-grid-table-wrapper[data-theme=white] .filter-serach-inpt input{background-color:#f6f8ff!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .active-filters{background-color:#f8f9fa!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .custom-modal-overlay .custom-modal-content{background-color:#f6f8ff!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .circle-value{background-color:#f8f9fa!important;border-color:#d9d9db!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .pagination-container,.data-grid-table-wrapper[data-theme=white] .page-size,.data-grid-table-wrapper[data-theme=white] .page-info,.data-grid-table-wrapper[data-theme=white] .page-buttons{color:#000!important}.data-grid-table-wrapper[data-theme=white] .pagination-container select,.data-grid-table-wrapper[data-theme=white] .pagination-container button,.data-grid-table-wrapper[data-theme=white] .pagination-container span,.data-grid-table-wrapper[data-theme=white] .page-size select,.data-grid-table-wrapper[data-theme=white] .page-size button,.data-grid-table-wrapper[data-theme=white] .page-size span,.data-grid-table-wrapper[data-theme=white] .page-info select,.data-grid-table-wrapper[data-theme=white] .page-info button,.data-grid-table-wrapper[data-theme=white] .page-info span,.data-grid-table-wrapper[data-theme=white] .page-buttons select,.data-grid-table-wrapper[data-theme=white] .page-buttons button,.data-grid-table-wrapper[data-theme=white] .page-buttons span{background-color:#f6f8ff!important;border-color:#d9d9db!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .pagination-container button.active,.data-grid-table-wrapper[data-theme=white] .page-size button.active,.data-grid-table-wrapper[data-theme=white] .page-info button.active,.data-grid-table-wrapper[data-theme=white] .page-buttons button.active{background-color:#e3f2fd!important}.data-grid-table-wrapper[data-theme=white] .footer-row{background-color:#f8f9fa!important;border-top-color:#d9d9db!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] ::-webkit-scrollbar{background-color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=white] ::-webkit-scrollbar-thumb{background-color:#d9d9db!important}.data-grid-table-wrapper[data-theme=white] ::-webkit-scrollbar-thumb:hover{background-color:#adb5bd!important}.data-grid-table-wrapper[data-theme=white] ::-webkit-scrollbar-track{background-color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker{background-color:#f6f8ff!important;color:#000!important;border-color:#d9d9db!important}.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker .bs-datepicker-head{background:linear-gradient(135deg,#343a40,#495057)!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker .bs-datepicker-body{background-color:#f6f8ff!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker table td,.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker table th{color:#000!important}.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker table td.is-other-month,.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker table th.is-other-month{color:#6c757d!important}.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker table td.active,.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker table th.active{background-color:#e3f2fd!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker table td span.in-range,.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker table th span.in-range{background-color:#e3f2fd!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker table td:hover:not(.active),.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker table th:hover:not(.active){background-color:#007bff1a!important}.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker .bs-datepicker-buttons{background-color:#f8f9fa!important;border-top-color:#d9d9db!important}.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker .bs-datepicker-buttons .btn-primary{background:linear-gradient(135deg,#007bff,#0056b3)!important;color:#f6f8ff!important;border-color:#007bff!important}.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker .bs-datepicker-buttons .btn-secondary{background-color:#f6f8ff!important;color:#000!important;border-color:#d9d9db!important}.data-grid-table-wrapper[data-theme=white] button,.data-grid-table-wrapper[data-theme=white] .btn,.data-grid-table-wrapper[data-theme=white] .button{background-color:#f6f8ff!important;border-color:#d9d9db!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] button:hover,.data-grid-table-wrapper[data-theme=white] .btn:hover,.data-grid-table-wrapper[data-theme=white] .button:hover{background-color:#007bff1a!important}.data-grid-table-wrapper[data-theme=white] button.btn-primary,.data-grid-table-wrapper[data-theme=white] .btn.btn-primary,.data-grid-table-wrapper[data-theme=white] .button.btn-primary{background-color:#007bff!important;border-color:#007bff!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=white] button.btn-outline-primary,.data-grid-table-wrapper[data-theme=white] .btn.btn-outline-primary,.data-grid-table-wrapper[data-theme=white] .button.btn-outline-primary{border-color:#007bff!important;color:#007bff!important;background-color:transparent!important}.data-grid-table-wrapper[data-theme=white] a:not(.text-primary){color:#007bff!important}.data-grid-table-wrapper[data-theme=white] a:not(.text-primary):hover{color:#0056b3!important}.data-grid-table-wrapper[data-theme=white] .text-primary{color:#007bff!important}.data-grid-table-wrapper[data-theme=white] .text-danger{color:#dc3545!important}.data-grid-table-wrapper[data-theme=white] .text-success{color:#28a745!important}.data-grid-table-wrapper[data-theme=white] .text-warning{color:#ffc107!important}.data-grid-table-wrapper[data-theme=white] .text-info{color:#17a2b8!important}.data-grid-table-wrapper[data-theme=white] .text-muted,.data-grid-table-wrapper[data-theme=white] .muted-text{color:#6c757d!important}.data-grid-table-wrapper[data-theme=white] .border,.data-grid-table-wrapper[data-theme=white] .border-top,.data-grid-table-wrapper[data-theme=white] .border-bottom,.data-grid-table-wrapper[data-theme=white] .border-left,.data-grid-table-wrapper[data-theme=white] .border-right,.data-grid-table-wrapper[data-theme=white] .border-below,.data-grid-table-wrapper[data-theme=white] .border-start,.data-grid-table-wrapper[data-theme=white] .border-end{border-color:#d9d9db!important}.data-grid-table-wrapper[data-theme=white] .accordion-details,.data-grid-table-wrapper[data-theme=white] .nested-table,.data-grid-table-wrapper[data-theme=white] .detail-virtual-scroll{background-color:#f6f8ff!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .accordion-details td,.data-grid-table-wrapper[data-theme=white] .accordion-details th,.data-grid-table-wrapper[data-theme=white] .nested-table td,.data-grid-table-wrapper[data-theme=white] .nested-table th,.data-grid-table-wrapper[data-theme=white] .detail-virtual-scroll td,.data-grid-table-wrapper[data-theme=white] .detail-virtual-scroll th{color:#000!important;border-color:#d9d9db!important}.data-grid-table-wrapper[data-theme=blue]{border-color:#b3d9ff;background-color:#f0f8ff;color:#1e3a5f}.data-grid-table-wrapper[data-theme=blue] *,.data-grid-table-wrapper[data-theme=blue] *:before,.data-grid-table-wrapper[data-theme=blue] *:after{color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] ::selection{background-color:#007cf5!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=blue] ::-moz-selection{background-color:#007cf5!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=blue] .data-grid-header-wrapper{background-color:#e6f3ff;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .data-grid-body-wrapper{background-color:#f0f8ff;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .data-grid-row{border-bottom-color:#b3d9ff;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .data-grid-row:nth-child(2n){background-color:#f0f8ff!important}.data-grid-table-wrapper[data-theme=blue] .data-grid-row:nth-child(odd){background-color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=blue] .data-grid-row:hover{background-color:#1e3a5f1a!important}.data-grid-table-wrapper[data-theme=blue] .selected-cell,.data-grid-table-wrapper[data-theme=blue] .row-selected{background-color:#cce5ff!important}.data-grid-table-wrapper[data-theme=blue] .cell,.data-grid-table-wrapper[data-theme=blue] .header-cell,.data-grid-table-wrapper[data-theme=blue] .data-grid-row,.data-grid-table-wrapper[data-theme=blue] .data-grid-header,.data-grid-table-wrapper[data-theme=blue] .cell-content,.data-grid-table-wrapper[data-theme=blue] .full-text-content,.data-grid-table-wrapper[data-theme=blue] .circle-value,.data-grid-table-wrapper[data-theme=blue] .pic,.data-grid-table-wrapper[data-theme=blue] .image-placeholder,.data-grid-table-wrapper[data-theme=blue] .s-no,.data-grid-table-wrapper[data-theme=blue] .fw-500{color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] span,.data-grid-table-wrapper[data-theme=blue] div,.data-grid-table-wrapper[data-theme=blue] p,.data-grid-table-wrapper[data-theme=blue] td,.data-grid-table-wrapper[data-theme=blue] th,.data-grid-table-wrapper[data-theme=blue] label,.data-grid-table-wrapper[data-theme=blue] a:not(.text-primary){color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] svg,.data-grid-table-wrapper[data-theme=blue] svg path,.data-grid-table-wrapper[data-theme=blue] svg circle,.data-grid-table-wrapper[data-theme=blue] svg rect,.data-grid-table-wrapper[data-theme=blue] svg polygon{color:#1e3a5f!important;fill:#1e3a5f!important;stroke:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .data-grid-svg-icon{color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .data-grid-svg-icon path{stroke:#1e3a5f!important;fill:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .badge.badge-danger{background-color:#ff8787!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=blue] .badge.badge-success{background-color:#69db7c!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=blue] .badge.badge-warning{background-color:#ffd43b!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .badge.badge-info{background-color:#74c0fc!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=blue] .context-menu{background:#e6f3ff;border-color:#b3d9ff;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .context-menu li{color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .context-menu li:hover{background-color:#1e3a5f1a!important}.data-grid-table-wrapper[data-theme=blue] .custom-tooltip,.data-grid-table-wrapper[data-theme=blue] .popover__content,.data-grid-table-wrapper[data-theme=blue] .custom-break-tooltip{background:#e6f3ff!important;border-color:#b3d9ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .actions-dropdown,.data-grid-table-wrapper[data-theme=blue] .custom-menu{background-color:#e6f3ff!important;border-color:#b3d9ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .actions-dropdown .dropdown-item,.data-grid-table-wrapper[data-theme=blue] .custom-menu .dropdown-item{color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .actions-dropdown .dropdown-item:hover,.data-grid-table-wrapper[data-theme=blue] .custom-menu .dropdown-item:hover{background-color:#1e3a5f1a!important}.data-grid-table-wrapper[data-theme=blue] .taskbar .selected-rows-action-bar{background-color:#1e3a5f!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=blue] .taskbar .selected-rows-action-bar .action-btn{color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=blue] .manual-logs-modal .modal-header{background:linear-gradient(135deg,#1e3a5f,#2d4a6b)!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=blue] .manual-logs-modal .modal-header .modal-title{color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=blue] .manual-logs-modal .modal-body{background-color:#f0f8ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .manual-logs-modal .modal-body .table{color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .manual-logs-modal .modal-body .table thead th{background:linear-gradient(135deg,#e6f3ff,#cce5ff)!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .manual-logs-modal .modal-body .table tbody tr{color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .manual-logs-modal .modal-body .table tbody tr:nth-child(2n){background-color:#f0f8ff!important}.data-grid-table-wrapper[data-theme=blue] .manual-logs-modal .modal-body .table tbody tr:hover{background-color:#1e3a5f1a!important}.data-grid-table-wrapper[data-theme=blue] .manual-logs-modal .modal-body .table tbody tr td{color:#1e3a5f!important;border-color:#b3d9ff!important}.data-grid-table-wrapper[data-theme=blue] .form-control,.data-grid-table-wrapper[data-theme=blue] .form-select{background-color:#f6f8ff!important;border-color:#b3d9ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .form-control::placeholder,.data-grid-table-wrapper[data-theme=blue] .form-select::placeholder{color:#888!important}.data-grid-table-wrapper[data-theme=blue] .form-control option,.data-grid-table-wrapper[data-theme=blue] .form-select option{background-color:#f6f8ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .filter-serach-inpt{background-color:#f6f8ff!important;border-color:#b3d9ff!important}.data-grid-table-wrapper[data-theme=blue] .filter-serach-inpt input{background-color:#f6f8ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .active-filters,.data-grid-table-wrapper[data-theme=blue] .custom-modal-overlay .custom-modal-content{background-color:#e6f3ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .circle-value{background-color:#f6f8ff!important;border-color:#b3d9ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .pagination-container,.data-grid-table-wrapper[data-theme=blue] .page-size,.data-grid-table-wrapper[data-theme=blue] .page-info,.data-grid-table-wrapper[data-theme=blue] .page-buttons{color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .pagination-container select,.data-grid-table-wrapper[data-theme=blue] .pagination-container button,.data-grid-table-wrapper[data-theme=blue] .pagination-container span,.data-grid-table-wrapper[data-theme=blue] .page-size select,.data-grid-table-wrapper[data-theme=blue] .page-size button,.data-grid-table-wrapper[data-theme=blue] .page-size span,.data-grid-table-wrapper[data-theme=blue] .page-info select,.data-grid-table-wrapper[data-theme=blue] .page-info button,.data-grid-table-wrapper[data-theme=blue] .page-info span,.data-grid-table-wrapper[data-theme=blue] .page-buttons select,.data-grid-table-wrapper[data-theme=blue] .page-buttons button,.data-grid-table-wrapper[data-theme=blue] .page-buttons span{background-color:#f6f8ff!important;border-color:#b3d9ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .pagination-container button.active,.data-grid-table-wrapper[data-theme=blue] .page-size button.active,.data-grid-table-wrapper[data-theme=blue] .page-info button.active,.data-grid-table-wrapper[data-theme=blue] .page-buttons button.active{background-color:#cce5ff!important}.data-grid-table-wrapper[data-theme=blue] .footer-row{background-color:#e6f3ff!important;border-top-color:#b3d9ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] ::-webkit-scrollbar{background-color:#f0f8ff!important}.data-grid-table-wrapper[data-theme=blue] ::-webkit-scrollbar-thumb{background-color:#b3d9ff!important}.data-grid-table-wrapper[data-theme=blue] ::-webkit-scrollbar-thumb:hover{background-color:#74c0fc!important}.data-grid-table-wrapper[data-theme=blue] ::-webkit-scrollbar-track{background-color:#f0f8ff!important}.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker{background-color:#e6f3ff!important;color:#1e3a5f!important;border-color:#b3d9ff!important}.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker .bs-datepicker-head{background:linear-gradient(135deg,#1e3a5f,#2d4a6b)!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker .bs-datepicker-body{background-color:#f0f8ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker table td,.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker table th{color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker table td.is-other-month,.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker table th.is-other-month{color:#888!important}.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker table td.active,.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker table th.active{background-color:#cce5ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker table td span.in-range,.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker table th span.in-range{background-color:#cce5ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker table td:hover:not(.active),.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker table th:hover:not(.active){background-color:#1e3a5f1a!important}.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker .bs-datepicker-buttons{background-color:#f6f8ff!important;border-top-color:#b3d9ff!important}.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker .bs-datepicker-buttons .btn-primary{background:linear-gradient(135deg,#1e3a5f,#2d4a6b)!important;color:#f6f8ff!important;border-color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker .bs-datepicker-buttons .btn-secondary{background-color:#f0f8ff!important;color:#1e3a5f!important;border-color:#b3d9ff!important}.data-grid-table-wrapper[data-theme=blue] button,.data-grid-table-wrapper[data-theme=blue] .btn,.data-grid-table-wrapper[data-theme=blue] .button{background-color:#f6f8ff!important;border-color:#b3d9ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] button:hover,.data-grid-table-wrapper[data-theme=blue] .btn:hover,.data-grid-table-wrapper[data-theme=blue] .button:hover{background-color:#1e3a5f1a!important}.data-grid-table-wrapper[data-theme=blue] button.btn-primary,.data-grid-table-wrapper[data-theme=blue] .btn.btn-primary,.data-grid-table-wrapper[data-theme=blue] .button.btn-primary{background-color:#007cf5!important;border-color:#007cf5!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=blue] button.btn-outline-primary,.data-grid-table-wrapper[data-theme=blue] .btn.btn-outline-primary,.data-grid-table-wrapper[data-theme=blue] .button.btn-outline-primary{border-color:#007cf5!important;color:#007cf5!important;background-color:transparent!important}.data-grid-table-wrapper[data-theme=blue] a:not(.text-primary){color:#007cf5!important}.data-grid-table-wrapper[data-theme=blue] a:not(.text-primary):hover{color:#0056b3!important}.data-grid-table-wrapper[data-theme=blue] .text-primary{color:#007cf5!important}.data-grid-table-wrapper[data-theme=blue] .text-danger{color:#dc3545!important}.data-grid-table-wrapper[data-theme=blue] .text-success{color:#28a745!important}.data-grid-table-wrapper[data-theme=blue] .text-warning{color:#ffc107!important}.data-grid-table-wrapper[data-theme=blue] .text-info{color:#17a2b8!important}.data-grid-table-wrapper[data-theme=blue] .text-muted,.data-grid-table-wrapper[data-theme=blue] .muted-text{color:#6c757d!important}.data-grid-table-wrapper[data-theme=blue] .border,.data-grid-table-wrapper[data-theme=blue] .border-top,.data-grid-table-wrapper[data-theme=blue] .border-bottom,.data-grid-table-wrapper[data-theme=blue] .border-left,.data-grid-table-wrapper[data-theme=blue] .border-right,.data-grid-table-wrapper[data-theme=blue] .border-below,.data-grid-table-wrapper[data-theme=blue] .border-start,.data-grid-table-wrapper[data-theme=blue] .border-end{border-color:#b3d9ff!important}.data-grid-table-wrapper[data-theme=blue] .accordion-details,.data-grid-table-wrapper[data-theme=blue] .nested-table,.data-grid-table-wrapper[data-theme=blue] .detail-virtual-scroll{background-color:#f0f8ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .accordion-details td,.data-grid-table-wrapper[data-theme=blue] .accordion-details th,.data-grid-table-wrapper[data-theme=blue] .nested-table td,.data-grid-table-wrapper[data-theme=blue] .nested-table th,.data-grid-table-wrapper[data-theme=blue] .detail-virtual-scroll td,.data-grid-table-wrapper[data-theme=blue] .detail-virtual-scroll th{color:#1e3a5f!important;border-color:#b3d9ff!important}.data-grid-header{position:sticky;top:0}.data-grid-header{display:flex}.header-row{display:grid;width:100%}.header-cell{display:flex;align-items:center;position:relative;width:100%;padding:8px 0 8px 8px;font-weight:700;border-bottom:1px solid #d9d9db;white-space:nowrap;min-width:30px}.header-cell .filter-applied-on-text{color:#5d9cff!important}.filter-cell{padding:4px!important;display:flex;align-items:center;gap:8px;width:100%}.filter-cell .filter-applied{background-color:#bddef9}.border-right{border-right:1px solid #d9d9db}.merged-grid{display:grid;grid-auto-rows:40px;border-bottom:1px solid #ccc}.span-two-rows{grid-row:span 2;display:flex;justify-content:space-between;align-items:center}.group-header{display:flex;justify-content:space-between;position:relative}.group-header-content{position:sticky;left:10px;overflow:hidden;text-overflow:ellipsis}.resize-handle{width:6px;cursor:e-resize;right:0;top:0;color:#00000026;position:relative}.resize-handle.resizing{z-index:9999!important;opacity:1!important;background-color:#007bff1a;border-right:2px solid #007bff;box-shadow:0 0 8px #007bff4d;position:relative!important;pointer-events:none!important}.group-header .resize-handle{top:25%}.h-100{height:100%}.data-grid-body{position:relative;overflow-y:auto;overflow-x:hidden;box-shadow:none!important}.cell{padding:8px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;height:100%;display:flex;align-items:center}.data-grid-row{display:flex;min-width:max-content;align-items:center;border-bottom:1px solid #d9d9db;transition:all .25s cubic-bezier(.4,0,.2,1);transform:translateZ(0);will-change:transform,box-shadow;backface-visibility:hidden}.data-grid-row:hover{transform:translate(2px);box-shadow:2px 0 8px #007bff1a}.hovered-row{background-color:#ccc}.checkbox-row{border-bottom:#d9d9db}.w-100{width:100%}.data-grid-header-wrapper{display:flex;position:relative;overflow:hidden;-webkit-user-select:none;user-select:none}.data-grid-header{display:flex;position:relative;z-index:1}.left-pinned,.right-pinned{position:sticky;top:0;background:#f6f8ff}.right-pinned-header{position:absolute;right:0;border-left:1px solid #d9d9db;z-index:unset}.left-pinned{left:0;border-right:1px solid #d9d9db}.right-pinned{right:0;border-left:1px solid #d9d9db}.center-scrollable{z-index:unset!important;overflow-x:auto;overflow-y:visible;white-space:nowrap;scrollbar-width:none;-ms-overflow-style:none}.center-scrollable::-webkit-scrollbar{display:none}.data-grid-body-wrapper{display:flex}.data-grid-body-wrapper{scrollbar-width:none;-ms-overflow-style:none}.data-grid-body-wrapper::-webkit-scrollbar{display:none}.center-scrollable-body{overflow-x:auto;scrollbar-width:none;-ms-overflow-style:none}.center-scrollable-body::-webkit-scrollbar{display:none}.left-pinned-body,.right-pinned-body{position:sticky;top:0;z-index:unset;background:#f6f8ff;scrollbar-width:none;-ms-overflow-style:none}.left-pinned-body::-webkit-scrollbar,.right-pinned-body::-webkit-scrollbar{display:none}.left-pinned-body{left:0}.border-end{border-right:1px solid #d9d9db!important}.right-pinned-body{right:-15px;border-left:1px solid #d9d9db}.fake-scroll-bar{height:14px;overflow:scroll;margin-bottom:10px}.text-ellipsis{overflow:hidden;text-overflow:ellipsis}.select-all-checkbox-cell{width:50px;display:flex;justify-content:center;align-items:center;height:100%;border-right:1px solid #d9d9db}.select-all-checkbox-cell input{width:16px;height:16px}.border-below{border-bottom:1px solid #d9d9db!important}.three-dots{width:22px;height:22px;display:flex;justify-content:center;align-items:center;border-radius:6px;margin-right:8px;cursor:pointer;transition:all .25s cubic-bezier(.4,0,.2,1);transform:translateZ(0);position:relative}.three-dots:before{content:\"\";position:absolute;top:50%;left:50%;width:0;height:0;background:#007bff1a;border-radius:50%;transform:translate(-50%,-50%);transition:width .25s,height .25s}.three-dots:hover{background-color:#007bff1a;transform:rotate(90deg)}.three-dots:hover:before{width:28px;height:28px}.three-dots:active{transform:rotate(90deg) scale(.95);transition-duration:.15s}.filter-icon-wrapper{min-height:22px;max-height:22px;min-width:22px;max-width:22px;display:flex;justify-content:center;align-items:center;border-radius:6px;cursor:pointer;transition:all .25s cubic-bezier(.4,0,.2,1);transform:translateZ(0);position:relative}.filter-icon-wrapper:before{content:\"\";position:absolute;top:50%;left:50%;width:0;height:0;background:#007bff1a;border-radius:50%;transform:translate(-50%,-50%);transition:width .25s,height .25s}.filter-icon-wrapper:hover{background-color:#007bff1a;transform:scale(1.05)}.filter-icon-wrapper:hover:before{width:32px;height:32px}.filter-icon-wrapper:active{transform:scale(.95);transition-duration:.15s}.column-panel-item{font-size:.875rem;color:#333;transition:all .25s cubic-bezier(.4,0,.2,1);transform:translateZ(0)}.column-panel-item:hover{background-color:#007bff0d;color:#007bff;transform:translate(2px)}.column-menu,.filter-menu{box-shadow:0 0 16px #00000026;border-radius:4px}.column-menu{background:#fff;width:100%;width:240px;border:1px solid #ddd;box-shadow:0 0 16px #00000026;border:1px solid #d9d9db;padding:4px 0;font-size:14px;position:fixed}.column-menu-item{padding:8px 12px;cursor:pointer;display:flex;align-items:center;transition:background-color .2s ease}.column-menu-item:hover{background-color:#deebf7}.pin-parent{position:relative;width:100%!important}.column-submenu{position:absolute;top:0;left:100%;background:#fff;border:1px solid #ddd;width:130px;box-shadow:0 0 16px #00000026;border:1px solid #d9d9db;display:none;padding:4px 0;z-index:10;border-radius:4px}.pin-parent:hover .column-submenu{display:block}.filter-menu-container{position:fixed;width:210px;background:#fff;border:1px solid #ddd;border-radius:4px;padding:12px;box-shadow:0 0 16px #00000026;border:1px solid #d9d9db;z-index:1000;font-size:14px}.filter-menu-header{font-weight:600;margin-bottom:10px}.filter-dropdown-section{max-height:350px;overflow-y:auto}.dropdown-options{overflow-y:auto;scrollbar-width:thin;height:100%}.filter-text-section select,.filter-text-section input{width:100%}.filter-radio-inputs{width:14px!important;height:14px!important}.right-menu{border-left:1px solid #d9d9db;font-size:14px}.border-start{border-left:1px solid #d9d9db!important}.column-panel-item{font-size:.875rem;color:#333}.toggle-icon{cursor:pointer;transition:all .25s cubic-bezier(.4,0,.2,1);transform:translateZ(0);border-radius:4px;padding:2px}.toggle-icon:hover{background-color:#007bff1a;transform:scale(1.1)}.toggle-icon:active{transform:scale(.95)}.grab-icon{cursor:grab;color:#6c757d;transition:all .25s cubic-bezier(.4,0,.2,1);transform:translateZ(0)}.grab-icon:hover{color:#007bff;transform:scale(1.1)}.grab-icon:active{cursor:grabbing;transform:scale(.95)}.text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:100%}.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:-3px}.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:20px;left:50%;transform:translate(-50%);display:flex;justify-content:center;z-index:1000;padding:0;width:auto;max-width:90vw}.taskbar .action-btn{transition:all .3s ease;font-weight:500;font-size:14px;padding:8px 16px;border-radius:6px;cursor:pointer;display:inline-flex;align-items:center;gap:6px}.taskbar .action-btn:hover{transform:translateY(-1px);box-shadow:0 4px 12px #00000026}.taskbar .action-btn:active{transform:translateY(0)}.taskbar .delete{background-color:#dc3545;color:#fff;border:1px solid #dc3545}.taskbar .delete:hover{background-color:#c82333;border-color:#bd2130}.taskbar .export{background-color:#28a745;color:#fff;border:1px solid #28a745}.taskbar .export:hover{background-color:#218838;border-color:#1e7e34}.taskbar .verify{background-color:#007bff;color:#fff;border:1px solid #007bff}.taskbar .verify:hover{background-color:#0056b3;border-color:#004085}.selected-count,.action-btn,.dropdown-content a{font-weight:500;font-size:14px}.selected-rows-action-bar{background:linear-gradient(135deg,#667eea,#764ba2);color:#fff;padding:12px 24px;border-radius:12px;display:flex;align-items:center;justify-content:space-between;gap:16px;box-shadow:0 8px 32px #0003;backdrop-filter:blur(10px);border:1px solid rgba(255,255,255,.1);min-width:300px}.selected-rows-action-bar .selected-count{font-weight:600;font-size:14px;flex:1;text-align:center}.selected-rows-action-bar .action-buttons{display:flex;align-items:center;gap:8px}.selected-rows-action-bar .action-buttons .separator{color:#ffffff80;font-weight:700;font-size:16px}.selected-rows-action-bar .action-buttons .action-btn{background:#fff3;color:#fff!important;border:1px solid rgba(255,255,255,.3);padding:8px 16px;border-radius:8px;font-weight:500;font-size:13px;transition:all .3s ease;cursor:pointer;display:inline-flex;align-items:center;gap:6px}.selected-rows-action-bar .action-buttons .action-btn:hover{background:#ffffff4d;transform:translateY(-1px);box-shadow:0 4px 12px #0003}.selected-rows-action-bar .action-buttons .action-btn:active{transform:translateY(0)}.selected-rows-action-bar .action-buttons .action-btn.Export{background:#28a745cc;border-color:#28a745e6}.selected-rows-action-bar .action-buttons .action-btn.Export:hover{background:#218838e6}.selected-rows-action-bar .action-buttons .action-btn.Delete{background:#dc3545cc;border-color:#dc3545e6}.selected-rows-action-bar .action-buttons .action-btn.Delete:hover{background:#c82333e6}.selected-rows-action-bar .action-buttons .action-btn.Verify{background:#007bffcc;border-color:#007bffe6}.selected-rows-action-bar .action-buttons .action-btn.Verify:hover{background:#0056b3e6}.selected-rows-action-bar .btn:active,.selected-rows-action-bar .btn:focus{outline:0!important;border:0!important;border-color:transparent!important}@media (max-width: 768px){.taskbar{bottom:10px;max-width:95vw}.taskbar .selected-rows-action-bar{padding:8px 16px;min-width:280px;flex-direction:column;gap:12px}.taskbar .selected-rows-action-bar .selected-count{font-size:13px;text-align:center}.taskbar .selected-rows-action-bar .action-buttons{justify-content:center;flex-wrap:wrap;gap:6px}.taskbar .selected-rows-action-bar .action-buttons .action-btn{padding:6px 12px;font-size:12px;min-width:80px}.taskbar .selected-rows-action-bar .action-buttons .separator{display:none}}@media (max-width: 480px){.taskbar .selected-rows-action-bar{min-width:250px;padding:6px 12px}.taskbar .selected-rows-action-bar .action-buttons .action-btn{padding:5px 10px;font-size:11px;min-width:70px}}.cell .dropdown-menu,.cell .form-select,.cell input{color:#000!important}.cell input::placeholder{color:#727272!important}.cell .badge{font-size:14px;padding:6px 12px;border-radius:6px;text-align:center;height:auto;min-height:28px;display:inline-flex;align-items:center;justify-content:center;font-weight:500;line-height:1.5;white-space:nowrap;transition:all .2s cubic-bezier(.4,0,.2,1);will-change:transform,opacity;backface-visibility:hidden;transform:translateZ(0)}.cell .badge-danger{color:#ea5353!important;border:1px solid #ea5353!important;background-color:#ff00000d!important}.cell .badge-success{background-color:#84ca8130!important;border:1.5px solid rgb(70,227,114)!important;color:#46e372!important}.cell .badge-warning{background-color:#fff3dc!important;color:orange!important;border:1px solid #ffa000!important}.cell .badge-info{color:#00bad1;background-color:#e8fbfd;border:1px solid #00bad1}.header-tag ::ng-deep svg path{stroke:#727272!important}.cross-secondary:hover ::ng-deep svg path{stroke:#000!important}.disable-sorting{pointer-events:none;opacity:.5}.rows-grouping-top-container ::ng-deep .cdk-drag-placeholder{background-color:transparent!important}input.is-invalid:focus{border:2.5px solid red!important;outline:none}.table-cell input.is-invalid:focus{border:2.5px solid red!important;outline-color:red!important;outline:none!important;box-shadow:none!important}.active-for-editing:has(input.is-invalid:focus){outline:none!important;box-shadow:none!important;border:0!important}.selected-cell,.row-selected{background-color:#c2e0fe;animation:pulse .25s cubic-bezier(.4,0,.2,1);transform:translateZ(0);position:relative}.selected-cell:before,.row-selected:before{content:\"\";position:absolute;inset:0;background:linear-gradient(45deg,transparent,rgba(255,255,255,.1),transparent);animation:shimmer 1.5s ease-in-out infinite}.first-row-selected{border-top:2px solid #2196f3!important}.last-row-selected{border-bottom:2px solid #2196f3!important}.left-selection-border{border-left:2px solid #2196f3!important}.s-no{font-size:14px;font-weight:500}.top-border{border-top:2px solid #2196f3!important}.bottom-border{border-bottom:2px solid #2196f3!important}.left-border{border-left:2px solid #2196f3!important}.right-border{border-right:2px solid #2196f3!important}.top-left-corner{border-top-left-radius:4px}.top-right-corner{border-top-right-radius:4px}.bottom-left-corner{border-bottom-left-radius:4px}.bottom-right-corner{border-bottom-right-radius:4px}.flash-bg{animation:flashAnim 1000s ease}@keyframes flashAnim{0%{background-color:#48a2fc}50%{background-color:#c2e0fe}to{background-color:#c2e0fe}}.cut-flash-bg{animation:cut-flash .8s ease}@keyframes cut-flash{0%{background-color:#f006}50%{background-color:#f00c}to{background-color:#c2e0fe}}.accordion-details.dragging th,.accordion-details.dragging td{pointer-events:none}.accordion-details.dragging th{z-index:2}.drag-handle{cursor:move;opacity:.5;transition:opacity .2s}.drag-handle:hover{opacity:1}.detail-edit-input{z-index:100;position:relative}.detail-filter-menu{position:fixed;width:210px;background:#fff;border:1px solid #ddd;border-radius:4px;padding:12px;box-shadow:0 0 16px #00000026;border:1px solid #d9d9db;z-index:1000;font-size:14px}.detail-filter-menu-positioned{width:280px;right:unset;max-width:230px;z-index:99;left:375px;top:225px}.resize-handle{cursor:col-resize;opacity:.5;width:8px;display:flex;align-items:center;justify-content:center}.resize-handle:hover{opacity:1;background-color:#f0f0f0}.detail-header-row{transition:all .3s ease}.detail-header-row.dragging{opacity:.7;transform:translate(5px)}.detail-cell{transition:background-color .2s ease,transform .3s ease}.detail-cell.active-drag{background-color:#f0f0f0;transform:scale(1.02)}.break-color-paid{background-color:#4caf50!important}.break-color-unpaid{background-color:#f44336!important}.break-color-lunch{background-color:#2196f3!important}.break-color-default{background-color:#f44336!important}.circle-value{display:flex;align-items:center;justify-content:center;width:32px;height:32px;border-radius:50%;background-color:#f8f9fa;border:2px solid #d9d9db;font-size:12px;font-weight:600;color:#fff;text-align:center;line-height:1;vertical-align:middle;box-sizing:border-box;white-space:nowrap;overflow:hidden;cursor:pointer;transition:all .3s cubic-bezier(.4,0,.2,1);transform:translateZ(0);will-change:transform,box-shadow,background-color;backface-visibility:hidden}.circle-value:hover{background-color:#e9ecef;box-shadow:0 6px 16px #007bff40;transform:scale(1.15) translateY(-2px);border-color:#007bff}.circle-value:active{transform:scale(1.08) translateY(-1px);transition-duration:.15s}.break-tooltip-wrapper{position:relative;display:inline-block}.break-tooltip-wrapper:hover .custom-break-tooltip{opacity:1;visibility:visible}.circle-value[title]{position:relative}.circle-value[title]:after{content:attr(title);position:absolute;bottom:100%;left:50%;transform:translate(-50%);background-color:#333;color:#fff;padding:4px 8px;border-radius:4px;font-size:12px;white-space:nowrap;opacity:0;transition:opacity .2s ease;pointer-events:none}.circle-value[title]:hover:after{opacity:1}.custom-tooltip{position:fixed;background:#fff;border:1px solid #dcdcdc;border-radius:8px;padding:12px 16px;max-width:300px;z-index:9999;font-size:13px;animation:fadeIn .2s ease-in-out}.tooltip-title{font-size:14px;font-weight:600;margin-bottom:8px;color:#333}.tooltip-list{margin:0;padding-left:16px;list-style-type:disc}.tooltip-list li{margin-bottom:4px;line-height:1.4;color:#444}.tooltip-total{font-weight:700;margin-top:8px;color:#222}@keyframes fadeIn{0%{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:translateY(0)}}.restriction-indicator{position:absolute;display:inline-block;padding-right:10px}.restriction-indicator:after{content:\"\";position:absolute;top:0;right:0;width:8px;height:8px;background-color:#0d6efd;border-radius:50%}.manual-logs-indicator{position:absolute;top:2px;right:2px;width:8px;height:8px;background-color:#0d6efd;border-radius:50%;border:1px solid #fff;box-shadow:0 0 2px #0d6efd80;cursor:pointer;z-index:10;transition:all .2s ease}.manual-logs-indicator:hover{transform:scale(1.2);box-shadow:0 0 4px #0d6efdcc}.manual-logs-table-tooltip{background:#fff!important;border:1px solid #dcdcdc!important;border-radius:8px!important;box-shadow:0 4px 12px #00000026!important;font-size:13px!important;animation:fadeIn .2s ease-in-out!important;display:block!important;visibility:visible!important;opacity:1!important}.manual-logs-table-tooltip .popover__content,.manual-logs-table-tooltip .modal-area{padding:0!important;display:block!important;visibility:visible!important}.manual-logs-table-tooltip .table-responsive{max-height:300px;overflow-y:auto;display:block!important;visibility:visible!important}.manual-logs-table-tooltip table{margin:0!important;border-collapse:collapse!important;display:table!important;visibility:visible!important}.manual-logs-table-tooltip table th,.manual-logs-table-tooltip table td{padding:6px 8px!important;border:1px solid #f1f1f1!important;text-align:center!important;vertical-align:middle!important;display:table-cell!important;visibility:visible!important}.manual-logs-table-tooltip table th{background-color:#f8f9fa!important;font-weight:600!important;color:#495057!important;position:sticky!important;top:0!important;z-index:1!important}.manual-logs-table-tooltip table tbody tr:nth-child(2n){background-color:#f8f9fa!important}.manual-logs-table-tooltip table tbody tr:hover{background-color:#e3f2fd!important}.manual-logs-table-tooltip table .text-primary{color:#0d6efd!important;text-decoration:none!important}.manual-logs-table-tooltip table .capitalize{text-transform:capitalize!important}@keyframes fadeIn{0%{opacity:0;transform:translate(-50%) translateY(-110%)}to{opacity:1;transform:translate(-50%) translateY(-100%)}}.detail-column-menu{max-height:250px;overflow-y:auto;overflow-x:auto;white-space:nowrap;padding:8px 0;border-radius:6px;scrollbar-width:thin}.detail-column-menu-wrapper{z-index:1001;position:absolute}.accordion-details{position:relative;z-index:999}.detail-column-menu .column-menu-item{padding:8px 12px;cursor:pointer;display:flex;align-items:center;transition:all .25s cubic-bezier(.4,0,.2,1);font-size:14px;transform:translateZ(0);border-radius:4px}.detail-column-menu .column-menu-item:hover{background-color:#007bff1a;transform:translate(2px);color:#007bff}.detail-column-menu .column-menu-item:active{transform:translate(0) scale(.98)}.detail-column-menu .column-menu-item:hover{background-color:#deebf7}.nested-table th[pinned=left],.nested-table td[pinned=left]{border-right:2px solid #ccc;border-left:none;border-bottom:2px solid #ccc}.nested-table th[pinned=right],.nested-table td[pinned=right]{border-left:2px solid #ccc;border-right:none;border-bottom:2px solid #ccc}.data-grid-accordion-table.show-borders{border:1px solid #d9d9db;border-collapse:collapse}.data-grid-accordion-table.show-borders th,.data-grid-accordion-table.show-borders td{border:1px solid #d9d9db}.data-grid-accordion-table.show-shadow tbody tr:hover{box-shadow:0 4px 8px #0000001a;transition:box-shadow .3s ease}.data-grid-accordion-table tbody tr:hover{background-color:#deebf7;transition:background-color .3s ease}.data-grid-pin-icon{display:inline-block;vertical-align:middle;margin-left:4px}.accordion-details.center-section{position:relative;display:flex}.detail-side-menu-wrapper{display:flex;flex-shrink:0;position:sticky;right:0;top:0;height:100%;max-height:275px}.detail-side-menu-content{width:250px;box-shadow:-2px 0 5px #0000001a;display:flex;flex-direction:column}.side-menu-scrollable{flex:1;overflow-y:auto;padding:0 12px 12px;max-height:calc(100% - 40px)}.filter-input-container{padding:8px;background:#f9f9f9;border-radius:4px}.toggle-icon.rotate{transform:rotate(90deg)}.resize-handle{top:0;right:3px;bottom:0;width:8px;cursor:col-resize;z-index:10;display:flex;align-items:center;justify-content:center;opacity:1.4;transition:all .25s cubic-bezier(.4,0,.2,1);background:transparent;transform:translateZ(0)}.resize-handle:hover{opacity:1;background:#007bff1a}.resize-handle:active{opacity:1;background:#007bff33;transform:scaleX(1.2)}th:hover .resize-handle{opacity:40}.resize-handles{top:0;right:3px;bottom:0;width:8px;cursor:col-resize;z-index:10;display:flex;align-items:center;justify-content:center;position:absolute;opacity:1.4;transition:all .25s cubic-bezier(.4,0,.2,1);background:transparent;transform:translateZ(0)}.resize-handles:hover{opacity:1;background:#007bff1a}.resize-handles:active{opacity:1;background:#007bff33;transform:scaleX(1.2)}.resize-handles.resizing{z-index:9999!important;opacity:1!important;background-color:#007bff1a;border-right:2px solid #007bff;box-shadow:0 0 8px #007bff4d;pointer-events:none!important}th:hover .resize-handles{opacity:40}.resizing-highlight{background-color:#007bff1a!important}.accordion-details-wrapper{display:flex;width:100%;max-height:350px;overflow:hidden}.accordion-details.show-borders,.accordion-details-wrapper.show-borders{border:1px solid #d9d9db;border-radius:4px}.accordion-left-section,.accordion-right-section,.detail-side-menu-wrapper{flex-shrink:0;max-height:350px;overflow:hidden;height:fit-content}.accordion-center-section{flex:1;min-width:0;overflow:auto;max-height:350px}.detail-virtual-scroll{display:block;width:100%;height:250px;overflow:auto}.detail-virtual-scroll table{table-layout:fixed;width:100%}.detail-virtual-scroll td,.detail-virtual-scroll th{overflow:hidden!important;text-overflow:ellipsis!important;white-space:nowrap!important}.nested-table th{overflow:hidden!important}.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:10;background-color:#f6f8ff!important}.data-pin-body-wrapper{-webkit-user-select:none;user-select:none;display:flex}.data-pin-body-wrapper{scrollbar-width:none;-ms-overflow-style:none}.data-pin-body-wrapper::-webkit-scrollbar{display:none}.detail-virtual-scroll .selected-cell,.accordion-left-section .selected-cell,.accordion-right-section .selected-cell{background-color:#cce5ff!important}.custom-datepicker-buttons button{height:28px;padding:0 10px;font-size:12px}.manual-logs-modal{max-width:800px;max-height:80vh;overflow:hidden;border-radius:12px;box-shadow:0 10px 40px #0003}.manual-logs-modal .modal-header{background:linear-gradient(135deg,#4361ee,#3a0ca3);color:#fff;padding:16px 20px;border-bottom:none;border-radius:12px 12px 0 0}.manual-logs-modal .modal-header .modal-title{font-weight:600;font-size:18px;margin:0}.manual-logs-modal .modal-header .btn-close{background:#fff3;border:none;border-radius:50%;width:32px;height:32px;display:flex;align-items:center;justify-content:center;color:#fff;opacity:.8;transition:all .25s cubic-bezier(.4,0,.2,1);transform:translateZ(0)}.manual-logs-modal .modal-header .btn-close:hover{background:#ffffff4d;opacity:1;transform:scale(1.1) rotate(90deg)}.manual-logs-modal .modal-header .btn-close:active{transform:scale(.95) rotate(90deg)}.manual-logs-modal .modal-body{padding:20px;max-height:calc(80vh - 80px);overflow-y:auto}.manual-logs-modal .modal-body .table-responsive{border-radius:8px;overflow:hidden;box-shadow:0 2px 8px #0000001a}.manual-logs-modal .modal-body .table-responsive .table{margin-bottom:0;font-size:14px}.manual-logs-modal .modal-body .table-responsive .table thead th{background:linear-gradient(135deg,#f8f9fa,#e9ecef);border-bottom:2px solid #dee2e6;font-weight:600;color:#495057;padding:12px 16px;position:sticky;top:0;z-index:10}.manual-logs-modal .modal-body .table-responsive .table tbody tr{transition:background-color .2s ease}.manual-logs-modal .modal-body .table-responsive .table tbody tr:hover{background-color:#f8f9fa}.manual-logs-modal .modal-body .table-responsive .table tbody tr:nth-child(2n){background-color:#f8f9fa}.manual-logs-modal .modal-body .table-responsive .table tbody tr td{padding:10px 16px;vertical-align:middle;border-color:#e9ecef}.manual-logs-modal .modal-body .table-responsive .table tbody tr td .text-primary{color:#0d6efd!important;font-weight:500;text-decoration:none}.manual-logs-modal .modal-body .table-responsive .table tbody tr td .text-primary:hover{text-decoration:underline}.manual-logs-modal .modal-body .table-responsive .table tbody tr td .capitalize{text-transform:capitalize}::ng-deep bs-daterangepicker-container .bs-datepicker{border-radius:4px!important;box-shadow:0 2px 8px #0000001a!important;font-size:14px!important;display:flex!important;align-items:flex-start!important;left:142px!important}::ng-deep .bs-datepicker-head{background:#f8f9fa!important;color:#495057!important;border-bottom:1px solid #dee2e6!important;padding:8px 12px!important;border-radius:4px 4px 0 0!important}::ng-deep .bs-datepicker-head .current{font-weight:600!important;color:#495057!important;font-size:13px!important}::ng-deep .bs-datepicker-head .previous,::ng-deep .bs-datepicker-head .next{background:#fff!important;color:#495057!important;border:1px solid #dee2e6!important;width:24px!important;border-radius:4px!important;font-size:12px!important}::ng-deep .bs-datepicker-head .previous:hover,::ng-deep .bs-datepicker-head .next:hover{background:#e9ecef!important}::ng-deep .bs-datepicker .bs-datepicker-buttons{padding:8px!important;background:#f8f9fa!important;border-top:1px solid #dee2e6!important;border-radius:0 0 4px 4px!important}::ng-deep .bs-datepicker .bs-datepicker-buttons .btn-primary{background:#007bff!important;color:#fff!important;border:1px solid #007bff!important;font-weight:500!important;padding:4px 8px!important;border-radius:4px!important;font-size:12px!important}::ng-deep .bs-datepicker .bs-datepicker-buttons .btn-primary:hover{background:#0056b3!important;border-color:#0056b3!important}::ng-deep .bs-datepicker .bs-datepicker-buttons .btn-secondary{background:#fff!important;color:#495057!important;border:1px solid #dee2e6!important;font-weight:500!important;padding:4px 8px!important;border-radius:4px!important;font-size:12px!important}::ng-deep .bs-datepicker .bs-datepicker-buttons .btn-secondary:hover{background:#e9ecef!important}::ng-deep .bs-datepicker-body{background:#fff!important;padding:6px!important}::ng-deep .bs-datepicker-body table{background:#fff!important;border-collapse:separate!important;border-spacing:1px!important}::ng-deep .bs-datepicker-body table th,::ng-deep .bs-datepicker-body table td{border:1px solid #dee2e6!important;border-radius:4px!important;text-align:center!important;font-weight:500!important;color:#495057!important;cursor:pointer!important;transition:all .2s ease!important;font-size:12px!important;width:32px!important;height:32px!important;line-height:24px!important}::ng-deep .bs-datepicker-body table th{background:#f8f9fa!important;font-weight:600!important;font-size:11px!important;padding:2px!important;height:24px!important;line-height:20px!important}::ng-deep .bs-datepicker-body table td:hover:not(.disabled){background:#e9ecef!important}::ng-deep .bs-datepicker-body table td.active{background:#007bff!important;color:#fff!important;border-color:#007bff!important}::ng-deep .bs-datepicker-body table td.is-other-month{color:#6c757d!important;background:#f8f9fa!important}::ng-deep .bs-datepicker-body table td.disabled{color:#adb5bd!important;background:#e9ecef!important;cursor:not-allowed!important}::ng-deep .bs-datepicker-custom-range{background:transparent!important;border-right:1px solid #dee2e6!important;padding:6px!important;width:130px!important;margin-right:8px!important;align-self:flex-start!important}::ng-deep .bs-datepicker-predefined-btns{display:flex!important;flex-direction:column!important;gap:2px!important}::ng-deep .bs-datepicker-predefined-btns button{background:transparent!important;color:#495057!important;border:1px solid #dee2e6!important;border-radius:4px!important;padding:4px 6px!important;font-size:11px!important;font-weight:500!important;text-align:left!important;cursor:pointer!important;transition:all .2s ease!important;width:100%!important;margin:0!important}::ng-deep .bs-datepicker-predefined-btns button:hover{background:#e9ecef!important;border-color:#adb5bd!important}::ng-deep .bs-datepicker-predefined-btns button:active,::ng-deep .bs-datepicker-predefined-btns button:focus{outline:none!important;box-shadow:0 0 0 2px #007bff40!important;background:#007bff!important;color:#fff!important;border-color:#007bff!important}.manual-logs-modal-overlay{position:fixed;top:0;left:0;width:100%;height:100%;background-color:#00000080;display:flex;justify-content:center;align-items:center;z-index:9999}.manual-logs-modal-content{background:#fff;border-radius:8px;max-width:800px;max-height:80vh;overflow:auto;box-shadow:0 4px 8px #0000001a}.popover__wrapper{position:relative;display:inline-block}.popover__content{position:absolute;bottom:100%;left:50%;transform:translate(-50%);background:#fff;border:1px solid #ccc;border-radius:8px;padding:12px;box-shadow:0 4px 12px #00000026;z-index:1000;opacity:0;visibility:hidden;transition:opacity .3s ease,visibility .3s ease;min-width:250px;max-width:400px;font-size:14px}.popover__wrapper:hover .popover__content{opacity:1;visibility:visible}.popover__content .modal-area{padding:0}.popover__content h4{margin:0 0 8px;font-size:16px;font-weight:600;color:#333}.popover__content .break-status{font-size:12px;color:#666;margin-bottom:8px}.popover__content .d-flex{gap:12px}.popover__content p{margin:0 0 4px;font-size:12px;color:#666}.popover__content h5{margin:0;font-size:14px;font-weight:500;color:#333}.popover__content .break-footer{border-top:1px solid #eee;margin-top:8px;padding-top:8px}.popover__content .break-footer p{font-size:12px;color:#666;margin:0}.custom-break-tooltip{position:fixed;z-index:1000;background:#fff;border:1px solid #ddd;border-radius:8px;box-shadow:0 4px 12px #00000026;padding:12px;font-size:13px;max-width:220px;pointer-events:none;top:0;left:0;transform:translate(var(--tooltip-x, 0px),var(--tooltip-y, 0px))}.custom-break-tooltips{position:fixed;z-index:1000;background:#fff;border:1px solid #ddd;border-radius:8px;box-shadow:0 4px 12px #00000026;padding:8px;font-size:12px;max-width:500px;max-height:300px;top:0;left:0;transform:translate(var(--tooltip-x, 0px),var(--tooltip-y, 0px))}.custom-break-tooltips .modal-body{max-height:250px!important;overflow-y:auto;padding:0}.custom-break-tooltips .table-responsive{max-height:250px}.custom-break-tooltips thead th{position:sticky;top:0;background:#f8f9fa;z-index:10;border-bottom:2px solid #dee2e6;font-size:11px;padding:4px 8px;font-weight:600}.custom-break-tooltips table{font-size:11px;margin-bottom:0}.custom-break-tooltips table td{padding:4px 8px;white-space:nowrap}.custom-break-tooltips .table-striped tbody tr:nth-of-type(odd){background-color:#00000005}.popver_content_progress_bar{visibility:hidden}.badge-overflow-container{display:flex;flex-wrap:nowrap;gap:4px;align-items:center;min-width:0;overflow:hidden;width:100%}.badge-overflow-container .badge{flex-shrink:0;white-space:nowrap;font-size:12px;padding:4px 8px;border-radius:50%;display:inline-flex;align-items:center;justify-content:center;font-weight:600;line-height:1;text-transform:uppercase;letter-spacing:.5px;transition:all .3s cubic-bezier(.4,0,.2,1);border:2px solid transparent;width:32px;height:32px;box-sizing:border-box;cursor:pointer;transform:translateZ(0);will-change:transform,box-shadow,background-color;backface-visibility:hidden}.badge-overflow-container .badge:hover{transform:scale(1.15) translateY(-2px);box-shadow:0 6px 16px #007bff40}.badge-overflow-container .badge:active{transform:scale(1.08) translateY(-1px);transition-duration:.15s}.badge-overflow-container .badge-overflow-count{background-color:#6c757d!important;color:#fff!important;cursor:pointer;border:2px solid #6c757d!important;flex-shrink:0;border-radius:50%;width:32px;height:32px;display:inline-flex;align-items:center;justify-content:center;font-weight:600;transition:all .3s cubic-bezier(.4,0,.2,1);transform:translateZ(0);will-change:transform,box-shadow,background-color;backface-visibility:hidden}.badge-overflow-container .badge-overflow-count:hover{background-color:#5a6268!important;border-color:#5a6268!important;transform:scale(1.15) translateY(-2px);box-shadow:0 6px 16px #007bff40}.badge-overflow-container .badge-overflow-count:active{transform:scale(1.08) translateY(-1px);transition-duration:.15s}.timeline-view-container{padding:1rem;background-color:#f8f9fa}.timeline-view-container .timeline-header{margin-bottom:2rem}.timeline-view-container .timeline-header h5{color:#495057;font-weight:600;margin-bottom:1rem}.timeline-view-container .timeline-header .timeline-hours{display:flex;justify-content:space-between;padding:.5rem 0;border-bottom:1px solid #dee2e6;margin-bottom:1rem;background:#fff;border-radius:8px;padding:1rem}.timeline-view-container .timeline-header .timeline-hours .timeline-hour{font-size:.8rem;color:#6c757d;font-weight:500;min-width:40px;text-align:center;padding:.5rem;border-radius:4px;background:#f8f9fa}.timeline-view-container .timeline-body .timeline-row{background:#fff;border:1px solid #dee2e6;border-radius:8px;margin-bottom:1rem;padding:1rem;box-shadow:0 2px 4px #0000001a;transition:box-shadow .2s ease}.timeline-view-container .timeline-body .timeline-row:hover{box-shadow:0 4px 8px #00000026}.timeline-view-container .timeline-body .timeline-row .timeline-employee{margin-bottom:1rem}.timeline-view-container .timeline-body .timeline-row .timeline-employee .employee-name{font-weight:600;color:#495057;font-size:1.1rem}.timeline-view-container .timeline-body .timeline-row .timeline-track{position:relative;height:40px;background:#f8f9fa;border-radius:4px;border:1px solid #e9ecef}.timeline-view-container .timeline-body .timeline-row .timeline-track .work-duration-bar{position:absolute;height:100%;background:linear-gradient(135deg,#28a745,#20c997);border-radius:4px;box-shadow:0 2px 4px #28a7454d;transition:opacity .2s ease}.timeline-view-container .timeline-body .timeline-row .timeline-track .work-duration-bar:hover{opacity:.8}.timeline-view-container .timeline-body .timeline-row .timeline-track .break-bar{position:absolute;height:100%;border-radius:4px;box-shadow:0 2px 4px #0003;border:1px solid rgba(255,255,255,.5);transition:opacity .2s ease}.timeline-view-container .timeline-body .timeline-row .timeline-track .break-bar:hover{opacity:.8}.calendar-view-container .calendar-header{margin-bottom:2rem}.calendar-view-container .calendar-header h5{color:#495057;font-weight:600}.calendar-view-container .calendar-header .calendar-nav button{border:1px solid #dee2e6;background:#fff;color:#495057;padding:.375rem .75rem;border-radius:.375rem;transition:all .2s ease}.calendar-view-container .calendar-header .calendar-nav button:hover{background-color:#f8f9fa;border-color:#adb5bd}.calendar-view-container .calendar-header .calendar-nav button:first-child{border-top-right-radius:0;border-bottom-right-radius:0;border-right:none}.calendar-view-container .calendar-header .calendar-nav button:last-child{border-top-left-radius:0;border-bottom-left-radius:0}.calendar-view-container .calendar-grid .calendar-week-header{display:flex;background-color:#f8f9fa;border:1px solid #dee2e6;border-bottom:none}.calendar-view-container .calendar-grid .calendar-week-header .calendar-day-header{flex:1;padding:.75rem;text-align:center;font-weight:600;color:#495057;border-right:1px solid #dee2e6}.calendar-view-container .calendar-grid .calendar-week-header .calendar-day-header:last-child{border-right:none}.calendar-view-container .calendar-grid .calendar-weeks{border:1px solid #dee2e6;border-top:none}.calendar-view-container .calendar-grid .calendar-weeks .calendar-week{display:flex;border-bottom:1px solid #dee2e6}.calendar-view-container .calendar-grid .calendar-weeks .calendar-week:last-child{border-bottom:none}.calendar-view-container .calendar-grid .calendar-weeks .calendar-week .calendar-day{flex:1;min-height:100px;padding:.5rem;border-right:1px solid #dee2e6;background:#fff}.calendar-view-container .calendar-grid .calendar-weeks .calendar-week .calendar-day:last-child{border-right:none}.calendar-view-container .calendar-grid .calendar-weeks .calendar-week .calendar-day.current-month{background:#fff}.calendar-view-container .calendar-grid .calendar-weeks .calendar-week .calendar-day.today{background-color:#fff3cd;border:2px solid #ffc107}.calendar-view-container .calendar-grid .calendar-weeks .calendar-week .calendar-day .day-number{font-weight:600;color:#495057;margin-bottom:.25rem}.calendar-view-container .calendar-grid .calendar-weeks .calendar-week .calendar-day .day-entries .entry-dot{width:8px;height:8px;border-radius:50%;display:inline-block;margin-right:2px;margin-bottom:2px}.heatmap-view-container .heatmap-header{margin-bottom:2rem}.heatmap-view-container .heatmap-header h5{color:#495057;font-weight:600}.heatmap-view-container .heatmap-header .heatmap-legend .legend-colors{display:flex;margin:0 1rem}.heatmap-view-container .heatmap-header .heatmap-legend .legend-colors .legend-color{width:12px;height:12px;margin-right:2px;border-radius:2px}.heatmap-view-container .heatmap-header .heatmap-legend span{font-size:.875rem;color:#6c757d}.heatmap-view-container .heatmap-grid .heatmap-months{display:flex;margin-bottom:.5rem}.heatmap-view-container .heatmap-grid .heatmap-months .month-label{flex:1;text-align:center;font-size:.8rem;font-weight:600;color:#495057}.heatmap-view-container .heatmap-grid .heatmap-weeks .heatmap-week{display:flex;margin-bottom:2px}.heatmap-view-container .heatmap-grid .heatmap-weeks .heatmap-week .heatmap-day{flex:1;aspect-ratio:1;border-radius:2px;margin-right:2px;transition:opacity .2s ease}.heatmap-view-container .heatmap-grid .heatmap-weeks .heatmap-week .heatmap-day:hover{opacity:.8}.heatmap-view-container .heatmap-grid .heatmap-weeks .heatmap-week .heatmap-day:last-child{margin-right:0}.card-view-container{padding:1rem;height:100%;overflow-y:auto;overflow-x:hidden}.card-view-container[data-theme=white]{background-color:#f6f8ff;color:#000}.card-view-container[data-theme=white] .attendance-card{background-color:#f6f8ff;border-color:#d9d9db;color:#000}.card-view-container[data-theme=white] .attendance-card:hover{background-color:#007bff1a}.card-view-container[data-theme=white] .attendance-card .card-header{background-color:#f8f9fa;color:#000;border-bottom-color:#d9d9db}.card-view-container[data-theme=white] .attendance-card .card-body{background-color:#f6f8ff;color:#000}.card-view-container[data-theme=white] .attendance-card .badge.bg-success{background-color:#84ca81;color:#f6f8ff}.card-view-container[data-theme=white] .attendance-card .badge.bg-danger{background-color:#ea5353;color:#f6f8ff}.card-view-container[data-theme=white] .attendance-card .badge.bg-warning{background-color:#fff3dc;color:#000}.card-view-container[data-theme=white] .attendance-card .badge.bg-info{background-color:#e8fbfd;color:#00bad1}.card-view-container[data-theme=blue]{background-color:#f0f8ff;color:#1e3a5f}.card-view-container[data-theme=blue] .attendance-card{background-color:#f6f8ff;border-color:#b3d9ff;color:#1e3a5f}.card-view-container[data-theme=blue] .attendance-card:hover{background-color:#1e3a5f1a}.card-view-container[data-theme=blue] .attendance-card .card-header{background-color:#e6f3ff;color:#1e3a5f;border-bottom-color:#b3d9ff}.card-view-container[data-theme=blue] .attendance-card .card-body{background-color:#f6f8ff;color:#1e3a5f}.card-view-container[data-theme=blue] .attendance-card .badge.bg-success{background-color:#69db7c;color:#f6f8ff}.card-view-container[data-theme=blue] .attendance-card .badge.bg-danger{background-color:#ff8787;color:#f6f8ff}.card-view-container[data-theme=blue] .attendance-card .badge.bg-warning{background-color:#ffd43b;color:#1e3a5f}.card-view-container[data-theme=blue] .attendance-card .badge.bg-info{background-color:#74c0fc;color:#f6f8ff}.card-view-container .row{margin:0}.card-view-container .row .col-xl-4,.card-view-container .row .col-lg-6,.card-view-container .row .col-md-6,.card-view-container .row .col-sm-12{padding:.5rem}.card-view-container .attendance-card{transition:background-color .2s ease;border:1px solid #d9d9db;border-radius:4px;overflow:hidden;height:100%;display:flex;flex-direction:column;font-family:sans-serif;font-size:16px}.card-view-container .attendance-card:hover{box-shadow:0 2px 4px #0000001a}.card-view-container .attendance-card.expanded .card-body{max-height:none}.card-view-container .attendance-card .card-header{padding:8px;border-bottom:1px solid #d9d9db;flex-shrink:0;font-weight:500}.card-view-container .attendance-card .card-header .employee-avatar{margin-right:.75rem;flex-shrink:0}.card-view-container .attendance-card .card-header .employee-avatar img,.card-view-container .attendance-card .card-header .employee-avatar .avatar-placeholder{border:1px solid #d9d9db;width:40px;height:40px;border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:16px;font-weight:400}.card-view-container .attendance-card .card-header .flex-grow-1{min-width:0}.card-view-container .attendance-card .card-header h6{margin:0;font-weight:500;font-size:16px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.card-view-container .attendance-card .card-header small{opacity:.9;font-weight:400;font-size:16px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.card-view-container .attendance-card .card-header .card-actions{flex-shrink:0}.card-view-container .attendance-card .card-header .card-actions .btn{background-color:transparent;border:1px solid #d9d9db;color:inherit;padding:.25rem .5rem}.card-view-container .attendance-card .card-header .card-actions .btn:hover{background-color:#007bff1a}.card-view-container .attendance-card .card-header .card-actions .btn i{font-size:.8rem}.card-view-container .attendance-card .card-body{padding:8px;flex:1;display:flex;flex-direction:column}.card-view-container .attendance-card .card-body .info-item{text-align:center;margin-bottom:.5rem}.card-view-container .attendance-card .card-body .info-item small{display:block;font-weight:400;color:#6c757d;text-transform:uppercase;font-size:12px;letter-spacing:.5px;margin-bottom:.25rem}.card-view-container .attendance-card .card-body .info-item span{font-size:16px;font-weight:400;color:inherit}.card-view-container .attendance-card .card-body .badge{font-size:12px;padding:.25rem .5rem;border-radius:4px;font-weight:400;text-transform:uppercase;letter-spacing:.5px;border:none}.card-view-container .attendance-card .card-body .badge.bg-success,.card-view-container .attendance-card .card-body .badge.bg-danger{color:#f6f8ff}.card-view-container .attendance-card .card-body .badge.bg-warning{color:#000}.card-view-container .attendance-card .card-body .badge.bg-secondary{color:#f6f8ff}.card-view-container .attendance-card .card-body .card-details{margin-top:1rem}.card-view-container .attendance-card .card-body .card-details .section-title{font-size:14px;font-weight:500;color:inherit;margin-bottom:.75rem;display:flex;align-items:center}.card-view-container .attendance-card .card-body .card-details .section-title i{margin-right:.5rem;opacity:.8}.card-view-container .attendance-card .card-body .card-details .breaks-list .break-item,.card-view-container .attendance-card .card-body .card-details .breaks-list .leave-item,.card-view-container .attendance-card .card-body .card-details .short-leave-list .break-item,.card-view-container .attendance-card .card-body .card-details .short-leave-list .leave-item{background-color:inherit;border:1px solid #d9d9db;border-radius:4px;padding:8px;margin-bottom:.5rem;cursor:pointer;transition:all .25s cubic-bezier(.4,0,.2,1);transform:translateZ(0)}.card-view-container .attendance-card .card-body .card-details .breaks-list .break-item .d-flex,.card-view-container .attendance-card .card-body .card-details .breaks-list .leave-item .d-flex,.card-view-container .attendance-card .card-body .card-details .short-leave-list .break-item .d-flex,.card-view-container .attendance-card .card-body .card-details .short-leave-list .leave-item .d-flex{gap:.75rem;align-items:center}.card-view-container .attendance-card .card-body .card-details .breaks-list .break-item .d-flex small,.card-view-container .attendance-card .card-body .card-details .breaks-list .leave-item .d-flex small,.card-view-container .attendance-card .card-body .card-details .short-leave-list .break-item .d-flex small,.card-view-container .attendance-card .card-body .card-details .short-leave-list .leave-item .d-flex small{font-weight:500;color:inherit;margin-bottom:.25rem}.card-view-container .attendance-card .card-body .card-details .breaks-list .break-item .d-flex .text-muted,.card-view-container .attendance-card .card-body .card-details .breaks-list .leave-item .d-flex .text-muted,.card-view-container .attendance-card .card-body .card-details .short-leave-list .break-item .d-flex .text-muted,.card-view-container .attendance-card .card-body .card-details .short-leave-list .leave-item .d-flex .text-muted{font-size:12px;color:#6c757d}.card-view-container .attendance-card .card-body .card-details .breaks-list .break-item .d-flex .badge,.card-view-container .attendance-card .card-body .card-details .breaks-list .leave-item .d-flex .badge,.card-view-container .attendance-card .card-body .card-details .short-leave-list .break-item .d-flex .badge,.card-view-container .attendance-card .card-body .card-details .short-leave-list .leave-item .d-flex .badge{font-size:10px;padding:.2rem .4rem}.card-view-container .attendance-card .card-body .card-details .additional-details .row .col-6{margin-bottom:.5rem}.card-view-container .attendance-card .card-body .card-details .additional-details .row .col-6 small{font-weight:400;color:#6c757d;text-transform:uppercase;font-size:12px;letter-spacing:.5px;margin-bottom:.25rem}.card-view-container .attendance-card .card-body .card-details .additional-details .row .col-6 span{font-weight:400;color:inherit;font-size:14px}@media (max-width: 1200px){.card-view-container .row .col-xl-4{flex:0 0 50%;max-width:50%}}@media (max-width: 768px){.card-view-container .row .col-xl-4,.card-view-container .col-lg-6,.card-view-container .col-md-6{flex:0 0 100%;max-width:100%}.card-view-container .attendance-card .card-body{padding:8px}.card-view-container .attendance-card .card-body .info-item small{font-size:10px}.card-view-container .attendance-card .card-body .info-item span{font-size:14px}}@media (max-width: 576px){.card-view-container{padding:.5rem}.card-view-container .row .col-sm-12{padding:.25rem}.card-view-container .attendance-card .card-header{padding:8px}.card-view-container .attendance-card .card-header h6,.card-view-container .attendance-card .card-header small{font-size:14px}.card-view-container .attendance-card .card-body{padding:8px}}.btn-xs{padding:.125rem .3rem!important;font-size:.9rem!important;border-radius:.2rem!important;line-height:1.5!important}.form-select.form-select-sm:invalid{border-color:#d9d9db!important}.form-select.form-select-sm:valid{border-color:#d9d9db!important}.date-range-container{gap:8px;flex-wrap:nowrap;align-items:center}.date-range-btn{padding:6px 12px;font-size:14px;font-weight:500;border-radius:6px;transition:all .25s cubic-bezier(.4,0,.2,1);white-space:nowrap;display:inline-flex;align-items:center;justify-content:center;min-height:36px;transform:translateZ(0);position:relative;overflow:hidden}.date-range-btn:before{content:\"\";position:absolute;top:50%;left:50%;width:0;height:0;background:#fff3;border-radius:50%;transform:translate(-50%,-50%);transition:width .25s,height .25s}.date-range-btn:active:before{width:300px;height:300px}.calendar-btn{border-color:#0d6efd;color:#0d6efd;background-color:transparent}.calendar-btn:hover{background-color:#0d6efd;color:#fff;transform:translateY(-1px);box-shadow:0 4px 12px #0d6efd4d}.clear-btn{border-color:#dc3545;color:#dc3545;background-color:transparent}.clear-btn:hover{background-color:#dc3545;color:#fff;transform:translateY(-1px);box-shadow:0 4px 12px #dc35454d}.date-range-label{font-size:14px;font-weight:500;padding:4px 8px;min-width:180px;text-align:center;white-space:nowrap;cursor:pointer}.date-range-btn .bi{font-size:14px;transition:transform .2s ease}.date-range-btn:hover .bi{transform:scale(1.1)}@media (max-width: 768px){.date-range-container{flex-wrap:wrap;justify-content:flex-start}.date-range-label{min-width:100%;margin-top:8px;order:3}}.date-range-btn:focus{outline:none;box-shadow:0 0 0 3px #0d6efd40}.clear-btn:focus{box-shadow:0 0 0 3px #dc354540}.action-buttons-row .button{display:inline-flex;align-items:center;justify-content:center;overflow:hidden;color:#fff;border-radius:6px;height:34px;padding:0 10px;white-space:nowrap;transition:max-width .4s ease,background-color .3s ease;max-width:40px;background-color:transparent;border:1px solid #6F61CF}.action-buttons-row .button .label-hidden{opacity:0;margin-left:8px;transition:opacity .3s ease;pointer-events:none;display:none}.action-buttons-row .button:hover{max-width:200px;background-color:#6f61cf}.action-buttons-row .button:hover .label-hidden{opacity:1;pointer-events:auto;margin-left:8px!important;display:block}.action-buttons-row ::ng-deep .button .svg-icon svg path{stroke:#6f61cf;transition:fill .3s ease,stroke .3s ease}.action-buttons-row ::ng-deep .button:hover .svg-icon svg path{stroke:#fff!important}.action-buttons-row ::ng-deep .button:active .svg-icon svg path{stroke:#6f61cf!important}.action-buttons-row ::ng-deep .button:focus .svg-icon svg path{stroke:#6f61cf!important}.badge-overflow-wrapper{width:100%;min-width:0;display:flex;align-items:center}.custom-overlay-wrapper{position:fixed;top:0;left:0;width:100%;height:100%;background-color:#00000080;display:flex;justify-content:center;align-items:center;z-index:9999}.custom-overlay{background:#fff;border-radius:8px;box-shadow:0 4px 12px #00000026;min-width:300px;max-width:400px}.custom-modal-body{padding:20px;text-align:center}.custom-modal-body .modal-message{font-size:16px;margin-bottom:20px;color:#333}.custom-modal-body .modal-actions{display:flex;gap:10px;justify-content:center}.custom-modal-body .modal-actions button{padding:8px 16px;border:none;border-radius:4px;cursor:pointer;font-size:14px;transition:background-color .2s ease}.custom-modal-body .modal-actions button.btn-confirm{background-color:#007bff;color:#fff}.custom-modal-body .modal-actions button.btn-confirm:hover{background-color:#0056b3}.custom-modal-body .modal-actions button.btn-cancel{background-color:#6c757d;color:#fff}.custom-modal-body .modal-actions button.btn-cancel:hover{background-color:#545b62}.custom-break-tooltip .short-break-table{width:100%;border-collapse:collapse;font-size:12px}.custom-break-tooltip .short-break-table th,.custom-break-tooltip .short-break-table td{padding:4px 6px;text-align:center;border:1px solid #ddd}.custom-break-tooltip .short-break-table th{background-color:#f8f9fa;font-weight:600}.custom-break-tooltip .short-break-table tbody tr:nth-child(2n){background-color:#fafafa}.text-truncate{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;display:flex;align-items:center;min-width:0}\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: "ngmodule", type: FormsModule }, { kind: "directive", type: i3.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i3.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i3.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i3.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i3.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i3.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i3.RadioControlValueAccessor, selector: "input[type=radio][formControlName],input[type=radio][formControl],input[type=radio][ngModel]", inputs: ["name", "formControlName", "value"] }, { kind: "directive", type: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i3.PatternValidator, selector: "[pattern][formControlName],[pattern][formControl],[pattern][ngModel]", inputs: ["pattern"] }, { kind: "directive", type: i3.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: InlineSVGModule }, { kind: "directive", type: i4.InlineSVGDirective, selector: "[inlineSVG]", inputs: ["inlineSVG", "resolveSVGUrl", "replaceContents", "prepend", "injectComponent", "cacheSVG", "setSVGAttributes", "removeSVGAttributes", "forceEvalStyles", "evalScripts", "fallbackImgUrl", "fallbackSVG", "onSVGLoaded"], outputs: ["onSVGInserted", "onSVGFailed"] }, { kind: "pipe", type: FilterPipe, name: "filter" }, { kind: "pipe", type: PinnedColumnsPipe, name: "pinnedColumns" }, { kind: "ngmodule", type: DragDropModule }, { kind: "directive", type: i5.CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: i5.CdkDropListGroup, selector: "[cdkDropListGroup]", inputs: ["cdkDropListGroupDisabled"], exportAs: ["cdkDropListGroup"] }, { kind: "directive", type: i5.CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "directive", type: i5.CdkDragHandle, selector: "[cdkDragHandle]", inputs: ["cdkDragHandleDisabled"] }, { kind: "directive", type: i5.CdkDragPreview, selector: "ng-template[cdkDragPreview]", inputs: ["data", "matchSize"] }, { kind: "directive", type: i5.CdkDragPlaceholder, selector: "ng-template[cdkDragPlaceholder]", inputs: ["data"] }, { kind: "ngmodule", type: BsDatepickerModule }, { kind: "directive", type: i6.BsDaterangepickerDirective, selector: "[bsDaterangepicker]", inputs: ["placement", "triggers", "outsideClick", "container", "outsideEsc", "isOpen", "bsValue", "bsConfig", "isDisabled", "minDate", "maxDate", "dateCustomClasses", "daysDisabled", "datesDisabled", "datesEnabled"], outputs: ["onShown", "onHidden", "bsValueChange"], exportAs: ["bsDaterangepicker"] }, { kind: "directive", type: i6.BsDaterangepickerInputDirective, selector: "input[bsDaterangepicker]" }, { kind: "ngmodule", type: ScrollingModule }, { kind: "directive", type: i7.CdkFixedSizeVirtualScroll, selector: "cdk-virtual-scroll-viewport[itemSize]", inputs: ["itemSize", "minBufferPx", "maxBufferPx"] }, { kind: "directive", type: i7.CdkVirtualForOf, selector: "[cdkVirtualFor][cdkVirtualForOf]", inputs: ["cdkVirtualForOf", "cdkVirtualForTrackBy", "cdkVirtualForTemplate", "cdkVirtualForTemplateCacheSize"] }, { kind: "component", type: i7.CdkVirtualScrollViewport, selector: "cdk-virtual-scroll-viewport", inputs: ["orientation", "appendOnly"], outputs: ["scrolledIndexChange"] }, { kind: "component", type: BadgeOverflowComponent, selector: "app-badge-overflow", inputs: ["badges", "maxWidth"], outputs: ["badgeMouseEnter", "badgeMouseLeave", "overflowCountClick"] }, { kind: "pipe", type: TimezoneFormatPipe, name: "timezoneFormat" }], animations: [
9335
9455
  trigger('accordionToggle', [
9336
9456
  state('collapsed', style({ height: '0px', overflow: 'unset' })),
9337
9457
  state('expanded', style({ height: '*', overflow: 'unset' })),
@@ -9585,7 +9705,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
9585
9705
  ], { optional: true })
9586
9706
  ]),
9587
9707
  ])
9588
- ], template: "<div class=\"position-relative h-100\">\n <!-- <h1>abu </h1> -->\n <div\n class=\"d-flex justify-content-between mb-3 align-items-center position-relative\"\n >\n <div class=\"col-4 global-search position-relative\">\n\n <span\n\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/search.svg'\"\n class=\"data-grid-svg-icon mx-2 position-absolute icon\"\n ></span>\n <input\n style=\"height: 36px\"\n class=\"form-control\"\n placeholder=\"Search all columns and press Enter\"\n [(ngModel)]=\"tableSearch\"\n (keydown.enter)=\"onGlobalSearch()\"\n\n />\n <span\n *ngIf=\"tableSearch\"\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/x.svg'\"\n class=\"data-grid-svg-icon position-absolute end-0 top-50 translate-middle-y me-2 cursor-pointer\"\n (click)=\"onSearchReset()\"\n title=\"Clear search\"\n ></span>\n\n </div>\n\n <!-- Date Picker Buttons -->\n <!-- Date Picker Section - Improved Version -->\n<div class=\"position-relative d-flex justify-content-center align-items-center ms-2 date-range-container\">\n\n <!-- Hidden Date Picker Input -->\n <input\n type=\"text\"\n class=\"form-control\"\n bsDaterangepicker\n #picker=\"bsDaterangepicker\"\n [(ngModel)]=\"bsRangeValue\"\n [bsConfig]=\"bsConfig\"\n (bsValueChange)=\"onRangeSelected($event, picker)\"\n style=\"opacity: 0; width: 0; height: 0; position: absolute;\"\n />\n\n <!-- Left Arrow Button -->\n <span\n class=\"text-primary cursor-pointer me-2 date-range-btn arrow-btn\"\n (click)=\"navigateDate('left')\"\n title=\"Previous Date Range\"\n *ngIf=\"bsRangeValue && bsRangeValue.length > 0\"\n >\n <span class=\"bi bi-chevron-left\"></span>\n </span>\n\n <!-- Date Range Label -->\n <span\n *ngIf=\"bsRangeValue && bsRangeValue.length > 0\"\n class=\"text-primary date-range-label cursor-pointer\"\n (click)=\"togglePicker(picker)\"\n title=\"Click to open calendar\"\n >\n {{ bsRangeValue[0] | timezoneFormat:prefs:'date' }} - {{ bsRangeValue[1] | timezoneFormat:prefs:'date' }}\n </span>\n\n <!-- Right Arrow Button -->\n <span\n class=\"text-primary cursor-pointer ms-2 date-range-btn arrow-btn\"\n (click)=\"navigateDate('right')\"\n title=\"Next Date Range\"\n *ngIf=\"bsRangeValue && bsRangeValue.length > 0\"\n >\n <span class=\"bi bi-chevron-right\"></span>\n </span>\n\n\n\n</div>\n\n <div class=\"d-flex gap-2 align-items-center table-right-top-actions\">\n\n <!-- Pivot Mode Button -->\n <!-- <a\n href=\"JavaScript:void(0)\"\n class=\"button button-small btn btn-active-primary border border-primary me-2 header-icon\"\n (click)=\"togglePivotMode()\"\n [class.active]=\"pivotMode\"\n title=\"Toggle Pivot Mode\"\n >\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/pivot.svg'\"\n class=\"svg-icon svg-icon-2\"\n ></span>\n </a> -->\n\n <div class=\"action-buttons-row d-flex gap-2 align-items-center\">\n <a\n href=\"JavaScript:void(0)\"\n class=\"button button-small btn btn-active-primary border border-primary p-0 d-flex align-items-center justify-content-center px-3\"\n (click)=\"togglePicker(picker)\"\n title=\"Select Date Range\"\n >\n <span class=\"bi bi-calendar3 text-primary\"></span>\n <span class=\"label-hidden text-white\">Calendar</span>\n </a>\n <button\n *ngIf=\"bsRangeValue && bsRangeValue.length > 0 && !isDefaultDateRange\"\n type=\"button\"\n class=\"button button-small btn btn-active-danger border border-danger p-0 d-flex align-items-center justify-content-center px-3\"\n (click)=\"clearDateRange()\"\n title=\"Clear Date Range\"\n >\n <span class=\"bi bi-x-circle text-danger\"></span>\n <span class=\"label-hidden text-white\">Clear</span>\n </button>\n</div>\n<ng-container *ngFor=\"let button of buttons\">\n <div\n class=\"action-buttons-row d-flex align-items-center\"\n *ngIf=\"getButtonPermission(button) && (!button.condition || (button.condition === '!isSingleDay' && !isSingleDay) || (button.condition === 'isSingleDay' && isSingleDay))\"\n >\n <a\n href=\"JavaScript:void(0)\"\n (click)=\"onActionButtonClick(button.name)\"\n class=\"button\"\n [title]=\"button.name\"\n >\n <span\n *ngIf=\"button.is_showIcon\"\n [inlineSVG]=\"button.iconPath\"\n class=\"svg-icon\"\n ></span>\n <span\n class=\"label-hidden\"\n >{{ button.name }}</span\n >\n </a>\n </div>\n</ng-container>\n\n<!-- Calendar Button -->\n\n\n<!-- Existing filter, settings, etc. -->\n <div\n *ngIf=\"!showFilterRow\"\n class=\"cursor-pointer position-relative action-buttons-row d-flex align-items-center\"\n (click)=\"toggleOpenFilter()\"\n [class.active]=\"showFilters\"\n >\n <a\n href=\"JavaScript:void(0)\"\n class=\"button button-small btn btn-active-primary border border-primary p-0 d-flex align-items-center justify-content-center px-3\"\n >\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\"\n class=\"svg-icon svg-icon-2\"\n ></span>\n <span class=\"label-hidden text-white\">Filters</span>\n </a>\n <span\n *ngIf=\"activeFilteredColumns?.length\"\n style=\"\n width: 7px;\n height: 7px;\n box-shadow: 0px 0px 3px #0022ff;\n background-color: rgb(0, 60, 255);\n position: absolute;\n right: 16px;\n top: 10px;\n \"\n class=\"rounded-circle d-block\"\n ></span>\n </div>\n <div\n class=\"cursor-pointer d-none\"\n (click)=\"toggleActions('advance-filter')\"\n [class.active]=\"activeTopButton === 'advance-filter'\"\n >\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/zoom-charge.svg'\"\n class=\"data-grid-svg-icon top-icon me-2\"\n ></span>\n </div>\n <div\n class=\"cursor-pointer action-buttons-row\"\n (click)=\"toggleActions('setting')\"\n [class.active]=\"\n activeTopButton === 'setting' ||\n activeTopButton === 'table-layout' ||\n activeTopButton === 'table-presets' ||\n activeTopButton === 'show-hide-columns'\n \"\n >\n <!-- <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/settings-2.svg'\"\n class=\"data-grid-svg-icon top-icon me-2\"\n ></span> -->\n <a\n href=\"JavaScript:void(0)\"\n class=\"button button-small btn btn-active-primary border border-primary p-0 d-flex align-items-center justify-content-center px-3\"\n >\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/settings-2.svg'\"\n class=\"svg-icon svg-icon-2\"\n ></span>\n <span class=\"label-hidden text-white\">Setting</span>\n </a>\n\n <div\n *ngIf=\"activeTopButton === 'setting'\"\n class=\"actions-dropdown mt-1 actions-dropdown-setting\"\n style=\"position: absolute\"\n >\n <div class=\"dropdown-menu show shadow custom-menu\">\n <!-- Table Layout -->\n <a\n class=\"dropdown-item d-flex justify-content-between align-items-center cursor-pointer\"\n (click)=\"$event.stopPropagation(); toggleActions('table-layout')\"\n >\n <span\n ><span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/table-2.svg'\n \"\n class=\"data-grid-svg-icon me-2\"\n ></span>\n Table Layout</span\n >\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\n \"\n class=\"data-grid-svg-icon me-2\"\n ></span>\n </a>\n <!-- Table Presets -->\n <a\n (click)=\"$event.stopPropagation(); toggleActions('table-presets')\"\n class=\"dropdown-item d-flex justify-content-between align-items-center cursor-pointer\"\n >\n <span\n ><span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/list-details.svg'\n \"\n class=\"data-grid-svg-icon me-2\"\n ></span>\n Table Presets</span\n >\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\n \"\n class=\"data-grid-svg-icon me-2\"\n ></span>\n </a>\n\n <!-- Columns -->\n <a\n *ngIf=\"!showSideMenu\"\n (click)=\"\n $event.stopPropagation(); toggleActions('show-hide-columns')\n \"\n class=\"dropdown-item d-flex justify-content-between align-items-center cursor-pointer\"\n >\n <span\n ><span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/eye.svg'\"\n class=\"data-grid-svg-icon me-2\"\n ></span>\n Columns</span\n >\n <div class=\"d-flex gap-2\">\n <span class=\"muted-text\">{{ columnsCount }}</span>\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\n \"\n class=\"data-grid-svg-icon me-2\"\n ></span>\n </div>\n </a>\n\n <div class=\"dropdown-divider\"></div>\n\n <!-- Filter -->\n <a\n class=\"dropdown-item cursor-pointer\"\n (click)=\"toggleOpenFilter(); activeTopButton = ''\"\n *ngIf=\"!showFilterRow\"\n >\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\n \"\n class=\"data-grid-svg-icon me-2 mt-1 cursor-pointer\"\n ></span>\n Filter\n </a>\n\n <!-- Download -->\n <!-- <a\n class=\"dropdown-item cursor-pointer\"\n (click)=\"downloadCsv('csv')\"\n >\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/download.svg'\n \"\n class=\"data-grid-svg-icon me-2 cursor-pointer\"\n ></span>\n CSV Export\n </a> -->\n <!-- <a\n *ngIf=\"enableExport\"\n class=\"dropdown-item cursor-pointer\"\n (click)=\"downloadCsv('xlsx')\"\n >\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/download.svg'\n \"\n class=\"data-grid-svg-icon me-2 cursor-pointer\"\n ></span>\n Excel Export\n </a> -->\n <!-- Font Family & Font Size -->\n <div class=\"px-2 pb-2 pt-2\">\n <div class=\"d-flex gap-2\">\n <!-- Font Family -->\n <select\n class=\"form-select form-select-sm\"\n [(ngModel)]=\"fontFaimly\"\n (change)=\"onFontChange()\"\n >\n <option *ngFor=\"let font of fontFamilies\" [value]=\"font\">\n {{ font }}\n </option>\n </select>\n\n <!-- Font Size -->\n <select\n class=\"form-select form-select-sm\"\n (change)=\"onFontChange()\"\n [(ngModel)]=\"bodyTextFontsSize\"\n >\n <option *ngFor=\"let size of fontSizes\" [value]=\"size\">\n {{ size }}\n </option>\n </select>\n </div>\n </div>\n </div>\n </div>\n\n <!-- Table Layout -->\n\n <ng-container *ngIf=\"activeTopButton === 'table-layout'\">\n <div\n *ngTemplateOutlet=\"tableLayout\"\n class=\"actions-dropdown mt-1\"\n style=\"position: absolute\"\n ></div>\n </ng-container>\n\n <!-- Table Presets -->\n <ng-container *ngIf=\"activeTopButton === 'table-presets'\">\n <div\n *ngTemplateOutlet=\"tablePreset\"\n class=\"actions-dropdown mt-1\"\n style=\"position: absolute\"\n ></div>\n </ng-container>\n\n <!-- Table Presets -->\n <ng-container *ngIf=\"activeTopButton === 'show-hide-columns'\">\n <div\n *ngTemplateOutlet=\"showHideColumns\"\n class=\"actions-dropdown mt-1\"\n style=\"position: absolute\"\n ></div>\n </ng-container>\n </div>\n <div>\n <!-- Example single danger button -->\n\n <!-- <button\n type=\"button\"\n class=\"btn btn-primary btn-sm d-flex gap-2 action-button\"\n (click)=\"toggleActions('actions')\"\n >\n Action\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/Vector.svg'\"\n class=\"data-grid-svg-icon\"\n ></span>\n </button>\n <div\n *ngIf=\"activeTopButton === 'actions'\"\n class=\"actions-dropdown mt-1\"\n >\n <div class=\"dropdown-menu show\">\n <a class=\"dropdown-item\" href=\"#\">Action</a>\n <a class=\"dropdown-item\" href=\"#\">Another action</a>\n <a class=\"dropdown-item\" href=\"#\">Something else here</a>\n <div class=\"dropdown-divider\"></div>\n <a class=\"dropdown-item\" href=\"#\">Separated link</a>\n </div>\n </div> -->\n </div>\n </div>\n </div>\n\n <div\n *ngIf=\"showFilters && !showFilterRow\"\n class=\"top-filter-row border-top py-2 d-flex justify-content-between align-items-center\"\n [style.height.px]=\"topFilterRowHeight\"\n >\n <!-- LEFT SIDE (Filter tags + Filter button) -->\n <div class=\"d-flex gap-2 align-items-center\">\n <ng-container *ngIf=\"activeFilteredColumns?.length\">\n <div\n *ngFor=\"let col of activeFilteredColumns; trackBy: trackByField\"\n class=\"filter-tags\"\n >\n <div\n (click)=\"\n isActiveFilterOpen = true;\n activeTopButton = 'filter-columns';\n openFilter(col)\n \"\n class=\"d-flex justify-content-center align-items-center muted-text add-filter-button active-filters\"\n style=\"white-space: nowrap\"\n [class.active]=\"\n col?.field == selectedColumnForFilter?.field &&\n isActiveFilterOpen &&\n activeTopButton == 'filter-columns'\n \"\n >\n <span class=\"header-tag mt-0 d-flex align-items-center\">\n <span\n *ngIf=\"col?.pinned\"\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/pin.svg'\"\n class=\"data-grid-svg-icon me-2\"\n ></span>\n {{ col.header }}\n <span\n (click)=\"\n $event.stopPropagation(); removeColumnFilterFromColumn(col)\n \"\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/cross-primary.svg'\n \"\n class=\"data-grid-svg-icon cross-secondary ms-2 mb-1\"\n ></span>\n </span>\n </div>\n\n <ng-container\n *ngIf=\"\n activeTopButton === 'filter-columns' &&\n col?.field == selectedColumnForFilter?.field &&\n isActiveFilterOpen\n \"\n >\n <div\n *ngTemplateOutlet=\"filterColumns; context: { column: col }\"\n class=\"actions-dropdown mt-1\"\n ></div>\n </ng-container>\n </div>\n </ng-container>\n\n <!-- Filter Button -->\n <div class=\"add-filter-button-menu\">\n <div\n (click)=\"toggleActions('filter-columns'); isActiveFilterOpen = false\"\n class=\"d-flex justify-content-center align-items-center muted-text add-filter-button button-filter\"\n style=\"width: 70px\"\n >\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/plus.svg'\"\n class=\"me-2 data-grid-svg-icon\"\n ></span>\n Filter\n </div>\n\n <ng-container\n *ngIf=\"activeTopButton === 'filter-columns' && !isActiveFilterOpen\"\n >\n <div\n *ngTemplateOutlet=\"filterColumns\"\n class=\"actions-dropdown mt-1\"\n ></div>\n </ng-container>\n </div>\n </div>\n\n <!-- RIGHT SIDE (Update + Reset) -->\n <div class=\"d-flex gap-3 align-items-center\">\n <div\n (click)=\"savePreset()\"\n class=\"text-primary cursor-pointer all-filters-reset-button\"\n *ngIf=\"!checkFilterChangesEffect()\"\n >\n Update View\n </div>\n\n <div\n class=\"text-primary cursor-pointer all-filters-reset-button\"\n *ngIf=\"!tableFilterViewId && activeFilteredColumns?.length\"\n (click)=\"clearAllFilters()\"\n >\n Reset\n </div>\n </div>\n </div>\n\n <div\n [style.height]=\"\n showFilters ? 'calc(100% - ' + topFilterRowHeight + 'px)' : '100%'\n \"\n cdkDropListGroup\n class=\"data-grid-table-wrapper overflow-hidden\"\n #dataGridContainer\n [style.fontFamily]=\"fontFaimly\"\n >\n <div\n *ngIf=\"showRowsGrouping\"\n [style.height.px]=\"headerRowHeight\"\n [cdkDropListData]=\"columns\"\n [style.backgroundColor]=\"\n topGroupedBadgesBackgroundColor || headerBackgroundColor\n \"\n cdkDropList\n (cdkDropListEntered)=\"enterToTopRowGrouping($event)\"\n (cdkDropListExited)=\"exitedFromTheTopRow($event)\"\n (cdkDropListDropped)=\"onDropTopGroup($event)\"\n [cdkDropListEnterPredicate]=\"canEnterToRowsGrouping\"\n id=\"rows-grouping-top-container\"\n class=\"border-below d-flex px-4 align-items-center\"\n >\n <div class=\"d-flex gap-2 align-items-center me-5\">\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/justify.svg'\"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n <div *ngIf=\"!draggingInGroupArea && !groupedColumns?.length\">\n Drag here to set row groups\n </div>\n <ng-container\n *ngFor=\"\n let child of groupedColumns;\n let i = index;\n trackBy: trackByField\n \"\n >\n <ng-container\n *ngTemplateOutlet=\"\n topGroupingRowPlaceholder;\n context: {\n $implicit: child,\n showChevron:\n groupedColumns.length > 1 && i != groupedColumns.length - 1\n }\n \"\n ></ng-container>\n </ng-container>\n </div>\n\n\n\n\n</div>\n<div\n class=\"d-flex overflow-hidden\"\n [style.height]=\"\n 'calc(100% - ' +\n (showRowsGrouping\n ? headerRowHeight + footerRowHeight\n : footerRowHeight) +\n 'px)'\n \"\n>\n <div\n class=\"h-100\"\n [style.width]=\"\n !showSideMenu\n ? '100%'\n : sideMenuVisible\n ? 'calc(100% - 280px)'\n : 'calc(100% - 30px)'\n \"\n >\n <div class=\"h-100 transition position-relative w-100\">\n <!-- ##################################################################################################################################################################################### -->\n <!-- ##################################################################################################################################################################################### -->\n <!-- Data Grid Header starts here -->\n <!-- ##################################################################################################################################################################################### -->\n <!-- ##################################################################################################################################################################################### -->\n\n <div\n class=\"data-grid-header-wrapper w-100\"\n [style.color]=\"headerTextColor\"\n [style.fontSize.px]=\"headerTextFontsSize\"\n [style.backgroundColor]=\"headerBackgroundColor\"\n [class.border-below]=\"!hasAnyVisibleColumn\"\n [style.height.px]=\"\n showColumnsGrouping && showFilterRow\n ? headerRowHeight * 3\n : showColumnsGrouping || showFilterRow\n ? headerRowHeight * 2\n : headerRowHeight\n \"\n >\n <!-- ********************************************************************************* -->\n <!-- ********************************************************************************* -->\n <!-- Data Grid Left Pinned Header starts here -->\n <!-- ********************************************************************************* -->\n <!-- ********************************************************************************* -->\n <div class=\"data-grid-header left-pinned\" #leftPinnedHeader>\n <div\n *ngIf=\"showSerialNumber\"\n [style.backgroundColor]=\"checkboxesBackgroundColor\"\n class=\"select-all-checkbox-cell border-below\"\n [style.width.px]=\"65\"\n [style.height.px]=\"\n showColumnsGrouping && showFilterRow\n ? headerRowHeight * 3\n : showColumnsGrouping || showFilterRow\n ? headerRowHeight * 2\n : headerRowHeight\n \"\n >\n S.No</div>\n <div\n [style.backgroundColor]=\"checkboxesBackgroundColor\"\n class=\"select-all-checkbox-cell border-below\"\n [style.height.px]=\"\n showColumnsGrouping && showFilterRow\n ? headerRowHeight * 3\n : showColumnsGrouping || showFilterRow\n ? headerRowHeight * 2\n : headerRowHeight\n \"\n >\n <input\n *ngIf=\"hasAnyVisibleColumn\"\n type=\"checkbox\"\n [indeterminate]=\"isIndeterminateState(dataSet)\"\n [checked]=\"isAllSelected(dataSet)\"\n (change)=\"toggleSelectAll(dataSet)\"\n />\n </div>\n <div\n class=\"d-flex\"\n cdkDropList\n id=\"left-pinned-header\"\n cdkDropListOrientation=\"horizontal\"\n [cdkDropListData]=\"leftPinnedColumns\"\n (cdkDropListEntered)=\"onDropListEnter($event, 'left')\"\n (cdkDropListSorted)=\"\n onSortGroup($event, 'previewLeftPinnedColumns')\n \"\n (cdkDropListDropped)=\"onDropGroup()\"\n style=\"min-width: 0.2px\"\n [style.background-color]=\"headerBackgroundColor\"\n >\n <div\n class=\"dragable-header\"\n cdkDrag\n [cdkDragData]=\"col\"\n *ngFor=\"\n let col of leftPinnedColumns;\n let i = index;\n trackBy: trackByField\n \"\n >\n <ng-container\n *ngTemplateOutlet=\"\n headerCell;\n context: {\n $implicit: col,\n index: i,\n section: 'previewLeftPinnedColumns'\n }\n \"\n ></ng-container>\n <ng-template cdkDragPreview\n ><div class=\"p-2 border d-flex gap-2\">\n <div>\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath +\n 'data-grid/icons/arrows-move.svg'\n \"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n </div>\n <div>{{ col.header }}</div>\n </div>\n </ng-template>\n <ng-template cdkDragPlaceholder>\n <div *ngIf=\"!draggingInGroupArea\">\n <div\n *ngTemplateOutlet=\"\n headerCell;\n context: {\n $implicit: col,\n index: i,\n section: ''\n }\n \"\n ></div>\n </div>\n <div\n *ngIf=\"draggingInGroupArea\"\n class=\"d-flex gap-2 ms-2\"\n style=\"opacity: 0.6\"\n >\n <ng-container\n *ngIf=\"col?.children?.length; else singleCol\"\n >\n <ng-container\n *ngFor=\"\n let child of col.children;\n let i = index;\n trackBy: trackByField\n \"\n >\n <ng-container\n *ngTemplateOutlet=\"\n topGroupingRowPlaceholder;\n context: {\n $implicit: child,\n showChevron:\n col.children.length > 1 &&\n i != col.children.length - 1\n }\n \"\n ></ng-container>\n </ng-container>\n </ng-container>\n\n <ng-template #singleCol>\n <ng-container\n *ngTemplateOutlet=\"\n topGroupingRowPlaceholder;\n context: {\n $implicit: col,\n showChevron: col?.children?.length > 1\n }\n \"\n ></ng-container>\n </ng-template>\n </div>\n </ng-template>\n </div>\n </div>\n </div>\n\n <!-- ********************************************************************************* -->\n <!-- ********************************************************************************* -->\n <!-- Data Grid Center Pinned Header starts here -->\n <!-- ********************************************************************************* -->\n <!-- ********************************************************************************* -->\n <div\n class=\"data-grid-header center-scrollable\"\n #centerPinnedHeader\n (scroll)=\"onCenterHeaderScroll($event)\"\n id=\"center-pinned-header\"\n cdkDropList\n [cdkDropListConnectedTo]=\"\n showRowsGrouping ? ['rows-grouping-top-container'] : []\n \"\n [cdkDropListData]=\"centerColumns\"\n cdkDropListOrientation=\"horizontal\"\n [cdkDropListSortingDisabled]=\"\n isDisableColumnGrouping && draggingInGroupArea\n \"\n (cdkDropListEntered)=\"onDropListEnter($event, 'center')\"\n (cdkDropListSorted)=\"onSortGroup($event, 'previewCenterColumns')\"\n (cdkDropListDropped)=\"onDropGroup()\"\n [style.maxWidth]=\"\n 'calc(100% - ' +\n (rightPinnedHeader.offsetWidth + leftPinnedHeader.offsetWidth) +\n 'px)'\n \"\n >\n <div\n *ngIf=\"groupedColumns?.length\"\n style=\"min-width: 200px\"\n class=\"h-100 align-items-center\"\n #columnsGroupedBox\n id=\"groupBoxHeaderDiv\"\n >\n <div\n class=\"d-flex w-100 justify-content-between align-items-center border-below\"\n [style.height.px]=\"\n showFilterRow ? headerRowHeight * 2 : headerRowHeight\n \"\n >\n <div class=\"ps-3\">Group</div>\n <div class=\"d-flex\">\n <div\n class=\"three-dots cursor-pointer\"\n (click)=\"openThreeDotsMenu($event, 'group')\"\n >\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath +\n 'data-grid/icons/three-dots-vertical.svg'\n \"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n </div>\n <div\n (mousedown)=\"onResizeGroupBox($event)\"\n class=\"resize-handle\"\n style=\"margin-right: -2px\"\n >\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath +\n 'data-grid/icons/resize-handle.svg'\n \"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n </div>\n </div>\n </div>\n\n <div\n [style.height.px]=\"headerRowHeight\"\n class=\"border-below\"\n ></div>\n </div>\n <!-- <span\n class=\"d-flex align-items-center justify-content-center cursor-pointer border-below\"\n style=\"min-width: 30px; height: 100%;\"\n *ngIf=\"gridType === 'TimeSheet' && !areDatesSelectedAndEqual\"\n >\n </span> -->\n <div\n class=\"dragable-header\"\n (cdkDragStarted)=\"\n checkColumnGroupingStatus(col); dragStartOnGroup(col)\n \"\n cdkDrag\n [cdkDragData]=\"col\"\n *ngFor=\"\n let col of centerColumns;\n let i = index;\n trackBy: trackById\n \"\n >\n <ng-container\n *ngTemplateOutlet=\"\n headerCell;\n context: {\n $implicit: col,\n index: i,\n section: 'previewCenterColumns'\n }\n \"\n >\n </ng-container>\n <ng-template cdkDragPreview\n ><div class=\"p-2 border d-flex gap-2\">\n <div>\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath +\n 'data-grid/icons/arrows-move.svg'\n \"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n </div>\n <div>{{ col.header }}</div>\n </div>\n </ng-template>\n <ng-template cdkDragPlaceholder>\n <div *ngIf=\"!draggingInGroupArea\">\n <div\n *ngTemplateOutlet=\"\n headerCell;\n context: {\n $implicit: col,\n index: i,\n section: 'centerColumns'\n }\n \"\n ></div>\n </div>\n <div\n *ngIf=\"draggingInGroupArea\"\n class=\"d-flex gap-2 ms-2\"\n style=\"opacity: 0.6\"\n >\n <ng-container *ngIf=\"col?.children?.length; else singleCol\">\n <ng-container\n *ngFor=\"\n let child of col.children;\n let i = index;\n trackBy: trackById\n \"\n >\n <ng-container *ngIf=\"child?.is_groupable\">\n <ng-container\n *ngTemplateOutlet=\"\n topGroupingRowPlaceholder;\n context: {\n $implicit: child,\n showChevron:\n col.children.length > 1 &&\n i != col.children.length - 1\n }\n \"\n ></ng-container>\n </ng-container>\n </ng-container>\n </ng-container>\n\n <ng-template #singleCol>\n <ng-container *ngIf=\"col?.is_groupable\">\n <ng-container\n *ngTemplateOutlet=\"\n topGroupingRowPlaceholder;\n context: {\n $implicit: col,\n showChevron: col?.children?.length > 1\n }\n \"\n ></ng-container>\n </ng-container>\n </ng-template>\n </div>\n </ng-template>\n </div>\n <div *ngIf=\"!areDatesSelectedAndEqual\" class=\"header-cell border-below\" [style.width.px]=\"30\" [style.height.px]=\"headerRowHeight\" [style.backgroundColor]=\"headerBackgroundColor\"></div>\n </div>\n\n <!-- ********************************************************************************* -->\n <!-- ********************************************************************************* -->\n <!-- Data Grid Right Pinned Header starts here -->\n <!-- ********************************************************************************* -->\n <!-- ********************************************************************************* -->\n <div\n cdkDropList\n id=\"right-pinned-header\"\n [cdkDropListConnectedTo]=\"\n showRowsGrouping ? ['rows-grouping-top-container'] : []\n \"\n cdkDropListOrientation=\"horizontal\"\n class=\"data-grid-header right-pinned\"\n (cdkDropListSorted)=\"\n onSortGroup($event, 'previewRightPinnedColumns')\n \"\n (cdkDropListEntered)=\"onDropListEnter($event, 'right')\"\n (cdkDropListDropped)=\"onDropGroup()\"\n #rightPinnedHeader\n class=\"right-pinned-header d-flex\"\n style=\"min-width: 0.2px\"\n >\n <div\n class=\"dragable-header\"\n cdkDrag\n [cdkDragData]=\"col\"\n *ngFor=\"\n let col of rightPinnedColumns;\n let i = index;\n trackBy: trackById\n \"\n >\n <ng-container\n *ngTemplateOutlet=\"\n headerCell;\n context: {\n $implicit: col,\n pinnedRight: true,\n index: i,\n section: 'previewRightPinnedColumns'\n }\n \"\n ></ng-container>\n <ng-template cdkDragPreview\n ><div class=\"p-2 border d-flex gap-2\">\n <div>\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath +\n 'data-grid/icons/arrows-move.svg'\n \"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n </div>\n <div>{{ col.header }}</div>\n </div>\n </ng-template>\n <ng-template cdkDragPlaceholder>\n <div *ngIf=\"!draggingInGroupArea\">\n <div\n *ngTemplateOutlet=\"\n headerCell;\n context: {\n $implicit: col,\n index: i,\n section: 'centerColumns'\n }\n \"\n ></div>\n </div>\n <div\n *ngIf=\"draggingInGroupArea\"\n class=\"d-flex gap-2 ms-2\"\n style=\"opacity: 0.6\"\n >\n <ng-container *ngIf=\"col?.children?.length; else singleCol\">\n <ng-container\n *ngFor=\"\n let child of col.children;\n let i = index;\n trackBy: trackById\n \"\n >\n <ng-container\n *ngTemplateOutlet=\"\n topGroupingRowPlaceholder;\n context: {\n $implicit: child,\n showChevron:\n col.children.length > 1 &&\n i != col.children.length - 1\n }\n \"\n ></ng-container>\n </ng-container>\n </ng-container>\n\n <ng-template #singleCol>\n <ng-container\n *ngTemplateOutlet=\"\n topGroupingRowPlaceholder;\n context: {\n $implicit: col,\n showChevron: col?.children?.length > 1\n }\n \"\n ></ng-container>\n </ng-template>\n </div>\n </ng-template>\n </div>\n </div>\n </div>\n\n <!--########################################################################################################################################################################################################################### -->\n <!--########################################################################################################################################################################################################################### -->\n <!-- Data Grid Body starts here -->\n <!--########################################################################################################################################################################################################################### -->\n <!--########################################################################################################################################################################################################################### -->\n <div\n class=\"h-100 d-flex justify-content-center align-items-center\"\n *ngIf=\"!dataSet.length && !loading\"\n >\n No Record Found\n </div>\n\n <div\n class=\"position-absolute w-100 h-100 d-flex justify-content-center align-items-center loading-overlay\"\n *ngIf=\"loading\"\n style=\"\n z-index: 999;\n background: rgba(255, 255, 255, 0.8);\n backdrop-filter: blur(1px);\n \"\n >\n <div class=\"text-center p-2\">\n <div class=\"spinner-border text-primary\" role=\"status\"></div> Loading...\n</div>\n </div>\n\n <!-- Card View -->\n \n\n <!-- Table View -->\n <div\n class=\"data-grid-body-wrapper position-relative d-flex\"\n [style.height]=\"bodyWrapperHeight\"\n style=\"overflow-y: auto; overflow-x: hidden\"\n #mainScroll\n (scroll)=\"onMainScroll($event)\"\n *ngIf=\"dataSet.length\"\n >\n <!-- LEFT PINNED -->\n <div [style.height.px]=\"!groupedColumns.length ? originalDataSet.length * rowHeight: 0\"></div>\n <div [class.h-100]=\"originalDataSet.length <= 10\">\n <div\n class=\"data-grid-body left-pinned-body w-100\"\n style=\"overflow-y: hidden\"\n [class.border-right]=\"hasLeftPinnedColumns\"\n [class.transparent-border-right]=\"!hasLeftPinnedColumns\"\n *ngIf=\"!loading && !dataSetLoading\"\n [@rowDynamic]=\"rowAnimation\"\n [style.transform]=\"\n 'translateY(' + startIndex * rowHeight + 'px)'\n \"\n >\n <ng-container\n *ngFor=\"\n let row of visibleRows;\n let i = index;\n trackBy: trackById\n \"\n >\n <ng-container\n *ngTemplateOutlet=\"\n rowCell;\n context: {\n $implicit: row,\n columns: previewLeftPinnedColumns,\n isEven: (startIndex + i) % 2 === 0,\n isOdd: (startIndex + i) % 2 !== 0,\n isLeft: true,\n section: 'left'\n }\n \"\n ></ng-container>\n </ng-container>\n </div>\n </div>\n\n <!-- CENTER -->\n <div\n class=\"\"\n [style.width.px]=\"centerPinnedHeader.clientWidth\"\n >\n <div\n class=\"data-grid-body center-scrollable\"\n [@rowDynamic]=\"rowAnimation\" *ngIf=\"!loading && !dataSetLoading\"\n style=\"overflow-y: hidden; overflow-x: auto\"\n [style.transform]=\"\n 'translateY(' + startIndex * rowHeight + 'px)'\n \"\n [style.backgroundColor]=\"bodyBackgroundColor\"\n #centerScrollableBody\n (scroll)=\"onCenterBodyScroll($event)\"\n [style.boxShadow]=\"leftPinnedBoxshadow\"\n\n >\n <ng-container \n *ngFor=\"\n let row of visibleRows;\n let i = index;\n trackBy: trackById\n \"\n >\n <ng-container\n *ngTemplateOutlet=\"\n rowCell;\n context: {\n $implicit: row,\n columns: previewCenterColumns,\n isEven: (startIndex + i) % 2 === 0,\n isOdd: (startIndex + i) % 2 !== 0,\n section: 'center'\n }\n \"\n ></ng-container>\n </ng-container>\n </div>\n </div>\n\n <!-- RIGHT PINNED -->\n <div\n class=\"right-pinned-body-wrapper\"\n *ngIf=\"hasRightPinnedColumns\"\n [class.h-100]=\"originalDataSet.length <= 10\"\n [style.max-width.px]=\"isScrollbarVisible ? rightPinnedHeader.offsetWidth - 15: rightPinnedHeader.offsetWidth\"\n >\n <div\n class=\"data-grid-body right-pinned-body w-100\"\n style=\"overflow-y: hidden\"\n [style.transform]=\"\n 'translateY(' + startIndex * rowHeight + 'px)'\n \"\n [style.boxShadow]=\"rightPinnedBoxshadow\"\n *ngIf=\"!loading && !dataSetLoading\"\n [@rowDynamic]=\"rowAnimation\"\n >\n <ng-container\n *ngFor=\"\n let row of visibleRows;\n let i = index;\n trackBy: trackById\n \"\n >\n <ng-container\n *ngTemplateOutlet=\"\n rowCell;\n context: {\n $implicit: row,\n columns: previewRightPinnedColumns,\n isEven: (startIndex + i) % 2 === 0,\n isOdd: (startIndex + i) % 2 !== 0,\n section: 'right'\n }\n \"\n ></ng-container>\n </ng-container>\n </div>\n </div>\n </div>\n <!-- Vertical Fake scroll Bar -->\n <div\n (scroll)=\"onMainFakeScroll($event)\"\n class=\"fake-scrollbar fake-scrollbar-vertical d-none\"\n [style.scrollbarWidth]=\"verticalScrollbarWidth\"\n [style.top.px]=\"\n showColumnsGrouping && showFilterRow\n ? headerRowHeight * 3\n : showColumnsGrouping || showFilterRow\n ? headerRowHeight * 2\n : headerRowHeight\n \"\n #fakeScroll\n [style.height]=\"bodyWrapperHeight\"\n style=\"\n overflow-y: auto;\n overflow-x: hidden;\n width: 17px;\n position: absolute;\n right: 0;\n background-color: f1f2f3;\n z-index: 10;\n \"\n >\n <div [style.height.px]=\"rowHeight * (paginationConfig.totalResults || flattenedData.length)\"></div>\n </div>\n </div>\n\n <!-- Horizintal Fake Scrollbars -->\n <div class=\"d-flex justify-content-between\" *ngIf=\"dataSet.length\">\n <div\n [style.scrollbarWidth]=\"horizintalScrollbarWidth\"\n class=\"fake-horizintal-scrollbar\"\n #fakeScroll\n [style.width.px]=\"leftPinnedHeader.offsetWidth\"\n style=\"overflow-x: scroll\"\n ></div>\n <div\n [style.scrollbarWidth]=\"horizintalScrollbarWidth\"\n (scroll)=\"onHorizintalFakeScroll($event)\"\n class=\"fake-horizintal-scrollbar\"\n #horizintalFakeScroll\n [style.width.px]=\"centerPinnedHeader.offsetWidth\"\n >\n <div [style.width.px]=\"centerPinnedHeader.scrollWidth\"></div>\n </div>\n <div\n [style.scrollbarWidth]=\"horizintalScrollbarWidth\"\n class=\"fake-horizintal-scrollbar\"\n #fakeScroll\n [style.width.px]=\"rightPinnedHeader.offsetWidth\"\n style=\"overflow-x: scroll\"\n ></div>\n </div>\n </div>\n\n <!-- Side Menu Implemented Here -->\n <div\n *ngIf=\"showSideMenu && !hasOpenAccordion\"\n [style.width.px]=\"sideMenuVisible ? 280 : 30\"\n class=\"right-menu h-100\"\n [style.backgroundColor]=\"sidemenuBackgroundColor\"\n >\n <div class=\"h-100 d-flex flex-row-reverse\">\n <div\n style=\"width: 30px\"\n class=\"d-flex flex-column align-items-center cursor-pointer\"\n [class.border-start]=\"sideMenuVisible\"\n >\n <div\n (click)=\"toggleSideMenu('cols')\"\n [class.bg-white]=\"\n currentOpenedSideMenue == 'cols' && sideMenuVisible\n \"\n [class.border-below]=\"sideMenuVisible\"\n class=\"columns-button d-flex flex-column align-items-center\"\n >\n <div>\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/ui-checks-grid.svg'\n \"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n </div>\n <div class=\"side-menue-text\">Columns</div>\n </div>\n\n <div\n (click)=\"toggleSideMenu('filtrs')\"\n [class.bg-white]=\"\n currentOpenedSideMenue == 'filtrs' && sideMenuVisible\n \"\n [class.border-below]=\"\n sideMenuVisible && currentOpenedSideMenue == 'filtrs'\n \"\n class=\"columns-button d-flex flex-column align-items-center\"\n >\n <div>\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\n \"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n </div>\n <div class=\"side-menue-text\">Filter</div>\n </div>\n </div>\n <div\n class=\"h-100\"\n *ngIf=\"sideMenuVisible\"\n [ngStyle]=\"{ width: sideMenuVisible ? '250px' : '' }\"\n >\n <div class=\"h-100\">\n <ng-container\n *ngIf=\"currentOpenedSideMenue == 'cols' && sideMenuVisible\"\n >\n <ng-container *ngTemplateOutlet=\"columnPannel\"></ng-container>\n <!-- Column Items -->\n <div class=\"column-panel-body px-3\">\n <ng-container\n *ngFor=\"let col of columns; trackBy: trackByField\"\n >\n <ng-container\n *ngTemplateOutlet=\"columnPanelItem; context: { col: col }\"\n ></ng-container>\n </ng-container>\n </div>\n <hr />\n\n <div class=\"side-menu-row-groups\" style=\"height: 30%\">\n <ng-container\n *ngTemplateOutlet=\"sideMenuRowGroups\"\n ></ng-container>\n </div>\n </ng-container>\n <ng-container\n *ngIf=\"currentOpenedSideMenue == 'filtrs' && sideMenuVisible\"\n >\n <ng-container *ngTemplateOutlet=\"sideFilters\"></ng-container>\n </ng-container>\n </div>\n </div>\n </div>\n </div>\n </div>\n <div [style.height.px]=\"footerRowHeight\" class=\"border-top\">\n <!-- Rows: <span class=\"fw-500 ms-1\">{{ dataSet.length }}</span> -->\n <div\n class=\"pagination-container\"\n [style.height.px]=\"footerRowHeight\"\n [style.padding.px]=\"footerPadding\"\n >\n <div class=\"page-size\">\n <select\n [(ngModel)]=\"paginationConfig.selectedPageSize\"\n (change)=\"onPageSizeChange()\"\n >\n <option *ngFor=\"let size of pageSizeOptions\" [value]=\"size\">\n {{ size }}\n </option>\n </select>\n <span class=\"\"> per page </span>\n </div>\n\n <div class=\"page-info\">\n Results: {{ startPageIndex }}-{{ endPageIndex }}\n of\n {{ paginationConfig.totalResults }}\n </div>\n\n <div class=\"page-buttons\">\n <button\n (click)=\"goToPage(paginationConfig.page - 1)\"\n [disabled]=\"paginationConfig.page === 1\"\n >\n \u2039\n </button>\n\n <ng-container *ngFor=\"let page of visiblePages\">\n <button\n *ngIf=\"page !== '...'\"\n (click)=\"goToPage(page)\"\n [class.active]=\"page === paginationConfig.page\"\n >\n {{ page }}\n </button>\n <span *ngIf=\"page === '...'\">...</span>\n </ng-container>\n\n <button\n (click)=\"goToPage(paginationConfig.page + 1)\"\n [disabled]=\"paginationConfig.page === paginationConfig.totalResults\"\n >\n \u203A\n </button>\n </div>\n </div>\n </div>\n </div>\n</div>\n\n<!-- ------------------------------------------------------------------------------------------------------------------------ -->\n<!-- ------------------------------------------------------------------------------------------------------------------------ -->\n<!-- Header Cell Template -->\n<!-- ------------------------------------------------------------------------------------------------------------------------ -->\n<!-- ------------------------------------------------------------------------------------------------------------------------ -->\n\n<ng-template\n #headerCell\n let-col\n let-pinnedRight=\"pinnedRight\"\n let-i=\"index\"\n let-sections=\"section\"\n let-calledFromNestedPlaceholder=\"calledFromNestedPlaceholder\"\n>\n <div>\n <!-- Group Header -->\n <ng-container *ngIf=\"col.children?.length > 0; else flatHeader\">\n <div cdkDroplistGroup class=\"group-column-wrapper\">\n <!-- Parent Header -->\n <div\n *ngIf=\"shouldTheGroupHeaderShow(col)\"\n class=\"header-cell group-header\"\n [style.height.px]=\"headerRowHeight\"\n [style.min-height.px]=\"headerRowHeight\"\n [style.max-height.px]=\"headerRowHeight\"\n [class.border-right]=\"showVerticalBorder\"\n [style.gridColumn]=\"'span ' + col.children.length\"\n [style.fontWeight]=\"headerFontWeight\"\n [class.flex-row-reverse]=\"pinnedRight\"\n [class.justify-content-end]=\"pinnedRight\"\n style=\"grid-row: 1\"\n >\n <div\n class=\"group-header-content\"\n [title]=\"col.header\"\n [class.ms-2]=\"pinnedRight\"\n >\n {{ col.header }}\n </div>\n <div\n class=\"resize-handle\"\n (dblclick)=\"autosizeColumn(col.children)\"\n (mousedown)=\"onResizeGroup($event, col, pinnedRight)\"\n >\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/resize-handle.svg'\n \"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n </div>\n </div>\n\n <!-- Child Headers and Filters -->\n\n <div\n class=\"d-flex\"\n cdkDropList\n cdkDropListOrientation=\"horizontal\"\n [cdkDropListData]=\"col.children\"\n (cdkDropListSorted)=\"onChildDroplistSorted($event, sections)\"\n (cdkDropListDropped)=\"onChildDroplistDroped($event)\"\n [cdkDropListSortingDisabled]=\"false\"\n [cdkDropListConnectedTo]=\"\n showRowsGrouping ? ['rows-grouping-top-container'] : []\n \"\n >\n <div\n cdkDrag\n [cdkDragData]=\"child\"\n *ngFor=\"let child of col.children; let i = index\"\n >\n <!-- Child Header -->\n <ng-container *ngIf=\"child.is_visible && !child['isRowGrouped']\">\n <div\n cdkDragHandle\n class=\"header-cell one-row-header-cells cursor-pointer\"\n [class.border-right]=\"showVerticalBorder\"\n [attr.field]=\"child.field\"\n [style.width.px]=\"child.width\"\n [style.min-width.px]=\"child.width\"\n [style.min-height.px]=\"headerRowHeight\"\n [style.max-height.px]=\"headerRowHeight\"\n [style.fontWeight]=\"headerFontWeight\"\n style=\"grid-row: 2\"\n [class.filter-applied-on-text]=\"isFilterAppliedOnColumn(child)\"\n >\n <div\n class=\"d-flex justify-content-between h-100 align-items-center w-100\"\n >\n <div\n class=\"d-flex justify-content-between w-100\"\n [class.flex-row-reverse]=\"pinnedRight\"\n >\n <div\n class=\"text-ellipsis h-100 d-flex align-items-center w-100\"\n [title]=\"col.header\"\n [class.w-100]=\"pinnedRight\"\n >\n <div\n class=\"text-ellipsis h-100\"\n [class.editable-header]=\"child?.is_editable\"\n (click)=\"openThreeDotsMenu($event, child); openFilteronThreeDotsClick(child)\"\n >\n {{ child.header }}\n </div>\n </div>\n\n <div\n class=\"position-relative d-flex\"\n [class.flex-row-reverse]=\"pinnedRight\"\n >\n <div\n [class.me-2]=\"pinnedRight\"\n class=\"d-flex align-items-center\"\n *ngIf=\"child.pinned\"\n >\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/pin-blue.svg'\n \"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n </div>\n <div\n class=\"three-dots p-1\"\n (click)=\"openThreeDotsMenu($event, child)\"\n style=\"cursor: pointer\"\n >\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath +\n 'data-grid/icons/three-dots-vertical.svg'\n \"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n </div>\n\n <!-- Only show menu if this column is active -->\n <div\n class=\"position-absolute\"\n *ngIf=\"activeCol === child\"\n style=\"top: -50%; z-index: 21\"\n [style.left.px]=\"\n -(!child?.pinned ? centerPinnedHeader.scrollLeft : 0)\n \"\n >\n <ng-container\n *ngTemplateOutlet=\"\n columnMenu;\n context: { col: child }\n \"\n ></ng-container>\n </div>\n\n <div\n class=\"resize-handle\"\n (dblclick)=\"autosizeColumn(child)\"\n (mousedown)=\"onResizeColumn($event, child)\"\n >\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath +\n 'data-grid/icons/resize-handle.svg'\n \"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n </div>\n </div>\n </div>\n </div>\n </div>\n\n <!-- Filter Cell -->\n <div\n *ngIf=\"showFilterRow\"\n [style.backgroundColor]=\"headerBackgroundColor\"\n class=\"header-cell filter-cell\"\n [class.border-right]=\"showVerticalBorder\"\n [attr.field]=\"child.field\"\n [style.width.px]=\"child.width\"\n [style.min-width.px]=\"child.width\"\n [style.height.px]=\"headerRowHeight\"\n [style.min-height.px]=\"headerRowHeight\"\n [style.max-height.px]=\"headerRowHeight\"\n [class.border-right]=\"showVerticalBorder\"\n style=\"grid-row: 3\"\n >\n <div\n class=\"header-cell filter-cell\"\n [attr.field]=\"col.field\"\n [style.width.px]=\"col.width\"\n [style.min-width.px]=\"col.width\"\n [style.height.px]=\"headerRowHeight\"\n [style.min-height.px]=\"headerRowHeight\"\n [style.max-height.px]=\"headerRowHeight\"\n >\n <input\n type=\"text\"\n class=\"form-control form-control-sm\"\n placeholder=\"Filter\"\n [(ngModel)]=\"col.filterValue\"\n (ngModelChange)=\"onFilterChange(col)\"\n />\n <span\n class=\"filter-icon-wrapper\"\n (click)=\"$event.stopPropagation(); openFilter(child)\"\n [class.filter-applied]=\"isFilterAppliedOnColumn(child)\"\n ><span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\n \"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n <span\n *ngIf=\"isFilterAppliedOnColumn(child)\"\n style=\"\n width: 7px;\n height: 7px;\n box-shadow: 0px 0px 3px #7486ff;\n background-color: rgb(0 163 233);\n position: absolute;\n right: 4px;\n top: 12px;\n \"\n class=\"rounded-circle d-block\"\n ></span\n ></span>\n\n <div\n class=\"position-absolute filter-row-filter-wrapper\"\n *ngIf=\"activeFilterCell?.field == child?.field\"\n style=\"top: 100%; right: 0; z-index: 99\"\n [style.left.px]=\"\n child?.pinned ? 0 : -centerPinnedHeader.scrollLeft\n \"\n >\n <ng-container\n *ngTemplateOutlet=\"filterMenu; context: { col: child }\"\n ></ng-container>\n </div>\n </div>\n </div>\n </ng-container>\n <ng-template cdkDragPreview\n ><div class=\"p-2 border d-flex gap-2\">\n <div\n *ngIf=\"\n !draggingInGroupArea ||\n (child.is_groupable && draggingInGroupArea)\n \"\n >\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/arrows-move.svg'\n \"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n </div>\n <div *ngIf=\"draggingInGroupArea && !child.is_groupable\">\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/ban.svg'\n \"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n </div>\n <div>{{ child.header }}</div>\n </div>\n </ng-template>\n <ng-template cdkDragPlaceholder>\n <div *ngIf=\"!draggingInGroupArea\" class=\"position-relative\">\n <div\n *ngTemplateOutlet=\"\n childHeaderPlaceholder;\n context: {\n $implicit: child,\n index: i,\n sections: sections,\n calledFromNestedPlaceholder: true,\n }\n \"\n ></div>\n </div>\n <div\n *ngIf=\"draggingInGroupArea && child?.is_groupable\"\n class=\"d-flex gap-2 ms-2\"\n style=\"opacity: 0.6\"\n >\n <ng-container\n *ngTemplateOutlet=\"\n topGroupingRowPlaceholder;\n context: {\n $implicit: child,\n showChevron: false,\n pinnedRight: pinnedRight,\n sections: sections,\n index: i\n }\n \"\n ></ng-container>\n </div>\n </ng-template>\n </div>\n </div>\n </div>\n </ng-container>\n\n <!-- Flat Header || Single Header Cell-->\n <ng-template #flatHeader>\n <div class=\"group-column-wrapper\">\n <!-- Full-height Header Cell (spans 2 rows visually) -->\n <div\n class=\"header-cell one-row-header-cells\"\n [attr.field]=\"col.field\"\n [style.width.px]=\"col.width\"\n [style.min-width.px]=\"col.width\"\n [class.border-right]=\"showVerticalBorder\"\n [style.min-height.px]=\"\n showColumnsGrouping ? headerRowHeight * 2 : headerRowHeight\n \"\n [style.height.px]=\"\n showColumnsGrouping ? headerRowHeight * 2 : headerRowHeight\n \"\n [style.fontWeight]=\"headerFontWeight\"\n style=\"grid-row: 1 / span 2\"\n >\n <div\n class=\"d-flex justify-content-between h-100 align-items-center w-100\"\n >\n <div\n class=\"d-flex justify-content-between w-100\"\n [class.flex-row-reverse]=\"pinnedRight\"\n >\n <div\n class=\"text-ellipsis h-100 d-flex align-items-center w-100\"\n [title]=\"col.header\"\n >\n <div\n class=\"text-ellipsis h-100 cursor-pointer\"\n [class.editable-header]=\"col?.is_editable\"\n [class.filter-applied-on-text]=\"isFilterAppliedOnColumn(col)\"\n (click)=\"openThreeDotsMenu($event, col); openFilteronThreeDotsClick(col)\"\n >\n {{ col.header }}\n </div>\n </div>\n\n <div\n class=\"position-relative d-flex\"\n [class.flex-row-reverse]=\"pinnedRight\"\n >\n <div\n [class.me-2]=\"pinnedRight\"\n class=\"d-flex align-items-center\"\n *ngIf=\"col?.pinned\"\n >\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/pin-blue.svg'\n \"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n </div>\n <div\n [class.me-2]=\"col.order_by\"\n class=\"d-flex align-items-center\"\n *ngIf=\"sortingConfig?.field == col.field\"\n >\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath +\n (sortingConfig?.order_by == 'desc'\n ? 'data-grid/icons/sort-desc.svg'\n : 'data-grid/icons/sort-asc.svg')\n \"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center mt-1\"\n ></span>\n </div>\n <div\n class=\"three-dots p-1\"\n (click)=\"openThreeDotsMenu($event, col)\"\n style=\"cursor: pointer\"\n >\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath +\n 'data-grid/icons/three-dots-vertical.svg'\n \"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n </div>\n\n <!-- Only show menu if this column is active -->\n <div\n class=\"position-absolute\"\n *ngIf=\"activeCol === col\"\n style=\"top: -50%; z-index: 21\"\n [style.left.px]=\"\n -(!col?.pinned ? centerPinnedHeader.scrollLeft : 0)\n \"\n >\n <ng-container\n *ngTemplateOutlet=\"columnMenu; context: { col: col }\"\n ></ng-container>\n </div>\n\n <div\n class=\"resize-handle\"\n [class.w-100]=\"col.pinned == 'right'\"\n (dblclick)=\"autosizeColumn(col)\"\n (mousedown)=\"onResizeColumn($event, col)\"\n >\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/resize-handle.svg'\n \"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n </div>\n </div>\n </div>\n </div>\n </div>\n\n <!-- Filter Cell -->\n <div\n *ngIf=\"showFilterRow\"\n [style.backgroundColor]=\"headerBackgroundColor\"\n class=\"header-cell filter-cell\"\n [class.border-right]=\"showVerticalBorder\"\n [attr.field]=\"col.field\"\n [style.width.px]=\"col.width\"\n [style.min-width.px]=\"col.width\"\n [style.height.px]=\"headerRowHeight\"\n [style.min-height.px]=\"headerRowHeight\"\n [style.max-height.px]=\"headerRowHeight\"\n >\n <input\n type=\"text\"\n class=\"form-control form-control-sm\"\n placeholder=\"Filter\"\n [(ngModel)]=\"col.filterValue\"\n (ngModelChange)=\"onFilterChange(col)\"\n />\n <span\n class=\"filter-icon-wrapper\"\n (click)=\"$event.stopPropagation(); openFilter(col)\"\n [class.filter-applied]=\"isFilterAppliedOnColumn(col)\"\n ><span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n <span\n *ngIf=\"isFilterAppliedOnColumn(col)\"\n style=\"\n width: 7px;\n height: 7px;\n box-shadow: 0px 0px 3px #7486ff;\n background-color: rgb(0 163 233);\n position: absolute;\n right: 4px;\n top: 12px;\n \"\n class=\"rounded-circle d-block\"\n ></span\n ></span>\n\n <div\n class=\"position-absolute filter-row-filter-wrapper\"\n *ngIf=\"activeFilterCell === col\"\n style=\"top: 100%; right: 0; z-index: 99\"\n [style.left.px]=\"col?.pinned ? 0 : -centerPinnedHeader.scrollLeft\"\n >\n <ng-container\n *ngTemplateOutlet=\"filterMenu; context: { col: col }\"\n ></ng-container>\n </div>\n </div>\n </div>\n </ng-template>\n </div>\n</ng-template>\n\n<!-- -------------------------------------------------------------------------------------------------------------------------------------------------------------------- -->\n<!-- -------------------------------------------------------------------------------------------------------------------------------------------------------------------- -->\n<!-- Body Cell Template -->\n<!-- -------------------------------------------------------------------------------------------------------------------------------------------------------------------- -->\n<!-- -------------------------------------------------------------------------------------------------------------------------------------------------------------------- -->\n\n<ng-template\n #rowCell\n let-row\n let-columns=\"columns\"\n let-isEven=\"isEven\"\n let-isOdd=\"isOdd\"\n let-isLeftSection=\"isLeft\"\n let-section=\"section\"\n let-rowIndex=\"rowIndex\"\n>\n <!-- Check if row is a group -->\n <ng-container\n *ngTemplateOutlet=\"groupRowTemplate; context: { $implicit: row, depth: 0 }\"\n ></ng-container>\n <ng-template #groupRowTemplate let-row let-depth=\"depth\">\n <ng-container *ngIf=\"row.isGroup; else regularRow\">\n <!-- Group Header -->\n <div\n class=\"group-header-row border-below d-flex align-items-center\"\n [style.height.px]=\"rowHeight\"\n [style.width]=\"\n section == 'center'\n ? centerScrollableBody?.nativeElement?.scrollWidth + 'px'\n : '100%'\n \"\n >\n <div\n *ngIf=\"section == 'left'\"\n class=\"h-100 d-flex\"\n [style.width.px]=\"leftPinnedHeader.offsetWidth - 1\"\n [class.row-selected]=\"rowSelectedIndexes.has(row.__virtualIndex)\"\n >\n <div\n *ngIf=\"showSerialNumber\"\n style=\"width: 50px\"\n class=\"d-flex align-items-center h-100 border-right justify-content-end pe-2 s-no\"\n [style.backgroundColor]=\"checkboxesBackgroundColor\"\n [style.width.px]=\"65\"\n [style.cursor]=\"\n 'url(' +\n singleSpaAssetsPath +\n 'data-grid/icons/arrow-right.svg), auto'\n \"\n (mousedown)=\"onRowMouseDown(row.__virtualIndex, $event)\"\n (mouseover)=\"onRowMouseOver(row.__virtualIndex, $event)\"\n >\n {{ row.__virtualIndex }}\n </div>\n <div\n style=\"width: 50px\"\n class=\"d-flex align-items-center justify-content-center h-100 border-right\"\n [style.backgroundColor]=\"checkboxesBackgroundColor\"\n [class.row-selected]=\"rowSelectedIndexes.has(row.__virtualIndex)\"\n [class.left-selection-border]=\"\n rowSelectedIndexes.has(row.__virtualIndex)\n \"\n [class.first-row-selected]=\"firstSelectedRow == row.__virtualIndex\"\n [class.last-row-selected]=\"lastSelectedRow == row.__virtualIndex\"\n >\n <input style=\"width: 16px; height: 16px\" type=\"checkbox\" />\n </div>\n </div>\n\n <div\n *ngIf=\"section == 'center'\"\n [style.width.px]=\"centerPinnedHeader.scrollWidth\"\n class=\"d-flex align-items-center ps-2 h-100\"\n [class.row-selected]=\"rowSelectedIndexes.has(row.__virtualIndex)\"\n [class.first-row-selected]=\"firstSelectedRow == row.__virtualIndex\"\n [class.last-row-selected]=\"lastSelectedRow == row.__virtualIndex\"\n >\n <div\n class=\"d-flex align-items-center justify-content-between\"\n [style.paddingLeft.px]=\"depth > 0 ? depth * 16 : 0\"\n >\n <span class=\"me-2 filter-icon-wrapper\" (click)=\"toggleExpand(row)\">\n <span\n class=\"data-grid-svg-icon\"\n [inlineSVG]=\"\n row.isExpand\n ? singleSpaAssetsPath + 'data-grid/icons/chevron-down.svg'\n : singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\n \"\n ></span>\n </span>\n <strong (click)=\"toggleExpand(row)\" class=\"cursor-pointer\">\n {{ row.groupValue }} ({{ countLeafRows(row) }})\n </strong>\n </div>\n </div>\n\n <div\n *ngIf=\"section == 'right'\"\n [style.width.px]=\"rightPinnedHeader.offsetWidth\"\n [class.row-selected]=\"rowSelectedIndexes.has(row.__virtualIndex)\"\n [class.first-row-selected]=\"firstSelectedRow == row.__virtualIndex\"\n [class.last-row-selected]=\"lastSelectedRow == row.__virtualIndex\"\n ></div>\n </div>\n\n <!-- Recursive Children -->\n <div class=\"group-children\" *ngIf=\"row.isExpand\">\n <ng-container\n *ngFor=\"let child of row.children; let i = index; trackBy: trackById\"\n >\n <ng-container *ngIf=\"child.isGroup; else dataRow\">\n <!-- Recursive call for nested group -->\n <ng-container\n *ngTemplateOutlet=\"\n groupRowTemplate;\n context: { $implicit: child, depth: depth + 1 }\n \"\n ></ng-container>\n </ng-container>\n\n <ng-template #dataRow>\n <!-- Regular data row -->\n <ng-container\n *ngTemplateOutlet=\"\n rowCell;\n context: {\n $implicit: child,\n columns: columns,\n isEven: i % 2 === 0,\n isOdd: i % 2 !== 0,\n isLeft: isLeftSection,\n section: section\n }\n \"\n ></ng-container>\n </ng-template>\n </ng-container>\n </div>\n </ng-container>\n </ng-template>\n\n <!-- Regular row (not a group) -->\n <ng-template #regularRow>\n <div class=\"d-flex\" [style.height.px]=\"rowHeight\">\n <span\n class=\"d-flex align-items-center justify-content-center cursor-pointer border-below\"\n style=\"min-width: 30px; height: 100%;\"\n *ngIf=\"section == 'center' && gridType === 'TimeSheet' && detailsIconPosition === 'start' && !areDatesSelectedAndEqual\"\n [ngStyle]=\"{\n 'background-color':\n hoveredRowId === (row._id || row.id)\n ? rowHoverColor\n : isRowSelected(row)\n ? checkedRowBackgroundColor\n : isEven\n ? evenRowsBackgroundColor\n : oddRowsBackgroundColor\n }\"\n (click)=\"toggleExpand(row)\"\n >\n <span\n class=\"data-grid-svg-icon\"\n [inlineSVG]=\"\n row.isDetailsExpand\n ? singleSpaAssetsPath + 'data-grid/icons/chevron-down.svg'\n : singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\n \"\n ></span>\n </span>\n <div\n [style.min-width.px]=\"\n section == 'center' && groupedColumns!.length ? groupBoxPadding : 0\n \"\n [class.row-selected]=\"rowSelectedIndexes.has(row.__virtualIndex)\"\n [class.first-row-selected]=\"firstSelectedRow == row.__virtualIndex\"\n [class.last-row-selected]=\"lastSelectedRow == row.__virtualIndex\"\n (contextmenu)=\"onRightClick($event, row, row?.details?.data?.length ? 'accordion-parent' : 'main')\"\n [style.height.px]=\"rowHeight\"\n class=\"data-grid-row h-100\"\n [class.even-row]=\"isEven\"\n [class.odd-row]=\"isOdd\"\n [class.hovered-row]=\"hoveredRowId === (row._id || row.id)\"\n (mouseenter)=\"onRowHover(row)\"\n (mouseleave)=\"onRowLeave()\"\n [ngStyle]=\"{\n 'background-color':\n hoveredRowId === (row._id || row.id)\n ? rowHoverColor\n : isRowSelected(row)\n ? checkedRowBackgroundColor\n : isEven\n ? evenRowsBackgroundColor\n : oddRowsBackgroundColor\n }\"\n ></div>\n <div\n (contextmenu)=\"onRightClick($event, row, row?.details?.data?.length ? 'accordion-parent' : 'main')\"\n [style.height.px]=\"rowHeight\"\n class=\"data-grid-row\"\n [class.even-row]=\"isEven\"\n [class.odd-row]=\"isOdd\"\n [class.hovered-row]=\"hoveredRowId === (row._id || row.id)\"\n (mouseenter)=\"onRowHover(row)\"\n (mouseleave)=\"onRowLeave()\"\n [ngStyle]=\"{\n 'background-color':\n hoveredRowId === (row._id || row.id)\n ? rowHoverColor\n : isRowSelected(row)\n ? checkedRowBackgroundColor\n : isEven\n ? evenRowsBackgroundColor\n : oddRowsBackgroundColor\n }\"\n >\n <div\n [style.backgroundColor]=\"checkboxesBackgroundColor\"\n class=\"select-all-checkbox-cell justify-content-end pe-2 s-no\"\n [style.width.px]=\"65\"\n *ngIf=\"isLeftSection && showSerialNumber\"\n [style.cursor]=\"\n 'url(' +\n singleSpaAssetsPath +\n 'data-grid/icons/arrow-right.svg), auto'\n \"\n (mousedown)=\"onRowMouseDown(row.__virtualIndex, $event)\"\n (mouseover)=\"onRowMouseOver(row.__virtualIndex, $event)\"\n >\n {{ row.__virtualIndex }}\n </div>\n <div\n [style.backgroundColor]=\"\n rowSelectedIndexes.has(row.__virtualIndex)\n ? selectedRowsBackgroundColor\n : checkboxesBackgroundColor\n \"\n class=\"select-all-checkbox-cell\"\n *ngIf=\"isLeftSection\"\n [class.left-selection-border]=\"\n rowSelectedIndexes.has(row.__virtualIndex)\n \"\n [class.first-row-selected]=\"firstSelectedRow == row.__virtualIndex\"\n [class.last-row-selected]=\"lastSelectedRow == row.__virtualIndex\"\n >\n <input\n *ngIf=\"hasAnyVisibleColumn\"\n type=\"checkbox\"\n [checked]=\"isRowSelected(row)\"\n (change)=\"toggleRowSelection(row)\"\n />\n </div>\n\n <!-- Render all columns -->\n <ng-container\n *ngFor=\"\n let col of columns;\n trackBy: trackByField;\n let colIndex = index\n \"\n >\n <ng-container *ngIf=\"col.children?.length > 0; else flatColumn\">\n <ng-container\n *ngFor=\"\n let child of col.children;\n trackBy: trackByField;\n let subColIndex = index\n \"\n >\n <ng-container *ngIf=\"child?.is_visible && !child?.isRowGrouped\">\n <ng-container\n *ngTemplateOutlet=\"\n cellTemplate;\n context: {\n col: child,\n row: row,\n rowIndex: rowIndex,\n colIndex: colIndex,\n subColIndex: subColIndex,\n section: section\n }\n \"\n ></ng-container>\n </ng-container>\n </ng-container>\n </ng-container>\n\n <ng-template #flatColumn>\n <ng-container\n *ngTemplateOutlet=\"\n cellTemplate;\n context: {\n col: col,\n row: row,\n rowIndex: rowIndex,\n colIndex: colIndex,\n subColIndex: null,\n section: section\n }\n \"\n ></ng-container>\n </ng-template>\n </ng-container>\n </div>\n\n <span\n class=\"d-flex align-items-center justify-content-center cursor-pointer border-below\"\n style=\"min-width: 30px; height: 100%;\"\n *ngIf=\"section == 'center' && gridType === 'TimeSheet' && detailsIconPosition === 'end' && !areDatesSelectedAndEqual\"\n [ngStyle]=\"{\n 'background-color':\n hoveredRowId === (row._id || row.id)\n ? rowHoverColor\n : isRowSelected(row)\n ? checkedRowBackgroundColor\n : isEven\n ? evenRowsBackgroundColor\n : oddRowsBackgroundColor\n }\"\n (click)=\"toggleExpand(row)\"\n >\n <span\n class=\"data-grid-svg-icon\"\n [inlineSVG]=\"\n row.isDetailsExpand\n ? singleSpaAssetsPath + 'data-grid/icons/chevron-down.svg'\n : singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\n \"\n ></span>\n </span>\n </div>\n <!-- LEFT PINNED: Empty table to keep alignment -->\n <div *ngIf=\"section === 'left' && row.isDetailsExpand && !isSingleDay\" class=\"accordion-details data-grid-accordion-section\" [style.color]=\"headerTextColor\" style=\"max-height: 350px; min-height: 150px ; overflow: hidden;\">\n <table class=\"nested-table table table-sm w-100 mb-0 data-grid-accordion-table\" [class.show-shadow]=\"rowShadingEnabled\">\n <thead>\n <tr [style.height.px]=\"nestedTableHeaderRowHeight\" [style.backgroundColor]=\"headerBackgroundColor\" [style.color]=\"headerTextColor\" [style.fontSize.px]=\"headerTextFontsSize\" [style.fontWeight]=\"headerFontWeight\">\n <th *ngFor=\"let _ of [1, 2, 3, 4, 5]\"></th>\n </tr>\n </thead>\n <tbody>\n <tr [style.height.px]=\"nestedTablerowHeight\" *ngFor=\"let _ of row.details.data\" [style.backgroundColor]=\"headerBackgroundColor\">\n <td *ngFor=\"let __ of [1, 2, 3, 4, 5]\"></td>\n </tr>\n </tbody>\n </table>\n </div>\n\n<!-- CENTER SECTION: Actual details table -->\n\n<div *ngIf=\"section === 'center' && row.isDetailsExpand && !isSingleDay\" class=\"accordion-details-wrapper data-grid-accordion\" [style.fontFamily]=\"fontFaimly\" [style.fontSize.px]=\"bodyTextFontsSize\" style=\"display: flex; width: 100%; max-height: 350px; min-height: 150px ; overflow: hidden ; \">\n <!-- LEFT SECTION OF ACCORDION -->\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;\">\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;\">\n <thead>\n <tr [style.height.px]=\"nestedTableHeaderRowHeight\" [style.backgroundColor]=\"headerBackgroundColor\" [style.color]=\"headerTextColor\" [style.fontSize.px]=\"headerTextFontsSize\" [style.fontWeight]=\"headerFontWeight\">\n <ng-container *ngFor=\"let col of row.details.columns | pinnedColumns:'left'; trackBy: trackByField\">\n <th *ngIf=\"col.is_visible !== false\"\n class=\"px-4\"\n [class.filter-applied]=\"isAccordionColumnFiltered(row, col)\"\n [style.color]=\"isAccordionColumnFiltered(row, col) ? '#007bff' : headerTextColor\"\n [attr.field]=\"col.field\"\n [attr.pinned]=\"col.pinned\"\n [style.width.px]=\"col.width || 200\"\n [style.min-width.px]=\"col.width || 200\">\n <div class=\"d-flex justify-content-between align-items-center\" style=\"width: 100%;\">\n <span class=\"d-flex align-items-center gap-1\" style=\"overflow: hidden; width: 100%;\">\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>\n <span class=\"text-truncate\" style=\"flex: 1; min-width: 0;\" title=\"{{ col.header }}\">{{ col.header }}</span>\n <span *ngIf=\"isAccordionColumnFiltered(row, col)\"\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\"\n class=\"data-grid-svg-icon text-primary ms-1\"\n style=\"font-size: 12px;\"></span>\n </span>\n <span class=\"three-dots p-1\"\n (click)=\"openDetailThreeDotsMenus($event, col, row, $any($event.currentTarget))\">\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/three-dots-vertical.svg'\" class=\"data-grid-svg-icon\"></span>\n </span>\n </div>\n <!-- <div class=\"resize-handles\" (mousedown)=\"onResizeDetailColumn($event, row, col)\">\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/resize-handle.svg'\" class=\"data-grid-svg-icon text-primary\"></span>\n </div> -->\n <ng-container *ngIf=\"activeDetailCol?.field == col.field && activeDetailRow === row\">\n <div class=\"position-absolute detail-column-menu-wrapper\"\n [style.top.px]=\"nestedTableHeaderRowHeight\"\n [style.left.px]=\"0\">\n <ng-container *ngTemplateOutlet=\"detailColumnMenu; context: { col: col, row: row }\"></ng-container>\n </div>\n </ng-container>\n </th>\n </ng-container>\n </tr>\n </thead>\n <tbody>\n <tr [style.height.px]=\"nestedTablerowHeight\" *ngFor=\"let d of row.details.data; let j = index; trackBy: trackById\" [ngStyle]=\"getAccordionRowStyle(j, row)\">\n <ng-container *ngFor=\"let col of row.details.columns | pinnedColumns:'left'; let localK = index; trackBy: trackByField\">\n <td *ngIf=\"col.is_visible !== false\"\n class=\"px-4\"\n (mousedown)=\"startDetailSelection(row, j, localK, col.field, $event, 'left')\"\n (mouseenter)=\"extendDetailSelection(row, j, localK, col.field, $event, 'left')\"\n [class.selected-cell]=\"isDetailCellSelected(row, j, localK, col.field, 'left')\"\n [attr.field]=\"col.field\"\n [attr.pinned]=\"col.pinned\"\n [style.fontSize.px]=\"bodyTextFontsSize\"\n (dblclick)=\"enableDetailEdits(row, d, col)\"\n [class.active-cell-detail]=\"isActiveDetailCell(row, d, col)\">\n <!-- Use the same rendering logic as center section -->\n <ng-container [ngSwitch]=\"col.field\">\n\n <ng-container *ngSwitchCase=\"'manually_logs'\" class=\"d-flex justify-content-start align-items-center pointer position-relative\">\n <ng-container *ngIf=\"d.manually_logs?.length > 0; else noManualLogsIcon\">\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/eye.svg'\"\n class=\"data-grid-svg-icon text-primary\"\n style=\"cursor: pointer; font-size: 16px;\"\n (mouseenter)=\"showManualLogsTooltip($event, row, d)\"\n (mouseleave)=\"hideManualLogsTooltip()\">\n </span>\n </ng-container>\n <ng-template #noManualLogsIcon>\u2013</ng-template>\n</ng-container>\n <!-- Breaks -->\n <ng-container *ngSwitchCase=\"'breaks'\">\n <ng-container *ngIf=\"d[col.field]?.length; else noBreaksLeft\">\n <app-badge-overflow\n [badges]=\"getBreakBadges(d[col.field])\"\n [maxWidth]=\"col.width || 200\"\n (badgeMouseEnter)=\"showBreakTooltip($event.event, $event.badge.data)\"\n (badgeMouseLeave)=\"hideBreakTooltip()\"\n (overflowCountClick)=\"onDetailBadgeOverflowCountClick(col, d)\">\n</app-badge-overflow>\n </ng-container>\n <ng-template #noBreaksLeft>\n <div >\n -\n </div>\n </ng-template>\n </ng-container>\n\n <!-- Short Breaks -->\n <ng-container *ngSwitchCase=\"'short_breaks'\">\n <ng-container *ngIf=\"d[col.field]?.short_break_duration; else noShortBreakLeft\">\n <div (dblclick)=\"onShortBreakClick.emit(d)\">\n <app-badge-overflow\n [badges]=\"getShortBreakBadges(d[col.field])\"\n [maxWidth]=\"col.width || 200\"\n (badgeMouseEnter)=\"showShortBreakTooltip($event.event, d)\"\n (badgeMouseLeave)=\"hideShortBreakTooltip()\"\n (badgeClick)=\"handleShortBreakClick(d, $event)\"\n (overflowCountClick)=\"onDetailBadgeOverflowCountClick(col, d)\">\n </app-badge-overflow>\n </div>\n </ng-container>\n <ng-template #noShortBreakLeft>\n <div >-</div>\n </ng-template>\n </ng-container>\n\n <!-- Short Leave -->\n <!-- Short Leave -->\n<ng-container *ngSwitchCase=\"'short_leave'\">\n <ng-container *ngIf=\"row.short_leave && row.short_leave.length > 0; else noShortLeaveMain\">\n <div class=\"w-100 d-flex main-progress-bar justify-content-center align-items-center\" \n style=\"background-color: rgb(111, 97, 207); height: 20px; border-radius: 4px; position: relative;\"\n (mouseenter)=\"showShortLeaveTooltip($event, row)\"\n (mouseleave)=\"hideShortLeaveTooltip()\">\n <span class=\"d-block\" [style.min-width.%]=\"row.short_leave[0].short_leave_time_percentage\" \n style=\"background-color: rgb(238, 99, 82); height: 100%; border-radius: 4px;\"></span>\n <span style=\"position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); color: white; font-size: 12px; font-weight: bold;\">\n {{ row.short_leave[0].short_leave_time_percentage }}%\n </span>\n </div>\n </ng-container>\n <ng-template #noShortLeaveMain>-</ng-template>\n</ng-container>\n\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()\">\n <div style=\"overflow: hidden; text-overflow: ellipsis; white-space: nowrap; width: 100%;\" [class.restriction-indicator]=\"row.attendance_log_detail?.length > 0\" title=\"{{ d.is_un_restricted ? 'Yes' : 'No' }}\">\n {{ d.is_un_restricted ? 'Yes' : 'No' }}\n </div>\n</div>\n\n <div *ngSwitchCase=\"'is_payroll_processed'\" class=\"d-flex justify-content-start flex-column pointer position-relative\" >\n <div style=\"overflow: hidden; text-overflow: ellipsis; white-space: nowrap; width: 100%;\">\n {{ d.is_payroll_processed ? 'Yes' : 'No' }}\n </div>\n </div>\n\n\n <!-- Status -->\n <ng-container *ngSwitchCase=\"'status'\">\n <ng-container *ngIf=\"getNestedValue(d, col.field); else noStatus\">\n <span class=\"badge\" [class]=\"getStatusBadgeClass(getNestedValue(d, col.field))\">\n {{ transformStatus(getNestedValue(d, col.field)) }}\n </span>\n </ng-container>\n <ng-template #noStatus>-</ng-template>\n</ng-container>\n\n<!-- Attendance Status -->\n<ng-container *ngSwitchCase=\"'attendanceStatus'\">\n <ng-container *ngIf=\"getNestedValue(d, col.field); else noAttendanceStatus\">\n <span class=\"badge\" [class]=\"getAttendanceStatusBadgeClass(getNestedValue(d, col.field))\">\n {{ transformStatus(getNestedValue(d, col.field)) }}\n </span>\n </ng-container>\n <ng-template #noAttendanceStatus>-</ng-template>\n</ng-container>\n\n <!-- Default fallback -->\n <ng-container *ngSwitchDefault>\n <div style=\"overflow: hidden; text-overflow: ellipsis; white-space: nowrap; width: 100%;\" title=\"{{\n col.type === 'date'\n ? (getNestedValue(d, col.field) ? (getNestedValue(d, col.field) | timezoneFormat:prefs:'date') : '-')\n : col.type === 'time'\n ? ((getTimeValue(getNestedValue(d, col.field)) | timezoneFormat:prefs:'time'))\n : (getNestedValue(d, col.field)?.value || getNestedValue(d, col.field)?.name || getNestedValue(d, col.field) || '-')\n }}\">{{ col.type === 'date'\n ? (getNestedValue(d, col.field) ? (getNestedValue(d, col.field) | timezoneFormat:prefs:'date') : '-')\n : col.type === 'time'\n ? ((getTimeValue(getNestedValue(d, col.field)) | timezoneFormat:prefs:'time'))\n : (getNestedValue(d, col.field)?.value || getNestedValue(d, col.field)?.name || getNestedValue(d, col.field) || '-')\n }}</div>\n </ng-container>\n </ng-container>\n </td>\n </ng-container>\n </tr>\n</tbody>\n </table>\n </div>\n\n <!-- CENTER SECTION OF ACCORDION (WITH VIRTUAL SCROLL) -->\n\n<div class=\"accordion-center-section data-grid-accordion-section\" style=\"flex: 1; min-width: 0; display: flex; flex-direction: column; overflow: hidden;\">\n <!-- Header Section -->\n <div class=\"header-container\" style=\"overflow-x: auto; scrollbar-width: none; -ms-overflow-style: none;\" #headerContainer (scroll)=\"syncScroll($event)\">\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%;\">\n <thead>\n <tr\n [style.height.px]=\"nestedTableHeaderRowHeight\"\n cdkDropList\n [cdkDropListData]=\"row?.details.columns\"\n cdkDropListOrientation=\"horizontal\"\n (cdkDropListDropped)=\"dropColumn($event, row)\"\n >\n <ng-container *ngFor=\"let col of row.details.columns; let i = index\">\n <th\n *ngIf=\"col.is_visible !== false && !col.pinned\"\n class=\"px-4\"\n cdkDrag\n [attr.field]=\"col.field\"\n [class.filter-applied]=\"isAccordionColumnFiltered(row, col)\"\n [style.width.px]=\"col.width || 200\"\n [style.min-width.px]=\"col.width || 200\"\n [style.backgroundColor]=\"headerBackgroundColor\"\n [style.color]=\"isAccordionColumnFiltered(row, col) ? '#007bff' : headerTextColor\"\n [style.fontSize.px]=\"headerTextFontsSize\"\n [style.fontWeight]=\"headerFontWeight\"\n style=\"cursor: move; position: relative;\">\n <div class=\"d-flex justify-content-between align-items-center\" style=\"width: 100%;\">\n <span class=\"d-flex align-items-center gap-1\" style=\"overflow: hidden; width: 100%;\">\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>\n <span class=\"text-truncate\" style=\"flex: 1; min-width: 0;\" title=\"{{ col.header }}\">{{ col.header }}</span>\n <span *ngIf=\"isAccordionColumnFiltered(row, col)\"\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\"\n class=\"data-grid-svg-icon text-primary ms-1\"\n style=\"font-size: 12px;\"></span>\n </span>\n <span class=\"three-dots p-1\"\n (click)=\"openDetailThreeDotsMenus($event, col, row, $any($event.currentTarget))\">\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/three-dots-vertical.svg'\" class=\"data-grid-svg-icon\"></span>\n </span>\n </div>\n <!-- <div class=\"resize-handles\" (mousedown)=\"onResizeDetailColumn($event, row, col)\">\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/resize-handle.svg'\" class=\"data-grid-svg-icon text-primary\"></span>\n </div> -->\n <ng-container *ngIf=\"activeDetailCol?.field == col.field && activeDetailRow === row\">\n <div class=\"position-absolute detail-column-menu-wrapper\" [style.top.px]=\"nestedTableHeaderRowHeight\" [style.left.px]=\"0\">\n <ng-container *ngTemplateOutlet=\"detailColumnMenu; context: { col: col, row: row }\"></ng-container>\n </div>\n </ng-container>\n </th>\n </ng-container>\n </tr>\n </thead>\n </table>\n </div>\n\n <!-- Group Badges (if any) -->\n <div *ngIf=\"row.details?.groupedColumns?.length\" class=\"detail-group-badges\">\n <span *ngFor=\"let g of row.details.groupedColumns; trackBy: trackByField\" class=\"badge bg-light text-dark me-1\">\n {{ g.header }}\n <span class=\"ms-1 cursor-pointer\" (click)=\"ungroupDetailColumn(g, row)\" [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/x.svg'\"></span>\n </span>\n </div>\n\n <!-- No Data Message when filtered results are empty -->\n <div *ngIf=\"row.details.data.length === 0\" class=\"d-flex justify-content-center align-items-center\" style=\"flex: 1; min-height: 104px ;\">\n <div class=\"text-center text-muted\">\n <div class=\"mb-2\">\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\" class=\"data-grid-svg-icon text-muted\" style=\"font-size: 24px;\"></span>\n </div>\n <div class=\"fw-bold\">No records found for this filter.</div>\n </div>\n </div>\n\n <!-- Data Table Section with Virtual Scroll -->\n <cdk-virtual-scroll-viewport\n *ngIf=\"row.details.data.length > 0\"\n itemSize=\"{{ nestedTablerowHeight }}\"\n minBufferPx=\"200\"\n maxBufferPx=\"400\"\n class=\"detail-virtual-scroll\"\n [attr.data-detail-row-id]=\"row._id || row.id\"\n style=\"flex: 1; overflow: auto;\"\n #dataContainer\n (scroll)=\"syncVerticalScroll($event)\"\n (scroll)=\"syncScroll($event)\">\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%;\">\n <tbody>\n <tr\n class=\"cursor-pointer data-grid-accordion-row\"\n *cdkVirtualFor=\"let d of row.details.data; trackBy: trackById; let j = index\"\n (contextmenu)=\"onRightClick($event, d, 'accordion-child')\"\n [style.height.px]=\"nestedTablerowHeight\"\n [ngStyle]=\"getAccordionRowStyle(j, row)\">\n <ng-container *ngFor=\"let col of row.details.columns; let k = index\">\n <td\n *ngIf=\"col.is_visible !== false && !col.pinned\"\n class=\"px-4\"\n (mousedown)=\"startDetailSelection(row, j, k, col.field, $event, 'center')\"\n (mouseenter)=\"extendDetailSelection(row, j, k, col.field, $event, 'center')\"\n [class.selected-cell]=\"isDetailCellSelected(row, j, k, col.field, 'center')\"\n [attr.field]=\"col.field\"\n [style.width.px]=\"col.width || 200\"\n [style.min-width.px]=\"col.width || 200\"\n [style.fontSize.px]=\"bodyTextFontsSize\"\n [class.active-cell-detail]=\"isActiveDetailCell(row, d, col)\"\n style=\"cursor: pointer; position: relative; overflow: visible; cursor: cell; \">\n <div class=\"time-sheet-container\" style=\"overflow: visible; display: flex; gap: 4px; align-items: center; height: 100%; \">\n <ng-container *ngIf=\"col.field === 'breaks' || col.field === 'short_breaks'; else defaultDetailCell\">\n <ng-container *ngIf=\"col.field === 'breaks'\">\n <ng-container *ngIf=\"d[col.field]?.length; else noBreaks\">\n <span *ngFor=\"let breakItem of d[col.field]; let breakIndex = index\"\n class=\"circle-value badge-outline break-on text-center\"\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'\"\n (mouseenter)=\"showBreakTooltip($event, breakItem)\"\n (mouseleave)=\"hideBreakTooltip()\">\n {{ breakItem.break_duration }}m\n</span>\n </ng-container>\n <ng-template #noBreaks>\n <div\n \n >\n -\n</div>\n</ng-template>\n</ng-container>\n <ng-container *ngIf=\"col.field === 'short_breaks' && !isDetailEditing(row, d, col)\">\n <ng-container *ngIf=\"d[col.field]?.short_break_duration; else noShortBreak\">\n <div (dblclick)=\"onShortBreakClick.emit(d)\">\n <app-badge-overflow\n [badges]=\"getShortBreakBadges(d[col.field])\"\n [maxWidth]=\"col.width || 200\"\n (badgeMouseEnter)=\"showShortBreakTooltip($event.event, d)\"\n (badgeMouseLeave)=\"hideShortBreakTooltip()\"\n (badgeClick)=\"handleShortBreakClick(d, $event)\"\n (overflowCountClick)=\"onDetailBadgeOverflowCountClick(col, d)\">\n </app-badge-overflow>\n </div>\n </ng-container>\n <ng-template #noShortBreak>\n <div >-</div>\n </ng-template>\n</ng-container>\n <ng-container *ngIf=\"isDetailEditing(row, d, col)\">\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;\" />\n </ng-container>\n </ng-container>\n <ng-template #defaultDetailCell>\n <span class=\"d-flex align-items-center h-100\">\n <ng-container *ngIf=\"!isDetailEditing(row, d, col)\">\n <ng-container [ngSwitch]=\"col.field\">\n <!-- \u2705 SHORT LEAVE: Progress bar in detail rows -->\n <div *ngSwitchCase=\"'short_leave'\" class=\"position-relative\" style=\"min-width: 100px; width: 200px;\">\n <ng-container *ngIf=\"d.short_leave && d.short_leave.length > 0; else noShortLeaveDetail\">\n <div\n class=\"w-100 d-flex main-progress-bar\"\n style=\"background-color: rgb(111, 97, 207); height: 20px; border-radius: 4px; position: relative;\"\n (mouseenter)=\"showShortLeaveTooltip($event, d)\"\n (mouseleave)=\"hideShortLeaveTooltip()\"\n >\n <span\n class=\"d-block\"\n [style.min-width.%]=\"d.short_leave[0].short_leave_time_percentage\"\n style=\"background-color: rgb(238, 99, 82); height: 100%; border-radius: 4px;\"\n ></span>\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>\n </div>\n </ng-container>\n <ng-template #noShortLeaveDetail>\n <div >-</div>\n </ng-template>\n </div>\n\n <!-- Status -->\n<ng-container *ngSwitchCase=\"'status'\">\n <ng-container *ngIf=\"getNestedValue(d, col.field); else noStatus\">\n <span class=\"badge\" [class]=\"getStatusBadgeClass(getNestedValue(d, col.field))\">\n {{ transformStatus(getNestedValue(d, col.field)) }}\n </span>\n </ng-container>\n <ng-template #noStatus>-</ng-template>\n</ng-container>\n\n<!-- Attendance Status -->\n<ng-container *ngSwitchCase=\"'attendanceStatus'\">\n <ng-container *ngIf=\"getNestedValue(d, col.field); else noAttendanceStatus\">\n <span class=\"badge\" [class]=\"getAttendanceStatusBadgeClass(getNestedValue(d, col.field))\">\n {{ transformStatus(getNestedValue(d, col.field)) }}\n </span>\n </ng-container>\n <ng-template #noAttendanceStatus>-</ng-template>\n</ng-container>\n\n <!-- Existing cases -->\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()\">\n <div class=\"popover__wrapper\" style=\"overflow: hidden; text-overflow: ellipsis; white-space: nowrap; width: 100%;\" [class.restriction-indicator]=\"row.attendance_log_detail?.length > 0\">\n {{ d.is_un_restricted ? 'Yes' : 'No' }}\n </div>\n </div>\n\n <div *ngSwitchCase=\"'is_payroll_processed'\" class=\"d-flex justify-content-start flex-column pointer position-relative\" >\n <div style=\"overflow: hidden; text-overflow: ellipsis; white-space: nowrap; width: 100%;\" title=\"{{ d.is_payroll_processed ? 'Yes' : 'No' }}\">\n {{ d.is_payroll_processed ? 'Yes' : 'No' }}\n </div>\n </div>\n <div *ngSwitchCase=\"'manually_logs'\" class=\"d-flex justify-content-start align-items-center pointer position-relative\">\n <ng-container *ngIf=\"d.manually_logs?.length > 0; else noManualLogsIcon\">\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>\n </ng-container>\n <ng-template #noManualLogsIcon>\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>\n </ng-template>\n </div>\n\n <!-- Default fallback -->\n <div *ngSwitchDefault style=\"overflow: hidden; text-overflow: ellipsis; white-space: nowrap; width: 100%;\" title=\"{{\n col.type === 'date'\n ? (getNestedValue(d, col.field) ? (getNestedValue(d, col.field) | timezoneFormat:prefs:'date') : '-')\n : col.type === 'time'\n ? ((getTimeValue(getNestedValue(d, col.field)) | timezoneFormat:prefs:'time'))\n : (getNestedValue(d, col.field)?.value || getNestedValue(d, col.field)?.name || getNestedValue(d, col.field) || '-')\n }}\">\n {{\n col.type === 'date'\n ? (getNestedValue(d, col.field) ? (getNestedValue(d, col.field) | timezoneFormat:prefs:'date') : '-')\n : col.type === 'time'\n ? ((getTimeValue(getNestedValue(d, col.field)) | timezoneFormat:prefs:'time'))\n : (getNestedValue(d, col.field)?.value || getNestedValue(d, col.field)?.name || getNestedValue(d, col.field) || '-')\n }}\n </div>\n</ng-container>\n </ng-container>\n <ng-container *ngIf=\"isDetailEditing(row, d, col)\">\n <ng-container [ngSwitch]=\"col.type\">\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;\" />\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;\" />\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;\" />\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;\" />\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;\" />\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;\">\n <option *ngFor=\"let option of col.column_dropdown_value\" [ngValue]=\"option?.value || option\">\n {{ option?.label || option?.name || option }}\n </option>\n </select>\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;\" />\n </ng-container>\n </ng-container>\n </span>\n </ng-template>\n </div>\n </td>\n </ng-container>\n </tr>\n </tbody>\n </table>\n </cdk-virtual-scroll-viewport>\n</div>\n\n <!-- RIGHT SECTION OF ACCORDION -->\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;\">\n <table class=\"nested-table table-sm mb-0 data-grid-accordion-table\" [class.show-shadow]=\"rowShadingEnabled\" style=\"table-layout: fixed; width: auto;\">\n <thead>\n <tr [style.height.px]=\"nestedTableHeaderRowHeight\" [style.backgroundColor]=\"headerBackgroundColor\" [style.color]=\"headerTextColor\" [style.fontSize.px]=\"headerTextFontsSize\" [style.fontWeight]=\"headerFontWeight\">\n <ng-container *ngFor=\"let col of row.details.columns | pinnedColumns:'right'; trackBy: trackByField\">\n <th *ngIf=\"col.is_visible !== false\"\n class=\"px-4\"\n [class.filter-applied]=\"isAccordionColumnFiltered(row, col)\"\n [style.width.px]=\"col.width || 200\"\n [style.min-width.px]=\"col.width || 200\"\n [style.color]=\"isAccordionColumnFiltered(row, col) ? '#007bff' : headerTextColor\"\n [attr.field]=\"col.field\"\n [attr.pinned]=\"col.pinned\">\n <div class=\"d-flex justify-content-between align-items-center\" style=\"width: 100%;\">\n <span class=\"d-flex align-items-center gap-1\" style=\"overflow: hidden; width: 100%;\">\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/pin-blue.svg'\"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"></span>\n <span class=\"text-truncate\" style=\"flex: 1; min-width: 0;\" title=\"{{ col.header }}\">{{ col.header }}</span>\n <span *ngIf=\"isAccordionColumnFiltered(row, col)\"\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\"\n class=\"data-grid-svg-icon text-primary ms-1\"\n style=\"font-size: 12px;\"></span>\n </span>\n <span class=\"three-dots p-1\"\n (click)=\"openDetailThreeDotsMenus($event, col, row, $any($event.currentTarget))\">\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/three-dots-vertical.svg'\" class=\"data-grid-svg-icon\"></span>\n </span>\n </div>\n\n <!-- <div class=\"resize-handles\" (mousedown)=\"onResizeDetailColumn($event, row, col)\">\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/resize-handle.svg'\" class=\"data-grid-svg-icon text-primary\"></span>\n </div> -->\n <ng-container *ngIf=\"activeDetailCol?.field == col.field && activeDetailRow === row\">\n <div class=\"position-absolute detail-column-menu-wrapper\"\n [style.top.px]=\"nestedTableHeaderRowHeight\"\n [style.left.px]=\"0\">\n <ng-container *ngTemplateOutlet=\"detailColumnMenu; context: { col: col, row: row }\"></ng-container>\n </div>\n </ng-container>\n </th>\n </ng-container>\n </tr>\n </thead>\n <tbody>\n <tr [style.height.px]=\"nestedTablerowHeight\" *ngFor=\"let d of row.details.data; let j = index; trackBy: trackById\" [ngStyle]=\"getAccordionRowStyle(j, row)\">\n <ng-container *ngFor=\"let col of row.details.columns | pinnedColumns:'right'; let localK = index; trackBy: trackByField\">\n <td *ngIf=\"col.is_visible !== false\"\n class=\"px-4\"\n [attr.field]=\"col.field\"\n [attr.pinned]=\"col.pinned\"\n (mousedown)=\"startDetailSelection(row, j, localK, col.field, $event, 'right')\"\n (mouseenter)=\"extendDetailSelection(row, j, localK, col.field, $event, 'right')\"\n [class.selected-cell]=\"isDetailCellSelected(row, j, localK, col.field, 'right')\"\n [style.fontSize.px]=\"bodyTextFontsSize\"\n [class.active-cell-detail]=\"isActiveDetailCell(row, d, col)\">\n <ng-container [ngSwitch]=\"col.field\">\n\n <ng-container *ngSwitchCase=\"'manually_logs'\" class=\"d-flex justify-content-start align-items-center pointer position-relative\">\n <ng-container *ngIf=\"d.manually_logs?.length > 0; else noManualLogsIcon\">\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/eye.svg'\"\n class=\"data-grid-svg-icon text-primary\"\n style=\"cursor: pointer; font-size: 16px;\"\n (mouseenter)=\"showManualLogsTooltip($event, row, d)\"\n (mouseleave)=\"hideManualLogsTooltip()\">\n </span>\n </ng-container>\n <ng-template #noManualLogsIcon>\u2013</ng-template>\n</ng-container>\n <!-- Breaks -->\n <ng-container *ngSwitchCase=\"'breaks'\">\n <ng-container *ngIf=\"d[col.field]?.length; else noBreaksLeft\">\n <app-badge-overflow\n [badges]=\"getBreakBadges(d[col.field])\"\n [maxWidth]=\"col.width || 200\"\n (badgeMouseEnter)=\"showBreakTooltip($event.event, $event.badge.data)\"\n (badgeMouseLeave)=\"hideBreakTooltip()\"\n (overflowCountClick)=\"onDetailBadgeOverflowCountClick(col, d)\">\n</app-badge-overflow>\n </ng-container>\n <ng-template #noBreaksLeft>\n <div>\n -\n </div>\n </ng-template>\n </ng-container>\n\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()\">\n <div style=\"overflow: hidden; text-overflow: ellipsis; white-space: nowrap; width: 100%;\" [class.restriction-indicator]=\"row.attendance_log_detail?.length > 0\" title=\"{{ d.is_un_restricted ? 'Yes' : 'No' }}\">\n {{ d.is_un_restricted ? 'Yes' : 'No' }}\n </div>\n </div>\n\n <div *ngSwitchCase=\"'is_payroll_processed'\" class=\"d-flex justify-content-start flex-column pointer position-relative\" >\n <div style=\"overflow: hidden; text-overflow: ellipsis; white-space: nowrap; width: 100%;\" title=\"{{ d.is_payroll_processed ? 'Yes' : 'No' }}\">\n {{ d.is_payroll_processed ? 'Yes' : 'No' }}\n </div>\n </div>\n\n <!-- Short Breaks -->\n <ng-container *ngSwitchCase=\"'short_breaks'\">\n <ng-container *ngIf=\"d[col.field]?.short_break_duration; else noShortBreakLeft\">\n <div (dblclick)=\"onShortBreakClick.emit(d)\">\n <app-badge-overflow\n [badges]=\"getShortBreakBadges(d[col.field])\"\n [maxWidth]=\"col.width || 200\"\n (badgeMouseEnter)=\"showShortBreakTooltip($event.event, d)\"\n (badgeMouseLeave)=\"hideShortBreakTooltip()\"\n (badgeClick)=\"handleShortBreakClick(d, $event)\"\n (overflowCountClick)=\"onDetailBadgeOverflowCountClick(col, d)\">\n </app-badge-overflow>\n </div>\n </ng-container>\n <ng-template #noShortBreakLeft>\n <div >-</div>\n </ng-template>\n </ng-container>\n\n <!-- Short Leave -->\n <!-- Short Leave -->\n<ng-container *ngSwitchCase=\"'short_leave'\">\n <ng-container *ngIf=\"row.short_leave && row.short_leave.length > 0; else noShortLeaveMain\">\n <div class=\"w-100 d-flex main-progress-bar justify-content-center align-items-center\" \n style=\"background-color: rgb(111, 97, 207); height: 20px; border-radius: 4px; position: relative;\"\n (mouseenter)=\"showShortLeaveTooltip($event, row)\"\n (mouseleave)=\"hideShortLeaveTooltip()\">\n <span class=\"d-block\" [style.min-width.%]=\"row.short_leave[0].short_leave_time_percentage\" \n style=\"background-color: rgb(238, 99, 82); height: 100%; border-radius: 4px;\"></span>\n <span style=\"position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); color: white; font-size: 12px; font-weight: bold;\">\n {{ row.short_leave[0].short_leave_time_percentage }}%\n </span>\n </div>\n </ng-container>\n <ng-template #noShortLeaveMain>-</ng-template>\n</ng-container>\n\n<ng-container *ngSwitchCase=\"'status'\">\n <ng-container *ngIf=\"getNestedValue(d, col.field); else noStatus\">\n <span class=\"badge\" [class]=\"getStatusBadgeClass(getNestedValue(d, col.field))\">\n {{ transformStatus(getNestedValue(d, col.field)) }}\n </span>\n </ng-container>\n <ng-template #noStatus>-</ng-template>\n</ng-container>\n\n<!-- Attendance Status -->\n<ng-container *ngSwitchCase=\"'attendanceStatus'\">\n <ng-container *ngIf=\"getNestedValue(d, col.field); else noAttendanceStatus\">\n <span class=\"badge\" [class]=\"getAttendanceStatusBadgeClass(getNestedValue(d, col.field))\">\n {{ transformStatus(getNestedValue(d, col.field)) }}\n </span>\n </ng-container>\n <ng-template #noAttendanceStatus>-</ng-template>\n</ng-container>\n\n <!-- Default -->\n <ng-container *ngSwitchDefault>\n<div style=\"overflow: hidden; text-overflow: ellipsis; white-space: nowrap; width: 100%;\" title=\"{{\n col.type === 'date'\n ? (getNestedValue(d, col.field) ? (getNestedValue(d, col.field) | timezoneFormat:prefs:'date') : '-')\n : col.type === 'time'\n ? ((getTimeValue(getNestedValue(d, col.field)) | timezoneFormat:prefs:'time'))\n : (getNestedValue(d, col.field)?.value || getNestedValue(d, col.field)?.name || getNestedValue(d, col.field) || '-')\n}}\">{{ col.type === 'date'\n ? (getNestedValue(d, col.field) ? (getNestedValue(d, col.field) | timezoneFormat:prefs:'date') : '-')\n : col.type === 'time'\n ? ((getTimeValue(getNestedValue(d, col.field)) | timezoneFormat:prefs:'time'))\n : (getNestedValue(d, col.field)?.value || getNestedValue(d, col.field)?.name || getNestedValue(d, col.field) || '-')\n}}</div>\n</ng-container>\n</ng-container>\n </td>\n </ng-container>\n </tr>\n</tbody>\n </table>\n\n </div>\n\n <!-- DETAIL SIDE MENU (Sticky on right end) -->\n <!-- <div class=\"detail-side-menu-wrapper\" >\n <div style=\"width: 30px\" class=\"d-flex flex-column align-items-center \">\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\">\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/ui-checks-grid.svg'\" class=\"data-grid-svg-icon\"></span>\n <div class=\"side-menue-text\">Columns</div>\n </div>\n \n </div>\n\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);\">\n <ng-container *ngIf=\"row.details.sideMenu.currentTab === 'cols'\">\n <div class=\"px-3 py-2 border-bottom d-flex align-items-center\">\n <strong class=\"me-auto\">Columns</strong>\n <input type=\"text\" class=\"form-control form-control-sm\" placeholder=\"Search...\" [(ngModel)]=\"row.details.sideMenu.columnSearch\" style=\"width: 120px; font-size: 12px;\" />\n </div>\n <div class=\"side-menu-scrollable\">\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\">\n <input type=\"checkbox\" class=\"form-check-input me-2\" [(ngModel)]=\"col.is_visible\" (change)=\"onDetailColumnVisibilityChange(row)\" />\n <span>{{ col.header }}</span>\n </div>\n </div>\n </ng-container>\n\n <ng-container *ngIf=\"row.details.sideMenu.currentTab === 'filtrs'\">\n <div class=\"px-3 py-2 border-bottom d-flex align-items-center\">\n <strong class=\"me-auto\">Filters</strong>\n <input type=\"text\" class=\"form-control form-control-sm\" placeholder=\"Search...\" [(ngModel)]=\"row.details.sideMenu.columnSearch\" style=\"width: 120px; font-size: 12px;\" />\n </div>\n <div class=\"side-menu-scrollable\">\n <div *ngFor=\"let col of row.details.columns | filter: row.details.sideMenu.columnSearch:'header'; trackBy: trackByField\" class=\"mb-3\">\n <div class=\"d-flex justify-content-between align-items-center cursor-pointer\" (click)=\"col.expandedFilter = !col.expandedFilter\">\n <label class=\"mb-0 small\">{{ col.header }}</label>\n <span class=\"toggle-icon data-grid-svg-icon\" [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\" [class.rotate]=\"col.expandedFilter\"></span>\n </div>\n <div *ngIf=\"col.expandedFilter\" class=\"mt-2 filter-input-container ps-3 pe-3\">\n <ng-container *ngIf=\"col.type === 'dropdown'; else textFilter\">\n <div class=\"p-1\">\n <input\n type=\"text\"\n class=\"form-control form-control-sm mb-2\"\n placeholder=\"Search...\"\n [(ngModel)]=\"col.searchValue\"\n />\n\n <div class=\"form-check mb-1 ms-1\">\n <input\n class=\"form-check-input\"\n type=\"checkbox\"\n [checked]=\"\n row.details.filters[col.field]?._ids?.length == col.column_dropdown_value?.length\n \"\n (change)=\"toggleSelectAllDetailFilters(col, row, $event)\"\n id=\"detail_selectAll_{{ col.field }}\"\n />\n <label class=\"form-check-label\" for=\"detail_selectAll_{{ col.field }}\">\n Select All\n </label>\n </div>\n\n <div class=\"dropdown-options\">\n <div\n class=\"form-check mb-1 ms-1\"\n *ngFor=\"\n let option of col?.column_dropdown_value\n | filter : col.searchValue : 'value';\n trackBy: trackById\n \"\n >\n <input\n class=\"form-check-input\"\n type=\"checkbox\"\n [value]=\"option\"\n [checked]=\"\n row.details.filters[col.field]?._ids?.includes(option?._id || option?.id || option)\n \"\n (change)=\"onDetailOptionToggle(col, option, row)\"\n id=\"detail_option_{{ col.field }}_{{\n option?.id || option?._id || option\n }}\"\n />\n <label\n class=\"form-check-label\"\n [for]=\"\n 'detail_option_' +\n col.field +\n '_' +\n (option?.id || option?._id || option)\n \"\n >\n {{ option.value || option }}\n </label>\n </div>\n </div>\n </div>\n </ng-container>\n\n <ng-template #textFilter>\n <div class=\"filter-text-section\">\n <div class=\"form-group mb-2\">\n <select\n class=\"form-select form-select-sm\"\n [(ngModel)]=\"row.details.filters[col.field].first_condition\"\n (ngModelChange)=\"applyDetailRowFilter(row)\"\n >\n <option value=\"contain\">Contains</option>\n <option value=\"equal\">Equals</option>\n <option value=\"before\">Begins With</option>\n <option value=\"after\">Ends With</option>\n </select>\n </div>\n\n <input\n [type]=\"col.type == 'date' ? 'date' : 'text'\"\n class=\"form-control form-control-sm mb-3\"\n placeholder=\"Value\"\n [(ngModel)]=\"row.details.filters[col.field].first_value\"\n (ngModelChange)=\"applyDetailRowFilter(row)\"\n />\n\n <ng-container *ngIf=\"row.details.filters[col.field]?.first_value\">\n <div class=\"form-group mb-2\">\n <div class=\"form-check form-check-inline\">\n <input\n class=\"form-check-input filter-radio-inputs\"\n type=\"radio\"\n name=\"detail_condition_{{ col.field }}\"\n [(ngModel)]=\"row.details.filters[col.field].condition\"\n (ngModelChange)=\"applyDetailRowFilter(row)\"\n value=\"and\"\n id=\"detail_and_{{ col.field }}\"\n />\n <label class=\"form-check-label\" for=\"detail_and_{{ col.field }}\"\n >AND</label\n >\n </div>\n <div class=\"form-check form-check-inline\">\n <input\n class=\"form-check-input filter-radio-inputs\"\n type=\"radio\"\n name=\"detail_condition_{{ col.field }}\"\n [(ngModel)]=\"row.details.filters[col.field].condition\"\n (ngModelChange)=\"applyDetailRowFilter(row)\"\n value=\"or\"\n id=\"detail_or_{{ col.field }}\"\n />\n <label class=\"form-check-label\" for=\"detail_or_{{ col.field }}\"\n >OR</label\n >\n </div>\n <div class=\"form-check form-check-inline\">\n <input\n class=\"form-check-input filter-radio-inputs\"\n type=\"radio\"\n name=\"detail_condition_{{ col.field }}\"\n [(ngModel)]=\"row.details.filters[col.field].condition\"\n (ngModelChange)=\"applyDetailRowFilter(row)\"\n value=\"none\"\n id=\"detail_none_{{ col.field }}\"\n />\n <label class=\"form-check-label\" for=\"detail_none_{{ col.field }}\"\n >None</label\n >\n </div>\n </div>\n\n <ng-container *ngIf=\"row.details.filters[col.field].condition !== 'none'\">\n <div class=\"form-group mb-2\">\n <select\n class=\"form-select form-select-sm\"\n [(ngModel)]=\"row.details.filters[col.field].second_condition\"\n (ngModelChange)=\"applyDetailRowFilter(row)\"\n >\n <option value=\"contain\">Contains</option>\n <option value=\"equal\">Equals</option>\n <option value=\"before\">Begins With</option>\n <option value=\"after\">Ends With</option>\n </select>\n </div>\n\n <input\n [type]=\"col.type == 'date' ? 'date' : 'text'\"\n class=\"form-control form-control-sm mb-2\"\n placeholder=\"Second Value\"\n [(ngModel)]=\"row.details.filters[col.field].second_value\"\n (ngModelChange)=\"applyDetailRowFilter(row)\"\n />\n </ng-container>\n </ng-container>\n </div>\n </ng-template>\n </div>\n </div>\n </div>\n </ng-container>\n </div>\n </div> -->\n</div>\n\n<!-- Detail Side Menu -->\n\n\n\n<!-- Popover for Restriction Logs (is_un_restricted) -->\n<!-- <div\n *ngIf=\"restrictionTooltipVisible\"\n class=\"popover__content m-l-10 popoverRestriction position-absolute border rounded bg-white p-3\"\n [style.left.px]=\"restrictionTooltipPosition.x\"\n [style.top.px]=\"restrictionTooltipPosition.y\"\n (mouseenter)=\"preventRestrictionTooltipHide()\"\n (mouseleave)=\"hideRestrictionTooltip()\"\n style=\"z-index: 1000; min-width: 300px; font-size: 12px;\"\n @tooltipAnimation\n>\n <div class=\"modal-area px-0 py-0\">\n <div class=\"table-responsive\">\n <table class=\"table table-row-primary-100 gs-0 gy-2 mb-0\">\n <thead>\n <tr class=\"fw-bolder text-muted bg-light\">\n <th class=\"center ps-2\">Clock in</th>\n <th class=\"center\">Clock out</th>\n <th class=\"center\">Log Hr</th>\n <th class=\"center\">Log Min</th>\n <th class=\"center pe-2\">Status</th>\n </tr>\n </thead>\n <tbody>\n <tr *ngFor=\"let item of currentRestrictionLogs\">\n <td class=\"center ps-2\">\n <span class=\"text-primary\"> {{ item?.clock_in_time | date:'shortTime'}}</span>\n </td>\n <td class=\"center\">\n <span class=\"text-primary\">{{ item?.clock_out_time | date:'shortTime'}}</span>\n </td>\n <td class=\"center\">\n <span class=\"text-primary\">{{ item?.logged_hours }}</span>\n </td>\n <td class=\"center\">\n <span class=\"text-primary\">{{ item?.logged_minutes }}</span>\n </td>\n <td class=\"center\">\n <span class=\"badge bg-light text-dark border\">\n {{ item?.status ? (item.status | titlecase) : 'N/A' }}\n </span>\n </td>\n </tr>\n </tbody>\n </table>\n </div>\n </div>\n</div> -->\n\n<!-- Popover for Manual Logs -->\n<!-- <div\n *ngIf=\"manualLogsTooltipVisible\"\n class=\"popover__content position-absolute border rounded bg-white p-3\"\n [style.left.px]=\"manualLogsTooltipPosition.x\"\n [style.top.px]=\"manualLogsTooltipPosition.y\"\n (mouseenter)=\"preventManualLogsTooltipHide()\"\n (mouseleave)=\"hideManualLogsTooltip()\"\n style=\"z-index: 1000; min-width: 500px; font-size: 12px;\"\n @tooltipAnimation\n>\n <div class=\"modal-area px-0 py-0\">\n <ng-container *ngIf=\"currentManualLogs.length > 0; else noManualLogs\">\n <div class=\"table-responsive\">\n <table class=\"table table-row-primary-100 gs-0 gy-2 mb-0\">\n <thead>\n <tr class=\"fw-bolder text-muted bg-light\">\n <th class=\"center ps-2\" style=\"width: 18%;\">Name</th>\n <th class=\"center\">Date/Time</th>\n <th class=\"center\">Previous Time</th>\n <th class=\"center\">Updated Time</th>\n <th class=\"center\">Status</th>\n <th class=\"center pe-2\">Remarks</th>\n </tr>\n </thead>\n <tbody>\n <tr *ngFor=\"let log of currentManualLogs\">\n <td class=\"center ps-2\">\n <span class=\"text-primary\">{{ log.name }}</span>\n </td>\n <td class=\"center\">\n <span class=\"text-primary\">{{ log.date_time }}</span>\n </td>\n <td class=\"center\">\n <span class=\"text-primary\">{{ log.previous_time }}</span>\n </td>\n <td class=\"center\">\n <span class=\"text-primary\">{{ log.updated_time }}</span>\n </td>\n <td class=\"center\">\n <span class=\"badge bg-light text-dark border\">\n {{ log.log_status ? (log.log_status | titlecase) : 'N/A' }}\n </span>\n </td>\n <td class=\"center pe-2\">\n <span class=\"text-primary\">{{ log.remarks }}</span>\n </td>\n </tr>\n </tbody>\n </table>\n </div>\n </ng-container>\n </div>\n\n <ng-template #noManualLogs>\n <div class=\"text-center p-3\">\n <p class=\"text-muted mb-0\">No manual logs available for this record.</p>\n </div>\n </ng-template>\n</div> -->\n\n\n\n\n<!-- Existing Custom Tooltip for Breaks -->\n\n\n\n\n\n <!-- RIGHT PINNED: Empty table to keep alignment -->\n <div *ngIf=\"section === 'right' && row.isDetailsExpand && !isSingleDay\" class=\"accordion-details data-grid-accordion-section\" style=\"max-height: 350px; min-height: 150px ; overflow: hidden;\">\n <table class=\"nested-table table table-sm w-100 mb-0 data-grid-accordion-table\" [class.show-shadow]=\"rowShadingEnabled\">\n <thead>\n <tr [style.height.px]=\"nestedTableHeaderRowHeight\" [style.backgroundColor]=\"headerBackgroundColor\">\n <th *ngFor=\"let _ of [1, 2, 3, 4, 5]\">&nbsp;</th>\n </tr>\n </thead>\n <tbody>\n <tr [style.height.px]=\"nestedTablerowHeight\" *ngFor=\"let _ of row.details.data\" [style.backgroundColor]=\"headerBackgroundColor\">\n <td *ngFor=\"let __ of [1, 2, 3, 4, 5]\">&nbsp;</td>\n </tr>\n </tbody>\n </table>\n </div>\n\n </ng-template>\n</ng-template>\n\n<!-- Actual Cell is Here -->\n<ng-template\n #cellTemplate\n let-col=\"col\"\n let-row=\"row\"\n let-section=\"section\"\n let-subColIndex=\"subColIndex\"\n let-rowIndex=\"rowIndex\"\n let-colIndex=\"colIndex\"\n>\n <div\n (click)=\"disableEdit(row, col); setActiveCell(row, col)\"\n [style.fontWeight]=\"bodyFontWeight\"\n [class.border-right]=\"showVerticalBorder\"\n class=\"cell overflow-visible position-relative\"\n [attr.field]=\"col.field\"\n [style.width.px]=\"col.width\"\n [style.min-width.px]=\"col.width\"\n [style.fontSize.px]=\"bodyTextFontsSize\"\n [class.active-cell]=\"\n isActiveCell(row, col) && !isEditing(row, col) && selectedKeys.size == 1\n \"\n (dblclick)=\"$event.preventDefault(); enableEdit(row, col)\"\n [class.row-selected]=\"rowSelectedIndexes.has(row.__virtualIndex)\"\n [class.first-row-selected]=\"firstSelectedRow === row.__virtualIndex\"\n [class.last-row-selected]=\"lastSelectedRow === row.__virtualIndex\"\n tabindex=\"0\"\n (keydown.enter)=\"$event.preventDefault(); enableEdit(row, col)\"\n (mousedown)=\"\n startSelection(\n row.__virtualIndex,\n colIndex,\n subColIndex ?? 0,\n col.field,\n $event,\n section\n )\n \"\n (mouseenter)=\"\n extendSelection(\n row.__virtualIndex,\n colIndex,\n subColIndex ?? 0,\n col.field,\n $event,\n section\n )\n \"\n (mouseup)=\"endSelection()\"\n [class.selected-cell]=\"\n isSelected(\n row.__virtualIndex,\n colIndex,\n subColIndex ?? 0,\n col.field,\n section\n )\n \"\n [class.top-border]=\"\n isTopBorder(row.__virtualIndex, colIndex, subColIndex, section)\n \"\n [class.bottom-border]=\"\n isBottomBorder(row.__virtualIndex, colIndex, subColIndex, section)\n \"\n [class.left-border]=\"\n isLeftBorder(row.__virtualIndex, colIndex, subColIndex, section)\n \"\n [class.right-border]=\"\n isRightBorder(row.__virtualIndex, colIndex, subColIndex, section)\n \"\n [class.top-left-corner]=\"\n isTopLeftCorner(row.__virtualIndex, colIndex, subColIndex, section)\n \"\n [class.top-right-corner]=\"\n isTopRightCorner(row.__virtualIndex, colIndex, subColIndex, section)\n \"\n [class.bottom-left-corner]=\"\n isBottomLeftCorner(row.__virtualIndex, colIndex, subColIndex, section)\n \"\n [class.bottom-right-corner]=\"\n isBottomRightCorner(row.__virtualIndex, colIndex, subColIndex, section)\n \"\n >\n <!-- (mousedown)=\"startSelection(row.__virtualIndex, colIndex, subColIndex ?? 0, col.field, $event)\"\n (mouseenter)=\"extendSelection(row.__virtualIndex, colIndex, subColIndex ?? 0, col.field, $event)\"\n (mouseup)=\"endSelection()\"\n [class.selected-cell]=\"isSelected(row.__virtualIndex, colIndex, subColIndex ?? 0, col.field)\" -->\n <div class=\"table-cell\" [class.active-for-editing]=\"isEditing(row, col) && getNestedValue(row, col.field)?.length <= 50\">\n <div\n (click)=\"$event.stopPropagation()\"\n *ngIf=\"isEditing(row, col) && getNestedValue(row, col.field)?.length <= 50; else viewMode\"\n >\n <ng-container [ngSwitch]=\"col.type\">\n <!-- Text Input -->\n <input\n [style.height.px]=\"rowHeight - 10\"\n *ngSwitchCase=\"'input'\"\n type=\"text\"\n [(ngModel)]=\"row[col.field]\"\n (blur)=\"disableEdit(row, col)\"\n autofocus\n class=\"form-control form-control-sm\"\n (mousedown)=\"$event.stopPropagation()\"\n />\n\n <!-- Number Input -->\n <input\n [style.height.px]=\"rowHeight - 8\"\n *ngSwitchCase=\"'number'\"\n #numberInput=\"ngModel\"\n #numberRef\n (keypress)=\"allowOnlyNumbers($event)\"\n type=\"number\"\n required\n [(ngModel)]=\"row[col.field]\"\n (blur)=\"disableEdit(row, col)\"\n autofocus\n (keydown.enter)=\"numberRef.blur()\"\n class=\"form-control form-control-sm\"\n [ngClass]=\"{\n 'is-invalid': numberInput.invalid\n }\"\n (mousedown)=\"$event.stopPropagation()\"\n />\n\n <!-- Date Input -->\n <input\n [style.height.px]=\"rowHeight - 8\"\n *ngSwitchCase=\"'date'\"\n type=\"date\"\n [(ngModel)]=\"row[col.field]\"\n (blur)=\"disableEdit(row, col)\"\n autofocus\n class=\"form-control form-control-sm\"\n #dateInput=\"ngModel\"\n [ngClass]=\"{\n 'is-invalid': dateInput.invalid\n }\"\n (mousedown)=\"$event.stopPropagation()\"\n />\n\n <!-- Dropdown -->\n <!-- ng-select like dropdown -->\n <div\n *ngSwitchCase=\"'dropdown'\"\n class=\"dropdown w-100\"\n (blur)=\"disableEdit(row, col)\"\n >\n <!-- Trigger -->\n <button\n class=\"form-select form-select-sm text-start w-100 text-ellipsis\"\n type=\"button\"\n data-bs-toggle=\"dropdown\"\n aria-expanded=\"false\"\n [style.minHeight.px]=\"rowHeight - 10\"\n data-bs-display=\"static\"\n (mousedown)=\"$event.stopPropagation()\"\n >\n <ng-container>\n {{\n getNestedValue(row, col.field)?.value ||\n getNestedValue(row, col.field)?.name ||\n getNestedValue(row, col.field)\n }}\n </ng-container>\n <ng-template #placeholder> Select options... </ng-template>\n </button>\n\n <!-- Menu -->\n <div\n class=\"dropdown-menu w-100 p-0 cell-editing-dropdown-menu rounded-3\"\n [class.show]=\"isEditing(row, col)\"\n >\n <!-- Search -->\n <div class=\"px-2 py-1\">\n <input\n type=\"text\"\n class=\"form-control form-control-sm\"\n placeholder=\"Search...\"\n [(ngModel)]=\"editinDropdownSearch\"\n />\n </div>\n\n <!-- Options -->\n <div\n class=\"cell-editin-dropdown\"\n style=\"max-height: 200px; overflow: auto\"\n >\n <div\n (click)=\"\n setNestedValue(row, col, option, true);\n disableEdit(row, col)\n \"\n class=\"px-2 py-1 d-flex align-items-center item\"\n *ngFor=\"\n let option of col.column_dropdown_value\n | filter : editinDropdownSearch : 'value'\n \"\n >\n <label\n class=\"form-check-label d-flex align-items-center mb-0\"\n [for]=\"col.field + '-' + option.value || option\"\n >\n {{ option.value || option }}\n </label>\n </div>\n </div>\n </div>\n </div>\n\n <input\n *ngSwitchCase=\"'email'\"\n [style.height.px]=\"rowHeight - 10\"\n [style.maxHeight.px]=\"rowHeight - 10\"\n #emailModel=\"ngModel\"\n #emailInput\n type=\"email\"\n [(ngModel)]=\"row[col.field]\"\n name=\"{{ col.field }}\"\n required\n pattern=\"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$\"\n (blur)=\"disableEdit(row, col, emailModel)\"\n (keydown.enter)=\"\n emailModel.control.markAsTouched(); emailInput.blur()\n \"\n autofocus\n class=\"form-control form-control-sm\"\n [ngClass]=\"{\n 'is-invalid': emailModel.invalid\n }\"\n (mousedown)=\"$event.stopPropagation()\"\n />\n <!-- Default fallback -->\n <input\n *ngSwitchDefault\n [style.height.px]=\"rowHeight - 10\"\n [style.maxHeight.px]=\"rowHeight - 10\"\n #textModel=\"ngModel\"\n #textInput\n type=\"text\"\n [(ngModel)]=\"row[col.field]\"\n name=\"{{ col.field }}\"\n required\n (blur)=\"disableEdit(row, col, textModel)\"\n (keydown.enter)=\"\n textModel.control.markAsTouched(); textInput.blur()\n \"\n autofocus\n class=\"form-control form-control-sm\"\n [ngClass]=\"{\n 'is-invalid': textModel.invalid\n }\"\n (mousedown)=\"$event.stopPropagation()\"\n />\n </ng-container>\n </div>\n\n <!-- Display mode -->\n <ng-template #viewMode>\n <div\n class=\"d-flex justify-between items-center w-100\"\n [ngClass]=\"getCellClasses(col, getNestedValue(row, col.field))\"\n >\n <!-- Text cell -->\n <div class=\"d-flex align-items-center w-100\">\n <div\n #cellText\n class=\"text-ellipsis flex-grow-1\"\n \n >\n <ng-container *ngIf=\"col.type !== 'image'\">\n <ng-container [ngSwitch]=\"col.field\">\n <!-- Breaks -->\n <ng-container *ngSwitchCase=\"'breaks'\">\n <ng-container *ngIf=\"getNestedValue(row, 'breaks')?.length; else noBreaksMain\">\n <app-badge-overflow\n [badges]=\"getBreakBadges(getNestedValue(row, 'breaks'))\"\n [maxWidth]=\"col.width || 200\"\n (badgeMouseEnter)=\"showBreakTooltip($event.event, $event.badge.data)\"\n (badgeMouseLeave)=\"hideBreakTooltip()\"\n (overflowCountClick)=\"onBadgeOverflowCountClick(col)\">\n </app-badge-overflow>\n </ng-container>\n <ng-template #noBreaksMain>\n <div >\n -\n </div>\n </ng-template>\n </ng-container>\n\n <!-- Short Breaks -->\n <ng-container *ngSwitchCase=\"'short_breaks'\">\n <ng-container *ngIf=\"row.short_breaks?.short_break_duration && row.short_breaks.short_break_duration > 0; else noShortBreak\">\n <div (dblclick)=\"onShortBreakClick.emit(row)\"> <app-badge-overflow\n [badges]=\"getShortBreakBadges(row.short_breaks)\"\n [maxWidth]=\"col.width || 200\"\n (badgeMouseEnter)=\"showShortBreakTooltip($event.event, row)\"\n (badgeMouseLeave)=\"hideShortBreakTooltip()\"\n (badgeClick)=\"handleShortBreakClick(row, $event)\"\n (overflowCountClick)=\"onShortBreakOverflowCountClick(col)\">\n </app-badge-overflow> </div>\n \n \n </ng-container>\n <ng-template #noShortBreak>\n <div >-</div>\n </ng-template>\n </ng-container>\n\n <!-- Short Leave -->\n <!-- Short Leave -->\n<ng-container *ngSwitchCase=\"'short_leave'\">\n <ng-container *ngIf=\"row.short_leave && row.short_leave.length > 0; else noShortLeaveMain\">\n <div class=\"w-100 d-flex main-progress-bar justify-content-center align-items-center\" \n style=\"background-color: rgb(111, 97, 207); height: 20px; border-radius: 4px; position: relative;\"\n (mouseenter)=\"showShortLeaveTooltip($event, row)\"\n (mouseleave)=\"hideShortLeaveTooltip()\">\n <span class=\"d-block\" [style.min-width.%]=\"row.short_leave[0].short_leave_time_percentage\" \n style=\"background-color: rgb(238, 99, 82); height: 100%; border-radius: 4px;\"></span>\n <span style=\"position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); color: white; font-size: 12px; font-weight: bold;\">\n {{ row.short_leave[0].short_leave_time_percentage }}%\n </span>\n </div>\n </ng-container>\n <ng-template #noShortLeaveMain>-</ng-template>\n</ng-container>\n\n <!-- Status -->\n <ng-container *ngSwitchCase=\"'status'\">\n <span class=\"badge\" [class]=\"getStatusBadgeClass(getNestedValue(row, col.field))\">\n {{ transformStatus(getNestedValue(row, col.field)) || '-' }}\n </span>\n </ng-container>\n\n <!-- Attendance Status -->\n <ng-container *ngSwitchCase=\"'attendanceStatus'\">\n <span class=\"badge\" [class]=\"getAttendanceStatusBadgeClass(getNestedValue(row, col.field))\">\n {{ transformStatus(getNestedValue(row, col.field)) || '-' }}\n </span>\n </ng-container>\n\n <!-- Payroll Processed -->\n <ng-container *ngSwitchCase=\"'is_payroll_processed'\">\n <span class=\"badge\" [class]=\"getNestedValue(row, col.field) ? 'badge-success' : 'badge-secondary'\">\n {{ getNestedValue(row, col.field) ? 'Yes' : 'No' }}\n </span>\n </ng-container>\n\n <!-- Restriction -->\n <ng-container *ngSwitchCase=\"'is_un_restricted'\">\n <span class=\"badge\" [class]=\"getNestedValue(row, col.field) ? 'badge-success' : 'badge-secondary'\">\n {{ getNestedValue(row, col.field) ? 'Yes' : 'No' }}\n </span>\n </ng-container>\n\n <!-- Default -->\n <ng-container *ngSwitchDefault>\n {{\n !isNestedValueArray(row, col.field)\n ? col.type === 'date'\n ? (isDate(getNestedValue(row, col.field))\n ? ((getNestedValue(row, col.field)) | timezoneFormat:prefs:'date' )\n : (getNestedValue(row, col.field)?.value ||\n getNestedValue(row, col.field)?.name ||\n getNestedValue(row, col.field) ||\n '-'))\n : col.type === 'time'\n ? ((getTimeValue(getNestedValue(row, col.field)) | timezoneFormat:prefs:'time'))\n : (getNestedValue(row, col.field)?.value ||\n getNestedValue(row, col.field)?.name ||\n getNestedValue(row, col.field) ||\n '-')\n : (getNestedValue(row, col.field)?.[0]?.department_name ||\n getNestedValue(row, col.field)?.[0]?.roleName ||\n '-')\n }}\n </ng-container>\n </ng-container>\n </ng-container>\n <ng-container *ngIf=\"col.type == 'image'\">\n <ng-container\n *ngTemplateOutlet=\"\n defaultImagePlaceholder;\n context: {\n row: row,\n col: col,\n }\n \"\n ></ng-container>\n </ng-container>\n </div>\n\n <!-- Active dot and eye icon for employee name -->\n <span *ngIf=\"col.field === 'User' && hasManualLogs(row) && !row.isDetailsExpand\" class=\"badge badge-dot badge-success ms-1\" (mouseenter)=\"showManualLogsTooltip($event, row, row)\"></span>\n <i *ngIf=\"col.field === 'User' && hasManualLogs(row)\" class=\"bi bi-eye ms-1\" (mouseenter)=\"showManualLogsTooltip($event, row, row)\"></i>\n </div>\n\n <!-- Expand / Collapse icon for multiple data showing in one coll-->\n\n <!-- <span\n *ngIf=\"\n (isOverflowing(cellText) &&\n showCellDetailsBox &&\n getNestedValue(row, col.field)?.length > 50) ||\n (isNestedValueArray(row, col.field) &&\n getNestedValue(row, col.field)?.length > 1)\n \"\n class=\"toggle-icon data-grid-svg-icon ms-2 cursor-pointer\"\n [inlineSVG]=\"\n isExpanded(row, col)\n ? singleSpaAssetsPath + 'data-grid/icons/chevron-down.svg'\n : singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\n \"\n (click)=\"\n $event.stopPropagation();\n toggleExpandOfLongCellText(row, col, columns, true)\n \"\n (dblclick)=\"$event.preventDefault(); $event.stopPropagation()\"\n ></span> -->\n </div>\n\n <!-- Expanded text -->\n <div\n class=\"position-absolute w-100\"\n *ngIf=\"isExpanded(row, col)\"\n [style.zIndex]=\"getZIndex(row, col)\"\n style=\"top: 100%; left: 0\"\n >\n <ng-container\n *ngTemplateOutlet=\"\n fullTextTemplate;\n context: {\n row: row,\n col: col,\n isArray: isNestedValueArray(row, col.field)\n }\n \"\n ></ng-container>\n </div>\n </ng-template>\n\n\n \n\n\n\n </div>\n </div>\n</ng-template>\n\n<div\n *ngIf=\"currentBreakTooltip\"\n class=\"custom-break-tooltip\"\n [style.--tooltip-x.px]=\"tooltipPosition.x\"\n [style.--tooltip-y.px]=\"tooltipPosition.y\"\n @tooltipAnimationBottom\n>\n <div class=\"break-tooltip-header\">\n <strong>{{ currentBreakTooltip.break_type?.data_value_name || 'Break' }}</strong>\n <span class=\"text-muted ms-2\">\n {{ currentBreakTooltip.breakInstatus === 'breakOut' ? 'Taken' : 'On Break' }}\n </span>\n </div>\n\n <div class=\"break-tooltip-body\">\n <div>\n <i class=\"bi bi-play-circle\"></i>\n In: {{ currentBreakTooltip.break_in_time | timezoneFormat:prefs:'time' }}\n </div>\n \n <div>\n <i class=\"bi bi-stop-circle\"></i>\n Out: {{ currentBreakTooltip.break_out_time | timezoneFormat:prefs:'time' }}\n </div>\n \n <div>\n <i class=\"bi bi-clock\"></i>\n Duration: {{ currentBreakTooltip.break_duration }} min\n </div>\n </div>\n</div>\n\n\n\n\n\n<!-- Short Break Tooltip -->\n<!-- Short Break Tooltip (Table Format) -->\n<div\n *ngIf=\"currentShortBreakTooltip\"\n class=\"custom-break-tooltip\"\n [style.--tooltip-x.px]=\"tooltipPosition.x\"\n [style.--tooltip-y.px]=\"tooltipPosition.y\"\n @tooltipAnimationBottom\n>\n <div class=\"break-tooltip-header\">\n <strong>{{ currentShortBreakTooltip.name }}</strong>\n </div>\n <div class=\"break-tooltip-body\">\n <table class=\"short-break-table\">\n <thead>\n <tr>\n <th>Start Time</th>\n <th>End Time</th>\n <th>Duration</th>\n </tr>\n </thead>\n <tbody>\n <tr *ngFor=\"let detail of currentShortBreakTooltip.details\">\n <td>\n {{\n detail.start_time\n ? (detail.start_time | timezoneFormat:prefs:'time')\n : 'N/A'\n }}\n </td>\n <td>\n {{\n detail.end_time\n ? (detail.end_time | timezoneFormat:prefs:'time')\n : 'N/A'\n }}\n </td>\n <td>{{ detail.duration }} min</td>\n </tr>\n <tr *ngIf=\"currentShortBreakTooltip.details.length === 0\">\n <td colspan=\"3\" class=\"text-center text-muted\">No timing details</td>\n </tr>\n </tbody>\n </table>\n </div>\n</div>\n\n\n\n\n<!-- Headers Action List On clicking three dots -->\n\n<ng-template #columnMenu let-col=\"col\">\n <div\n class=\"column-menu three-dots-col-menu\"\n [class.visually-hidden]=\"isMenueHidden\"\n *ngIf=\"activeCol && !isThreeDotsFilterOpen && !loading\"\n [style.backgroundColor]=\"dropdownsBackgroundColor\"\n >\n <!-- Sort Ascending -->\n <div class=\"border-below pb-2\" [class.disable-sorting]=\"!col.is_sortable\">\n <span class=\"muted-text fs-7\" style=\"margin-left: 12px\">Sort</span>\n <div\n *ngIf=\"\n columnThreedotsMunuConfig?.showAscending &&\n (sortingConfig?.field != col.field ||\n sortingConfig?.order_by == 'desc')\n \"\n class=\"column-menu-item\"\n (click)=\"sortAsc(activeCol)\"\n >\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrow-up.svg'\"\n class=\"data-grid-svg-icon me-2\"\n ></span>\n Sort Ascending\n </div>\n\n <!-- Sort Descending -->\n <div\n *ngIf=\"\n columnThreedotsMunuConfig?.showDescending &&\n (sortingConfig?.field != col.field ||\n sortingConfig?.order_by == 'asc')\n \"\n class=\"column-menu-item\"\n (click)=\"sortDesc(activeCol)\"\n >\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrow-down.svg'\"\n class=\"data-grid-svg-icon me-2\"\n ></span>\n Sort Descending\n </div>\n\n <div\n *ngIf=\"\n sortingConfig?.field === col.field &&\n (sortingConfig?.order_by === 'asc' ||\n sortingConfig?.order_by === 'desc')\n \"\n class=\"column-menu-item\"\n (click)=\"resetSort(activeCol)\"\n >\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/arrow-counterclockwise.svg'\n \"\n class=\"data-grid-svg-icon me-2\"\n ></span>\n Reset Sort\n </div>\n </div>\n <div class=\"py-2 border-below three-dots-filter\">\n <div\n *ngIf=\"columnThreedotsMunuConfig?.showFilter && !(col.is_search_able === false )\"\n class=\"column-menu-item three-dots-filter\"\n (click)=\"openFilteronThreeDotsClick(col)\"\n >\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\"\n class=\"data-grid-svg-icon me-2\"\n ></span>\n Filter\n </div>\n </div>\n\n <div class=\"py-2 border-below\">\n <span class=\"muted-text fs-7\" style=\"margin-left: 12px\">Pin</span>\n <div\n *ngIf=\"columnThreedotsMunuConfig?.showPinleft && col?.pinned !== 'left'\"\n class=\"column-menu-item\"\n (click)=\"updateColumnPinInSourceByField(activeCol, 'left')\"\n >\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/pin-left.svg'\"\n class=\"data-grid-svg-icon me-2\"\n ></span\n >Pin Left\n </div>\n\n <div\n *ngIf=\"\n columnThreedotsMunuConfig?.showPinright && col?.pinned !== 'right'\n \"\n class=\"column-menu-item\"\n (click)=\"updateColumnPinInSourceByField(activeCol, 'right')\"\n >\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/pin-right.svg'\"\n class=\"data-grid-svg-icon data-grid-svg-icon me-2\"\n ></span\n >Pin Right\n </div>\n\n <div\n *ngIf=\"col?.pinned\"\n class=\"column-menu-item\"\n (click)=\"updateColumnPinInSourceByField(activeCol, null)\"\n >\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/layout-three-columns.svg'\n \"\n class=\"data-grid-svg-icon me-2\"\n ></span\n >Unpin\n </div>\n </div>\n\n <div\n *ngIf=\"columnThreedotsMunuConfig?.showAutosizeThisColumn\"\n class=\"column-menu-item\"\n (click)=\"autosizeColumn(activeCol)\"\n >\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/arrows-expand-vertical.svg'\n \"\n class=\"me-2\"\n ></span>\n Autosize This Column\n </div>\n\n <!-- Autosize All Columns -->\n <div\n *ngIf=\"columnThreedotsMunuConfig?.showAutosizeAllColumns\"\n class=\"column-menu-item\"\n (click)=\"autosizeAllColumns()\"\n >\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/arrows-angle-expand.svg'\n \"\n class=\"data-grid-svg-icon me-2\"\n ></span\n >Autosize All Columns\n </div>\n\n <!-- Group By -->\n <div\n *ngIf=\"showRowsGrouping && !(col.is_groupable === false)\"\n class=\"column-menu-item\"\n (click)=\"groupBy(activeCol)\"\n >\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/diagram-3.svg'\"\n class=\"data-grid-svg-icon me-2\"\n ></span>\n Group by {{ col.header }}\n </div>\n\n <!-- Choose Columns -->\n <!-- <div\n *ngIf=\"columnThreedotsMunuConfig?.showChoseColumns\"\n class=\"column-menu-item\"\n (click)=\"chooseColumns()\"\n >\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/ui-checks-grid.svg'\"\n class=\"data-grid-svg-icon me-2\"\n ></span>\n Choose Columns\n </div> -->\n\n <!-- Reset Columns -->\n <!-- <div\n *ngIf=\"columnThreedotsMunuConfig?.showResetColumns\"\n class=\"column-menu-item\"\n (click)=\"resetColumns()\"\n >\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/arrow-counterclockwise.svg'\n \"\n class=\"data-grid-svg-icon me-2\"\n ></span\n >Reset Columns\n </div> -->\n </div>\n <div *ngIf=\"isThreeDotsFilterOpen\" class=\"three-dots-col-menu position-relative\" [style.left.px]=\"-140\" >\n <ng-container\n *ngTemplateOutlet=\"filterMenu; context: { col: col }\"\n ></ng-container>\n </div>\n</ng-template>\n\n\n\n<!-- Filter Menue -->\n<ng-template #filterMenu let-col=\"col\">\n <div\n class=\"filter-menu-container filter-menu\"\n [style.backgroundColor]=\"dropdownsBackgroundColor\"\n >\n <!-- Dropdown Type -->\n <ng-container *ngIf=\"col.type === 'dropdown'; else textFilter\">\n <div class=\"filter-dropdown-section p-1\">\n <input\n type=\"text\"\n class=\"form-control form-control-sm mb-2\"\n placeholder=\"Search...\"\n [(ngModel)]=\"addFilterDropdownSearch\"\n #filterMenueSearchInput\n />\n\n <div class=\"form-check mb-1\">\n <input\n class=\"form-check-input\"\n type=\"checkbox\"\n [checked]=\"isAllSideFilterOptionsSelected(col)\"\n (change)=\"toggleSelectAllSideFilters(col, $event)\"\n id=\"selectAll_{{ col.field }}\"\n />\n <label class=\"form-check-label\" for=\"selectAll_{{ col.field }}\">\n Select All\n </label>\n </div>\n\n <div class=\"dropdown-options\">\n <div class=\"form-check mb-1\"\n *ngFor=\"\n let option of getColumnOptions(col)\n | filter : addFilterDropdownSearch : 'value';\n trackBy: trackById\n\">\n <input\n class=\"form-check-input\"\n type=\"checkbox\"\n [checked]=\"isOptionSelected(col, option)\"\n [value]=\"option\"\n (change)=\"onOptionToggle(col, option)\"\n />\n <label class=\"form-check-label\">\n {{ option.value || option }}\n </label>\n </div>\n</div>\n </div>\n </ng-container>\n\n <!-- Text Filter Section -->\n <ng-template #textFilter>\n <div class=\"filter-text-section\">\n <div class=\"form-group mb-2\">\n <select\n class=\"form-select form-select-sm\"\n [ngModel]=\"col.query.first_condition || (col.type === 'date' || col.type === 'time' ? 'equal' : 'contain')\"\n (ngModelChange)=\"col.query.first_condition = $event\"\n >\n <ng-container *ngIf=\"col.type === 'date' || col.type === 'time'; else textOptions\">\n <option value=\"equal\">Equal to</option>\n <option value=\"not_equal\">Not Equal</option>\n <option value=\"after\">After</option>\n <option value=\"before\">Before</option>\n </ng-container>\n <ng-template #textOptions>\n <option value=\"contain\">Contains</option>\n <option value=\"equal\">Equals</option>\n <option value=\"before\">Begins With</option>\n <option value=\"after\">Ends With</option>\n </ng-template>\n </select>\n </div>\n\n <input\n [type]=\"col.type == 'string' ? 'text' : col.type\"\n class=\"form-control form-control-sm mb-3\"\n placeholder=\"Value\"\n [(ngModel)]=\"col.query.first_value\"\n [min]=\"col.type == 'number' ? 0 : null\"\n (input)=\"col.type == 'number' && $any($event.target).value < 0 ? $any($event.target).value = 0 : null\"\n (keydown)=\"col.type == 'number' && $event.key === '-' ? $event.preventDefault() : null\"\n [class.number-input]=\"col.type == 'number'\"\n #filterMenueTextchInput\n />\n\n <ng-container >\n <div class=\"form-group mb-2\">\n <div class=\"form-check form-check-inline\">\n <input\n class=\"form-check-input filter-radio-inputs\"\n type=\"radio\"\n name=\"condition\"\n [(ngModel)]=\"condition\"\n value=\"and\"\n id=\"and_{{ col.field }}\"\n />\n <label class=\"form-check-label\" for=\"and_{{ col.field }}\"\n >AND</label\n >\n </div>\n <div class=\"form-check form-check-inline\">\n <input\n class=\"form-check-input filter-radio-inputs\"\n type=\"radio\"\n name=\"condition\"\n [(ngModel)]=\"condition\"\n value=\"or\"\n id=\"or_{{ col.field }}\"\n />\n <label class=\"form-check-label\" for=\"or_{{ col.field }}\"\n >OR</label\n >\n </div>\n <div class=\"form-check form-check-inline\">\n <input\n class=\"form-check-input filter-radio-inputs\"\n type=\"radio\"\n name=\"condition\"\n [(ngModel)]=\"condition\"\n value=\"none\"\n id=\"none_{{ col.field }}\"\n />\n <label class=\"form-check-label\" for=\"none_{{ col.field }}\"\n >None</label\n >\n </div>\n </div>\n\n <ng-container *ngIf=\"col.query?.first_value && condition !== 'none'\">\n <div class=\"form-group mb-2\">\n <select\n class=\"form-select form-select-sm\"\n [ngModel]=\"col.query.second_condition || (col.type === 'date' || col.type === 'time' ? 'equal' : 'contain')\"\n (ngModelChange)=\"col.query.second_condition = $event\"\n >\n <ng-container *ngIf=\"col.type === 'date' || col.type === 'time'; else textOptionsSecond\">\n <option value=\"equal\">Equal to</option>\n <option value=\"not_equal\">Not Equal</option>\n <option value=\"after\">After</option>\n <option value=\"before\">Before</option>\n </ng-container>\n <ng-template #textOptionsSecond>\n <option value=\"contain\">Contains</option>\n <option value=\"equal\">Equals</option>\n <option value=\"before\">Begins With</option>\n <option value=\"after\">Ends With</option>\n </ng-template>\n </select>\n </div>\n\n <input\n [type]=\"col.type == 'string' ? 'text' : col.type\"\n class=\"form-control form-control-sm mb-2\"\n placeholder=\"Second Value\"\n [(ngModel)]=\"col.query.second_value\"\n [min]=\"col.type == 'number' ? 0 : null\"\n (input)=\"col.type == 'number' && $any($event.target).value < 0 ? $any($event.target).value = 0 : null\"\n (keydown)=\"col.type == 'number' && $event.key === '-' ? $event.preventDefault() : null\"\n [class.number-input]=\"col.type == 'number'\"\n />\n </ng-container>\n </ng-container>\n </div>\n </ng-template>\n\n <!-- Actions -->\n <div class=\"d-flex gap-2 mt-2\">\n <div\n class=\"btn btn-sm btn-primary d-flex justify-content-center align-items-center w-100\"\n style=\"height: 22px\"\n (click)=\"applyFilterFromFilterRow(col)\"\n >\n Apply\n </div>\n <div\n class=\"btn btn-sm btn-secondary d-flex justify-content-center align-items-center w-100\"\n style=\"height: 22px\"\n (click)=\"resetSideFilter(col)\"\n >\n Reset\n </div>\n </div>\n </div>\n</ng-template>\n\n<!-- Side Menue -->\n\n<!-- Add this new template for accordion detail column menu -->\n<ng-template #detailColumnMenu let-col=\"col\" let-row=\"row\">\n <div\n class=\"column-menu three-dots-col-menu detail-column-menu\"\n [class.visually-hidden]=\"isDetailMenueHidden\"\n *ngIf=\"activeDetailCol\"\n [style.backgroundColor]=\"dropdownsBackgroundColor\"\n >\n <!-- Sort Ascending -->\n <!-- <div class=\"border-below pb-2\" [class.disable-sorting]=\"!col.is_sortable\">\n <span class=\"muted-text fs-7\" style=\"margin-left: 12px\">Sort</span> -->\n <!-- <div\n *ngIf=\"columnThreedotsMunuConfig?.showAscending\"\n class=\"column-menu-item\"\n (click)=\"sortDetailAsc(activeDetailCol, row)\"\n >\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrow-up.svg'\"\n class=\"data-grid-svg-icon me-2\"\n ></span>\n Sort Ascending\n </div> -->\n\n <!-- Sort Descending -->\n <!-- <div\n *ngIf=\"columnThreedotsMunuConfig?.showDescending\"\n class=\"column-menu-item\"\n (click)=\"sortDetailDesc(activeDetailCol, row)\"\n >\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrow-down.svg'\"\n class=\"data-grid-svg-icon me-2\"\n ></span>\n Sort Descending\n </div> -->\n\n <!-- <div\n *ngIf=\"col?.sortOrder\"\n class=\"column-menu-item\"\n (click)=\"resetDetailSort(activeDetailCol, row)\"\n >\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/arrow-counterclockwise.svg'\n \"\n class=\"data-grid-svg-icon me-2\"\n ></span>\n Reset Sort\n </div> -->\n <!-- </div> -->\n\n <div class=\"py-2 border-below\" *ngIf=\"isColumnFilterable(col)\">\n <span class=\"muted-text fs-7\" style=\"margin-left: 12px\">Filter</span>\n <div\n *ngIf=\"columnThreedotsMunuConfig?.showFilter\"\n class=\"column-menu-item\"\n (click)=\"openDetailFilterMenu($event, col, row)\"\n >\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\"\n class=\"data-grid-svg-icon me-2\"\n ></span>\n Filter\n </div>\n </div>\n\n <div class=\"py-2 border-below\">\n <span class=\"muted-text fs-7\" style=\"margin-left: 12px\">Pin</span>\n <div\n *ngIf=\"columnThreedotsMunuConfig?.showPinleft && col?.pinned !== 'left'\"\n class=\"column-menu-item\"\n (click)=\"updateDetailColumnPin(activeDetailCol, row, 'left')\"\n >\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/pin-left.svg'\"\n class=\"data-grid-svg-icon me-2\"\n ></span\n >Pin Left\n </div>\n\n <div\n *ngIf=\"\n columnThreedotsMunuConfig?.showPinright && col?.pinned !== 'right'\n \"\n class=\"column-menu-item\"\n (click)=\"updateDetailColumnPin(activeDetailCol, row, 'right')\"\n >\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/pin-right.svg'\"\n class=\"data-grid-svg-icon data-grid-svg-icon me-2\"\n ></span\n >Pin Right\n </div>\n\n <div\n *ngIf=\"col?.pinned\"\n class=\"column-menu-item\"\n (click)=\"updateDetailColumnPin(activeDetailCol, row, null)\"\n >\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/layout-three-columns.svg'\n \"\n class=\"data-grid-svg-icon me-2\"\n ></span\n >Unpin\n </div>\n </div>\n\n <div\n *ngIf=\"columnThreedotsMunuConfig?.showAutosizeThisColumn\"\n class=\"column-menu-item\"\n (click)=\"autosizeDetailColumn(activeDetailCol, row)\"\n >\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/arrows-expand-vertical.svg'\n \"\n class=\"me-2\"\n ></span>\n Autosize This Column\n </div>\n\n <!-- Autosize All Columns -->\n <div\n *ngIf=\"columnThreedotsMunuConfig?.showAutosizeAllColumns\"\n class=\"column-menu-item\"\n (click)=\"autosizeAllDetailColumns(row)\"\n >\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/arrows-angle-expand.svg'\n \"\n class=\"data-grid-svg-icon me-2\"\n ></span\n >Autosize All Columns\n </div>\n\n\n <!-- Choose Columns -->\n <div\n *ngIf=\"columnThreedotsMunuConfig?.showChoseColumns\"\n class=\"column-menu-item\"\n (click)=\"openDetailChooseColumns(row)\"\n>\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/ui-checks-grid.svg'\"\n class=\"data-grid-svg-icon me-2\"\n ></span>\n Choose Columns\n</div>\n\n <!-- Reset Columns -->\n <!-- <div\n *ngIf=\"columnThreedotsMunuConfig?.showResetColumns\"\n class=\"column-menu-item\"\n (click)=\"resetDetailColumns(row)\"\n >\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/arrow-counterclockwise.svg'\n \"\n class=\"data-grid-svg-icon me-2\"\n ></span\n >Reset Columns\n </div> -->\n </div>\n</ng-template>\n\n<!-- Column Pannel / Pivot Mode / Searching -->\n\n<ng-template #columnPannel>\n <div class=\"column-panel-header\">\n <!-- Pivot Toggle -->\n <div\n class=\"form-check form-switch d-flex align-items-center mb-2 pivot-mode px-5 ms-2\"\n >\n <input\n class=\"form-check-input me-2\"\n type=\"checkbox\"\n id=\"pivotToggle\"\n [(ngModel)]=\"pivotMode\"\n />\n <label class=\"form-check-label\" for=\"pivotToggle\">Pivot Mode</label>\n </div>\n\n <!-- Select All & Search -->\n <div class=\"d-flex align-items-center mb-2 px-3\">\n <span class=\"filter-icon-wrapper me-2\" *ngIf=\"showColumnsGrouping\">\n <span\n class=\"toggle-icon data-grid-svg-icon\"\n [inlineSVG]=\"\n accordionState === 'all'\n ? singleSpaAssetsPath + 'data-grid/icons/chevron-down.svg'\n : accordionState === 'some'\n ? singleSpaAssetsPath + 'data-grid/icons/dash.svg'\n : singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\n \"\n (click)=\"toggleAllAccordions()\"\n ></span>\n </span>\n <input\n type=\"checkbox\"\n class=\"form-check-input me-2\"\n [checked]=\"allColumnsSelected()\"\n (change)=\"toggleAllColumnsVisibility()\"\n />\n <input\n type=\"text\"\n class=\"form-control form-control-sm\"\n placeholder=\"Search columns...\"\n [(ngModel)]=\"columnSearch\"\n />\n </div>\n\n <!-- Separator -->\n <hr class=\"my-2\" />\n </div>\n</ng-template>\n\n<!-- Right Columns Menue -->\n\n<!-- Column Panel Item Template -->\n<ng-template #columnPanelItem let-col=\"col\">\n <!-- Group Column -->\n <ng-container *ngIf=\"col.children?.length\">\n <div class=\"column-group d-flex align-items-center mb-2\">\n <span class=\"filter-icon-wrapper me-2\">\n <span\n class=\"toggle-icon data-grid-svg-icon\"\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\n \"\n [class.rotate]=\"col.expanded\"\n (click)=\"col.expanded = !col.expanded\"\n ></span>\n </span>\n <input\n type=\"checkbox\"\n class=\"form-check-input me-2\"\n [id]=\"'group_' + col.header\"\n [checked]=\"isColumnVisible(col)\"\n (change)=\"toggleGroupVisibility(col)\"\n />\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/grid-3x2-gap.svg'\"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center me-2\"\n ></span>\n <label\n class=\"d-flex align-items-center mb-0 w-100\"\n [for]=\"'group_' + col.header\"\n style=\"cursor: pointer\"\n >\n <span class=\"text-truncate\">{{ col.header }}</span>\n </label>\n </div>\n <div *ngIf=\"col.expanded\" class=\"ps-4\">\n <ng-container *ngFor=\"let child of col.children; trackBy: trackByField\">\n <ng-container\n *ngTemplateOutlet=\"columnPanelItem; context: { col: child }\"\n ></ng-container>\n </ng-container>\n </div>\n </ng-container>\n\n <!-- Leaf Column -->\n <ng-container *ngIf=\"!col.children?.length\">\n <div class=\"d-flex align-items-center mb-2\">\n <span class=\"me-2\" style=\"width: 1.5rem\"></span>\n <input\n type=\"checkbox\"\n class=\"form-check-input me-2\"\n [(ngModel)]=\"col.is_visible\"\n [id]=\"'col_' + col.field\"\n (change)=\"onSideMenuColumnsVisibilityChange()\"\n />\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/grid-3x2-gap.svg'\"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center me-2\"\n ></span>\n <label\n class=\"d-flex align-items-center mb-0 w-100\"\n [for]=\"'col_' + col.field\"\n style=\"cursor: pointer\"\n >\n <span class=\"text-truncate\">{{ col.header }}</span>\n </label>\n </div>\n </ng-container>\n</ng-template>\n<!-- Columns Side Filter -->\n<ng-template #sideFilters>\n <div class=\"py-3 px-2 pe-3 h-100\">\n <div class=\"d-flex align-items-center mb-2\">\n <span class=\"filter-icon-wrapper me-2\">\n <span\n class=\"toggle-icon data-grid-svg-icon\"\n [inlineSVG]=\"\n filterAccordionState === 'all'\n ? singleSpaAssetsPath + 'data-grid/icons/chevron-down.svg'\n : filterAccordionState === 'some'\n ? singleSpaAssetsPath + 'data-grid/icons/dash.svg'\n : singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\n \"\n (click)=\"toggleAllFilterAccordions()\"\n ></span>\n </span>\n\n <input\n type=\"text\"\n class=\"form-control form-control-sm\"\n placeholder=\"Search...\"\n [(ngModel)]=\"columnSearch\"\n />\n </div>\n <div\n class=\"overflow-auto side-filter-columns-wrapper\"\n style=\"height: calc(100% - 120px); scrollbar-width: thin\"\n >\n <ng-container\n *ngFor=\"\n let col of columns | filter : columnSearch : 'header';\n trackBy: trackByField\n \"\n >\n <ng-container\n *ngTemplateOutlet=\"filterPannelItem; context: { col: col }\"\n ></ng-container>\n </ng-container>\n </div>\n <!-- Apply and Reset Buttons -->\n <!-- <div class=\"d-flex gap-2 mt-3 px-2\">\n <button\n class=\"btn btn-sm btn-primary d-flex justify-content-center align-items-center flex-fill\"\n style=\"height: 32px;\"\n (click)=\"applySideMenuFilters()\"\n >\n Apply\n </button>\n <button\n class=\"btn btn-sm btn-secondary d-flex justify-content-center align-items-center flex-fill\"\n style=\"height: 32px;\"\n (click)=\"resetSideMenuFilters()\"\n >\n Reset\n </button>\n </div> -->\n </div>\n</ng-template>\n\n<ng-template #filterPannelItem let-col=\"col\">\n <!-- Group Column -->\n <ng-container *ngIf=\"col.children?.length\">\n <div class=\"column-group d-flex align-items-center mb-2\">\n <!-- Chevron toggle -->\n <span class=\"filter-icon-wrapper me-2\">\n <span\n class=\"toggle-icon data-grid-svg-icon\"\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\n \"\n [class.rotate]=\"col.expandedFilter\"\n (click)=\"col.expandedFilter = !col.expandedFilter\"\n ></span>\n </span>\n\n <!-- Group label toggle -->\n <label\n class=\"d-flex align-items-center mb-0 w-100\"\n style=\"cursor: pointer\"\n (click)=\"col.expandedFilter = !col.expandedFilter\"\n >\n <span class=\"fw-bold text-truncate\"\n >{{ col.header }}\n <span\n class=\"text-primary ms-1\"\n *ngIf=\"col?.query?._ids?.length || col?.query?._first_value\"\n >*</span\n >\n </span>\n </label>\n </div>\n\n <!-- Children columns -->\n <div *ngIf=\"col.expandedFilter\" class=\"ps-4\">\n <ng-container *ngFor=\"let child of col.children; trackBy: trackByField\">\n <ng-container\n *ngTemplateOutlet=\"filterPannelItem; context: { col: child }\"\n ></ng-container>\n </ng-container>\n </div>\n </ng-container>\n\n <!-- Leaf Column -->\n <ng-container *ngIf=\"!col.children?.length\">\n <div class=\"d-flex align-items-center mb-2\">\n <span\n class=\"me-2 filter-icon-wrapper me-2\"\n (click)=\"col.expandedFilter = !col.expandedFilter\"\n >\n <span\n class=\"toggle-icon data-grid-svg-icon\"\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\n \"\n [class.rotate]=\"col.expandedFilter\"\n ></span>\n </span>\n\n <label\n class=\"d-flex align-items-center mb-0 w-100\"\n style=\"cursor: pointer\"\n (click)=\"col.expandedFilter = !col.expandedFilter\"\n >\n <span class=\"text-truncate fw-bold\">{{ col.header }}</span>\n </label>\n </div>\n\n <!-- Show filter when expanded -->\n <div *ngIf=\"col.expandedFilter\" class=\"ps-4 pe-3\">\n <ng-container\n *ngTemplateOutlet=\"sideNestedFilter; context: { col: col }\"\n ></ng-container>\n </div>\n </ng-container>\n</ng-template>\n\n<!-- Side Nested Filters -->\n<ng-template #sideNestedFilter let-col=\"col\">\n <div class=\"\">\n <!-- Dropdown Type -->\n <ng-container *ngIf=\"col.type === 'dropdown'; else textFilter\">\n <div class=\"p-1\">\n <!-- Search -->\n <input\n type=\"text\"\n class=\"form-control form-control-sm mb-2\"\n placeholder=\"Search...\"\n [(ngModel)]=\"col.searchValue\"\n />\n\n <!-- Select All -->\n <div class=\"form-check mb-1 ms-1\">\n <input\n class=\"form-check-input\"\n type=\"checkbox\"\n [checked]=\"\n col.query?._ids?.length == col?.column_dropdown_value?.length\n \"\n (change)=\"toggleSelectAllSideFilters(col, $event)\"\n id=\"selectAll_{{ col.field }}\"\n />\n <label class=\"form-check-label\" for=\"selectAll_{{ col.field }}\">\n Select All\n </label>\n </div>\n\n <!-- Options -->\n <div class=\"dropdown-options\">\n <div\n class=\"form-check mb-1 ms-1\"\n *ngFor=\"\n let option of col?.column_dropdown_value\n | filter : addFilterDropdownSearch : 'header'\n \"\n >\n <input\n class=\"form-check-input\"\n type=\"checkbox\"\n [value]=\"option\"\n [checked]=\"isOptionSelected(col, option)\"\n (change)=\"onOptionToggle(col, option)\"\n id=\"option_{{ col.field }}_{{\n option?.id || option?._id || option\n }}\"\n />\n <label\n class=\"form-check-label\"\n [for]=\"\n 'option_' +\n col.field +\n '_' +\n (option?.id || option?._id || option)\n \"\n >\n {{ option.value || option }}\n </label>\n </div>\n </div>\n\n <!-- Actions -->\n <!-- <div class=\"d-flex gap-2 mt-2\">\n <div\n class=\"btn btn-sm btn-primary d-flex justify-content-center align-items-center\"\n style=\"height: 22px;\"\n (click)=\"applySideMenuFilters()\"\n >\n Apply\n </div>\n <div\n class=\"btn btn-sm btn-secondary d-flex justify-content-center align-items-center\"\n style=\"height: 22px;\"\n (click)=\"resetSideMenuFilters()\"\n >\n Reset\n </div>\n </div> -->\n </div>\n </ng-container>\n\n <!-- Text Filter Section -->\n <ng-template #textFilter>\n <div class=\"filter-text-section\">\n <div class=\"form-group mb-2\">\n <select\n class=\"form-select form-select-sm\"\n [ngModel]=\"col!.query!.first_condition || (col.type === 'date' || col.type === 'time' ? 'equal' : 'contain')\"\n (ngModelChange)=\"col!.query!.first_condition = $event\"\n >\n <ng-container *ngIf=\"col.type === 'date' || col.type === 'time'; else textOptions\">\n <option value=\"equal\">Equal to</option>\n <option value=\"not_equal\">Not Equal</option>\n <option value=\"after\">After</option>\n <option value=\"before\">Before</option>\n </ng-container>\n <ng-template #textOptions>\n <option value=\"contain\">Contains</option>\n <option value=\"equal\">Equals</option>\n <option value=\"before\">Begins With</option>\n <option value=\"after\">Ends With</option>\n </ng-template>\n </select>\n </div>\n\n <input\n [type]=\"col.type == 'date' ? 'date' : col.type == 'number' ? 'number' : 'text'\"\n class=\"form-control form-control-sm mb-3\"\n placeholder=\"Value\"\n [(ngModel)]=\"col!.query!.first_value\"\n [min]=\"col.type == 'number' ? 0 : null\"\n (input)=\"col.type == 'number' && $any($event.target).value < 0 ? $any($event.target).value = 0 : null\"\n (keydown)=\"col.type == 'number' && $event.key === '-' ? $event.preventDefault() : null\"\n [class.number-input]=\"col.type == 'number'\"\n />\n\n <ng-container *ngIf=\"col?.query?.first_value && col?.query?.condition !== 'none'\">\n <div class=\"form-group mb-2\">\n <div class=\"form-check form-check-inline\">\n <input\n class=\"form-check-input filter-radio-inputs\"\n type=\"radio\"\n name=\"condition\"\n [(ngModel)]=\"col!.query.condition\"\n value=\"and\"\n id=\"and_{{ col.field }}\"\n />\n <label class=\"form-check-label\" for=\"and_{{ col.field }}\"\n >AND</label\n >\n </div>\n <div class=\"form-check form-check-inline\">\n <input\n class=\"form-check-input filter-radio-inputs\"\n type=\"radio\"\n name=\"condition\"\n [(ngModel)]=\"col!.query.condition\"\n value=\"or\"\n id=\"or_{{ col.field }}\"\n />\n <label class=\"form-check-label\" for=\"or_{{ col.field }}\"\n >OR</label\n >\n </div>\n <div class=\"form-check form-check-inline\">\n <input\n class=\"form-check-input filter-radio-inputs\"\n type=\"radio\"\n name=\"condition\"\n [(ngModel)]=\"col!.query.condition\"\n value=\"none\"\n id=\"none_{{ col.field }}\"\n />\n <label class=\"form-check-label\" for=\"none_{{ col.field }}\"\n >None</label\n >\n </div>\n </div>\n\n <div class=\"form-group mb-2\">\n <select\n class=\"form-select form-select-sm\"\n [ngModel]=\"col!.query.second_condition || (col.type === 'date' || col.type === 'time' ? 'equal' : 'contain')\"\n (ngModelChange)=\"col!.query.second_condition = $event\"\n >\n <ng-container *ngIf=\"col.type === 'date' || col.type === 'time'; else textOptionsSecond\">\n <option value=\"equal\">Equal to</option>\n <option value=\"not_equal\">Not Equal</option>\n <option value=\"after\">After</option>\n <option value=\"before\">Before</option>\n </ng-container>\n <ng-template #textOptionsSecond>\n <option value=\"contain\">Contains</option>\n <option value=\"equal\">Equals</option>\n <option value=\"before\">Begins With</option>\n <option value=\"after\">Ends With</option>\n </ng-template>\n </select>\n </div>\n\n <input\n [type]=\"col.type == 'date' ? 'date' : col.type == 'number' ? 'number' : 'text'\"\n class=\"form-control form-control-sm mb-2\"\n placeholder=\"Second Value\"\n [(ngModel)]=\"col!.query.second_value\"\n [min]=\"col.type == 'number' ? 0 : null\"\n (input)=\"col.type == 'number' && $any($event.target).value < 0 ? $any($event.target).value = 0 : null\"\n (keydown)=\"col.type == 'number' && $event.key === '-' ? $event.preventDefault() : null\"\n [class.number-input]=\"col.type == 'number'\"\n />\n </ng-container>\n\n <!-- Apply and Reset Buttons -->\n <div class=\"d-flex gap-2 mt-2\">\n <div\n class=\"btn btn-sm btn-primary d-flex justify-content-center align-items-center w-100\"\n style=\"height: 22px\"\n (click)=\"applyFilterFromFilterRow(col)\"\n >\n Apply\n </div>\n <div\n class=\"btn btn-sm btn-secondary d-flex justify-content-center align-items-center w-100\"\n style=\"height: 22px\"\n (click)=\"resetSideFilter(col)\"\n >\n Reset\n </div>\n </div>\n </div>\n </ng-template>\n </div>\n</ng-template>\n\n<!-- Centr Overlay for showing the chose columns -->\n\n<div *ngIf=\"showColumnPanel\" class=\"custom-modal-overlay\" (click)=\"closeModalColumnPanel()\">\n <div\n class=\"custom-modal-content\"\n [style.backgroundColor]=\"dropdownsBackgroundColor\"\n (click)=\"$event.stopPropagation()\"\n >\n <ng-container *ngTemplateOutlet=\"modalColumnPannel\"></ng-container>\n </div>\n</div>\n\n<!-- The existing ng-template you provided -->\n<ng-template #modalColumnPannel>\n <div class=\"column-panel-header\">\n <div\n class=\"d-flex justify-content-between align-items-center px-2 ps-3 rounded-top-2 moda-header\"\n [style.height.px]=\"48\"\n >\n Choose Columns\n <span class=\"filter-icon-wrapper\" (click)=\"closeModalColumnPanel()\"\n ><span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/x.svg'\"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span\n ></span>\n </div>\n <hr class=\"my-0\" />\n <div>\n <div class=\"d-flex align-items-center px-2 pe-3\" [style.height.px]=\"48\">\n <span class=\"filter-icon-wrapper me-2\" *ngIf=\"showColumnsGrouping\">\n <span\n class=\"toggle-icon data-grid-svg-icon\"\n [inlineSVG]=\"\n accordionState === 'all'\n ? singleSpaAssetsPath + 'data-grid/icons/chevron-down.svg'\n : accordionState === 'some'\n ? singleSpaAssetsPath + 'data-grid/icons/dash.svg'\n : singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\n \"\n (click)=\"toggleAllAccordions()\"\n ></span>\n </span>\n <input\n type=\"checkbox\"\n class=\"form-check-input me-2\"\n [checked]=\"allColumnsSelected()\"\n (change)=\"toggleAllColumnsVisibility()\"\n />\n <input\n type=\"text\"\n class=\"form-control form-control-sm\"\n placeholder=\"Search columns...\"\n [(ngModel)]=\"choseColumnsSearch\"\n />\n </div>\n\n <hr class=\"mt-0 mb-1\" />\n <div class=\"px-2 overlay-scrollable\">\n <ng-container\n *ngFor=\"\n let col of columns | filter : choseColumnsSearch : 'header';\n trackBy: trackByField\n \"\n >\n <ng-container\n *ngTemplateOutlet=\"columnPanelItem; context: { col: col }\"\n ></ng-container>\n </ng-container>\n </div>\n </div>\n </div>\n</ng-template>\n\n<ng-template #sideMenuRowGroups>\n <div class=\"d-flex flex-column h-100\">\n <div class=\"px-3 h-100\">\n <div class=\"d-flex gap-3 mb-4\">\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/justify.svg'\"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n <span>Row Groups</span>\n </div>\n <div class=\"h-50\">\n <div\n class=\"px-3 py-2 border-dashed h-100 d-flex justify-content-center align-items-center\"\n style=\"font-size: 14px\"\n >\n Drag here to set row Groups\n </div>\n </div>\n </div>\n\n <hr class=\"mt-4\" />\n\n <div class=\"px-3 h-100\">\n <div class=\"d-flex gap-3 mb-4\">\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/justify.svg'\"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n <span>Values</span>\n </div>\n <div class=\"h-50 d-flex\">\n <div\n class=\"px-3 py-2 border-dashed h-100 d-flex justify-content-center align-items-center\"\n style=\"font-size: 14px\"\n >\n Drag here aggregate\n </div>\n </div>\n </div>\n </div>\n</ng-template>\n\n<!-- *************************************************** -->\n<!-- *************************************************** -->\n<!-- *************************************************** -->\n<!-- Drag Preview Template -->\n<!-- *************************************************** -->\n<!-- *************************************************** -->\n<ng-template #dragPreview let-col>\n <div class=\"p-2 border d-flex gap-2\">\n <div>\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrows-move.svg'\"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n </div>\n <div>{{ col.header }}</div>\n </div>\n</ng-template>\n\n<!-- Drag Placeholder Template -->\n<ng-template\n #dragPlaceholder\n let-col\n let-i=\"index\"\n let-section=\"section\"\n let-draggingInGroupArea=\"draggingInGroupArea\"\n>\n <div *ngIf=\"!draggingInGroupArea\">\n <div\n *ngTemplateOutlet=\"\n headerCell;\n context: { $implicit: col, index: i, section: section }\n \"\n ></div>\n </div>\n <div *ngIf=\"draggingInGroupArea\">New Placeholder</div>\n</ng-template>\n\n<!-- Top Group Row Placeholder -->\n<ng-template #topGroupingRowPlaceholder let-col let-showChevron=\"showChevron\">\n <div class=\"d-flex gap-2\">\n <div\n class=\"d-flex gap-2 top-row-grouping-placeholder\"\n [style.backgroundColor]=\"topGroupedBadgesBackgroundColor\"\n >\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/grid-3x2-gap.svg'\"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n <span>{{ col.header }}</span>\n <span\n (click)=\"ungroupColumn(col)\"\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/x.svg'\"\n class=\"cursor-pointer data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n </div>\n </div>\n <div *ngIf=\"showChevron\" style=\"opacity: 0.6; font-size: 14px\">\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n </div>\n</ng-template>\n\n<ng-template\n #childHeaderPlaceholder\n let-col\n let-pinnedRight=\"pinnedRight\"\n let-i=\"index\"\n let-sections=\"sections\"\n>\n <div\n class=\"header-cell one-row-header-cells\"\n [class.border-right]=\"showVerticalBorder\"\n [style.width.px]=\"col.width\"\n [style.min-width.px]=\"col.width\"\n [style.min-height.px]=\"headerRowHeight\"\n [style.max-height.px]=\"headerRowHeight\"\n [class.border-right]=\"showVerticalBorder\"\n [style.fontWeight]=\"headerFontWeight\"\n >\n <div class=\"d-flex justify-content-between h-100 align-items-center w-100\">\n <div\n class=\"d-flex justify-content-between w-100\"\n [class.flex-row-reverse]=\"pinnedRight\"\n >\n <div\n class=\"text-ellipsis h-100 d-flex align-items-center\"\n [title]=\"col.header\"\n [class.w-100]=\"pinnedRight\"\n >\n {{ col.header }}\n </div>\n\n <div\n class=\"position-relative d-flex\"\n [class.flex-row-reverse]=\"pinnedRight\"\n >\n <div class=\"three-dots p-1\" style=\"cursor: pointer\">\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/three-dots-vertical.svg'\n \"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n </div>\n\n <div class=\"resize-handle\">\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/resize-handle.svg'\n \"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n </div>\n </div>\n </div>\n </div>\n </div>\n <div\n *ngIf=\"showFilterRow\"\n [style.backgroundColor]=\"headerBackgroundColor\"\n class=\"header-cell filter-cell\"\n [class.border-right]=\"showVerticalBorder\"\n [style.width.px]=\"col.width\"\n [style.min-width.px]=\"col.width\"\n [style.height.px]=\"headerRowHeight\"\n [style.min-height.px]=\"headerRowHeight\"\n [style.max-height.px]=\"headerRowHeight\"\n [class.border-right]=\"showVerticalBorder\"\n style=\"grid-row: 3\"\n >\n <div\n class=\"header-cell filter-cell\"\n [style.backgroundColor]=\"headerBackgroundColor\"\n [style.width.px]=\"col.width\"\n [style.min-width.px]=\"col.width\"\n [style.height.px]=\"headerRowHeight\"\n [style.min-height.px]=\"headerRowHeight\"\n [style.max-height.px]=\"headerRowHeight\"\n >\n <input\n type=\"text\"\n class=\"form-control form-control-sm\"\n placeholder=\"Filter\"\n [(ngModel)]=\"col.filterValue\"\n />\n <span\n class=\"filter-icon-wrapper\"\n (click)=\"activeFilterCell = col; activeCol = null\"\n ><span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span\n ></span>\n\n <div\n class=\"position-absolute\"\n *ngIf=\"activeFilterCell === col\"\n style=\"top: 100%; right: 0; z-index: 10; left: 0\"\n ></div>\n </div>\n </div>\n</ng-template>\n\n<ng-template #tableLayout>\n <div\n (click)=\"$event.stopPropagation()\"\n class=\"p-3 shadow rounded-3 bg-white actions-dropdown mt-1 dropdown-menu show shadow custom-menu table-layout\"\n style=\"width: 320px\"\n >\n <div class=\"d-flex align-items-center mb-3\">\n <button\n class=\"btn btn-link p-0\"\n style=\"margin-left: -10px\"\n (click)=\"toggleActions('setting')\"\n >\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrow-left.svg'\"\n class=\"data-grid-svg-icon me-2\"\n ></span>\n </button>\n <h6 class=\"mb-0 ms-2\" style=\"font-weight: 500\">Table Layout</h6>\n </div>\n <hr class=\"my-2\" />\n <div class=\"w-100 mb-3 d-flex\" role=\"group\">\n <input\n type=\"radio\"\n class=\"btn-check layout-button-check\"\n name=\"layoutSize\"\n id=\"small\"\n autocomplete=\"off\"\n (change)=\"changeTableLayout($event, 'small')\"\n [checked]=\"selectedTableLayout == 'small'\"\n />\n <label\n class=\"border d-flex flex-column align-items-center layout-button\"\n for=\"small\"\n [ngStyle]=\"{\n color: selectedTableLayout == 'small' ? '#000' : '#727272'\n }\"\n >\n <div class=\"preview-box border mb-1\" style=\"height: 8px\"></div>\n Small\n </label>\n\n <input\n type=\"radio\"\n class=\"btn-check layout-button-check\"\n name=\"layoutSize\"\n id=\"medium\"\n autocomplete=\"off\"\n [checked]=\"selectedTableLayout == 'medium'\"\n (change)=\"changeTableLayout($event, 'medium')\"\n />\n <label\n class=\"border mx-3 d-flex flex-column align-items-center layout-button\"\n for=\"medium\"\n [ngStyle]=\"{\n color: selectedTableLayout == 'medium' ? '#000' : '#727272'\n }\"\n >\n <div class=\"preview-box border mb-1\" style=\"height: 12px\"></div>\n Medium\n </label>\n\n <input\n type=\"radio\"\n class=\"btn-check layout-button-check\"\n name=\"layoutSize\"\n id=\"large\"\n autocomplete=\"off\"\n (change)=\"changeTableLayout($event, 'large')\"\n [checked]=\"selectedTableLayout == 'large'\"\n />\n <label\n class=\"border d-flex flex-column align-items-center layout-button\"\n for=\"large\"\n [ngStyle]=\"{\n color: selectedTableLayout == 'large' ? '#000' : '#727272'\n }\"\n >\n <div class=\"preview-box border mb-1\" style=\"height: 16px\"></div>\n Large\n </label>\n </div>\n\n <hr class=\"my-2\" />\n <div class=\"d-flex justify-content-between align-items-center mb-2\">\n <span>Show separators</span>\n <div class=\"form-check form-switch m-0\">\n <input\n class=\"form-check-input\"\n type=\"checkbox\"\n id=\"separators\"\n [(ngModel)]=\"showVerticalBorder\"\n (change)=\"emitConfigUpdate()\"\n />\n </div>\n </div>\n <div class=\"d-flex justify-content-between align-items-center\">\n <span>Row shading</span>\n <div class=\"form-check form-switch m-0\">\n <input\n class=\"form-check-input\"\n [(ngModel)]=\"rowShadingEnabled\"\n (change)=\"toggleRowShading()\"\n type=\"checkbox\"\n id=\"rowShading\"\n />\n </div>\n </div>\n </div>\n</ng-template>\n\n<ng-template #tablePreset>\n <div\n *ngIf=\"activeSubButton !== 'save-preset'\"\n (click)=\"$event.stopPropagation();\"\n class=\"p-3 shadow rounded-3 bg-white actions-dropdown mt-1 dropdown-menu show shadow custom-menu table-layout\"\n style=\"width: 280px\"\n >\n <!-- Header -->\n <div class=\"d-flex justify-content-between align-items-center mb-3\">\n <div class=\"d-flex align-items-center\">\n <button\n class=\"btn btn-link p-0\"\n style=\"margin-left: -10px\"\n (click)=\"toggleActions('setting')\"\n >\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrow-left.svg'\"\n class=\"data-grid-svg-icon\"\n ></span>\n </button>\n <h6 class=\"mb-0 ms-2\" style=\"font-weight: 500\">Table Presets</h6>\n </div>\n <!-- Save/Update Preset Button -->\n <div>\n <a\n class=\"text-decoration-none btn btn-link\"\n type=\"button\"\n id=\"savePresetDropdown\"\n (click)=\"$event.stopPropagation(); toggleSubActions('save-preset')\"\n >\n {{ tableFilterViewId && tableFilterViewId !== 'default' ? 'Update Preset' : 'Save Preset' }}\n </a>\n </div>\n </div>\n\n <!-- Search -->\n <div class=\"mb-3\">\n <div class=\"col-12 global-search\">\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/search.svg'\"\n class=\"data-grid-svg-icon mx-2 position-absolute icon\"\n ></span>\n <input\n class=\"form-control form-control-sm\"\n placeholder=\"Search...\"\n [(ngModel)]=\"searchTextPresetTable\"\n type=\"search\"\n />\n </div>\n </div>\n\n <!-- Preset List -->\n <ng-container\n *ngIf=\"\n tableView | filter : searchTextPresetTable : 'name' as filteredList\n \"\n >\n <!-- If filteredList exists and none is default -> show fallback -->\n <div class=\"\" (click)=\"selectDefault()\">\n <div class=\"fw-semibold\">Default View\n <span\n *ngIf=\"tableFilterViewId === 'default'\"\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/check-blue.svg'\"\n class=\"me-2\"\n ></span>\n </div>\n </div>\n <div class=\"d-flex justify-content-between\">\n <small class=\"text-dark\">Created by system</small>\n <span\n *ngIf=\"tableFilterViewId === 'default'\"\n class=\"badge bg-light text-primary ms-2\"\n >Default</span\n >\n <div\n class=\"dropdown d-flex justify-content-end\"\n *ngIf=\"tableFilterViewId\"\n >\n <a\n href=\"javascript:void(0)\"\n class=\"muted-text\"\n data-bs-toggle=\"dropdown\"\n >\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/horizontal-dots.svg'\n \"\n class=\"me-2\"\n ></span>\n </a>\n <ul class=\"dropdown-menu dropdown-menu-end\">\n <a\n (click)=\"actionPreset({ id: 'default' }, 'setPreset')\"\n class=\"dropdown-item d-flex align-items-center\"\n >\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/star.svg'\"\n class=\"me-2\"\n ></span>\n Set as default\n </a>\n </ul>\n </div>\n </div>\n\n <!-- The list: render each table from filteredList -->\n <div\n class=\"list-group list-group-flush\"\n *ngFor=\"let table of filteredList; trackBy: trackByTable\"\n >\n <!-- Item -->\n <div\n class=\"list-group-item px-0 d-flex justify-content-between align-items-center\"\n >\n <div (click)=\"selectFilter(table)\">\n <div class=\"fw-semibold\" style=\"cursor: pointer;\">\n {{ table?.name }}\n <!-- {{table?.is_temp}} -->\n <span\n *ngIf=\"table?.is_temp\"\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/check-blue.svg'\n \"\n class=\"me-2\"\n ></span>\n <span\n *ngIf=\"table?.is_default\"\n class=\"badge bg-light text-primary ms-2\"\n >Default</span\n >\n </div>\n <small class=\"text-dark\"\n >Created {{ table?.createdAt | timezoneFormat:prefs:'date' }}</small\n >\n </div>\n\n <div class=\"d-flex align-items-center\">\n <span\n *ngIf=\"table?.is_default\"\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/check-blue.svg'\n \"\n class=\"me-2\"\n ></span>\n\n <div class=\"dropdown position-relative\" *ngIf=\"!table?.is_default\">\n <a href=\"javascript:void(0)\" class=\"muted-text\" (click)=\"togglePresetDropdown(table.id)\">\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/horizontal-dots.svg'\" class=\"me-2\"></span>\n </a>\n\n <div\n *ngIf=\"activePresetDropdownId === table.id\"\n class=\"dropdown-menu dropdown-menu-end show position-absolute\"\n style=\"z-index: 1000; top: 100%; right: 0; min-width: 180px\"\n (click)=\"$event.stopPropagation()\"\n >\n <a\n [class.d-none]=\"confirmDeletePresetId === table.id\"\n (click)=\"setPresetAsDefault(table); activePresetDropdownId = null;\"\n class=\"dropdown-item d-flex align-items-center\"\n >\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/star.svg'\" class=\"me-2\"></span>\n Set as default\n </a>\n\n <ng-container *ngIf=\"confirmDeletePresetId !== table.id; else confirmBlock\">\n <a\n (click)=\"confirmDeletePresetId = table.id\"\n class=\"dropdown-item d-flex align-items-center text-danger\"\n >\n <span style=\"margin-top: -4px\" [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/trash-red.svg'\" class=\"me-2\"></span>\n Delete\n </a>\n </ng-container>\n\n <ng-template #confirmBlock>\n <div class=\"dropdown-item\"><b>Delete preset</b></div>\n <div class=\"dropdown-item text-center\">\n <div class=\"mb-2\">\n Are you sure you want to delete the <br />\n <b>\u201C{{ table?.name }}\u201D</b> preset?\n </div>\n <button\n class=\"btn btn-sm btn-light me-2\"\n (click)=\"confirmDeletePresetId = null\"\n >\n Cancel\n </button>\n <button\n class=\"btn btn-sm btn-danger delete-preset\"\n (click)=\"actionPreset(table, 'deletePreset'); confirmDeletePresetId = null; activePresetDropdownId = null;\"\n >\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/trash-red.svg'\" class=\"confirm-preset-delete\"></span>\n Delete\n </button>\n </div>\n </ng-template>\n </div>\n</div>\n </div>\n </div>\n <!-- Item End Here -->\n </div>\n\n </ng-container>\n </div>\n\n <div\n (click)=\"$event.stopPropagation()\"\n *ngIf=\"activeSubButton == 'save-preset'\"\n class=\"dropdown-menu p-3 badge mt-4 save-preset-dropdown mt-1\"\n aria-labelledby=\"savePresetDropdown\"\n style=\"min-width: 250px\"\n >\n <div class=\"fw-bold fs-14px mb-2\">Save preset</div>\n <div class=\"fs-14px mb-2\" style=\"line-height: 20px\">\n This will save the current table adjustments as a preset.\n </div>\n <!-- Input -->\n <div class=\"mb-2\">\n <label for=\"presetName\" class=\"form-label fs-12px fw-bold\"\n >Preset Name</label\n >\n <div class=\"col-12 global-search\">\n <input\n #presetNameCtrl=\"ngModel\"\n required\n [(ngModel)]=\"presetName\"\n [ngClass]=\"{\n 'is-invalid':\n presetNameCtrl.invalid &&\n (presetNameCtrl.dirty || presetNameCtrl.touched)\n }\"\n class=\"form-control form-control-sm ps-2\"\n placeholder=\"Enter preset name\"\n type=\"text\"\n />\n </div>\n </div>\n\n <!-- Checkbox -->\n <div class=\"form-check mb-2\">\n <input\n class=\"form-check-input\"\n [(ngModel)]=\"presetFilter\"\n type=\"checkbox\"\n id=\"saveFilters\"\n />\n <label class=\"form-check-label mt-1\" for=\"saveFilters\">\n Save active filters\n </label>\n </div>\n\n <!-- Save Button -->\n <div class=\"d-flex justify-content-center gap-2\" style=\"height: 32px\">\n <button\n type=\"button\"\n style=\"height: 32px\"\n class=\"btn border w-100 d-flex align-items-center justify-content-center btn-light\"\n (click)=\"$event.stopPropagation(); toggleActions('table-presets')\"\n style=\"margin-top: -2px\"\n >\n <span>Cancel</span>\n </button>\n <button\n [disabled]=\"closeDropdown.preset.loading\"\n (click)=\"savePreset(presetNameCtrl)\"\n type=\"button\"\n style=\"height: 32px\"\n class=\"btn btn-primary w-100 d-flex align-items-center justify-content-center\"\n >\n <span style=\"margin-top: -2px\">\n <ng-container *ngIf=\"!closeDropdown.preset.loading && (!tableFilterViewId || tableFilterViewId === 'default')\"\n >Save</ng-container\n >\n <ng-container *ngIf=\"!closeDropdown.preset.loading && tableFilterViewId && tableFilterViewId !== 'default'\"\n >Update</ng-container\n >\n <ng-container *ngIf=\"closeDropdown.preset.loading\"\n ><span class=\"spinner-border spinner-border-sm\"></span\n ></ng-container>\n </span>\n </button>\n </div>\n </div>\n</ng-template>\n\n<ng-template #showHideColumns>\n <div\n (click)=\"$event.stopPropagation()\"\n class=\"p-3 shadow rounded-3 bg-white actions-dropdown mt-1 dropdown-menu show shadow custom-menu table-layout\"\n style=\"width: 280px\"\n >\n <!-- Header -->\n <div class=\"d-flex justify-content-between align-items-center mb-3\">\n <div class=\"d-flex align-items-center\">\n <button\n class=\"btn btn-link p-0\"\n style=\"margin-left: -10px\"\n (click)=\"toggleActions('setting')\"\n >\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrow-left.svg'\"\n class=\"data-grid-svg-icon\"\n ></span>\n </button>\n <h6 class=\"mb-0 ms-2\" style=\"font-weight: 500\">Columns</h6>\n </div>\n <a\n (click)=\"resetColumns()\"\n href=\"javascript:void(0)\"\n class=\"text-primary text-decoration-none\"\n >Reset</a\n >\n </div>\n\n <!-- Search -->\n <div class=\"mb-3\">\n <div class=\"col-12 global-search\">\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/search.svg'\"\n class=\"mx-2 position-absolute icon data-grid-svg-icon\"\n ></span>\n <input\n class=\"form-control form-control-sm\"\n placeholder=\"Search column\"\n type=\"search\"\n [(ngModel)]=\"topShowHideColumns\"\n />\n </div>\n </div>\n <!-- Preset List -->\n <div\n class=\"list-group list-group-flush\"\n style=\"\n max-height: calc(100vh - 300px);\n overflow: auto;\n scrollbar-width: thin;\n \"\n >\n <div class=\"muted-text show-hide-table-label d-flex justify-content-between\" *ngIf=\"hasAnyVisibleColumn\">\n Show in table\n <div class=\"form-check\">\n <input\n type=\"checkbox\"\n id=\"show_hide_all\"\n class=\"form-check-input\"\n [checked]=\"areAllNonMandatoryVisible()\"\n (change)=\"toggleAllVisibleColumns()\"\n />\n <label for=\"show_hide_all\" class=\"form-check-label fw-semibold\">Show/Hide All</label>\n </div>\n </div>\n <!-- <div class=\"d-flex align-items-center mb-2\" *ngIf=\"hasAnyVisibleColumn\">\n <input\n type=\"checkbox\"\n class=\"form-check-input me-2\"\n [checked]=\"areAllNonMandatoryVisible()\"\n (change)=\"toggleAllVisibleColumns()\"\n />\n <label class=\"form-check-label fw-semibold\">Show All</label>\n </div> -->\n <!-- Item -->\n <ng-container\n *ngFor=\"\n let col of columns | filter : topShowHideColumns : 'header';\n trackBy: trackByField\n \"\n >\n <div\n *ngIf=\"col.is_visible\"\n class=\"list-group-item border-0 px-0 d-flex justify-content-between align-items-center\"\n >\n <div class=\"d-flex gap-1\">\n <div>\n <span\n *ngIf=\"!col?.pinned\"\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/grip-vertical.svg'\n \"\n class=\"cursor-grap data-grid-svg-icon\"\n (mousedown)=\"$event.preventDefault()\"\n ></span>\n <span\n *ngIf=\"col?.pinned\"\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/pin-blue.svg'\n \"\n class=\"cursor-grap data-grid-svg-icon\"\n (mousedown)=\"$event.preventDefault()\"\n ></span>\n </div>\n <div class=\"fw-semibold\">\n {{ col.header }}\n </div>\n </div>\n <div\n *ngIf=\"!col?.query?.first_value && !col?.query?._ids?.length && !isMandatory(col)\"\n class=\"d-flex align-items-center cursor-pointer\"\n (click)=\"toggleColumnVisibility(col, false)\"\n >\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/eye.svg'\"\n class=\"data-grid-svg-icon me-2\"\n ></span>\n </div>\n <div\n *ngIf=\"(!col?.query?.first_value && !col?.query?._ids?.length && isMandatory(col)) || (col?.query?.first_value || col?.query?._ids?.length)\"\n class=\"d-flex align-items-center\"\n style=\"opacity: 0.5\"\n >\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/eye.svg'\"\n class=\"data-grid-svg-icon me-2\"\n ></span>\n </div>\n </div>\n </ng-container>\n\n <!-- Item End Here -->\n\n <div\n class=\"dropdown-divider\"\n *ngIf=\"hasAnyVisibleColumn && hasAnyInVisibleColumn\"\n ></div>\n\n <!-- <div\n class=\"muted-text show-hide-table-label\"\n *ngIf=\"hasAnyInVisibleColumn\"\n >\n Hide in table\n </div>\n <div class=\"d-flex align-items-center mb-2\" *ngIf=\"hasAnyInVisibleColumn\">\n <input\n type=\"checkbox\"\n id=\"hide_show_all\"\n class=\"form-check-input me-2\"\n [checked]=\"areAllNonMandatoryHidden()\"\n (change)=\"toggleAllInvisibleColumns()\"\n />\n <label class=\"form-check-label fw-semibold\">Hide All</label>\n </div> -->\n\n \n\n\n\n <div class=\"muted-text show-hide-table-label d-flex justify-content-between\" *ngIf=\"hasAnyInVisibleColumn\">\n Hide in table\n <div class=\"form-check\">\n <input\n type=\"checkbox\"\n id=\"hide_show_all\"\n class=\"form-check-input\"\n [checked]=\"areAllNonMandatoryHidden()\"\n (change)=\"toggleAllInvisibleColumns()\"\n />\n <label for=\"hide_show_all\" class=\"form-check-label fw-semibold\">Hide/Show All</label>\n </div>\n </div>\n <div class=\"list-group list-group-flush\">\n <ng-container *ngFor=\"let col of columns; trackBy: trackByField\">\n <div\n *ngIf=\"!col.is_visible\"\n class=\"list-group-item border-0 px-0 d-flex justify-content-between align-items-center\"\n >\n <div class=\"d-flex gap-1\">\n <div>\n <span\n *ngIf=\"!col?.pinned\"\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/grip-vertical.svg'\n \"\n class=\"data-grid-svg-icon cursor-grap\"\n (mousedown)=\"$event.preventDefault()\"\n ></span>\n <span\n *ngIf=\"col?.pinned\"\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/pin-blue.svg'\n \"\n class=\"data-grid-svg-icon cursor-grap\"\n (mousedown)=\"$event.preventDefault()\"\n ></span>\n </div>\n <div class=\"fw-semibold\">\n {{ col.header }}\n </div>\n </div>\n <div\n class=\"d-flex align-items-center cursor-pointer\"\n (click)=\"toggleColumnVisibility(col, true)\"\n >\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/eye-cross.svg'\n \"\n class=\"data-grid-svg-icon me-2\"\n ></span>\n </div>\n </div>\n </ng-container>\n </div>\n\n <!-- Item End Here -->\n </div>\n </div>\n</ng-template>\n\n<ng-template #filterColumns let-col=\"column\">\n <div\n @slideToggle\n *ngIf=\"!isFilterOpen && activeTopButton == 'filter-columns'\"\n (click)=\"$event.stopPropagation()\"\n class=\"shadow rounded-3 bg-white actions-dropdown mt-1 show shadow custom-menu table-layout filter-columns\"\n style=\"width: 280px; right: unset; max-width: 230px\"\n >\n <div class=\"mb-2 px-3\">\n <div class=\"col-12 global-search\">\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/search.svg'\"\n class=\"data-grid-svg-icon mx-2 position-absolute icon\"\n ></span>\n <input\n class=\"form-control form-control-sm\"\n placeholder=\"Filter by\"\n type=\"search\"\n [(ngModel)]=\"addFilterColumnInput\"\n />\n </div>\n </div>\n <div\n class=\"list-group list-group-flush\"\n style=\"max-height: calc(100vh - 500px); overflow: auto\"\n >\n <ng-container\n *ngFor=\"\n let col of columns | filter : addFilterColumnInput : 'header';\n trackBy: trackByField\n \"\n >\n <div\n (click)=\"openFilter(col)\"\n *ngIf=\"\n col.is_visible &&\n !col?.query?.first_value &&\n !col?.query?._ids?.length\n \"\n class=\"list-group-item border-0 px-0 d-flex justify-content-between align-items-center dropdown-item cursor-pointer\"\n >\n <div class=\"d-flex gap-1\">\n <div style=\"margin-top: -3px\"></div>\n <div class=\"fw-semibold\">\n {{ col.header }}\n </div>\n </div>\n </div>\n </ng-container>\n </div>\n </div>\n\n <!-- Dropdown -->\n <div\n @slideToggle\n *ngIf=\"isFilterOpen && selectedColumnForFilter.type == 'dropdown'\"\n (click)=\"$event.stopPropagation()\"\n class=\"shadow rounded-3 bg-white actions-dropdown mt-1 show shadow custom-menu table-layout filter-columns\"\n style=\"width: 280px; right: unset; max-width: 230px\"\n >\n <div class=\"px-3 my-2 border-below py-1 pb-2 mb-3 d-flex ps-1\">\n <span\n (click)=\"toggleActions('filter-columns'); isActiveFilterOpen = false\"\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrow-left.svg'\"\n class=\"data-grid-svg-icon me-2 cursor-pointer\"\n ></span\n ><b>{{ selectedColumnForFilter?.header }}</b>\n </div>\n <div class=\"mb-2 px-3\">\n <div\n class=\"col-12 global-search position-relative border rounded d-flex align-items-center flex-wrap px-2 filter-serach-inpt\"\n >\n <span\n *ngFor=\"let selected of selectedFilterOptions\"\n class=\"badge d-flex align-items-center gap-1 me-1 mb-1\"\n >\n {{ selected?.value ? selected.value : selected }}\n <span\n (click)=\"toggleSelectionInFilter(selected)\"\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/cross-primary.svg'\n \"\n class=\"me-2\"\n ></span>\n </span>\n <input\n class=\"form-control form-control-sm border-0 flex-grow-1\"\n style=\"padding: 0\"\n [placeholder]=\"selectedFilterOptions!.length ? '' : 'Filter by'\"\n type=\"search\"\n [(ngModel)]=\"searchTextForFilterDropDown\"\n (keydown.backspace)=\"handleBackspace($event)\"\n (ngModelChange)=\"selectedFilterOptions.length === 0 ? condition = 'none' : null\"\n />\n </div>\n </div>\n <div\n class=\"list-group list-group-flush\"\n style=\"max-height: calc(100vh - 600px); overflow: auto\"\n >\n <ng-container\n *ngFor=\"\n let col of selectedColumnForFilter.column_dropdown_value\n | filter : searchTextForFilterDropDown : 'value';\n let i = index\n \"\n >\n <div\n class=\"list-group-item border-0 px-2 d-flex justify-content-between align-items-center dropdown-item cursor-pointer\"\n >\n <div class=\"form-check\">\n <input\n class=\"form-check-input\"\n type=\"checkbox\"\n [id]=\"i\"\n [checked]=\"currentFilterSelectedIds.has(col.id || col._id || col)\"\n (change)=\"toggleSelectionInFilter(col)\"\n />\n <label class=\"form-check-label fw-semibold\" [for]=\"i\">\n {{ col?.value || col?.name || col }}\n </label>\n </div>\n </div>\n </ng-container>\n </div>\n <div\n class=\"d-flex justify-content-center gap-2 px-2 border-top\"\n style=\"height: 38px\"\n >\n <button\n type=\"button\"\n style=\"height: 32px\"\n class=\"btn btn-outline-secondary btn-light border w-100 d-flex align-items-center justify-content-center mt-1 btn-light\"\n (click)=\"$event.stopPropagation(); resetFilterChanges()\"\n >\n <span>Cancel</span>\n </button>\n <button\n type=\"button\"\n style=\"height: 32px\"\n class=\"btn btn-primary w-100 d-flex align-items-center justify-content-center mt-1\"\n (click)=\"applyDropdownFilter()\"\n >\n <span style=\"margin-top: -2px\">Save</span>\n </button>\n </div>\n </div>\n\n <!-- For Text fields and number fields-->\n\n <div\n @slideToggle\n *ngIf=\"\n isFilterOpen &&\n (selectedColumnForFilter.type == 'string' ||\n selectedColumnForFilter.type == 'number' ||\n selectedColumnForFilter.type == 'date')\n \"\n (click)=\"$event.stopPropagation()\"\n class=\"shadow rounded-3 bg-white actions-dropdown mt-1 show shadow custom-menu table-layout filter-columns\"\n style=\"width: 280px; right: unset; max-width: 230px\"\n >\n <div class=\"px-3 border-below py-1 pb-2 d-flex ps-1\">\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrow-left.svg'\"\n (click)=\"toggleActions('filter-columns'); isActiveFilterOpen = false\"\n class=\"data-grid-svg-icon me-2 cursor-pointer\"\n ></span\n ><b>{{ selectedColumnForFilter?.header }}</b>\n </div>\n <div class=\"col-12 position-relative p-2 text-filter\">\n <div class=\"mb-2\">\n <select\n class=\"form-select form-select-sm custom-select\"\n [(ngModel)]=\"firstCondition\"\n >\n <ng-container *ngIf=\"selectedColumnForFilter.type === 'date' || selectedColumnForFilter.type === 'time'; else textOptions\">\n <option value=\"equal\">Equal to</option>\n <option value=\"not_equal\">Not Equal</option>\n <option value=\"after\">After</option>\n <option value=\"before\">Before</option>\n </ng-container>\n <ng-template #textOptions>\n <option value=\"equal\">Equals</option>\n <!-- <option value=\"not_equal\">Not Equals</option> -->\n <option value=\"contain\">Contains</option>\n <option value=\"before\">Begins With</option>\n <option value=\"after\">Ends With</option>\n </ng-template>\n </select>\n </div>\n <div class=\"mb-2\">\n <input\n class=\"form-control form-control-sm\"\n placeholder=\"Enter first value\"\n [type]=\"\n selectedColumnForFilter.type == 'string'\n ? 'text'\n : selectedColumnForFilter.type\n \"\n [(ngModel)]=\"firstValue\"\n [min]=\"selectedColumnForFilter.type == 'number' ? 0 : null\"\n [class.number-input]=\"selectedColumnForFilter.type == 'number'\"\n (input)=\"selectedColumnForFilter.type == 'number' && $any($event.target).value < 0 ? $any($event.target).value = 0 : null\"\n (ngModelChange)=\"!firstValue ? condition = 'none' : null\"\n (keydown)=\"selectedColumnForFilter.type == 'number' && $event.key === '-' ? $event.preventDefault() : null\"\n />\n </div>\n <div class=\"d-flex my-3\">\n <div class=\"form-check form-check-inline\">\n <input\n class=\"form-check-input\"\n type=\"radio\"\n id=\"logicalAnd\"\n name=\"logicalOperator\"\n value=\"and\"\n [(ngModel)]=\"condition\"\n />\n <label class=\"form-check-label\" for=\"logicalAnd\">AND</label>\n </div>\n\n <div class=\"form-check form-check-inline\">\n <input\n class=\"form-check-input\"\n type=\"radio\"\n id=\"logicalOr\"\n name=\"logicalOperator\"\n value=\"or\"\n [(ngModel)]=\"condition\"\n />\n <label class=\"form-check-label\" for=\"logicalOr\">OR</label>\n </div>\n\n <div class=\"form-check form-check-inline\">\n <input\n class=\"form-check-input\"\n type=\"radio\"\n id=\"logicalNone\"\n name=\"logicalOperator\"\n value=\"none\"\n [(ngModel)]=\"condition\"\n />\n <label class=\"form-check-label\" for=\"logicalNone\">None</label>\n </div>\n </div>\n\n <div *ngIf=\"firstValue && condition !== 'none'\">\n <div class=\"my-3\">\n <!-- Second condition select -->\n <select\n class=\"form-select form-select-sm\"\n [(ngModel)]=\"secondCondition\"\n >\n <ng-container *ngIf=\"selectedColumnForFilter.type === 'date' || selectedColumnForFilter.type === 'time'; else textOptionsSecond\">\n <option value=\"equal\">Equal to</option>\n <option value=\"not_equal\">Not Equal</option>\n <option value=\"after\">After</option>\n <option value=\"before\">Before</option>\n </ng-container>\n <ng-template #textOptionsSecond>\n <option value=\"equal\">Equals</option>\n <!-- <option value=\"not_equal\">Not Equals</option> -->\n <option value=\"contain\">Contains</option>\n <option value=\"before\">Begins With</option>\n <option value=\"after\">Ends With</option>\n </ng-template>\n </select>\n </div>\n\n <div class=\"mb-2\">\n <!-- Second value input -->\n <input\n [type]=\"\n selectedColumnForFilter.type == 'string'\n ? 'text'\n : selectedColumnForFilter.type\n \"\n class=\"form-control form-control-sm\"\n placeholder=\"Enter second value\"\n [(ngModel)]=\"secondValue\"\n [min]=\"selectedColumnForFilter.type == 'number' ? 0 : null\"\n [class.number-input]=\"selectedColumnForFilter.type == 'number'\"\n (input)=\"selectedColumnForFilter.type == 'number' && $any($event.target).value < 0 ? $any($event.target).value = 0 : null\"\n (keydown)=\"selectedColumnForFilter.type == 'number' && $event.key === '-' ? $event.preventDefault() : null\"\n />\n </div>\n </div>\n </div>\n\n <div\n class=\"d-flex justify-content-center gap-2 px-2 border-top\"\n style=\"height: 38px\"\n >\n <button\n type=\"button\"\n style=\"height: 32px\"\n class=\"btn btn-outline-secondary btn-light border w-100 d-flex align-items-center justify-content-center mt-1 btn-light\"\n (click)=\"$event.stopPropagation(); resetTextFilterChanges()\"\n >\n <span>Cancel</span>\n </button>\n <button\n type=\"button\"\n style=\"height: 32px\"\n class=\"btn btn-primary w-100 d-flex align-items-center justify-content-center mt-1\"\n (click)=\"applyDropdownFilter()\"\n >\n <span style=\"margin-top: -2px\">Save</span>\n </button>\n </div>\n </div>\n</ng-template>\n\n<!-- Detail Filter Menu -->\n <div\n *ngIf=\"activeAccordionFilterMenu && detailFilterMenuPosition\"\n class=\"detail-filter-menu\"\n [style.backgroundColor]=\"dropdownsBackgroundColor\"\n [style.left.px]=\"detailFilterMenuPosition.x\"\n [style.top.px]=\"detailFilterMenuPosition.y\"\n (click)=\"$event.stopPropagation()\"\n >\n <div class=\"px-3 border-below py-1 pb-2 d-flex ps-1\">\n <span\n (click)=\"closeDetailFilterMenu()\"\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrow-left.svg'\"\n class=\"data-grid-svg-icon me-2 cursor-pointer\"\n ></span\n ><b>{{ activeDetailFilterCol?.header }}</b>\n </div>\n\n <!-- Text Filter -->\n <div *ngIf=\"detailFilterType === 'string'\" class=\"col-12 position-relative p-2 text-filter\">\n <div class=\"mb-2\">\n <select\n class=\"form-select form-select-sm custom-select\"\n [(ngModel)]=\"detailFilterCondition\"\n >\n <option value=\"contain\">Contains</option>\n <option value=\"equal\">Equals</option>\n <option value=\"before\">Begins With</option>\n <option value=\"after\">Ends With</option>\n </select>\n </div>\n <div class=\"mb-2\">\n <input\n class=\"form-control form-control-sm\"\n placeholder=\"Enter value\"\n [(ngModel)]=\"detailFilterValue\"\n (keydown.enter)=\"applyDetailFilter()\"\n />\n </div>\n </div>\n\n <!-- Date Filter -->\n <div *ngIf=\"detailFilterType === 'date'\" class=\"col-12 position-relative p-2 text-filter\">\n <div class=\"mb-2\">\n <select\n class=\"form-select form-select-sm custom-select\"\n [(ngModel)]=\"detailFilterCondition\"\n >\n <option value=\"equal\">Equal to</option>\n <option value=\"before\">Before</option>\n <option value=\"after\">After</option>\n </select>\n </div>\n <div class=\"mb-2\">\n <input\n type=\"date\"\n class=\"form-control form-control-sm\"\n placeholder=\"Select date\"\n [(ngModel)]=\"detailFilterDateValue\"\n (keydown.enter)=\"applyDetailFilter()\"\n />\n <small class=\"text-muted d-block mt-1\">{{ detailFilterDateValue | timezoneFormat:prefs:'date' }}</small>\n </div>\n </div>\n\n <!-- Time Filter -->\n <div *ngIf=\"detailFilterType === 'time'\" class=\"col-12 position-relative p-2 text-filter\">\n <div class=\"mb-2\">\n <select\n class=\"form-select form-select-sm custom-select\"\n [(ngModel)]=\"detailFilterCondition\"\n >\n <option value=\"equal\">Equal to</option>\n <option value=\"before\">Before</option>\n <option value=\"after\">After</option>\n </select>\n </div>\n <div class=\"mb-2\">\n <input\n type=\"time\"\n class=\"form-control form-control-sm\"\n placeholder=\"Select time\"\n [(ngModel)]=\"detailFilterTimeValue\"\n (keydown.enter)=\"applyDetailFilter()\"\n />\n </div>\n </div>\n\n <!-- Dropdown Filter -->\n <div *ngIf=\"detailFilterType === 'dropdown'\" class=\"col-12 position-relative p-2 text-filter\">\n <div class=\"mb-2\">\n <input\n type=\"text\"\n class=\"form-control form-control-sm\"\n placeholder=\"Search options...\"\n [(ngModel)]=\"detailFilterSearch\"\n (input)=\"filterDetailDropdownOptions()\"\n />\n </div>\n <div class=\"dropdown-options\" style=\"max-height: 150px; overflow-y: auto;\">\n <div\n *ngFor=\"let option of filteredDetailDropdownOptions; let i = index\"\n class=\"form-check mb-1 ms-1\"\n >\n <input\n class=\"form-check-input\"\n type=\"checkbox\"\n [id]=\"'detail-filter-option-' + i\"\n [checked]=\"detailSelectedFilterOptions.includes(option._id || option.id || option.value)\"\n (change)=\"toggleDetailFilterOption(option)\"\n />\n <label\n class=\"form-check-label\"\n [for]=\"'detail-filter-option-' + i\"\n >\n {{ option.value || option.name || option }}\n </label>\n </div>\n </div>\n </div>\n\n <!-- <div class=\"d-flex gap-2\">\n <button\n type=\"button\"\n class=\"btn btn-primary w-100 d-flex align-items-center justify-content-center mt-1\"\n (click)=\"applyDetailFilter()\"\n >\n <span>Apply</span>\n </button>\n <button\n type=\"button\"\n class=\"btn btn-danger w-100 d-flex align-items-center justify-content-center mt-1\"\n (click)=\"resetDetailFilter()\"\n >\n <span>Reset</span>\n </button>\n \n</div> -->\n\n <div class=\"d-flex gap-2 mt-2\">\n <div\n class=\"btn btn-sm btn-primary d-flex justify-content-center align-items-center w-100\"\n style=\"height: 22px\"\n (click)=\"applyDetailFilter()\"\n >\n Apply\n </div>\n <div\n class=\"btn btn-sm btn-secondary d-flex justify-content-center align-items-center w-100\"\n style=\"height: 22px\"\n (click)=\"resetDetailFilter()\"\n >\n Reset\n </div>\n </div>\n</div>\n\n<!-- Edit dropdown here -->\n<ng-template let-col>\n <div class=\"drop-down-edit\"></div>\n</ng-template>\n\n<ng-template\n #fullTextTemplate\n let-row=\"row\"\n let-col=\"col\"\n let-isArray=\"isArray\"\n>\n <div\n class=\"full-text-box\"\n (dblclick)=\"$event.stopPropagation(); $event.preventDefault();\"\n (click)=\"$event.stopPropagation(); $event.preventDefault()\"\n >\n <ng-container *ngIf=\"!isEditing(row, col)\">\n <div\n *ngIf=\"!isArray\"\n class=\"full-text-content\"\n (dblclick)=\"$event.stopPropagation(); $event.preventDefault(); enableEdit(row, col)\"\n (click)=\"$event.stopPropagation(); $event.preventDefault()\"\n >\n {{\n getNestedValue(row, col.field)?.value ||\n getNestedValue(row, col.field)?.name ||\n getNestedValue(row, col.field)\n }}\n </div>\n <div *ngIf=\"isArray\">\n <ul>\n <ng-container\n *ngFor=\"let item of getNestedValue(row, col.field); let i = index\"\n >\n <li *ngIf=\"i !== 0\">\n <ng-container>\n {{ item?.department_name || item?.roleName || \"-\" }}\n </ng-container>\n </li>\n </ng-container>\n </ul>\n </div>\n </ng-container>\n <ng-container *ngIf=\"isEditing(row, col)\">\n <textarea\n #textModel=\"ngModel\"\n rows=\"4\"\n #textAreadInput\n [(ngModel)]=\"row[col.field]\"\n name=\"{{ col.field }}\"\n required\n (blur)=\"disableEdit(row, col, textModel)\"\n (keydown.enter)=\"textAreadInput.blur()\"\n autofocus\n class=\"form-control\"\n [ngClass]=\"{\n 'is-invalid': textModel.invalid\n }\"\n (mousedown)=\"$event.stopPropagation()\"\n ></textarea>\n\n </ng-container>\n </div>\n</ng-template>\n\n<ng-template #defaultImagePlaceholder let-row=\"row\" let-col=\"col\">\n <span\n class=\"px-2 d-flex align-items-center w-100 cell-content image-placeholder cursor-pointer position-relative\"\n \n (click)=\"onEmployeeClick(row)\"\n >\n <!-- Blue dot for manual logs -->\n <span\n *ngIf=\"row?.manually_logs && row.manually_logs.length > 0\"\n class=\"manual-logs-indicator\"\n (mouseenter)=\"openManualLogsModal($event, row)\"\n (mouseleave)=\"closeManualLogsModal()\"\n ></span>\n <ng-container\n *ngIf=\"\n row?.User?.logo || row?.User?.profile_pictures?.length || row?.logo || row?.profile_pictures?.length || row?.assetImage || row?.invoice?.invoice_image;\n else placeholder\n \"\n >\n <span class=\"pic\">\n <img\n [width]=\"rowHeight - 12\"\n [height]=\"rowHeight - 12\"\n [src]=\"row?.User?.profile_pictures?.[4]?.path || row?.User?.logo || row?.profile_pictures?.[4]?.path || row?.logo || row?.assetImage || row?.invoice?.invoice_image\"\n alt=\"icon\"\n />\n </span>\n </ng-container>\n\n <ng-template #placeholder>\n <span\n [ngClass]=\"getDynamicClass(row?.User?.full_name || row?.full_name || row?.name)\"\n class=\"pic d-flex align-items-center rounded-circle\"\n [style.width.px]=\"rowHeight - 12\"\n [style.height.px]=\"rowHeight - 12\"\n [style.fontSize.px]=\"rowHeight / 3\"\n >\n {{ getInitials(row?.User?.full_name || row?.full_name) }}\n </span>\n </ng-template>\n </span>\n</ng-template>\n\n<!-- Cell Content Template for Card View -->\n<ng-template #cellContent let-row=\"row\" let-parentRow=\"parentRow\" let-col=\"col\">\n <ng-container [ngSwitch]=\"col.type\">\n <!-- String/Text -->\n <ng-container *ngSwitchCase=\"'string'\">\n {{ getNestedValue(row, col.field) || getNestedValue(parentRow, col.field) || '-' }}\n </ng-container>\n\n <!-- Number -->\n <ng-container *ngSwitchCase=\"'number'\">\n {{ getNestedValue(row, col.field) || getNestedValue(parentRow, col.field) || '-' }}\n </ng-container>\n\n <!-- Date -->\n <ng-container *ngSwitchCase=\"'date'\">\n {{ getNestedValue(row, col.field) || getNestedValue(parentRow, col.field) ? (getNestedValue(row, col.field) || getNestedValue(parentRow, col.field) | timezoneFormat:prefs:'date') : '-' }}\n </ng-container>\n\n <!-- Time -->\n <ng-container *ngSwitchCase=\"'time'\">\n {{ (getNestedValue(row, col.field) || getNestedValue(parentRow, col.field)) !== null && (getNestedValue(row, col.field) || getNestedValue(parentRow, col.field)) !== undefined ? ((getTimeValue(getNestedValue(row, col.field) || getNestedValue(parentRow, col.field)) | timezoneFormat:prefs:'time')) : '-' }}\n </ng-container>\n\n <!-- Boolean -->\n <ng-container *ngSwitchCase=\"'boolean'\">\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'\">\n {{ (getNestedValue(row, col.field) || getNestedValue(parentRow, col.field) === true || getNestedValue(row, col.field) || getNestedValue(parentRow, col.field) === 'true') ? 'Yes' : 'No' }}\n </span>\n </ng-container>\n\n <!-- <div *ngSwitchCase=\"'is_payroll_processed'\" class=\"d-flex justify-content-start flex-column pointer position-relative\" >\n <span class=\"popover__wrapper\" >none\n {{ row.is_payroll_processed ? 'Yes' : 'No' }}\n </span>\n </div> -->\n\n <!-- Status -->\n <ng-container *ngSwitchCase=\"'status'\">\n <span class=\"badge\" [class]=\"getStatusBadgeClass(getNestedValue(row, col.field) || getNestedValue(parentRow, col.field))\">\n {{ transformStatus(getNestedValue(row, col.field) || getNestedValue(parentRow, col.field)) || '-' }}\n </span>\n </ng-container>\n\n <!-- Array -->\n <ng-container *ngSwitchCase=\"'array'\">\n <ng-container *ngIf=\"isArray(getNestedValue(row, col.field) || getNestedValue(parentRow, col.field))\">\n <ng-container *ngIf=\"col.field === 'breaks' || col.header?.toLowerCase().includes('break')\">\n <app-badge-overflow\n [badges]=\"getBreakBadges(getNestedValue(row, col.field) || getNestedValue(parentRow, col.field) || [])\"\n [maxWidth]=\"col.width || 200\"\n (badgeMouseEnter)=\"showBreakTooltip($event.event, $event.badge.data)\"\n (badgeMouseLeave)=\"hideBreakTooltip()\"\n (overflowCountClick)=\"onBadgeOverflowCountClick(col)\">\n </app-badge-overflow>\n </ng-container>\n <ng-container *ngIf=\"!(col.field === 'breaks' || col.header?.toLowerCase().includes('break'))\">\n {{ (getNestedValue(row, col.field) || getNestedValue(parentRow, col.field) || []).length }} items\n </ng-container>\n </ng-container>\n <ng-container *ngIf=\"!isArray(getNestedValue(row, col.field) || getNestedValue(parentRow, col.field))\">\n {{ getNestedValue(row, col.field) || getNestedValue(parentRow, col.field) || '-' }}\n </ng-container>\n </ng-container>\n\n <!-- Default -->\n <ng-container *ngSwitchDefault>\n {{ getNestedValue(row, col.field) || getNestedValue(parentRow, col.field) || '-' }}\n </ng-container>\n \n </ng-container>\n</ng-template>\n\n<!-- Right Click Menue -->\n<div\n [class.invisible]=\"!positionedYet\"\n class=\"context-menu p-2\"\n *ngIf=\"actionHide && actions?.length\"\n [ngStyle]=\"{ 'top.px': yPos, 'left.px': xPos }\"\n [class.show]=\"isVisible\"\n appendTo=\"body\"\n>\n <ul>\n <li\n *ngFor=\"let action of actions\"\n class=\"rounded d-flex align-items-center\"\n (click)=\"onActionClick(action)\"\n >\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/' + action + '.svg'\"\n class=\"data-grid-svg-icon me-2\"\n ></span>\n <span class=\"text-capitalize fw-500\">{{ action }}</span>\n </li>\n </ul>\n</div>\n\n<!-- Details Toggle from bottom -->\n <div\n [style.bottom.px]=\"footerRowHeight + 50\"\n *ngIf=\"selectedRows.size > 0 && showTaskbar\"\n class=\"taskbar\"\n >\n <div class=\"selected-rows-action-bar\" [@slideUp]>\n <span class=\"selected-count\">\n {{ selectedRows.size }} selected of\n {{\n paginationConfig.totalResults ||\n config?.paginationParams?.totalItems\n }}\n Total\n </span>\n <div class=\"action-buttons\">\n <ng-container *ngFor=\"let action of computedTaskbarActions; let i = index\">\n <span\n class=\"action-btn verified btn {{ action }}\"\n (click)=\"action === 'Export' ? onExportClick() : action === 'Delete' ? onDeleteClick() : onVerifyClick(action)\"\n >{{ action }}</span\n >\n <span\n *ngIf=\"computedTaskbarActions.length > 1 && i !== computedTaskbarActions.length - 1\"\n class=\"separator\"\n >|</span\n >\n </ng-container>\n </div>\n </div>\n </div>\n\n<!-- Detail Row Choose Columns Modal -->\n<div *ngIf=\"showDetailColumnPanel\" class=\"custom-modal-overlay\" (click)=\"closeDetailColumnPanel()\">\n <div\n class=\"custom-modal-content\"\n [style.backgroundColor]=\"dropdownsBackgroundColor\"\n (click)=\"$event.stopPropagation()\"\n >\n <ng-container *ngTemplateOutlet=\"detailModalColumnPannel\"></ng-container>\n </div>\n</div>\n\n<!-- Paste Confirmation Modal -->\n<div *ngIf=\"showPasteConfirmationModal\" class=\"custom-modal-overlay\" (click)=\"cancelPaste()\">\n <div class=\"custom-modal-content\" [style.backgroundColor]=\"dropdownsBackgroundColor\" (click)=\"$event.stopPropagation()\">\n <div class=\"column-panel-header\">\n <div class=\"d-flex justify-content-between align-items-center px-2 ps-3 rounded-top-2 moda-header\" style=\"height: 48px;\">\n Confirm Paste Operation\n <span class=\"filter-icon-wrapper\" (click)=\"cancelPaste()\">\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/x.svg'\" class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"></span>\n </span>\n </div>\n <hr class=\"my-0\" />\n <div class=\"p-3\">\n <div class=\"mb-3\">\n <h6 class=\"mb-3\">You are about to paste the following data:</h6>\n <div class=\"border rounded p-3 bg-light\">\n <pre class=\"mb-0 text-dark small\">{{ pastePreviewData }}</pre>\n </div>\n </div>\n <div class=\"alert alert-warning\" role=\"alert\">\n <strong>Warning:</strong> This action will overwrite existing data in the selected cells. This cannot be undone.\n </div>\n <div class=\"d-flex justify-content-end gap-2 mt-4\">\n <button type=\"button\" class=\"btn btn-secondary\" (click)=\"cancelPaste()\">Cancel</button>\n <button type=\"button\" class=\"btn btn-primary\" (click)=\"confirmPaste()\">Confirm Paste</button>\n </div>\n </div>\n </div>\n </div>\n</div>\n\n<!-- Short Leave Tooltip Modal -->\n<div *ngIf=\"showShortLeaveTooltipModal\"\n class=\"custom-break-tooltips\"\n @tooltipAnimationBottom\n [style.--tooltip-x.px]=\"shortLeaveTooltipPosition.x\"\n [style.--tooltip-y.px]=\"shortLeaveTooltipPosition.y\"\n (mouseenter)=\"preventShortLeaveTooltipHide()\"\n (mouseleave)=\"hideShortLeaveTooltip()\">\n <div class=\"modal-body\">\n <div class=\"table-responsive\">\n <table class=\"table table-striped text-dark\">\n <thead>\n <tr>\n <th>Leave Type</th>\n <th>Start Time</th>\n <th>End Time</th>\n <th>Duration (min)</th>\n </tr>\n </thead>\n <tbody>\n <tr *ngFor=\"let item of currentShortLeaveData\">\n <td>{{ item.leave_type || 'N/A' }}</td>\n\n <!-- Start Time -->\n <td>\n {{\n item.star_time\n ? (getTimeValue(item.star_time) | timezoneFormat:prefs:'time')\n : 'N/A'\n }}\n </td>\n\n <!-- End Time -->\n <td>\n {{\n item.end_time\n ? (getTimeValue(item.end_time) | timezoneFormat:prefs:'time')\n : 'N/A'\n }}\n </td>\n\n <td>{{ item.minutes || 'N/A' }}</td>\n</tr>\n\n </tbody>\n </table>\n </div>\n </div>\n </div>\n\n<!-- Paste Confirmation Modal -->\n<div *ngIf=\"showPasteConfirmationModal\" class=\"custom-modal-overlay\" (click)=\"cancelPaste()\">\n <div class=\"custom-modal-content\" [style.backgroundColor]=\"dropdownsBackgroundColor\" (click)=\"$event.stopPropagation()\">\n <div class=\"column-panel-header\">\n <div class=\"d-flex justify-content-between align-items-center px-2 ps-3 rounded-top-2 moda-header\" style=\"height: 48px;\">\n <span class=\"fw-bold\">Confirm Paste</span>\n <span class=\"filter-icon-wrapper\" (click)=\"cancelPaste()\">\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/x.svg'\" class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"></span>\n </span>\n </div>\n <hr class=\"my-0\" />\n <div class=\"p-3\">\n <div class=\"mb-3\">\n <p class=\"mb-2\">Are you sure you want to paste the following data?</p>\n <div class=\"border rounded p-2 bg-light\">\n <small class=\"text-muted\">{{ pastePreviewData }}</small>\n </div>\n </div>\n <div class=\"d-flex gap-2 justify-content-end\">\n <button type=\"button\" class=\"btn btn-secondary\" (click)=\"cancelPaste()\">Cancel</button>\n <button type=\"button\" class=\"btn btn-primary\" (click)=\"confirmPaste()\">Confirm Paste</button>\n </div>\n </div>\n </div>\n </div>\n</div>\n\n<!-- Paste Confirmation Modal -->\n<div *ngIf=\"showPasteConfirmationModal\" class=\"custom-modal-overlay\" (click)=\"cancelPaste()\">\n <div class=\"custom-modal-content\" [style.backgroundColor]=\"dropdownsBackgroundColor\" (click)=\"$event.stopPropagation()\">\n <div class=\"modal-header d-flex justify-content-between align-items-center p-3\">\n <h5 class=\"modal-title mb-0\">Confirm Paste</h5>\n <button type=\"button\" class=\"btn-close\" (click)=\"cancelPaste()\"></button>\n </div>\n <div class=\"modal-body p-3\">\n <p class=\"mb-3\">Are you sure you want to paste the clipboard data into the selected cells?</p>\n <div class=\"alert alert-info\" *ngIf=\"pastePreviewData\">\n <strong>Paste Preview:</strong>\n <pre class=\"mt-2\">{{ pastePreviewData }}</pre>\n </div>\n </div>\n <div class=\"modal-footer p-3\">\n <button type=\"button\" class=\"btn btn-secondary\" (click)=\"cancelPaste()\">Cancel</button>\n <button type=\"button\" class=\"btn btn-primary\" (click)=\"confirmPaste()\">Paste</button>\n </div>\n </div>\n</div>\n\n<!-- Tooltip for accordion manual logs -->\n<!-- Tooltip for accordion manual logs -->\n<div *ngIf=\"showManualLogsTooltipModal\" class=\"custom-break-tooltips\"\n [style.--tooltip-x.px]=\"manualLogsTooltipPosition.x\"\n [style.--tooltip-y.px]=\"manualLogsTooltipPosition.y\"\n \n (mouseenter)=\"preventManualLogsTooltipHide()\"\n (mouseleave)=\"hideManualLogsTooltip()\">\n\n <div class=\"modal-body\">\n <div class=\"table-responsive\">\n <table class=\"table table-striped text-dark\">\n <thead>\n <tr>\n <th>Name</th>\n <th>Date/Time</th>\n <th>Previous</th>\n <th>Updated</th>\n <th>Status</th>\n <th>Remarks</th>\n </tr>\n </thead>\n <tbody>\n <ng-container *ngFor=\"let item of selectedManualLogs; let i = index\">\n <tr>\n <td>{{ item?.updated_by?.full_name || selectedManualLogsRow?.User?.full_name }}</td>\n <td>{{ item?.log_date && item.log_date !== '--' ? (item.log_date | timezoneFormat:prefs:'datetime') : (selectedManualLogsRow?.attendanceDate && selectedManualLogsRow?.attendanceDate !== '--' ? (selectedManualLogsRow?.attendanceDate | timezoneFormat:prefs:'datetime') : '-') }}</td>\n <td>\n <ng-container [ngSwitch]=\"isDate(item?.log_details?.previous_state)\">\n \n <!-- If it is a date -->\n <span *ngSwitchCase=\"true\">\n {{ formatLogState(item?.log_details?.previous_state) | timezoneFormat:prefs:'time' }}\n </span>\n\n <!-- If it is NOT a date -->\n <span *ngSwitchDefault>\n {{ item?.log_details?.previous_state || '-' }}\n </span>\n\n </ng-container>\n</td>\n\n\n<td>\n <ng-container [ngSwitch]=\"isDate(item?.log_details?.updated_state)\">\n \n <!-- If it is a date -->\n <span *ngSwitchCase=\"true\">\n {{ formatLogState(item?.log_details?.updated_state) | timezoneFormat:prefs:'time' }}\n </span>\n\n <!-- If it is NOT a date -->\n <span *ngSwitchDefault>\n {{ item?.log_details?.updated_state || '-' }}\n </span>\n\n </ng-container>\n</td>\n\n <td>{{ item?.log_details?.status ? transformStatus(item.log_details.status) : (item.log_details?.status || '-') }}</td>\n <td>{{ item?.log_details?.remarks || item?.remarks || selectedManualLogsRow?.message || '-' }}</td>\n </tr>\n </ng-container>\n\n <!-- Fallback for empty manual logs -->\n <tr *ngIf=\"!selectedManualLogs || selectedManualLogs.length === 0\">\n <td colspan=\"6\" class=\"text-center\">No manual logs available</td>\n </tr>\n </tbody>\n </table>\n </div>\n </div>\n </div>\n<!-- </div> -->\n\n<ng-template #detailModalColumnPannel>\n <div class=\"column-panel-header detail-column-modal\">\n <div\n class=\"d-flex justify-content-between align-items-center px-2 ps-3 rounded-top-2 moda-header\"\n [style.height.px]=\"48\"\n >\n Choose Detail Columns\n <span class=\"filter-icon-wrapper\" (click)=\"closeDetailColumnPanel()\">\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/x.svg'\"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n </span>\n </div>\n <hr class=\"my-0\" />\n <div>\n <div class=\"d-flex align-items-center px-2 pe-3\" [style.height.px]=\"48\">\n <input\n type=\"checkbox\"\n class=\"form-check-input me-2\"\n [checked]=\"allDetailColumnsSelected()\"\n (change)=\"toggleAllDetailColumnsVisibility()\"\n />\n <input\n type=\"text\"\n class=\"form-control form-control-sm\"\n placeholder=\"Search detail columns...\"\n [(ngModel)]=\"choseColumnsSearch\"\n />\n </div>\n <hr class=\"mt-0 mb-1\" />\n <div class=\"px-2 overlay-scrollable\">\n <ng-container\n *ngFor=\"\n let col of (currentDetailRowForColumnSelection?.details?.columns || [])\n | filter : choseColumnsSearch : 'header';\n trackBy: trackByField\n \"\n >\n <div class=\"d-flex align-items-center mb-2\">\n <input\n type=\"checkbox\"\n class=\"form-check-input me-2\"\n [checked]=\"col.is_visible !== false\"\n (change)=\"toggleDetailColumnVisibility(col, !col.is_visible)\"\n [id]=\"'detail_col_' + col.field\"\n />\n <label\n class=\"d-flex align-items-center mb-0 w-100\"\n [for]=\"'detail_col_' + col.field\"\n style=\"cursor: pointer\"\n >\n <span class=\"text-truncate\">{{ col.header }}</span>\n </label>\n </div>\n </ng-container>\n </div>\n </div>\n <!-- <div class=\"px-3 py-2 border-top d-flex justify-content-end\">\n <button class=\"btn btn-sm btn-link\" (click)=\"resetDetailColumnsInModal()\">Reset</button>\n </div> -->\n </div>\n</ng-template>\n\n\n\n\n\n\n\n\n\n\n\n", styles: ["@charset \"UTF-8\";@keyframes fadeInUp{0%{opacity:0;transform:translateY(8px)}to{opacity:1;transform:translateY(0)}}@keyframes fadeInScale{0%{opacity:0;transform:scale(.95)}to{opacity:1;transform:scale(1)}}@keyframes slideInRight{0%{opacity:0;transform:translate(16px)}to{opacity:1;transform:translate(0)}}@keyframes pulse{0%{transform:scale(1)}50%{transform:scale(1.02)}to{transform:scale(1)}}@keyframes shimmer{0%{background-position:-200px 0}to{background-position:calc(200px + 100%) 0}}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.loading-overlay{animation:fadeInScale .25s cubic-bezier(.4,0,.2,1);transform:translateZ(0)}.loading-overlay .spinner-border{animation:spin 1s linear infinite}.data-grid-table-wrapper{height:100%;width:100%;border:1px solid #d9d9db;border-radius:12px;box-shadow:none!important;position:relative;animation:fadeInScale .35s cubic-bezier(.4,0,.2,1);transform:translateZ(0)}.data-grid-table-wrapper[data-theme=white]{border-color:#d9d9db;background-color:#f6f8ff;color:#000}.data-grid-table-wrapper[data-theme=white] *,.data-grid-table-wrapper[data-theme=white] *:before,.data-grid-table-wrapper[data-theme=white] *:after{color:#000!important}.data-grid-table-wrapper[data-theme=white] ::selection{background-color:#007bff!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=white] ::-moz-selection{background-color:#007bff!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=white] .data-grid-header-wrapper{background-color:#f8f9fa;color:#000!important}.data-grid-table-wrapper[data-theme=white] .data-grid-body-wrapper{background-color:#f6f8ff;box-shadow:none!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .data-grid-row{border-bottom-color:#d9d9db;box-shadow:none!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .data-grid-row:nth-child(2n){background-color:#f8f9fa!important}.data-grid-table-wrapper[data-theme=white] .data-grid-row:nth-child(odd){background-color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=white] .data-grid-row:hover{background-color:#007bff1a!important}.data-grid-table-wrapper[data-theme=white] .selected-cell,.data-grid-table-wrapper[data-theme=white] .row-selected{background-color:#e3f2fd!important}.data-grid-table-wrapper[data-theme=white] .cell,.data-grid-table-wrapper[data-theme=white] .header-cell,.data-grid-table-wrapper[data-theme=white] .data-grid-row,.data-grid-table-wrapper[data-theme=white] .data-grid-header,.data-grid-table-wrapper[data-theme=white] .cell-content,.data-grid-table-wrapper[data-theme=white] .full-text-content,.data-grid-table-wrapper[data-theme=white] .circle-value,.data-grid-table-wrapper[data-theme=white] .pic,.data-grid-table-wrapper[data-theme=white] .image-placeholder,.data-grid-table-wrapper[data-theme=white] .s-no,.data-grid-table-wrapper[data-theme=white] .fw-500{color:#000!important}.data-grid-table-wrapper[data-theme=white] span,.data-grid-table-wrapper[data-theme=white] div,.data-grid-table-wrapper[data-theme=white] p,.data-grid-table-wrapper[data-theme=white] td,.data-grid-table-wrapper[data-theme=white] th,.data-grid-table-wrapper[data-theme=white] label,.data-grid-table-wrapper[data-theme=white] a:not(.text-primary){color:#000!important}.data-grid-table-wrapper[data-theme=white] svg,.data-grid-table-wrapper[data-theme=white] svg path,.data-grid-table-wrapper[data-theme=white] svg circle,.data-grid-table-wrapper[data-theme=white] svg rect,.data-grid-table-wrapper[data-theme=white] svg polygon{color:#000!important;fill:#000!important;stroke:#000!important}.data-grid-table-wrapper[data-theme=white] .data-grid-svg-icon{color:#000!important}.data-grid-table-wrapper[data-theme=white] .data-grid-svg-icon path{stroke:#000!important;fill:#000!important}.data-grid-table-wrapper[data-theme=white] .badge.badge-danger{background-color:#ea5353!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=white] .badge.badge-success{background-color:#84ca81!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=white] .badge.badge-warning{background-color:#fff3dc!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .badge.badge-info{background-color:#e8fbfd!important;color:#00bad1!important}.data-grid-table-wrapper[data-theme=white] .context-menu{background:#f6f8ff;border-color:#d9d9db;color:#000!important}.data-grid-table-wrapper[data-theme=white] .context-menu li{color:#000!important}.data-grid-table-wrapper[data-theme=white] .context-menu li:hover{background-color:#007bff1a!important}.data-grid-table-wrapper[data-theme=white] .custom-tooltip,.data-grid-table-wrapper[data-theme=white] .popover__content,.data-grid-table-wrapper[data-theme=white] .custom-break-tooltip{background:#f6f8ff!important;border-color:#d9d9db!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .actions-dropdown,.data-grid-table-wrapper[data-theme=white] .custom-menu{background-color:#f6f8ff!important;border-color:#d9d9db!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .actions-dropdown .dropdown-item,.data-grid-table-wrapper[data-theme=white] .custom-menu .dropdown-item{color:#000!important}.data-grid-table-wrapper[data-theme=white] .actions-dropdown .dropdown-item:hover,.data-grid-table-wrapper[data-theme=white] .custom-menu .dropdown-item:hover{background-color:#007bff1a!important}.data-grid-table-wrapper[data-theme=white] .taskbar .selected-rows-action-bar{background-color:#343a40!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=white] .taskbar .selected-rows-action-bar .action-btn{color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=white] .manual-logs-modal .modal-header{background:linear-gradient(135deg,#343a40,#495057)!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=white] .manual-logs-modal .modal-header .modal-title{color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=white] .manual-logs-modal .modal-body{background-color:#f6f8ff!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .manual-logs-modal .modal-body .table{color:#000!important}.data-grid-table-wrapper[data-theme=white] .manual-logs-modal .modal-body .table thead th{background:linear-gradient(135deg,#f8f9fa,#e9ecef)!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .manual-logs-modal .modal-body .table tbody tr{color:#000!important}.data-grid-table-wrapper[data-theme=white] .manual-logs-modal .modal-body .table tbody tr:nth-child(2n){background-color:#f8f9fa!important}.data-grid-table-wrapper[data-theme=white] .manual-logs-modal .modal-body .table tbody tr:hover{background-color:#007bff1a!important}.data-grid-table-wrapper[data-theme=white] .manual-logs-modal .modal-body .table tbody tr td{color:#000!important;border-color:#d9d9db!important}.data-grid-table-wrapper[data-theme=white] .form-control,.data-grid-table-wrapper[data-theme=white] .form-select{background-color:#f6f8ff!important;border-color:#d9d9db!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .form-control::placeholder,.data-grid-table-wrapper[data-theme=white] .form-select::placeholder{color:#6c757d!important}.data-grid-table-wrapper[data-theme=white] .form-control option,.data-grid-table-wrapper[data-theme=white] .form-select option{background-color:#f6f8ff!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .filter-serach-inpt{background-color:#f6f8ff!important;border-color:#d9d9db!important}.data-grid-table-wrapper[data-theme=white] .filter-serach-inpt input{background-color:#f6f8ff!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .active-filters{background-color:#f8f9fa!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .custom-modal-overlay .custom-modal-content{background-color:#f6f8ff!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .circle-value{background-color:#f8f9fa!important;border-color:#d9d9db!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .pagination-container,.data-grid-table-wrapper[data-theme=white] .page-size,.data-grid-table-wrapper[data-theme=white] .page-info,.data-grid-table-wrapper[data-theme=white] .page-buttons{color:#000!important}.data-grid-table-wrapper[data-theme=white] .pagination-container select,.data-grid-table-wrapper[data-theme=white] .pagination-container button,.data-grid-table-wrapper[data-theme=white] .pagination-container span,.data-grid-table-wrapper[data-theme=white] .page-size select,.data-grid-table-wrapper[data-theme=white] .page-size button,.data-grid-table-wrapper[data-theme=white] .page-size span,.data-grid-table-wrapper[data-theme=white] .page-info select,.data-grid-table-wrapper[data-theme=white] .page-info button,.data-grid-table-wrapper[data-theme=white] .page-info span,.data-grid-table-wrapper[data-theme=white] .page-buttons select,.data-grid-table-wrapper[data-theme=white] .page-buttons button,.data-grid-table-wrapper[data-theme=white] .page-buttons span{background-color:#f6f8ff!important;border-color:#d9d9db!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .pagination-container button.active,.data-grid-table-wrapper[data-theme=white] .page-size button.active,.data-grid-table-wrapper[data-theme=white] .page-info button.active,.data-grid-table-wrapper[data-theme=white] .page-buttons button.active{background-color:#e3f2fd!important}.data-grid-table-wrapper[data-theme=white] .footer-row{background-color:#f8f9fa!important;border-top-color:#d9d9db!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] ::-webkit-scrollbar{background-color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=white] ::-webkit-scrollbar-thumb{background-color:#d9d9db!important}.data-grid-table-wrapper[data-theme=white] ::-webkit-scrollbar-thumb:hover{background-color:#adb5bd!important}.data-grid-table-wrapper[data-theme=white] ::-webkit-scrollbar-track{background-color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker{background-color:#f6f8ff!important;color:#000!important;border-color:#d9d9db!important}.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker .bs-datepicker-head{background:linear-gradient(135deg,#343a40,#495057)!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker .bs-datepicker-body{background-color:#f6f8ff!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker table td,.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker table th{color:#000!important}.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker table td.is-other-month,.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker table th.is-other-month{color:#6c757d!important}.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker table td.active,.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker table th.active{background-color:#e3f2fd!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker table td span.in-range,.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker table th span.in-range{background-color:#e3f2fd!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker table td:hover:not(.active),.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker table th:hover:not(.active){background-color:#007bff1a!important}.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker .bs-datepicker-buttons{background-color:#f8f9fa!important;border-top-color:#d9d9db!important}.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker .bs-datepicker-buttons .btn-primary{background:linear-gradient(135deg,#007bff,#0056b3)!important;color:#f6f8ff!important;border-color:#007bff!important}.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker .bs-datepicker-buttons .btn-secondary{background-color:#f6f8ff!important;color:#000!important;border-color:#d9d9db!important}.data-grid-table-wrapper[data-theme=white] button,.data-grid-table-wrapper[data-theme=white] .btn,.data-grid-table-wrapper[data-theme=white] .button{background-color:#f6f8ff!important;border-color:#d9d9db!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] button:hover,.data-grid-table-wrapper[data-theme=white] .btn:hover,.data-grid-table-wrapper[data-theme=white] .button:hover{background-color:#007bff1a!important}.data-grid-table-wrapper[data-theme=white] button.btn-primary,.data-grid-table-wrapper[data-theme=white] .btn.btn-primary,.data-grid-table-wrapper[data-theme=white] .button.btn-primary{background-color:#007bff!important;border-color:#007bff!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=white] button.btn-outline-primary,.data-grid-table-wrapper[data-theme=white] .btn.btn-outline-primary,.data-grid-table-wrapper[data-theme=white] .button.btn-outline-primary{border-color:#007bff!important;color:#007bff!important;background-color:transparent!important}.data-grid-table-wrapper[data-theme=white] a:not(.text-primary){color:#007bff!important}.data-grid-table-wrapper[data-theme=white] a:not(.text-primary):hover{color:#0056b3!important}.data-grid-table-wrapper[data-theme=white] .text-primary{color:#007bff!important}.data-grid-table-wrapper[data-theme=white] .text-danger{color:#dc3545!important}.data-grid-table-wrapper[data-theme=white] .text-success{color:#28a745!important}.data-grid-table-wrapper[data-theme=white] .text-warning{color:#ffc107!important}.data-grid-table-wrapper[data-theme=white] .text-info{color:#17a2b8!important}.data-grid-table-wrapper[data-theme=white] .text-muted,.data-grid-table-wrapper[data-theme=white] .muted-text{color:#6c757d!important}.data-grid-table-wrapper[data-theme=white] .border,.data-grid-table-wrapper[data-theme=white] .border-top,.data-grid-table-wrapper[data-theme=white] .border-bottom,.data-grid-table-wrapper[data-theme=white] .border-left,.data-grid-table-wrapper[data-theme=white] .border-right,.data-grid-table-wrapper[data-theme=white] .border-below,.data-grid-table-wrapper[data-theme=white] .border-start,.data-grid-table-wrapper[data-theme=white] .border-end{border-color:#d9d9db!important}.data-grid-table-wrapper[data-theme=white] .accordion-details,.data-grid-table-wrapper[data-theme=white] .nested-table,.data-grid-table-wrapper[data-theme=white] .detail-virtual-scroll{background-color:#f6f8ff!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .accordion-details td,.data-grid-table-wrapper[data-theme=white] .accordion-details th,.data-grid-table-wrapper[data-theme=white] .nested-table td,.data-grid-table-wrapper[data-theme=white] .nested-table th,.data-grid-table-wrapper[data-theme=white] .detail-virtual-scroll td,.data-grid-table-wrapper[data-theme=white] .detail-virtual-scroll th{color:#000!important;border-color:#d9d9db!important}.data-grid-table-wrapper[data-theme=blue]{border-color:#b3d9ff;background-color:#f0f8ff;color:#1e3a5f}.data-grid-table-wrapper[data-theme=blue] *,.data-grid-table-wrapper[data-theme=blue] *:before,.data-grid-table-wrapper[data-theme=blue] *:after{color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] ::selection{background-color:#007cf5!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=blue] ::-moz-selection{background-color:#007cf5!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=blue] .data-grid-header-wrapper{background-color:#e6f3ff;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .data-grid-body-wrapper{background-color:#f0f8ff;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .data-grid-row{border-bottom-color:#b3d9ff;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .data-grid-row:nth-child(2n){background-color:#f0f8ff!important}.data-grid-table-wrapper[data-theme=blue] .data-grid-row:nth-child(odd){background-color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=blue] .data-grid-row:hover{background-color:#1e3a5f1a!important}.data-grid-table-wrapper[data-theme=blue] .selected-cell,.data-grid-table-wrapper[data-theme=blue] .row-selected{background-color:#cce5ff!important}.data-grid-table-wrapper[data-theme=blue] .cell,.data-grid-table-wrapper[data-theme=blue] .header-cell,.data-grid-table-wrapper[data-theme=blue] .data-grid-row,.data-grid-table-wrapper[data-theme=blue] .data-grid-header,.data-grid-table-wrapper[data-theme=blue] .cell-content,.data-grid-table-wrapper[data-theme=blue] .full-text-content,.data-grid-table-wrapper[data-theme=blue] .circle-value,.data-grid-table-wrapper[data-theme=blue] .pic,.data-grid-table-wrapper[data-theme=blue] .image-placeholder,.data-grid-table-wrapper[data-theme=blue] .s-no,.data-grid-table-wrapper[data-theme=blue] .fw-500{color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] span,.data-grid-table-wrapper[data-theme=blue] div,.data-grid-table-wrapper[data-theme=blue] p,.data-grid-table-wrapper[data-theme=blue] td,.data-grid-table-wrapper[data-theme=blue] th,.data-grid-table-wrapper[data-theme=blue] label,.data-grid-table-wrapper[data-theme=blue] a:not(.text-primary){color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] svg,.data-grid-table-wrapper[data-theme=blue] svg path,.data-grid-table-wrapper[data-theme=blue] svg circle,.data-grid-table-wrapper[data-theme=blue] svg rect,.data-grid-table-wrapper[data-theme=blue] svg polygon{color:#1e3a5f!important;fill:#1e3a5f!important;stroke:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .data-grid-svg-icon{color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .data-grid-svg-icon path{stroke:#1e3a5f!important;fill:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .badge.badge-danger{background-color:#ff8787!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=blue] .badge.badge-success{background-color:#69db7c!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=blue] .badge.badge-warning{background-color:#ffd43b!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .badge.badge-info{background-color:#74c0fc!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=blue] .context-menu{background:#e6f3ff;border-color:#b3d9ff;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .context-menu li{color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .context-menu li:hover{background-color:#1e3a5f1a!important}.data-grid-table-wrapper[data-theme=blue] .custom-tooltip,.data-grid-table-wrapper[data-theme=blue] .popover__content,.data-grid-table-wrapper[data-theme=blue] .custom-break-tooltip{background:#e6f3ff!important;border-color:#b3d9ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .actions-dropdown,.data-grid-table-wrapper[data-theme=blue] .custom-menu{background-color:#e6f3ff!important;border-color:#b3d9ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .actions-dropdown .dropdown-item,.data-grid-table-wrapper[data-theme=blue] .custom-menu .dropdown-item{color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .actions-dropdown .dropdown-item:hover,.data-grid-table-wrapper[data-theme=blue] .custom-menu .dropdown-item:hover{background-color:#1e3a5f1a!important}.data-grid-table-wrapper[data-theme=blue] .taskbar .selected-rows-action-bar{background-color:#1e3a5f!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=blue] .taskbar .selected-rows-action-bar .action-btn{color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=blue] .manual-logs-modal .modal-header{background:linear-gradient(135deg,#1e3a5f,#2d4a6b)!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=blue] .manual-logs-modal .modal-header .modal-title{color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=blue] .manual-logs-modal .modal-body{background-color:#f0f8ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .manual-logs-modal .modal-body .table{color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .manual-logs-modal .modal-body .table thead th{background:linear-gradient(135deg,#e6f3ff,#cce5ff)!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .manual-logs-modal .modal-body .table tbody tr{color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .manual-logs-modal .modal-body .table tbody tr:nth-child(2n){background-color:#f0f8ff!important}.data-grid-table-wrapper[data-theme=blue] .manual-logs-modal .modal-body .table tbody tr:hover{background-color:#1e3a5f1a!important}.data-grid-table-wrapper[data-theme=blue] .manual-logs-modal .modal-body .table tbody tr td{color:#1e3a5f!important;border-color:#b3d9ff!important}.data-grid-table-wrapper[data-theme=blue] .form-control,.data-grid-table-wrapper[data-theme=blue] .form-select{background-color:#f6f8ff!important;border-color:#b3d9ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .form-control::placeholder,.data-grid-table-wrapper[data-theme=blue] .form-select::placeholder{color:#888!important}.data-grid-table-wrapper[data-theme=blue] .form-control option,.data-grid-table-wrapper[data-theme=blue] .form-select option{background-color:#f6f8ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .filter-serach-inpt{background-color:#f6f8ff!important;border-color:#b3d9ff!important}.data-grid-table-wrapper[data-theme=blue] .filter-serach-inpt input{background-color:#f6f8ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .active-filters,.data-grid-table-wrapper[data-theme=blue] .custom-modal-overlay .custom-modal-content{background-color:#e6f3ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .circle-value{background-color:#f6f8ff!important;border-color:#b3d9ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .pagination-container,.data-grid-table-wrapper[data-theme=blue] .page-size,.data-grid-table-wrapper[data-theme=blue] .page-info,.data-grid-table-wrapper[data-theme=blue] .page-buttons{color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .pagination-container select,.data-grid-table-wrapper[data-theme=blue] .pagination-container button,.data-grid-table-wrapper[data-theme=blue] .pagination-container span,.data-grid-table-wrapper[data-theme=blue] .page-size select,.data-grid-table-wrapper[data-theme=blue] .page-size button,.data-grid-table-wrapper[data-theme=blue] .page-size span,.data-grid-table-wrapper[data-theme=blue] .page-info select,.data-grid-table-wrapper[data-theme=blue] .page-info button,.data-grid-table-wrapper[data-theme=blue] .page-info span,.data-grid-table-wrapper[data-theme=blue] .page-buttons select,.data-grid-table-wrapper[data-theme=blue] .page-buttons button,.data-grid-table-wrapper[data-theme=blue] .page-buttons span{background-color:#f6f8ff!important;border-color:#b3d9ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .pagination-container button.active,.data-grid-table-wrapper[data-theme=blue] .page-size button.active,.data-grid-table-wrapper[data-theme=blue] .page-info button.active,.data-grid-table-wrapper[data-theme=blue] .page-buttons button.active{background-color:#cce5ff!important}.data-grid-table-wrapper[data-theme=blue] .footer-row{background-color:#e6f3ff!important;border-top-color:#b3d9ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] ::-webkit-scrollbar{background-color:#f0f8ff!important}.data-grid-table-wrapper[data-theme=blue] ::-webkit-scrollbar-thumb{background-color:#b3d9ff!important}.data-grid-table-wrapper[data-theme=blue] ::-webkit-scrollbar-thumb:hover{background-color:#74c0fc!important}.data-grid-table-wrapper[data-theme=blue] ::-webkit-scrollbar-track{background-color:#f0f8ff!important}.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker{background-color:#e6f3ff!important;color:#1e3a5f!important;border-color:#b3d9ff!important}.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker .bs-datepicker-head{background:linear-gradient(135deg,#1e3a5f,#2d4a6b)!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker .bs-datepicker-body{background-color:#f0f8ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker table td,.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker table th{color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker table td.is-other-month,.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker table th.is-other-month{color:#888!important}.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker table td.active,.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker table th.active{background-color:#cce5ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker table td span.in-range,.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker table th span.in-range{background-color:#cce5ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker table td:hover:not(.active),.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker table th:hover:not(.active){background-color:#1e3a5f1a!important}.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker .bs-datepicker-buttons{background-color:#f6f8ff!important;border-top-color:#b3d9ff!important}.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker .bs-datepicker-buttons .btn-primary{background:linear-gradient(135deg,#1e3a5f,#2d4a6b)!important;color:#f6f8ff!important;border-color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker .bs-datepicker-buttons .btn-secondary{background-color:#f0f8ff!important;color:#1e3a5f!important;border-color:#b3d9ff!important}.data-grid-table-wrapper[data-theme=blue] button,.data-grid-table-wrapper[data-theme=blue] .btn,.data-grid-table-wrapper[data-theme=blue] .button{background-color:#f6f8ff!important;border-color:#b3d9ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] button:hover,.data-grid-table-wrapper[data-theme=blue] .btn:hover,.data-grid-table-wrapper[data-theme=blue] .button:hover{background-color:#1e3a5f1a!important}.data-grid-table-wrapper[data-theme=blue] button.btn-primary,.data-grid-table-wrapper[data-theme=blue] .btn.btn-primary,.data-grid-table-wrapper[data-theme=blue] .button.btn-primary{background-color:#007cf5!important;border-color:#007cf5!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=blue] button.btn-outline-primary,.data-grid-table-wrapper[data-theme=blue] .btn.btn-outline-primary,.data-grid-table-wrapper[data-theme=blue] .button.btn-outline-primary{border-color:#007cf5!important;color:#007cf5!important;background-color:transparent!important}.data-grid-table-wrapper[data-theme=blue] a:not(.text-primary){color:#007cf5!important}.data-grid-table-wrapper[data-theme=blue] a:not(.text-primary):hover{color:#0056b3!important}.data-grid-table-wrapper[data-theme=blue] .text-primary{color:#007cf5!important}.data-grid-table-wrapper[data-theme=blue] .text-danger{color:#dc3545!important}.data-grid-table-wrapper[data-theme=blue] .text-success{color:#28a745!important}.data-grid-table-wrapper[data-theme=blue] .text-warning{color:#ffc107!important}.data-grid-table-wrapper[data-theme=blue] .text-info{color:#17a2b8!important}.data-grid-table-wrapper[data-theme=blue] .text-muted,.data-grid-table-wrapper[data-theme=blue] .muted-text{color:#6c757d!important}.data-grid-table-wrapper[data-theme=blue] .border,.data-grid-table-wrapper[data-theme=blue] .border-top,.data-grid-table-wrapper[data-theme=blue] .border-bottom,.data-grid-table-wrapper[data-theme=blue] .border-left,.data-grid-table-wrapper[data-theme=blue] .border-right,.data-grid-table-wrapper[data-theme=blue] .border-below,.data-grid-table-wrapper[data-theme=blue] .border-start,.data-grid-table-wrapper[data-theme=blue] .border-end{border-color:#b3d9ff!important}.data-grid-table-wrapper[data-theme=blue] .accordion-details,.data-grid-table-wrapper[data-theme=blue] .nested-table,.data-grid-table-wrapper[data-theme=blue] .detail-virtual-scroll{background-color:#f0f8ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .accordion-details td,.data-grid-table-wrapper[data-theme=blue] .accordion-details th,.data-grid-table-wrapper[data-theme=blue] .nested-table td,.data-grid-table-wrapper[data-theme=blue] .nested-table th,.data-grid-table-wrapper[data-theme=blue] .detail-virtual-scroll td,.data-grid-table-wrapper[data-theme=blue] .detail-virtual-scroll th{color:#1e3a5f!important;border-color:#b3d9ff!important}.data-grid-header{position:sticky;top:0}.data-grid-header{display:flex}.header-row{display:grid;width:100%}.header-cell{display:flex;align-items:center;position:relative;width:100%;padding:8px 0 8px 8px;font-weight:700;border-bottom:1px solid #d9d9db;white-space:nowrap;min-width:30px}.header-cell .filter-applied-on-text{color:#5d9cff!important}.filter-cell{padding:4px!important;display:flex;align-items:center;gap:8px;width:100%}.filter-cell .filter-applied{background-color:#bddef9}.border-right{border-right:1px solid #d9d9db}.merged-grid{display:grid;grid-auto-rows:40px;border-bottom:1px solid #ccc}.span-two-rows{grid-row:span 2;display:flex;justify-content:space-between;align-items:center}.group-header{display:flex;justify-content:space-between;position:relative}.group-header-content{position:sticky;left:10px;overflow:hidden;text-overflow:ellipsis}.resize-handle{width:6px;cursor:e-resize;right:0;top:0;color:#00000026;position:relative}.resize-handle.resizing{z-index:9999!important;opacity:1!important;background-color:#007bff1a;border-right:2px solid #007bff;box-shadow:0 0 8px #007bff4d;position:relative!important;pointer-events:none!important}.group-header .resize-handle{top:25%}.h-100{height:100%}.data-grid-body{position:relative;overflow-y:auto;overflow-x:hidden;box-shadow:none!important}.cell{padding:8px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;height:100%;display:flex;align-items:center}.data-grid-row{display:flex;min-width:max-content;align-items:center;border-bottom:1px solid #d9d9db;transition:all .25s cubic-bezier(.4,0,.2,1);transform:translateZ(0);will-change:transform,box-shadow;backface-visibility:hidden}.data-grid-row:hover{transform:translate(2px);box-shadow:2px 0 8px #007bff1a}.hovered-row{background-color:#ccc}.checkbox-row{border-bottom:#d9d9db}.w-100{width:100%}.data-grid-header-wrapper{display:flex;position:relative;overflow:hidden;-webkit-user-select:none;user-select:none}.data-grid-header{display:flex;position:relative;z-index:1}.left-pinned,.right-pinned{position:sticky;top:0;background:#f6f8ff}.right-pinned-header{position:absolute;right:0;border-left:1px solid #d9d9db;z-index:unset}.left-pinned{left:0;border-right:1px solid #d9d9db}.right-pinned{right:0;border-left:1px solid #d9d9db}.center-scrollable{z-index:unset!important;overflow-x:auto;overflow-y:visible;white-space:nowrap;scrollbar-width:none;-ms-overflow-style:none}.center-scrollable::-webkit-scrollbar{display:none}.data-grid-body-wrapper{display:flex}.data-grid-body-wrapper{scrollbar-width:none;-ms-overflow-style:none}.data-grid-body-wrapper::-webkit-scrollbar{display:none}.center-scrollable-body{overflow-x:auto;scrollbar-width:none;-ms-overflow-style:none}.center-scrollable-body::-webkit-scrollbar{display:none}.left-pinned-body,.right-pinned-body{position:sticky;top:0;z-index:unset;background:#f6f8ff;scrollbar-width:none;-ms-overflow-style:none}.left-pinned-body::-webkit-scrollbar,.right-pinned-body::-webkit-scrollbar{display:none}.left-pinned-body{left:0}.border-end{border-right:1px solid #d9d9db!important}.right-pinned-body{right:-15px;border-left:1px solid #d9d9db}.fake-scroll-bar{height:14px;overflow:scroll;margin-bottom:10px}.text-ellipsis{overflow:hidden;text-overflow:ellipsis}.select-all-checkbox-cell{width:50px;display:flex;justify-content:center;align-items:center;height:100%;border-right:1px solid #d9d9db}.select-all-checkbox-cell input{width:16px;height:16px}.border-below{border-bottom:1px solid #d9d9db!important}.three-dots{width:22px;height:22px;display:flex;justify-content:center;align-items:center;border-radius:6px;margin-right:8px;cursor:pointer;transition:all .25s cubic-bezier(.4,0,.2,1);transform:translateZ(0);position:relative}.three-dots:before{content:\"\";position:absolute;top:50%;left:50%;width:0;height:0;background:#007bff1a;border-radius:50%;transform:translate(-50%,-50%);transition:width .25s,height .25s}.three-dots:hover{background-color:#007bff1a;transform:rotate(90deg)}.three-dots:hover:before{width:28px;height:28px}.three-dots:active{transform:rotate(90deg) scale(.95);transition-duration:.15s}.filter-icon-wrapper{min-height:22px;max-height:22px;min-width:22px;max-width:22px;display:flex;justify-content:center;align-items:center;border-radius:6px;cursor:pointer;transition:all .25s cubic-bezier(.4,0,.2,1);transform:translateZ(0);position:relative}.filter-icon-wrapper:before{content:\"\";position:absolute;top:50%;left:50%;width:0;height:0;background:#007bff1a;border-radius:50%;transform:translate(-50%,-50%);transition:width .25s,height .25s}.filter-icon-wrapper:hover{background-color:#007bff1a;transform:scale(1.05)}.filter-icon-wrapper:hover:before{width:32px;height:32px}.filter-icon-wrapper:active{transform:scale(.95);transition-duration:.15s}.column-panel-item{font-size:.875rem;color:#333;transition:all .25s cubic-bezier(.4,0,.2,1);transform:translateZ(0)}.column-panel-item:hover{background-color:#007bff0d;color:#007bff;transform:translate(2px)}.column-menu,.filter-menu{box-shadow:0 0 16px #00000026;border-radius:4px}.column-menu{background:#fff;width:100%;width:240px;border:1px solid #ddd;box-shadow:0 0 16px #00000026;border:1px solid #d9d9db;padding:4px 0;font-size:14px;position:fixed}.column-menu-item{padding:8px 12px;cursor:pointer;display:flex;align-items:center;transition:background-color .2s ease}.column-menu-item:hover{background-color:#deebf7}.pin-parent{position:relative;width:100%!important}.column-submenu{position:absolute;top:0;left:100%;background:#fff;border:1px solid #ddd;width:130px;box-shadow:0 0 16px #00000026;border:1px solid #d9d9db;display:none;padding:4px 0;z-index:10;border-radius:4px}.pin-parent:hover .column-submenu{display:block}.filter-menu-container{position:fixed;width:210px;background:#fff;border:1px solid #ddd;border-radius:4px;padding:12px;box-shadow:0 0 16px #00000026;border:1px solid #d9d9db;z-index:1000;font-size:14px}.filter-menu-header{font-weight:600;margin-bottom:10px}.filter-dropdown-section{max-height:350px;overflow-y:auto}.dropdown-options{overflow-y:auto;scrollbar-width:thin;height:100%}.filter-text-section select,.filter-text-section input{width:100%}.filter-radio-inputs{width:14px!important;height:14px!important}.right-menu{border-left:1px solid #d9d9db;font-size:14px}.border-start{border-left:1px solid #d9d9db!important}.column-panel-item{font-size:.875rem;color:#333}.toggle-icon{cursor:pointer;transition:all .25s cubic-bezier(.4,0,.2,1);transform:translateZ(0);border-radius:4px;padding:2px}.toggle-icon:hover{background-color:#007bff1a;transform:scale(1.1)}.toggle-icon:active{transform:scale(.95)}.grab-icon{cursor:grab;color:#6c757d;transition:all .25s cubic-bezier(.4,0,.2,1);transform:translateZ(0)}.grab-icon:hover{color:#007bff;transform:scale(1.1)}.grab-icon:active{cursor:grabbing;transform:scale(.95)}.text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:100%}.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:-3px}.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:20px;left:50%;transform:translate(-50%);display:flex;justify-content:center;z-index:1000;padding:0;width:auto;max-width:90vw}.taskbar .action-btn{transition:all .3s ease;font-weight:500;font-size:14px;padding:8px 16px;border-radius:6px;cursor:pointer;display:inline-flex;align-items:center;gap:6px}.taskbar .action-btn:hover{transform:translateY(-1px);box-shadow:0 4px 12px #00000026}.taskbar .action-btn:active{transform:translateY(0)}.taskbar .delete{background-color:#dc3545;color:#fff;border:1px solid #dc3545}.taskbar .delete:hover{background-color:#c82333;border-color:#bd2130}.taskbar .export{background-color:#28a745;color:#fff;border:1px solid #28a745}.taskbar .export:hover{background-color:#218838;border-color:#1e7e34}.taskbar .verify{background-color:#007bff;color:#fff;border:1px solid #007bff}.taskbar .verify:hover{background-color:#0056b3;border-color:#004085}.selected-count,.action-btn,.dropdown-content a{font-weight:500;font-size:14px}.selected-rows-action-bar{background:linear-gradient(135deg,#667eea,#764ba2);color:#fff;padding:12px 24px;border-radius:12px;display:flex;align-items:center;justify-content:space-between;gap:16px;box-shadow:0 8px 32px #0003;backdrop-filter:blur(10px);border:1px solid rgba(255,255,255,.1);min-width:300px}.selected-rows-action-bar .selected-count{font-weight:600;font-size:14px;flex:1;text-align:center}.selected-rows-action-bar .action-buttons{display:flex;align-items:center;gap:8px}.selected-rows-action-bar .action-buttons .separator{color:#ffffff80;font-weight:700;font-size:16px}.selected-rows-action-bar .action-buttons .action-btn{background:#fff3;color:#fff!important;border:1px solid rgba(255,255,255,.3);padding:8px 16px;border-radius:8px;font-weight:500;font-size:13px;transition:all .3s ease;cursor:pointer;display:inline-flex;align-items:center;gap:6px}.selected-rows-action-bar .action-buttons .action-btn:hover{background:#ffffff4d;transform:translateY(-1px);box-shadow:0 4px 12px #0003}.selected-rows-action-bar .action-buttons .action-btn:active{transform:translateY(0)}.selected-rows-action-bar .action-buttons .action-btn.Export{background:#28a745cc;border-color:#28a745e6}.selected-rows-action-bar .action-buttons .action-btn.Export:hover{background:#218838e6}.selected-rows-action-bar .action-buttons .action-btn.Delete{background:#dc3545cc;border-color:#dc3545e6}.selected-rows-action-bar .action-buttons .action-btn.Delete:hover{background:#c82333e6}.selected-rows-action-bar .action-buttons .action-btn.Verify{background:#007bffcc;border-color:#007bffe6}.selected-rows-action-bar .action-buttons .action-btn.Verify:hover{background:#0056b3e6}.selected-rows-action-bar .btn:active,.selected-rows-action-bar .btn:focus{outline:0!important;border:0!important;border-color:transparent!important}@media (max-width: 768px){.taskbar{bottom:10px;max-width:95vw}.taskbar .selected-rows-action-bar{padding:8px 16px;min-width:280px;flex-direction:column;gap:12px}.taskbar .selected-rows-action-bar .selected-count{font-size:13px;text-align:center}.taskbar .selected-rows-action-bar .action-buttons{justify-content:center;flex-wrap:wrap;gap:6px}.taskbar .selected-rows-action-bar .action-buttons .action-btn{padding:6px 12px;font-size:12px;min-width:80px}.taskbar .selected-rows-action-bar .action-buttons .separator{display:none}}@media (max-width: 480px){.taskbar .selected-rows-action-bar{min-width:250px;padding:6px 12px}.taskbar .selected-rows-action-bar .action-buttons .action-btn{padding:5px 10px;font-size:11px;min-width:70px}}.cell .dropdown-menu,.cell .form-select,.cell input{color:#000!important}.cell input::placeholder{color:#727272!important}.cell .badge{font-size:14px;padding:6px 12px;border-radius:6px;text-align:center;height:auto;min-height:28px;display:inline-flex;align-items:center;justify-content:center;font-weight:500;line-height:1.5;white-space:nowrap;transition:all .2s cubic-bezier(.4,0,.2,1);will-change:transform,opacity;backface-visibility:hidden;transform:translateZ(0)}.cell .badge-danger{color:#ea5353!important;border:1px solid #ea5353!important;background-color:#ff00000d!important}.cell .badge-success{background-color:#84ca8130!important;border:1.5px solid rgb(70,227,114)!important;color:#46e372!important}.cell .badge-warning{background-color:#fff3dc!important;color:orange!important;border:1px solid #ffa000!important}.cell .badge-info{color:#00bad1;background-color:#e8fbfd;border:1px solid #00bad1}.header-tag ::ng-deep svg path{stroke:#727272!important}.cross-secondary:hover ::ng-deep svg path{stroke:#000!important}.disable-sorting{pointer-events:none;opacity:.5}.rows-grouping-top-container ::ng-deep .cdk-drag-placeholder{background-color:transparent!important}input.is-invalid:focus{border:2.5px solid red!important;outline:none}.table-cell input.is-invalid:focus{border:2.5px solid red!important;outline-color:red!important;outline:none!important;box-shadow:none!important}.active-for-editing:has(input.is-invalid:focus){outline:none!important;box-shadow:none!important;border:0!important}.selected-cell,.row-selected{background-color:#c2e0fe;animation:pulse .25s cubic-bezier(.4,0,.2,1);transform:translateZ(0);position:relative}.selected-cell:before,.row-selected:before{content:\"\";position:absolute;inset:0;background:linear-gradient(45deg,transparent,rgba(255,255,255,.1),transparent);animation:shimmer 1.5s ease-in-out infinite}.first-row-selected{border-top:2px solid #2196f3!important}.last-row-selected{border-bottom:2px solid #2196f3!important}.left-selection-border{border-left:2px solid #2196f3!important}.s-no{font-size:14px;font-weight:500}.top-border{border-top:2px solid #2196f3!important}.bottom-border{border-bottom:2px solid #2196f3!important}.left-border{border-left:2px solid #2196f3!important}.right-border{border-right:2px solid #2196f3!important}.top-left-corner{border-top-left-radius:4px}.top-right-corner{border-top-right-radius:4px}.bottom-left-corner{border-bottom-left-radius:4px}.bottom-right-corner{border-bottom-right-radius:4px}.flash-bg{animation:flashAnim 1000s ease}@keyframes flashAnim{0%{background-color:#48a2fc}50%{background-color:#c2e0fe}to{background-color:#c2e0fe}}.cut-flash-bg{animation:cut-flash .8s ease}@keyframes cut-flash{0%{background-color:#f006}50%{background-color:#f00c}to{background-color:#c2e0fe}}.accordion-details.dragging th,.accordion-details.dragging td{pointer-events:none}.accordion-details.dragging th{z-index:2}.drag-handle{cursor:move;opacity:.5;transition:opacity .2s}.drag-handle:hover{opacity:1}.detail-edit-input{z-index:100;position:relative}.detail-filter-menu{position:fixed;width:210px;background:#fff;border:1px solid #ddd;border-radius:4px;padding:12px;box-shadow:0 0 16px #00000026;border:1px solid #d9d9db;z-index:1000;font-size:14px}.detail-filter-menu-positioned{width:280px;right:unset;max-width:230px;z-index:99;left:375px;top:225px}.resize-handle{cursor:col-resize;opacity:.5;width:8px;display:flex;align-items:center;justify-content:center}.resize-handle:hover{opacity:1;background-color:#f0f0f0}.detail-header-row{transition:all .3s ease}.detail-header-row.dragging{opacity:.7;transform:translate(5px)}.detail-cell{transition:background-color .2s ease,transform .3s ease}.detail-cell.active-drag{background-color:#f0f0f0;transform:scale(1.02)}.break-color-paid{background-color:#4caf50!important}.break-color-unpaid{background-color:#f44336!important}.break-color-lunch{background-color:#2196f3!important}.break-color-default{background-color:#f44336!important}.circle-value{display:flex;align-items:center;justify-content:center;width:32px;height:32px;border-radius:50%;background-color:#f8f9fa;border:2px solid #d9d9db;font-size:12px;font-weight:600;color:#fff;text-align:center;line-height:1;vertical-align:middle;box-sizing:border-box;white-space:nowrap;overflow:hidden;cursor:pointer;transition:all .3s cubic-bezier(.4,0,.2,1);transform:translateZ(0);will-change:transform,box-shadow,background-color;backface-visibility:hidden}.circle-value:hover{background-color:#e9ecef;box-shadow:0 6px 16px #007bff40;transform:scale(1.15) translateY(-2px);border-color:#007bff}.circle-value:active{transform:scale(1.08) translateY(-1px);transition-duration:.15s}.break-tooltip-wrapper{position:relative;display:inline-block}.break-tooltip-wrapper:hover .custom-break-tooltip{opacity:1;visibility:visible}.circle-value[title]{position:relative}.circle-value[title]:after{content:attr(title);position:absolute;bottom:100%;left:50%;transform:translate(-50%);background-color:#333;color:#fff;padding:4px 8px;border-radius:4px;font-size:12px;white-space:nowrap;opacity:0;transition:opacity .2s ease;pointer-events:none}.circle-value[title]:hover:after{opacity:1}.custom-tooltip{position:fixed;background:#fff;border:1px solid #dcdcdc;border-radius:8px;padding:12px 16px;max-width:300px;z-index:9999;font-size:13px;animation:fadeIn .2s ease-in-out}.tooltip-title{font-size:14px;font-weight:600;margin-bottom:8px;color:#333}.tooltip-list{margin:0;padding-left:16px;list-style-type:disc}.tooltip-list li{margin-bottom:4px;line-height:1.4;color:#444}.tooltip-total{font-weight:700;margin-top:8px;color:#222}@keyframes fadeIn{0%{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:translateY(0)}}.restriction-indicator{position:absolute;display:inline-block;padding-right:10px}.restriction-indicator:after{content:\"\";position:absolute;top:0;right:0;width:8px;height:8px;background-color:#0d6efd;border-radius:50%}.manual-logs-indicator{position:absolute;top:2px;right:2px;width:8px;height:8px;background-color:#0d6efd;border-radius:50%;border:1px solid #fff;box-shadow:0 0 2px #0d6efd80;cursor:pointer;z-index:10;transition:all .2s ease}.manual-logs-indicator:hover{transform:scale(1.2);box-shadow:0 0 4px #0d6efdcc}.manual-logs-table-tooltip{background:#fff!important;border:1px solid #dcdcdc!important;border-radius:8px!important;box-shadow:0 4px 12px #00000026!important;font-size:13px!important;animation:fadeIn .2s ease-in-out!important;display:block!important;visibility:visible!important;opacity:1!important}.manual-logs-table-tooltip .popover__content,.manual-logs-table-tooltip .modal-area{padding:0!important;display:block!important;visibility:visible!important}.manual-logs-table-tooltip .table-responsive{max-height:300px;overflow-y:auto;display:block!important;visibility:visible!important}.manual-logs-table-tooltip table{margin:0!important;border-collapse:collapse!important;display:table!important;visibility:visible!important}.manual-logs-table-tooltip table th,.manual-logs-table-tooltip table td{padding:6px 8px!important;border:1px solid #f1f1f1!important;text-align:center!important;vertical-align:middle!important;display:table-cell!important;visibility:visible!important}.manual-logs-table-tooltip table th{background-color:#f8f9fa!important;font-weight:600!important;color:#495057!important;position:sticky!important;top:0!important;z-index:1!important}.manual-logs-table-tooltip table tbody tr:nth-child(2n){background-color:#f8f9fa!important}.manual-logs-table-tooltip table tbody tr:hover{background-color:#e3f2fd!important}.manual-logs-table-tooltip table .text-primary{color:#0d6efd!important;text-decoration:none!important}.manual-logs-table-tooltip table .capitalize{text-transform:capitalize!important}@keyframes fadeIn{0%{opacity:0;transform:translate(-50%) translateY(-110%)}to{opacity:1;transform:translate(-50%) translateY(-100%)}}.detail-column-menu{max-height:250px;overflow-y:auto;overflow-x:auto;white-space:nowrap;padding:8px 0;border-radius:6px;scrollbar-width:thin}.detail-column-menu-wrapper{z-index:1001;position:absolute}.accordion-details{position:relative;z-index:999}.detail-column-menu .column-menu-item{padding:8px 12px;cursor:pointer;display:flex;align-items:center;transition:all .25s cubic-bezier(.4,0,.2,1);font-size:14px;transform:translateZ(0);border-radius:4px}.detail-column-menu .column-menu-item:hover{background-color:#007bff1a;transform:translate(2px);color:#007bff}.detail-column-menu .column-menu-item:active{transform:translate(0) scale(.98)}.detail-column-menu .column-menu-item:hover{background-color:#deebf7}.nested-table th[pinned=left],.nested-table td[pinned=left]{border-right:2px solid #ccc;border-left:none;border-bottom:2px solid #ccc}.nested-table th[pinned=right],.nested-table td[pinned=right]{border-left:2px solid #ccc;border-right:none;border-bottom:2px solid #ccc}.data-grid-accordion-table.show-borders{border:1px solid #d9d9db;border-collapse:collapse}.data-grid-accordion-table.show-borders th,.data-grid-accordion-table.show-borders td{border:1px solid #d9d9db}.data-grid-accordion-table.show-shadow tbody tr:hover{box-shadow:0 4px 8px #0000001a;transition:box-shadow .3s ease}.data-grid-accordion-table tbody tr:hover{background-color:#deebf7;transition:background-color .3s ease}.data-grid-pin-icon{display:inline-block;vertical-align:middle;margin-left:4px}.accordion-details.center-section{position:relative;display:flex}.detail-side-menu-wrapper{display:flex;flex-shrink:0;position:sticky;right:0;top:0;height:100%;max-height:275px}.detail-side-menu-content{width:250px;box-shadow:-2px 0 5px #0000001a;display:flex;flex-direction:column}.side-menu-scrollable{flex:1;overflow-y:auto;padding:0 12px 12px;max-height:calc(100% - 40px)}.filter-input-container{padding:8px;background:#f9f9f9;border-radius:4px}.toggle-icon.rotate{transform:rotate(90deg)}.resize-handle{top:0;right:3px;bottom:0;width:8px;cursor:col-resize;z-index:10;display:flex;align-items:center;justify-content:center;opacity:1.4;transition:all .25s cubic-bezier(.4,0,.2,1);background:transparent;transform:translateZ(0)}.resize-handle:hover{opacity:1;background:#007bff1a}.resize-handle:active{opacity:1;background:#007bff33;transform:scaleX(1.2)}th:hover .resize-handle{opacity:40}.resize-handles{top:0;right:3px;bottom:0;width:8px;cursor:col-resize;z-index:10;display:flex;align-items:center;justify-content:center;position:absolute;opacity:1.4;transition:all .25s cubic-bezier(.4,0,.2,1);background:transparent;transform:translateZ(0)}.resize-handles:hover{opacity:1;background:#007bff1a}.resize-handles:active{opacity:1;background:#007bff33;transform:scaleX(1.2)}.resize-handles.resizing{z-index:9999!important;opacity:1!important;background-color:#007bff1a;border-right:2px solid #007bff;box-shadow:0 0 8px #007bff4d;pointer-events:none!important}th:hover .resize-handles{opacity:40}.resizing-highlight{background-color:#007bff1a!important}.accordion-details-wrapper{display:flex;width:100%;max-height:350px;overflow:hidden}.accordion-details.show-borders,.accordion-details-wrapper.show-borders{border:1px solid #d9d9db;border-radius:4px}.accordion-left-section,.accordion-right-section,.detail-side-menu-wrapper{flex-shrink:0;max-height:350px;overflow:hidden;height:fit-content}.accordion-center-section{flex:1;min-width:0;overflow:auto;max-height:350px}.detail-virtual-scroll{display:block;width:100%;height:250px;overflow:auto}.detail-virtual-scroll table{table-layout:fixed;width:100%}.detail-virtual-scroll td,.detail-virtual-scroll th{overflow:hidden!important;text-overflow:ellipsis!important;white-space:nowrap!important}.nested-table th{overflow:hidden!important}.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:10;background-color:#f6f8ff!important}.data-pin-body-wrapper{-webkit-user-select:none;user-select:none;display:flex}.data-pin-body-wrapper{scrollbar-width:none;-ms-overflow-style:none}.data-pin-body-wrapper::-webkit-scrollbar{display:none}.detail-virtual-scroll .selected-cell,.accordion-left-section .selected-cell,.accordion-right-section .selected-cell{background-color:#cce5ff!important}.custom-datepicker-buttons button{height:28px;padding:0 10px;font-size:12px}.manual-logs-modal{max-width:800px;max-height:80vh;overflow:hidden;border-radius:12px;box-shadow:0 10px 40px #0003}.manual-logs-modal .modal-header{background:linear-gradient(135deg,#4361ee,#3a0ca3);color:#fff;padding:16px 20px;border-bottom:none;border-radius:12px 12px 0 0}.manual-logs-modal .modal-header .modal-title{font-weight:600;font-size:18px;margin:0}.manual-logs-modal .modal-header .btn-close{background:#fff3;border:none;border-radius:50%;width:32px;height:32px;display:flex;align-items:center;justify-content:center;color:#fff;opacity:.8;transition:all .25s cubic-bezier(.4,0,.2,1);transform:translateZ(0)}.manual-logs-modal .modal-header .btn-close:hover{background:#ffffff4d;opacity:1;transform:scale(1.1) rotate(90deg)}.manual-logs-modal .modal-header .btn-close:active{transform:scale(.95) rotate(90deg)}.manual-logs-modal .modal-body{padding:20px;max-height:calc(80vh - 80px);overflow-y:auto}.manual-logs-modal .modal-body .table-responsive{border-radius:8px;overflow:hidden;box-shadow:0 2px 8px #0000001a}.manual-logs-modal .modal-body .table-responsive .table{margin-bottom:0;font-size:14px}.manual-logs-modal .modal-body .table-responsive .table thead th{background:linear-gradient(135deg,#f8f9fa,#e9ecef);border-bottom:2px solid #dee2e6;font-weight:600;color:#495057;padding:12px 16px;position:sticky;top:0;z-index:10}.manual-logs-modal .modal-body .table-responsive .table tbody tr{transition:background-color .2s ease}.manual-logs-modal .modal-body .table-responsive .table tbody tr:hover{background-color:#f8f9fa}.manual-logs-modal .modal-body .table-responsive .table tbody tr:nth-child(2n){background-color:#f8f9fa}.manual-logs-modal .modal-body .table-responsive .table tbody tr td{padding:10px 16px;vertical-align:middle;border-color:#e9ecef}.manual-logs-modal .modal-body .table-responsive .table tbody tr td .text-primary{color:#0d6efd!important;font-weight:500;text-decoration:none}.manual-logs-modal .modal-body .table-responsive .table tbody tr td .text-primary:hover{text-decoration:underline}.manual-logs-modal .modal-body .table-responsive .table tbody tr td .capitalize{text-transform:capitalize}::ng-deep bs-daterangepicker-container .bs-datepicker{border-radius:4px!important;box-shadow:0 2px 8px #0000001a!important;font-size:14px!important;display:flex!important;align-items:flex-start!important;left:142px!important}::ng-deep .bs-datepicker-head{background:#f8f9fa!important;color:#495057!important;border-bottom:1px solid #dee2e6!important;padding:8px 12px!important;border-radius:4px 4px 0 0!important}::ng-deep .bs-datepicker-head .current{font-weight:600!important;color:#495057!important;font-size:13px!important}::ng-deep .bs-datepicker-head .previous,::ng-deep .bs-datepicker-head .next{background:#fff!important;color:#495057!important;border:1px solid #dee2e6!important;width:24px!important;border-radius:4px!important;font-size:12px!important}::ng-deep .bs-datepicker-head .previous:hover,::ng-deep .bs-datepicker-head .next:hover{background:#e9ecef!important}::ng-deep .bs-datepicker .bs-datepicker-buttons{padding:8px!important;background:#f8f9fa!important;border-top:1px solid #dee2e6!important;border-radius:0 0 4px 4px!important}::ng-deep .bs-datepicker .bs-datepicker-buttons .btn-primary{background:#007bff!important;color:#fff!important;border:1px solid #007bff!important;font-weight:500!important;padding:4px 8px!important;border-radius:4px!important;font-size:12px!important}::ng-deep .bs-datepicker .bs-datepicker-buttons .btn-primary:hover{background:#0056b3!important;border-color:#0056b3!important}::ng-deep .bs-datepicker .bs-datepicker-buttons .btn-secondary{background:#fff!important;color:#495057!important;border:1px solid #dee2e6!important;font-weight:500!important;padding:4px 8px!important;border-radius:4px!important;font-size:12px!important}::ng-deep .bs-datepicker .bs-datepicker-buttons .btn-secondary:hover{background:#e9ecef!important}::ng-deep .bs-datepicker-body{background:#fff!important;padding:6px!important}::ng-deep .bs-datepicker-body table{background:#fff!important;border-collapse:separate!important;border-spacing:1px!important}::ng-deep .bs-datepicker-body table th,::ng-deep .bs-datepicker-body table td{border:1px solid #dee2e6!important;border-radius:4px!important;text-align:center!important;font-weight:500!important;color:#495057!important;cursor:pointer!important;transition:all .2s ease!important;font-size:12px!important;width:32px!important;height:32px!important;line-height:24px!important}::ng-deep .bs-datepicker-body table th{background:#f8f9fa!important;font-weight:600!important;font-size:11px!important;padding:2px!important;height:24px!important;line-height:20px!important}::ng-deep .bs-datepicker-body table td:hover:not(.disabled){background:#e9ecef!important}::ng-deep .bs-datepicker-body table td.active{background:#007bff!important;color:#fff!important;border-color:#007bff!important}::ng-deep .bs-datepicker-body table td.is-other-month{color:#6c757d!important;background:#f8f9fa!important}::ng-deep .bs-datepicker-body table td.disabled{color:#adb5bd!important;background:#e9ecef!important;cursor:not-allowed!important}::ng-deep .bs-datepicker-custom-range{background:transparent!important;border-right:1px solid #dee2e6!important;padding:6px!important;width:130px!important;margin-right:8px!important;align-self:flex-start!important}::ng-deep .bs-datepicker-predefined-btns{display:flex!important;flex-direction:column!important;gap:2px!important}::ng-deep .bs-datepicker-predefined-btns button{background:transparent!important;color:#495057!important;border:1px solid #dee2e6!important;border-radius:4px!important;padding:4px 6px!important;font-size:11px!important;font-weight:500!important;text-align:left!important;cursor:pointer!important;transition:all .2s ease!important;width:100%!important;margin:0!important}::ng-deep .bs-datepicker-predefined-btns button:hover{background:#e9ecef!important;border-color:#adb5bd!important}::ng-deep .bs-datepicker-predefined-btns button:active,::ng-deep .bs-datepicker-predefined-btns button:focus{outline:none!important;box-shadow:0 0 0 2px #007bff40!important;background:#007bff!important;color:#fff!important;border-color:#007bff!important}.manual-logs-modal-overlay{position:fixed;top:0;left:0;width:100%;height:100%;background-color:#00000080;display:flex;justify-content:center;align-items:center;z-index:9999}.manual-logs-modal-content{background:#fff;border-radius:8px;max-width:800px;max-height:80vh;overflow:auto;box-shadow:0 4px 8px #0000001a}.popover__wrapper{position:relative;display:inline-block}.popover__content{position:absolute;bottom:100%;left:50%;transform:translate(-50%);background:#fff;border:1px solid #ccc;border-radius:8px;padding:12px;box-shadow:0 4px 12px #00000026;z-index:1000;opacity:0;visibility:hidden;transition:opacity .3s ease,visibility .3s ease;min-width:250px;max-width:400px;font-size:14px}.popover__wrapper:hover .popover__content{opacity:1;visibility:visible}.popover__content .modal-area{padding:0}.popover__content h4{margin:0 0 8px;font-size:16px;font-weight:600;color:#333}.popover__content .break-status{font-size:12px;color:#666;margin-bottom:8px}.popover__content .d-flex{gap:12px}.popover__content p{margin:0 0 4px;font-size:12px;color:#666}.popover__content h5{margin:0;font-size:14px;font-weight:500;color:#333}.popover__content .break-footer{border-top:1px solid #eee;margin-top:8px;padding-top:8px}.popover__content .break-footer p{font-size:12px;color:#666;margin:0}.custom-break-tooltip{position:fixed;z-index:1000;background:#fff;border:1px solid #ddd;border-radius:8px;box-shadow:0 4px 12px #00000026;padding:12px;font-size:13px;max-width:220px;pointer-events:none;top:0;left:0;transform:translate(var(--tooltip-x, 0px),var(--tooltip-y, 0px))}.custom-break-tooltips{position:fixed;z-index:1000;background:#fff;border:1px solid #ddd;border-radius:8px;box-shadow:0 4px 12px #00000026;padding:8px;font-size:12px;max-width:500px;max-height:300px;top:0;left:0;transform:translate(var(--tooltip-x, 0px),var(--tooltip-y, 0px))}.custom-break-tooltips .modal-body{max-height:250px!important;overflow-y:auto;padding:0}.custom-break-tooltips .table-responsive{max-height:250px}.custom-break-tooltips thead th{position:sticky;top:0;background:#f8f9fa;z-index:10;border-bottom:2px solid #dee2e6;font-size:11px;padding:4px 8px;font-weight:600}.custom-break-tooltips table{font-size:11px;margin-bottom:0}.custom-break-tooltips table td{padding:4px 8px;white-space:nowrap}.custom-break-tooltips .table-striped tbody tr:nth-of-type(odd){background-color:#00000005}.popver_content_progress_bar{visibility:hidden}.badge-overflow-container{display:flex;flex-wrap:nowrap;gap:4px;align-items:center;min-width:0;overflow:hidden;width:100%}.badge-overflow-container .badge{flex-shrink:0;white-space:nowrap;font-size:12px;padding:4px 8px;border-radius:50%;display:inline-flex;align-items:center;justify-content:center;font-weight:600;line-height:1;text-transform:uppercase;letter-spacing:.5px;transition:all .3s cubic-bezier(.4,0,.2,1);border:2px solid transparent;width:32px;height:32px;box-sizing:border-box;cursor:pointer;transform:translateZ(0);will-change:transform,box-shadow,background-color;backface-visibility:hidden}.badge-overflow-container .badge:hover{transform:scale(1.15) translateY(-2px);box-shadow:0 6px 16px #007bff40}.badge-overflow-container .badge:active{transform:scale(1.08) translateY(-1px);transition-duration:.15s}.badge-overflow-container .badge-overflow-count{background-color:#6c757d!important;color:#fff!important;cursor:pointer;border:2px solid #6c757d!important;flex-shrink:0;border-radius:50%;width:32px;height:32px;display:inline-flex;align-items:center;justify-content:center;font-weight:600;transition:all .3s cubic-bezier(.4,0,.2,1);transform:translateZ(0);will-change:transform,box-shadow,background-color;backface-visibility:hidden}.badge-overflow-container .badge-overflow-count:hover{background-color:#5a6268!important;border-color:#5a6268!important;transform:scale(1.15) translateY(-2px);box-shadow:0 6px 16px #007bff40}.badge-overflow-container .badge-overflow-count:active{transform:scale(1.08) translateY(-1px);transition-duration:.15s}.timeline-view-container{padding:1rem;background-color:#f8f9fa}.timeline-view-container .timeline-header{margin-bottom:2rem}.timeline-view-container .timeline-header h5{color:#495057;font-weight:600;margin-bottom:1rem}.timeline-view-container .timeline-header .timeline-hours{display:flex;justify-content:space-between;padding:.5rem 0;border-bottom:1px solid #dee2e6;margin-bottom:1rem;background:#fff;border-radius:8px;padding:1rem}.timeline-view-container .timeline-header .timeline-hours .timeline-hour{font-size:.8rem;color:#6c757d;font-weight:500;min-width:40px;text-align:center;padding:.5rem;border-radius:4px;background:#f8f9fa}.timeline-view-container .timeline-body .timeline-row{background:#fff;border:1px solid #dee2e6;border-radius:8px;margin-bottom:1rem;padding:1rem;box-shadow:0 2px 4px #0000001a;transition:box-shadow .2s ease}.timeline-view-container .timeline-body .timeline-row:hover{box-shadow:0 4px 8px #00000026}.timeline-view-container .timeline-body .timeline-row .timeline-employee{margin-bottom:1rem}.timeline-view-container .timeline-body .timeline-row .timeline-employee .employee-name{font-weight:600;color:#495057;font-size:1.1rem}.timeline-view-container .timeline-body .timeline-row .timeline-track{position:relative;height:40px;background:#f8f9fa;border-radius:4px;border:1px solid #e9ecef}.timeline-view-container .timeline-body .timeline-row .timeline-track .work-duration-bar{position:absolute;height:100%;background:linear-gradient(135deg,#28a745,#20c997);border-radius:4px;box-shadow:0 2px 4px #28a7454d;transition:opacity .2s ease}.timeline-view-container .timeline-body .timeline-row .timeline-track .work-duration-bar:hover{opacity:.8}.timeline-view-container .timeline-body .timeline-row .timeline-track .break-bar{position:absolute;height:100%;border-radius:4px;box-shadow:0 2px 4px #0003;border:1px solid rgba(255,255,255,.5);transition:opacity .2s ease}.timeline-view-container .timeline-body .timeline-row .timeline-track .break-bar:hover{opacity:.8}.calendar-view-container .calendar-header{margin-bottom:2rem}.calendar-view-container .calendar-header h5{color:#495057;font-weight:600}.calendar-view-container .calendar-header .calendar-nav button{border:1px solid #dee2e6;background:#fff;color:#495057;padding:.375rem .75rem;border-radius:.375rem;transition:all .2s ease}.calendar-view-container .calendar-header .calendar-nav button:hover{background-color:#f8f9fa;border-color:#adb5bd}.calendar-view-container .calendar-header .calendar-nav button:first-child{border-top-right-radius:0;border-bottom-right-radius:0;border-right:none}.calendar-view-container .calendar-header .calendar-nav button:last-child{border-top-left-radius:0;border-bottom-left-radius:0}.calendar-view-container .calendar-grid .calendar-week-header{display:flex;background-color:#f8f9fa;border:1px solid #dee2e6;border-bottom:none}.calendar-view-container .calendar-grid .calendar-week-header .calendar-day-header{flex:1;padding:.75rem;text-align:center;font-weight:600;color:#495057;border-right:1px solid #dee2e6}.calendar-view-container .calendar-grid .calendar-week-header .calendar-day-header:last-child{border-right:none}.calendar-view-container .calendar-grid .calendar-weeks{border:1px solid #dee2e6;border-top:none}.calendar-view-container .calendar-grid .calendar-weeks .calendar-week{display:flex;border-bottom:1px solid #dee2e6}.calendar-view-container .calendar-grid .calendar-weeks .calendar-week:last-child{border-bottom:none}.calendar-view-container .calendar-grid .calendar-weeks .calendar-week .calendar-day{flex:1;min-height:100px;padding:.5rem;border-right:1px solid #dee2e6;background:#fff}.calendar-view-container .calendar-grid .calendar-weeks .calendar-week .calendar-day:last-child{border-right:none}.calendar-view-container .calendar-grid .calendar-weeks .calendar-week .calendar-day.current-month{background:#fff}.calendar-view-container .calendar-grid .calendar-weeks .calendar-week .calendar-day.today{background-color:#fff3cd;border:2px solid #ffc107}.calendar-view-container .calendar-grid .calendar-weeks .calendar-week .calendar-day .day-number{font-weight:600;color:#495057;margin-bottom:.25rem}.calendar-view-container .calendar-grid .calendar-weeks .calendar-week .calendar-day .day-entries .entry-dot{width:8px;height:8px;border-radius:50%;display:inline-block;margin-right:2px;margin-bottom:2px}.heatmap-view-container .heatmap-header{margin-bottom:2rem}.heatmap-view-container .heatmap-header h5{color:#495057;font-weight:600}.heatmap-view-container .heatmap-header .heatmap-legend .legend-colors{display:flex;margin:0 1rem}.heatmap-view-container .heatmap-header .heatmap-legend .legend-colors .legend-color{width:12px;height:12px;margin-right:2px;border-radius:2px}.heatmap-view-container .heatmap-header .heatmap-legend span{font-size:.875rem;color:#6c757d}.heatmap-view-container .heatmap-grid .heatmap-months{display:flex;margin-bottom:.5rem}.heatmap-view-container .heatmap-grid .heatmap-months .month-label{flex:1;text-align:center;font-size:.8rem;font-weight:600;color:#495057}.heatmap-view-container .heatmap-grid .heatmap-weeks .heatmap-week{display:flex;margin-bottom:2px}.heatmap-view-container .heatmap-grid .heatmap-weeks .heatmap-week .heatmap-day{flex:1;aspect-ratio:1;border-radius:2px;margin-right:2px;transition:opacity .2s ease}.heatmap-view-container .heatmap-grid .heatmap-weeks .heatmap-week .heatmap-day:hover{opacity:.8}.heatmap-view-container .heatmap-grid .heatmap-weeks .heatmap-week .heatmap-day:last-child{margin-right:0}.card-view-container{padding:1rem;height:100%;overflow-y:auto;overflow-x:hidden}.card-view-container[data-theme=white]{background-color:#f6f8ff;color:#000}.card-view-container[data-theme=white] .attendance-card{background-color:#f6f8ff;border-color:#d9d9db;color:#000}.card-view-container[data-theme=white] .attendance-card:hover{background-color:#007bff1a}.card-view-container[data-theme=white] .attendance-card .card-header{background-color:#f8f9fa;color:#000;border-bottom-color:#d9d9db}.card-view-container[data-theme=white] .attendance-card .card-body{background-color:#f6f8ff;color:#000}.card-view-container[data-theme=white] .attendance-card .badge.bg-success{background-color:#84ca81;color:#f6f8ff}.card-view-container[data-theme=white] .attendance-card .badge.bg-danger{background-color:#ea5353;color:#f6f8ff}.card-view-container[data-theme=white] .attendance-card .badge.bg-warning{background-color:#fff3dc;color:#000}.card-view-container[data-theme=white] .attendance-card .badge.bg-info{background-color:#e8fbfd;color:#00bad1}.card-view-container[data-theme=blue]{background-color:#f0f8ff;color:#1e3a5f}.card-view-container[data-theme=blue] .attendance-card{background-color:#f6f8ff;border-color:#b3d9ff;color:#1e3a5f}.card-view-container[data-theme=blue] .attendance-card:hover{background-color:#1e3a5f1a}.card-view-container[data-theme=blue] .attendance-card .card-header{background-color:#e6f3ff;color:#1e3a5f;border-bottom-color:#b3d9ff}.card-view-container[data-theme=blue] .attendance-card .card-body{background-color:#f6f8ff;color:#1e3a5f}.card-view-container[data-theme=blue] .attendance-card .badge.bg-success{background-color:#69db7c;color:#f6f8ff}.card-view-container[data-theme=blue] .attendance-card .badge.bg-danger{background-color:#ff8787;color:#f6f8ff}.card-view-container[data-theme=blue] .attendance-card .badge.bg-warning{background-color:#ffd43b;color:#1e3a5f}.card-view-container[data-theme=blue] .attendance-card .badge.bg-info{background-color:#74c0fc;color:#f6f8ff}.card-view-container .row{margin:0}.card-view-container .row .col-xl-4,.card-view-container .row .col-lg-6,.card-view-container .row .col-md-6,.card-view-container .row .col-sm-12{padding:.5rem}.card-view-container .attendance-card{transition:background-color .2s ease;border:1px solid #d9d9db;border-radius:4px;overflow:hidden;height:100%;display:flex;flex-direction:column;font-family:sans-serif;font-size:16px}.card-view-container .attendance-card:hover{box-shadow:0 2px 4px #0000001a}.card-view-container .attendance-card.expanded .card-body{max-height:none}.card-view-container .attendance-card .card-header{padding:8px;border-bottom:1px solid #d9d9db;flex-shrink:0;font-weight:500}.card-view-container .attendance-card .card-header .employee-avatar{margin-right:.75rem;flex-shrink:0}.card-view-container .attendance-card .card-header .employee-avatar img,.card-view-container .attendance-card .card-header .employee-avatar .avatar-placeholder{border:1px solid #d9d9db;width:40px;height:40px;border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:16px;font-weight:400}.card-view-container .attendance-card .card-header .flex-grow-1{min-width:0}.card-view-container .attendance-card .card-header h6{margin:0;font-weight:500;font-size:16px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.card-view-container .attendance-card .card-header small{opacity:.9;font-weight:400;font-size:16px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.card-view-container .attendance-card .card-header .card-actions{flex-shrink:0}.card-view-container .attendance-card .card-header .card-actions .btn{background-color:transparent;border:1px solid #d9d9db;color:inherit;padding:.25rem .5rem}.card-view-container .attendance-card .card-header .card-actions .btn:hover{background-color:#007bff1a}.card-view-container .attendance-card .card-header .card-actions .btn i{font-size:.8rem}.card-view-container .attendance-card .card-body{padding:8px;flex:1;display:flex;flex-direction:column}.card-view-container .attendance-card .card-body .info-item{text-align:center;margin-bottom:.5rem}.card-view-container .attendance-card .card-body .info-item small{display:block;font-weight:400;color:#6c757d;text-transform:uppercase;font-size:12px;letter-spacing:.5px;margin-bottom:.25rem}.card-view-container .attendance-card .card-body .info-item span{font-size:16px;font-weight:400;color:inherit}.card-view-container .attendance-card .card-body .badge{font-size:12px;padding:.25rem .5rem;border-radius:4px;font-weight:400;text-transform:uppercase;letter-spacing:.5px;border:none}.card-view-container .attendance-card .card-body .badge.bg-success,.card-view-container .attendance-card .card-body .badge.bg-danger{color:#f6f8ff}.card-view-container .attendance-card .card-body .badge.bg-warning{color:#000}.card-view-container .attendance-card .card-body .badge.bg-secondary{color:#f6f8ff}.card-view-container .attendance-card .card-body .card-details{margin-top:1rem}.card-view-container .attendance-card .card-body .card-details .section-title{font-size:14px;font-weight:500;color:inherit;margin-bottom:.75rem;display:flex;align-items:center}.card-view-container .attendance-card .card-body .card-details .section-title i{margin-right:.5rem;opacity:.8}.card-view-container .attendance-card .card-body .card-details .breaks-list .break-item,.card-view-container .attendance-card .card-body .card-details .breaks-list .leave-item,.card-view-container .attendance-card .card-body .card-details .short-leave-list .break-item,.card-view-container .attendance-card .card-body .card-details .short-leave-list .leave-item{background-color:inherit;border:1px solid #d9d9db;border-radius:4px;padding:8px;margin-bottom:.5rem;cursor:pointer;transition:all .25s cubic-bezier(.4,0,.2,1);transform:translateZ(0)}.card-view-container .attendance-card .card-body .card-details .breaks-list .break-item .d-flex,.card-view-container .attendance-card .card-body .card-details .breaks-list .leave-item .d-flex,.card-view-container .attendance-card .card-body .card-details .short-leave-list .break-item .d-flex,.card-view-container .attendance-card .card-body .card-details .short-leave-list .leave-item .d-flex{gap:.75rem;align-items:center}.card-view-container .attendance-card .card-body .card-details .breaks-list .break-item .d-flex small,.card-view-container .attendance-card .card-body .card-details .breaks-list .leave-item .d-flex small,.card-view-container .attendance-card .card-body .card-details .short-leave-list .break-item .d-flex small,.card-view-container .attendance-card .card-body .card-details .short-leave-list .leave-item .d-flex small{font-weight:500;color:inherit;margin-bottom:.25rem}.card-view-container .attendance-card .card-body .card-details .breaks-list .break-item .d-flex .text-muted,.card-view-container .attendance-card .card-body .card-details .breaks-list .leave-item .d-flex .text-muted,.card-view-container .attendance-card .card-body .card-details .short-leave-list .break-item .d-flex .text-muted,.card-view-container .attendance-card .card-body .card-details .short-leave-list .leave-item .d-flex .text-muted{font-size:12px;color:#6c757d}.card-view-container .attendance-card .card-body .card-details .breaks-list .break-item .d-flex .badge,.card-view-container .attendance-card .card-body .card-details .breaks-list .leave-item .d-flex .badge,.card-view-container .attendance-card .card-body .card-details .short-leave-list .break-item .d-flex .badge,.card-view-container .attendance-card .card-body .card-details .short-leave-list .leave-item .d-flex .badge{font-size:10px;padding:.2rem .4rem}.card-view-container .attendance-card .card-body .card-details .additional-details .row .col-6{margin-bottom:.5rem}.card-view-container .attendance-card .card-body .card-details .additional-details .row .col-6 small{font-weight:400;color:#6c757d;text-transform:uppercase;font-size:12px;letter-spacing:.5px;margin-bottom:.25rem}.card-view-container .attendance-card .card-body .card-details .additional-details .row .col-6 span{font-weight:400;color:inherit;font-size:14px}@media (max-width: 1200px){.card-view-container .row .col-xl-4{flex:0 0 50%;max-width:50%}}@media (max-width: 768px){.card-view-container .row .col-xl-4,.card-view-container .col-lg-6,.card-view-container .col-md-6{flex:0 0 100%;max-width:100%}.card-view-container .attendance-card .card-body{padding:8px}.card-view-container .attendance-card .card-body .info-item small{font-size:10px}.card-view-container .attendance-card .card-body .info-item span{font-size:14px}}@media (max-width: 576px){.card-view-container{padding:.5rem}.card-view-container .row .col-sm-12{padding:.25rem}.card-view-container .attendance-card .card-header{padding:8px}.card-view-container .attendance-card .card-header h6,.card-view-container .attendance-card .card-header small{font-size:14px}.card-view-container .attendance-card .card-body{padding:8px}}.btn-xs{padding:.125rem .3rem!important;font-size:.9rem!important;border-radius:.2rem!important;line-height:1.5!important}.form-select.form-select-sm:invalid{border-color:#d9d9db!important}.form-select.form-select-sm:valid{border-color:#d9d9db!important}.date-range-container{gap:8px;flex-wrap:nowrap;align-items:center}.date-range-btn{padding:6px 12px;font-size:14px;font-weight:500;border-radius:6px;transition:all .25s cubic-bezier(.4,0,.2,1);white-space:nowrap;display:inline-flex;align-items:center;justify-content:center;min-height:36px;transform:translateZ(0);position:relative;overflow:hidden}.date-range-btn:before{content:\"\";position:absolute;top:50%;left:50%;width:0;height:0;background:#fff3;border-radius:50%;transform:translate(-50%,-50%);transition:width .25s,height .25s}.date-range-btn:active:before{width:300px;height:300px}.calendar-btn{border-color:#0d6efd;color:#0d6efd;background-color:transparent}.calendar-btn:hover{background-color:#0d6efd;color:#fff;transform:translateY(-1px);box-shadow:0 4px 12px #0d6efd4d}.clear-btn{border-color:#dc3545;color:#dc3545;background-color:transparent}.clear-btn:hover{background-color:#dc3545;color:#fff;transform:translateY(-1px);box-shadow:0 4px 12px #dc35454d}.date-range-label{font-size:14px;font-weight:500;padding:4px 8px;min-width:180px;text-align:center;white-space:nowrap;cursor:pointer}.date-range-btn .bi{font-size:14px;transition:transform .2s ease}.date-range-btn:hover .bi{transform:scale(1.1)}@media (max-width: 768px){.date-range-container{flex-wrap:wrap;justify-content:flex-start}.date-range-label{min-width:100%;margin-top:8px;order:3}}.date-range-btn:focus{outline:none;box-shadow:0 0 0 3px #0d6efd40}.clear-btn:focus{box-shadow:0 0 0 3px #dc354540}.action-buttons-row .button{display:inline-flex;align-items:center;justify-content:center;overflow:hidden;color:#fff;border-radius:6px;height:34px;padding:0 10px;white-space:nowrap;transition:max-width .4s ease,background-color .3s ease;max-width:40px;background-color:transparent;border:1px solid #6F61CF}.action-buttons-row .button .label-hidden{opacity:0;margin-left:8px;transition:opacity .3s ease;pointer-events:none;display:none}.action-buttons-row .button:hover{max-width:200px;background-color:#6f61cf}.action-buttons-row .button:hover .label-hidden{opacity:1;pointer-events:auto;margin-left:8px!important;display:block}.action-buttons-row ::ng-deep .button .svg-icon svg path{stroke:#6f61cf;transition:fill .3s ease,stroke .3s ease}.action-buttons-row ::ng-deep .button:hover .svg-icon svg path{stroke:#fff!important}.action-buttons-row ::ng-deep .button:active .svg-icon svg path{stroke:#6f61cf!important}.action-buttons-row ::ng-deep .button:focus .svg-icon svg path{stroke:#6f61cf!important}.badge-overflow-wrapper{width:100%;min-width:0;display:flex;align-items:center}.custom-overlay-wrapper{position:fixed;top:0;left:0;width:100%;height:100%;background-color:#00000080;display:flex;justify-content:center;align-items:center;z-index:9999}.custom-overlay{background:#fff;border-radius:8px;box-shadow:0 4px 12px #00000026;min-width:300px;max-width:400px}.custom-modal-body{padding:20px;text-align:center}.custom-modal-body .modal-message{font-size:16px;margin-bottom:20px;color:#333}.custom-modal-body .modal-actions{display:flex;gap:10px;justify-content:center}.custom-modal-body .modal-actions button{padding:8px 16px;border:none;border-radius:4px;cursor:pointer;font-size:14px;transition:background-color .2s ease}.custom-modal-body .modal-actions button.btn-confirm{background-color:#007bff;color:#fff}.custom-modal-body .modal-actions button.btn-confirm:hover{background-color:#0056b3}.custom-modal-body .modal-actions button.btn-cancel{background-color:#6c757d;color:#fff}.custom-modal-body .modal-actions button.btn-cancel:hover{background-color:#545b62}.custom-break-tooltip .short-break-table{width:100%;border-collapse:collapse;font-size:12px}.custom-break-tooltip .short-break-table th,.custom-break-tooltip .short-break-table td{padding:4px 6px;text-align:center;border:1px solid #ddd}.custom-break-tooltip .short-break-table th{background-color:#f8f9fa;font-weight:600}.custom-break-tooltip .short-break-table tbody tr:nth-child(2n){background-color:#fafafa}.text-truncate{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;display:flex;align-items:center;min-width:0}\n"] }]
9708
+ ], template: "<div class=\"position-relative h-100\">\n <!-- <h1>abu </h1> -->\n <div\n class=\"d-flex justify-content-between mb-3 align-items-center position-relative\"\n >\n <div class=\"col-4 global-search position-relative\">\n\n <span\n\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/search.svg'\"\n class=\"data-grid-svg-icon mx-2 position-absolute icon\"\n ></span>\n <input\n #searchInput\n style=\"height: 36px\"\n class=\"form-control\"\n placeholder=\"Search all columns and press Enter\"\n [(ngModel)]=\"tableSearch\"\n (keydown.enter)=\"onGlobalSearch()\"\n\n />\n <span\n *ngIf=\"tableSearch\"\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/x.svg'\"\n class=\"data-grid-svg-icon position-absolute end-0 top-50 translate-middle-y me-2 cursor-pointer\"\n (click)=\"onSearchReset()\"\n title=\"Clear search\"\n ></span>\n\n </div>\n\n <!-- Date Picker Buttons -->\n <!-- Date Picker Section - Improved Version -->\n<div class=\"position-relative d-flex justify-content-center align-items-center ms-2 date-range-container\">\n\n <!-- Hidden Date Picker Input -->\n <input\n type=\"text\"\n class=\"form-control\"\n bsDaterangepicker\n #picker=\"bsDaterangepicker\"\n [(ngModel)]=\"bsRangeValue\"\n [bsConfig]=\"bsConfig\"\n (bsValueChange)=\"onRangeSelected($event, picker)\"\n style=\"opacity: 0; width: 0; height: 0; position: absolute;\"\n />\n\n <!-- Left Arrow Button -->\n <span\n class=\"text-primary cursor-pointer me-2 date-range-btn arrow-btn\"\n (click)=\"navigateDate('left')\"\n title=\"Previous Date Range\"\n *ngIf=\"bsRangeValue && bsRangeValue.length > 0\"\n >\n <span class=\"bi bi-chevron-left\"></span>\n </span>\n\n <!-- Date Range Label -->\n <span\n *ngIf=\"bsRangeValue && bsRangeValue.length > 0\"\n class=\"text-primary date-range-label cursor-pointer\"\n (click)=\"togglePicker(picker)\"\n title=\"Click to open calendar\"\n >\n {{ bsRangeValue[0] | timezoneFormat:prefs:'date' }} - {{ bsRangeValue[1] | timezoneFormat:prefs:'date' }}\n </span>\n\n <!-- Right Arrow Button -->\n <span\n class=\"text-primary cursor-pointer ms-2 date-range-btn arrow-btn\"\n (click)=\"navigateDate('right')\"\n title=\"Next Date Range\"\n *ngIf=\"bsRangeValue && bsRangeValue.length > 0\"\n >\n <span class=\"bi bi-chevron-right\"></span>\n </span>\n\n\n\n</div>\n\n <div class=\"d-flex gap-2 align-items-center table-right-top-actions\">\n\n <!-- Pivot Mode Button -->\n <!-- <a\n href=\"JavaScript:void(0)\"\n class=\"button button-small btn btn-active-primary border border-primary me-2 header-icon\"\n (click)=\"togglePivotMode()\"\n [class.active]=\"pivotMode\"\n title=\"Toggle Pivot Mode\"\n >\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/pivot.svg'\"\n class=\"svg-icon svg-icon-2\"\n ></span>\n </a> -->\n\n <div class=\"action-buttons-row d-flex gap-2 align-items-center\">\n <a\n href=\"JavaScript:void(0)\"\n class=\"button button-small btn btn-active-primary border border-primary p-0 d-flex align-items-center justify-content-center px-3\"\n (click)=\"togglePicker(picker)\"\n title=\"Select Date Range\"\n >\n <span class=\"bi bi-calendar3 text-primary\"></span>\n <span class=\"label-hidden text-white\">Calendar</span>\n </a>\n <button\n *ngIf=\"bsRangeValue && bsRangeValue.length > 0 && !isDefaultDateRange\"\n type=\"button\"\n class=\"button button-small btn btn-active-danger border border-danger p-0 d-flex align-items-center justify-content-center px-3\"\n (click)=\"clearDateRange()\"\n title=\"Clear Date Range\"\n >\n <span class=\"bi bi-x-circle text-danger\"></span>\n <span class=\"label-hidden text-white\">Clear</span>\n </button>\n</div>\n<ng-container *ngFor=\"let button of buttons\">\n <div\n class=\"action-buttons-row d-flex align-items-center\"\n *ngIf=\"getButtonPermission(button) && (!button.condition || (button.condition === '!isSingleDay' && !isSingleDay) || (button.condition === 'isSingleDay' && isSingleDay))\"\n >\n <a\n href=\"JavaScript:void(0)\"\n (click)=\"onActionButtonClick(button.name)\"\n class=\"button\"\n [title]=\"button.name\"\n >\n <span\n *ngIf=\"button.is_showIcon\"\n [inlineSVG]=\"button.iconPath\"\n class=\"svg-icon\"\n ></span>\n <span\n class=\"label-hidden\"\n >{{ button.name }}</span\n >\n </a>\n </div>\n</ng-container>\n\n<!-- Calendar Button -->\n\n\n<!-- Existing filter, settings, etc. -->\n <div\n *ngIf=\"!showFilterRow\"\n class=\"cursor-pointer position-relative action-buttons-row d-flex align-items-center\"\n (click)=\"toggleOpenFilter()\"\n [class.active]=\"showFilters\"\n >\n <a\n href=\"JavaScript:void(0)\"\n class=\"button button-small btn btn-active-primary border border-primary p-0 d-flex align-items-center justify-content-center px-3\"\n >\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\"\n class=\"svg-icon svg-icon-2\"\n ></span>\n <span class=\"label-hidden text-white\">Filters</span>\n </a>\n <span\n *ngIf=\"activeFilteredColumns?.length\"\n style=\"\n width: 7px;\n height: 7px;\n box-shadow: 0px 0px 3px #0022ff;\n background-color: rgb(0, 60, 255);\n position: absolute;\n right: 16px;\n top: 10px;\n \"\n class=\"rounded-circle d-block\"\n ></span>\n </div>\n <div\n class=\"cursor-pointer d-none\"\n (click)=\"toggleActions('advance-filter')\"\n [class.active]=\"activeTopButton === 'advance-filter'\"\n >\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/zoom-charge.svg'\"\n class=\"data-grid-svg-icon top-icon me-2\"\n ></span>\n </div>\n <div\n class=\"cursor-pointer action-buttons-row\"\n (click)=\"toggleActions('setting')\"\n [class.active]=\"\n activeTopButton === 'setting' ||\n activeTopButton === 'table-layout' ||\n activeTopButton === 'table-presets' ||\n activeTopButton === 'show-hide-columns'\n \"\n >\n <!-- <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/settings-2.svg'\"\n class=\"data-grid-svg-icon top-icon me-2\"\n ></span> -->\n <a\n href=\"JavaScript:void(0)\"\n class=\"button button-small btn btn-active-primary border border-primary p-0 d-flex align-items-center justify-content-center px-3\"\n >\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/settings-2.svg'\"\n class=\"svg-icon svg-icon-2\"\n ></span>\n <span class=\"label-hidden text-white\">Setting</span>\n </a>\n\n <div\n *ngIf=\"activeTopButton === 'setting'\"\n class=\"actions-dropdown mt-1 actions-dropdown-setting\"\n style=\"position: absolute\"\n >\n <div class=\"dropdown-menu show shadow custom-menu\">\n <!-- Table Layout -->\n <a\n class=\"dropdown-item d-flex justify-content-between align-items-center cursor-pointer\"\n (click)=\"$event.stopPropagation(); toggleActions('table-layout')\"\n >\n <span\n ><span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/table-2.svg'\n \"\n class=\"data-grid-svg-icon me-2\"\n ></span>\n Table Layout</span\n >\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\n \"\n class=\"data-grid-svg-icon me-2\"\n ></span>\n </a>\n <!-- Table Presets -->\n <a\n (click)=\"$event.stopPropagation(); toggleActions('table-presets')\"\n class=\"dropdown-item d-flex justify-content-between align-items-center cursor-pointer\"\n >\n <span\n ><span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/list-details.svg'\n \"\n class=\"data-grid-svg-icon me-2\"\n ></span>\n Table Presets</span\n >\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\n \"\n class=\"data-grid-svg-icon me-2\"\n ></span>\n </a>\n\n <!-- Columns -->\n <a\n *ngIf=\"!showSideMenu\"\n (click)=\"\n $event.stopPropagation(); toggleActions('show-hide-columns')\n \"\n class=\"dropdown-item d-flex justify-content-between align-items-center cursor-pointer\"\n >\n <span\n ><span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/eye.svg'\"\n class=\"data-grid-svg-icon me-2\"\n ></span>\n Columns</span\n >\n <div class=\"d-flex gap-2\">\n <span class=\"muted-text\">{{ columnsCount }}</span>\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\n \"\n class=\"data-grid-svg-icon me-2\"\n ></span>\n </div>\n </a>\n\n <div class=\"dropdown-divider\"></div>\n\n <!-- Filter -->\n <a\n class=\"dropdown-item cursor-pointer\"\n (click)=\"toggleOpenFilter(); activeTopButton = ''\"\n *ngIf=\"!showFilterRow\"\n >\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\n \"\n class=\"data-grid-svg-icon me-2 mt-1 cursor-pointer\"\n ></span>\n Filter\n </a>\n\n <!-- Download -->\n <!-- <a\n class=\"dropdown-item cursor-pointer\"\n (click)=\"downloadCsv('csv')\"\n >\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/download.svg'\n \"\n class=\"data-grid-svg-icon me-2 cursor-pointer\"\n ></span>\n CSV Export\n </a> -->\n <!-- <a\n *ngIf=\"enableExport\"\n class=\"dropdown-item cursor-pointer\"\n (click)=\"downloadCsv('xlsx')\"\n >\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/download.svg'\n \"\n class=\"data-grid-svg-icon me-2 cursor-pointer\"\n ></span>\n Excel Export\n </a> -->\n <!-- Font Family & Font Size -->\n <div class=\"px-2 pb-2 pt-2\">\n <div class=\"d-flex gap-2\">\n <!-- Font Family -->\n <select\n class=\"form-select form-select-sm\"\n [(ngModel)]=\"fontFaimly\"\n (change)=\"onFontChange()\"\n >\n <option *ngFor=\"let font of fontFamilies\" [value]=\"font\">\n {{ font }}\n </option>\n </select>\n\n <!-- Font Size -->\n <select\n class=\"form-select form-select-sm\"\n (change)=\"onFontChange()\"\n [(ngModel)]=\"bodyTextFontsSize\"\n >\n <option *ngFor=\"let size of fontSizes\" [value]=\"size\">\n {{ size }}\n </option>\n </select>\n </div>\n </div>\n </div>\n </div>\n\n <!-- Table Layout -->\n\n <ng-container *ngIf=\"activeTopButton === 'table-layout'\">\n <div\n *ngTemplateOutlet=\"tableLayout\"\n class=\"actions-dropdown mt-1\"\n style=\"position: absolute\"\n ></div>\n </ng-container>\n\n <!-- Table Presets -->\n <ng-container *ngIf=\"activeTopButton === 'table-presets'\">\n <div\n *ngTemplateOutlet=\"tablePreset\"\n class=\"actions-dropdown mt-1\"\n style=\"position: absolute\"\n ></div>\n </ng-container>\n\n <!-- Table Presets -->\n <ng-container *ngIf=\"activeTopButton === 'show-hide-columns'\">\n <div\n *ngTemplateOutlet=\"showHideColumns\"\n class=\"actions-dropdown mt-1\"\n style=\"position: absolute\"\n ></div>\n </ng-container>\n </div>\n <div>\n <!-- Example single danger button -->\n\n <!-- <button\n type=\"button\"\n class=\"btn btn-primary btn-sm d-flex gap-2 action-button\"\n (click)=\"toggleActions('actions')\"\n >\n Action\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/Vector.svg'\"\n class=\"data-grid-svg-icon\"\n ></span>\n </button>\n <div\n *ngIf=\"activeTopButton === 'actions'\"\n class=\"actions-dropdown mt-1\"\n >\n <div class=\"dropdown-menu show\">\n <a class=\"dropdown-item\" href=\"#\">Action</a>\n <a class=\"dropdown-item\" href=\"#\">Another action</a>\n <a class=\"dropdown-item\" href=\"#\">Something else here</a>\n <div class=\"dropdown-divider\"></div>\n <a class=\"dropdown-item\" href=\"#\">Separated link</a>\n </div>\n </div> -->\n </div>\n </div>\n </div>\n\n <div\n *ngIf=\"showFilters && !showFilterRow\"\n class=\"top-filter-row border-top py-2 d-flex justify-content-between align-items-center\"\n [style.height.px]=\"topFilterRowHeight\"\n >\n <!-- LEFT SIDE (Filter tags + Filter button) -->\n <div class=\"d-flex gap-2 align-items-center\">\n <ng-container *ngIf=\"activeFilteredColumns?.length\">\n <div\n *ngFor=\"let col of activeFilteredColumns; trackBy: trackByField\"\n class=\"filter-tags\"\n >\n <div\n (click)=\"\n isActiveFilterOpen = true;\n activeTopButton = 'filter-columns';\n openFilter(col)\n \"\n class=\"d-flex justify-content-center align-items-center muted-text add-filter-button active-filters\"\n style=\"white-space: nowrap\"\n [class.active]=\"\n col?.field == selectedColumnForFilter?.field &&\n isActiveFilterOpen &&\n activeTopButton == 'filter-columns'\n \"\n >\n <span class=\"header-tag mt-0 d-flex align-items-center\">\n <span\n *ngIf=\"col?.pinned\"\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/pin.svg'\"\n class=\"data-grid-svg-icon me-2\"\n ></span>\n {{ col.header }}\n <span\n (click)=\"\n $event.stopPropagation(); removeColumnFilterFromColumn(col)\n \"\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/cross-primary.svg'\n \"\n class=\"data-grid-svg-icon cross-secondary ms-2 mb-1\"\n ></span>\n </span>\n </div>\n\n <ng-container\n *ngIf=\"\n activeTopButton === 'filter-columns' &&\n col?.field == selectedColumnForFilter?.field &&\n isActiveFilterOpen\n \"\n >\n <div\n *ngTemplateOutlet=\"filterColumns; context: { column: col }\"\n class=\"actions-dropdown mt-1\"\n ></div>\n </ng-container>\n </div>\n </ng-container>\n\n <!-- Filter Button -->\n <div class=\"add-filter-button-menu\">\n <div\n (click)=\"toggleActions('filter-columns'); isActiveFilterOpen = false\"\n class=\"d-flex justify-content-center align-items-center muted-text add-filter-button button-filter\"\n style=\"width: 70px\"\n >\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/plus.svg'\"\n class=\"me-2 data-grid-svg-icon\"\n ></span>\n Filter\n </div>\n\n <ng-container\n *ngIf=\"activeTopButton === 'filter-columns' && !isActiveFilterOpen\"\n >\n <div\n *ngTemplateOutlet=\"filterColumns\"\n class=\"actions-dropdown mt-1\"\n ></div>\n </ng-container>\n </div>\n </div>\n\n <!-- RIGHT SIDE (Update + Reset) -->\n <div class=\"d-flex gap-3 align-items-center\">\n <div\n (click)=\"savePreset()\"\n class=\"text-primary cursor-pointer all-filters-reset-button\"\n *ngIf=\"!checkFilterChangesEffect()\"\n >\n Update View\n </div>\n\n <div\n class=\"text-primary cursor-pointer all-filters-reset-button\"\n *ngIf=\"!tableFilterViewId && activeFilteredColumns?.length\"\n (click)=\"clearAllFilters()\"\n >\n Reset\n </div>\n </div>\n </div>\n\n <div\n [style.height]=\"\n showFilters ? 'calc(100% - ' + topFilterRowHeight + 'px)' : '100%'\n \"\n cdkDropListGroup\n class=\"data-grid-table-wrapper overflow-hidden\"\n #dataGridContainer\n [style.fontFamily]=\"fontFaimly\"\n >\n <div\n *ngIf=\"showRowsGrouping\"\n [style.height.px]=\"headerRowHeight\"\n [cdkDropListData]=\"columns\"\n [style.backgroundColor]=\"\n topGroupedBadgesBackgroundColor || headerBackgroundColor\n \"\n cdkDropList\n (cdkDropListEntered)=\"enterToTopRowGrouping($event)\"\n (cdkDropListExited)=\"exitedFromTheTopRow($event)\"\n (cdkDropListDropped)=\"onDropTopGroup($event)\"\n [cdkDropListEnterPredicate]=\"canEnterToRowsGrouping\"\n id=\"rows-grouping-top-container\"\n class=\"border-below d-flex px-4 align-items-center\"\n >\n <div class=\"d-flex gap-2 align-items-center me-5\">\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/justify.svg'\"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n <div *ngIf=\"!draggingInGroupArea && !groupedColumns?.length\">\n Drag here to set row groups\n </div>\n <ng-container\n *ngFor=\"\n let child of groupedColumns;\n let i = index;\n trackBy: trackByField\n \"\n >\n <ng-container\n *ngTemplateOutlet=\"\n topGroupingRowPlaceholder;\n context: {\n $implicit: child,\n showChevron:\n groupedColumns.length > 1 && i != groupedColumns.length - 1\n }\n \"\n ></ng-container>\n </ng-container>\n </div>\n\n\n\n\n</div>\n<div\n class=\"d-flex overflow-hidden\"\n [style.height]=\"\n 'calc(100% - ' +\n (showRowsGrouping\n ? headerRowHeight + footerRowHeight\n : footerRowHeight) +\n 'px)'\n \"\n>\n <div\n class=\"h-100\"\n [style.width]=\"\n !showSideMenu\n ? '100%'\n : sideMenuVisible\n ? 'calc(100% - 280px)'\n : 'calc(100% - 30px)'\n \"\n >\n <div class=\"h-100 transition position-relative w-100\">\n <!-- ##################################################################################################################################################################################### -->\n <!-- ##################################################################################################################################################################################### -->\n <!-- Data Grid Header starts here -->\n <!-- ##################################################################################################################################################################################### -->\n <!-- ##################################################################################################################################################################################### -->\n\n <div\n class=\"data-grid-header-wrapper w-100\"\n [style.color]=\"headerTextColor\"\n [style.fontSize.px]=\"headerTextFontsSize\"\n [style.backgroundColor]=\"headerBackgroundColor\"\n [class.border-below]=\"!hasAnyVisibleColumn\"\n [style.height.px]=\"\n showColumnsGrouping && showFilterRow\n ? headerRowHeight * 3\n : showColumnsGrouping || showFilterRow\n ? headerRowHeight * 2\n : headerRowHeight\n \"\n >\n <!-- ********************************************************************************* -->\n <!-- ********************************************************************************* -->\n <!-- Data Grid Left Pinned Header starts here -->\n <!-- ********************************************************************************* -->\n <!-- ********************************************************************************* -->\n <div class=\"data-grid-header left-pinned\" #leftPinnedHeader>\n <div\n *ngIf=\"showSerialNumber\"\n [style.backgroundColor]=\"checkboxesBackgroundColor\"\n class=\"select-all-checkbox-cell border-below\"\n [style.width.px]=\"65\"\n [style.height.px]=\"\n showColumnsGrouping && showFilterRow\n ? headerRowHeight * 3\n : showColumnsGrouping || showFilterRow\n ? headerRowHeight * 2\n : headerRowHeight\n \"\n >\n S.No</div>\n <div\n [style.backgroundColor]=\"checkboxesBackgroundColor\"\n class=\"select-all-checkbox-cell border-below\"\n [style.height.px]=\"\n showColumnsGrouping && showFilterRow\n ? headerRowHeight * 3\n : showColumnsGrouping || showFilterRow\n ? headerRowHeight * 2\n : headerRowHeight\n \"\n >\n <input\n *ngIf=\"hasAnyVisibleColumn\"\n type=\"checkbox\"\n [indeterminate]=\"isIndeterminateState(dataSet)\"\n [checked]=\"isAllSelected(dataSet)\"\n (change)=\"toggleSelectAll(dataSet)\"\n />\n </div>\n <div\n class=\"d-flex\"\n cdkDropList\n id=\"left-pinned-header\"\n cdkDropListOrientation=\"horizontal\"\n [cdkDropListData]=\"leftPinnedColumns\"\n (cdkDropListEntered)=\"onDropListEnter($event, 'left')\"\n (cdkDropListSorted)=\"\n onSortGroup($event, 'previewLeftPinnedColumns')\n \"\n (cdkDropListDropped)=\"onDropGroup()\"\n style=\"min-width: 0.2px\"\n [style.background-color]=\"headerBackgroundColor\"\n >\n <div\n class=\"dragable-header\"\n cdkDrag\n [cdkDragData]=\"col\"\n *ngFor=\"\n let col of leftPinnedColumns;\n let i = index;\n trackBy: trackByField\n \"\n >\n <ng-container\n *ngTemplateOutlet=\"\n headerCell;\n context: {\n $implicit: col,\n index: i,\n section: 'previewLeftPinnedColumns'\n }\n \"\n ></ng-container>\n <ng-template cdkDragPreview\n ><div class=\"p-2 border d-flex gap-2\">\n <div>\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath +\n 'data-grid/icons/arrows-move.svg'\n \"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n </div>\n <div>{{ col.header }}</div>\n </div>\n </ng-template>\n <ng-template cdkDragPlaceholder>\n <div *ngIf=\"!draggingInGroupArea\">\n <div\n *ngTemplateOutlet=\"\n headerCell;\n context: {\n $implicit: col,\n index: i,\n section: ''\n }\n \"\n ></div>\n </div>\n <div\n *ngIf=\"draggingInGroupArea\"\n class=\"d-flex gap-2 ms-2\"\n style=\"opacity: 0.6\"\n >\n <ng-container\n *ngIf=\"col?.children?.length; else singleCol\"\n >\n <ng-container\n *ngFor=\"\n let child of col.children;\n let i = index;\n trackBy: trackByField\n \"\n >\n <ng-container\n *ngTemplateOutlet=\"\n topGroupingRowPlaceholder;\n context: {\n $implicit: child,\n showChevron:\n col.children.length > 1 &&\n i != col.children.length - 1\n }\n \"\n ></ng-container>\n </ng-container>\n </ng-container>\n\n <ng-template #singleCol>\n <ng-container\n *ngTemplateOutlet=\"\n topGroupingRowPlaceholder;\n context: {\n $implicit: col,\n showChevron: col?.children?.length > 1\n }\n \"\n ></ng-container>\n </ng-template>\n </div>\n </ng-template>\n </div>\n </div>\n </div>\n\n <!-- ********************************************************************************* -->\n <!-- ********************************************************************************* -->\n <!-- Data Grid Center Pinned Header starts here -->\n <!-- ********************************************************************************* -->\n <!-- ********************************************************************************* -->\n <div\n class=\"data-grid-header center-scrollable\"\n #centerPinnedHeader\n (scroll)=\"onCenterHeaderScroll($event)\"\n id=\"center-pinned-header\"\n cdkDropList\n [cdkDropListConnectedTo]=\"\n showRowsGrouping ? ['rows-grouping-top-container'] : []\n \"\n [cdkDropListData]=\"centerColumns\"\n cdkDropListOrientation=\"horizontal\"\n [cdkDropListSortingDisabled]=\"\n isDisableColumnGrouping && draggingInGroupArea\n \"\n (cdkDropListEntered)=\"onDropListEnter($event, 'center')\"\n (cdkDropListSorted)=\"onSortGroup($event, 'previewCenterColumns')\"\n (cdkDropListDropped)=\"onDropGroup()\"\n [style.maxWidth]=\"\n 'calc(100% - ' +\n (rightPinnedHeader.offsetWidth + leftPinnedHeader.offsetWidth) +\n 'px)'\n \"\n >\n <div\n *ngIf=\"groupedColumns?.length\"\n style=\"min-width: 200px\"\n class=\"h-100 align-items-center\"\n #columnsGroupedBox\n id=\"groupBoxHeaderDiv\"\n >\n <div\n class=\"d-flex w-100 justify-content-between align-items-center border-below\"\n [style.height.px]=\"\n showFilterRow ? headerRowHeight * 2 : headerRowHeight\n \"\n >\n <div class=\"ps-3\">Group</div>\n <div class=\"d-flex\">\n <div\n class=\"three-dots cursor-pointer\"\n (click)=\"openThreeDotsMenu($event, 'group')\"\n >\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath +\n 'data-grid/icons/three-dots-vertical.svg'\n \"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n </div>\n <div\n (mousedown)=\"onResizeGroupBox($event)\"\n class=\"resize-handle\"\n style=\"margin-right: -2px\"\n >\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath +\n 'data-grid/icons/resize-handle.svg'\n \"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n </div>\n </div>\n </div>\n\n <div\n [style.height.px]=\"headerRowHeight\"\n class=\"border-below\"\n ></div>\n </div>\n <!-- <span\n class=\"d-flex align-items-center justify-content-center cursor-pointer border-below\"\n style=\"min-width: 30px; height: 100%;\"\n *ngIf=\"gridType === 'TimeSheet' && !areDatesSelectedAndEqual\"\n >\n </span> -->\n <div\n class=\"dragable-header\"\n (cdkDragStarted)=\"\n checkColumnGroupingStatus(col); dragStartOnGroup(col)\n \"\n cdkDrag\n [cdkDragData]=\"col\"\n *ngFor=\"\n let col of centerColumns;\n let i = index;\n trackBy: trackById\n \"\n >\n <ng-container\n *ngTemplateOutlet=\"\n headerCell;\n context: {\n $implicit: col,\n index: i,\n section: 'previewCenterColumns'\n }\n \"\n >\n </ng-container>\n <ng-template cdkDragPreview\n ><div class=\"p-2 border d-flex gap-2\">\n <div>\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath +\n 'data-grid/icons/arrows-move.svg'\n \"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n </div>\n <div>{{ col.header }}</div>\n </div>\n </ng-template>\n <ng-template cdkDragPlaceholder>\n <div *ngIf=\"!draggingInGroupArea\">\n <div\n *ngTemplateOutlet=\"\n headerCell;\n context: {\n $implicit: col,\n index: i,\n section: 'centerColumns'\n }\n \"\n ></div>\n </div>\n <div\n *ngIf=\"draggingInGroupArea\"\n class=\"d-flex gap-2 ms-2\"\n style=\"opacity: 0.6\"\n >\n <ng-container *ngIf=\"col?.children?.length; else singleCol\">\n <ng-container\n *ngFor=\"\n let child of col.children;\n let i = index;\n trackBy: trackById\n \"\n >\n <ng-container *ngIf=\"child?.is_groupable\">\n <ng-container\n *ngTemplateOutlet=\"\n topGroupingRowPlaceholder;\n context: {\n $implicit: child,\n showChevron:\n col.children.length > 1 &&\n i != col.children.length - 1\n }\n \"\n ></ng-container>\n </ng-container>\n </ng-container>\n </ng-container>\n\n <ng-template #singleCol>\n <ng-container *ngIf=\"col?.is_groupable\">\n <ng-container\n *ngTemplateOutlet=\"\n topGroupingRowPlaceholder;\n context: {\n $implicit: col,\n showChevron: col?.children?.length > 1\n }\n \"\n ></ng-container>\n </ng-container>\n </ng-template>\n </div>\n </ng-template>\n </div>\n <div *ngIf=\"!areDatesSelectedAndEqual\" class=\"header-cell border-below\" [style.width.px]=\"30\" [style.height.px]=\"headerRowHeight\" [style.backgroundColor]=\"headerBackgroundColor\"></div>\n </div>\n\n <!-- ********************************************************************************* -->\n <!-- ********************************************************************************* -->\n <!-- Data Grid Right Pinned Header starts here -->\n <!-- ********************************************************************************* -->\n <!-- ********************************************************************************* -->\n <div\n cdkDropList\n id=\"right-pinned-header\"\n [cdkDropListConnectedTo]=\"\n showRowsGrouping ? ['rows-grouping-top-container'] : []\n \"\n cdkDropListOrientation=\"horizontal\"\n class=\"data-grid-header right-pinned\"\n (cdkDropListSorted)=\"\n onSortGroup($event, 'previewRightPinnedColumns')\n \"\n (cdkDropListEntered)=\"onDropListEnter($event, 'right')\"\n (cdkDropListDropped)=\"onDropGroup()\"\n #rightPinnedHeader\n class=\"right-pinned-header d-flex\"\n style=\"min-width: 0.2px\"\n >\n <div\n class=\"dragable-header\"\n cdkDrag\n [cdkDragData]=\"col\"\n *ngFor=\"\n let col of rightPinnedColumns;\n let i = index;\n trackBy: trackById\n \"\n >\n <ng-container\n *ngTemplateOutlet=\"\n headerCell;\n context: {\n $implicit: col,\n pinnedRight: true,\n index: i,\n section: 'previewRightPinnedColumns'\n }\n \"\n ></ng-container>\n <ng-template cdkDragPreview\n ><div class=\"p-2 border d-flex gap-2\">\n <div>\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath +\n 'data-grid/icons/arrows-move.svg'\n \"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n </div>\n <div>{{ col.header }}</div>\n </div>\n </ng-template>\n <ng-template cdkDragPlaceholder>\n <div *ngIf=\"!draggingInGroupArea\">\n <div\n *ngTemplateOutlet=\"\n headerCell;\n context: {\n $implicit: col,\n index: i,\n section: 'centerColumns'\n }\n \"\n ></div>\n </div>\n <div\n *ngIf=\"draggingInGroupArea\"\n class=\"d-flex gap-2 ms-2\"\n style=\"opacity: 0.6\"\n >\n <ng-container *ngIf=\"col?.children?.length; else singleCol\">\n <ng-container\n *ngFor=\"\n let child of col.children;\n let i = index;\n trackBy: trackById\n \"\n >\n <ng-container\n *ngTemplateOutlet=\"\n topGroupingRowPlaceholder;\n context: {\n $implicit: child,\n showChevron:\n col.children.length > 1 &&\n i != col.children.length - 1\n }\n \"\n ></ng-container>\n </ng-container>\n </ng-container>\n\n <ng-template #singleCol>\n <ng-container\n *ngTemplateOutlet=\"\n topGroupingRowPlaceholder;\n context: {\n $implicit: col,\n showChevron: col?.children?.length > 1\n }\n \"\n ></ng-container>\n </ng-template>\n </div>\n </ng-template>\n </div>\n </div>\n </div>\n\n <!--########################################################################################################################################################################################################################### -->\n <!--########################################################################################################################################################################################################################### -->\n <!-- Data Grid Body starts here -->\n <!--########################################################################################################################################################################################################################### -->\n <!--########################################################################################################################################################################################################################### -->\n <div\n class=\"h-100 d-flex justify-content-center align-items-center\"\n *ngIf=\"!dataSet.length && !loading\"\n >\n No Record Found\n </div>\n\n <div\n class=\"position-absolute w-100 h-100 d-flex justify-content-center align-items-center loading-overlay\"\n *ngIf=\"loading\"\n style=\"\n z-index: 999;\n background: rgba(255, 255, 255, 0.8);\n backdrop-filter: blur(1px);\n \"\n >\n <div class=\"text-center p-2\">\n <div class=\"spinner-border text-primary\" role=\"status\"></div> Loading...\n</div>\n </div>\n\n <!-- Card View -->\n \n\n <!-- Table View -->\n <div\n class=\"data-grid-body-wrapper position-relative d-flex\"\n [style.height]=\"bodyWrapperHeight\"\n style=\"overflow-y: auto; overflow-x: hidden\"\n #mainScroll\n (scroll)=\"onMainScroll($event)\"\n *ngIf=\"dataSet.length\"\n >\n <!-- LEFT PINNED -->\n <div [style.height.px]=\"!groupedColumns.length ? originalDataSet.length * rowHeight: 0\"></div>\n <div [class.h-100]=\"originalDataSet.length <= 10\">\n <div\n class=\"data-grid-body left-pinned-body w-100\"\n style=\"overflow-y: hidden\"\n [class.border-right]=\"hasLeftPinnedColumns\"\n [class.transparent-border-right]=\"!hasLeftPinnedColumns\"\n *ngIf=\"!loading && !dataSetLoading\"\n [@rowDynamic]=\"rowAnimation\"\n [style.transform]=\"\n 'translateY(' + startIndex * rowHeight + 'px)'\n \"\n >\n <ng-container\n *ngFor=\"\n let row of visibleRows;\n let i = index;\n trackBy: trackById\n \"\n >\n <ng-container\n *ngTemplateOutlet=\"\n rowCell;\n context: {\n $implicit: row,\n columns: previewLeftPinnedColumns,\n isEven: (startIndex + i) % 2 === 0,\n isOdd: (startIndex + i) % 2 !== 0,\n isLeft: true,\n section: 'left'\n }\n \"\n ></ng-container>\n </ng-container>\n </div>\n </div>\n\n <!-- CENTER -->\n <div\n class=\"\"\n [style.width.px]=\"centerPinnedHeader.clientWidth\"\n >\n <div\n class=\"data-grid-body center-scrollable\"\n [@rowDynamic]=\"rowAnimation\" *ngIf=\"!loading && !dataSetLoading\"\n style=\"overflow-y: hidden; overflow-x: auto\"\n [style.transform]=\"\n 'translateY(' + startIndex * rowHeight + 'px)'\n \"\n [style.backgroundColor]=\"bodyBackgroundColor\"\n #centerScrollableBody\n (scroll)=\"onCenterBodyScroll($event)\"\n [style.boxShadow]=\"leftPinnedBoxshadow\"\n\n >\n <ng-container \n *ngFor=\"\n let row of visibleRows;\n let i = index;\n trackBy: trackById\n \"\n >\n <ng-container\n *ngTemplateOutlet=\"\n rowCell;\n context: {\n $implicit: row,\n columns: previewCenterColumns,\n isEven: (startIndex + i) % 2 === 0,\n isOdd: (startIndex + i) % 2 !== 0,\n section: 'center'\n }\n \"\n ></ng-container>\n </ng-container>\n </div>\n </div>\n\n <!-- RIGHT PINNED -->\n <div\n class=\"right-pinned-body-wrapper\"\n *ngIf=\"hasRightPinnedColumns\"\n [class.h-100]=\"originalDataSet.length <= 10\"\n [style.max-width.px]=\"isScrollbarVisible ? rightPinnedHeader.offsetWidth - 15: rightPinnedHeader.offsetWidth\"\n >\n <div\n class=\"data-grid-body right-pinned-body w-100\"\n style=\"overflow-y: hidden\"\n [style.transform]=\"\n 'translateY(' + startIndex * rowHeight + 'px)'\n \"\n [style.boxShadow]=\"rightPinnedBoxshadow\"\n *ngIf=\"!loading && !dataSetLoading\"\n [@rowDynamic]=\"rowAnimation\"\n >\n <ng-container\n *ngFor=\"\n let row of visibleRows;\n let i = index;\n trackBy: trackById\n \"\n >\n <ng-container\n *ngTemplateOutlet=\"\n rowCell;\n context: {\n $implicit: row,\n columns: previewRightPinnedColumns,\n isEven: (startIndex + i) % 2 === 0,\n isOdd: (startIndex + i) % 2 !== 0,\n section: 'right'\n }\n \"\n ></ng-container>\n </ng-container>\n </div>\n </div>\n </div>\n <!-- Vertical Fake scroll Bar -->\n <div\n (scroll)=\"onMainFakeScroll($event)\"\n class=\"fake-scrollbar fake-scrollbar-vertical d-none\"\n [style.scrollbarWidth]=\"verticalScrollbarWidth\"\n [style.top.px]=\"\n showColumnsGrouping && showFilterRow\n ? headerRowHeight * 3\n : showColumnsGrouping || showFilterRow\n ? headerRowHeight * 2\n : headerRowHeight\n \"\n #fakeScroll\n [style.height]=\"bodyWrapperHeight\"\n style=\"\n overflow-y: auto;\n overflow-x: hidden;\n width: 17px;\n position: absolute;\n right: 0;\n background-color: f1f2f3;\n z-index: 10;\n \"\n >\n <div [style.height.px]=\"rowHeight * (paginationConfig.totalResults || flattenedData.length)\"></div>\n </div>\n </div>\n\n <!-- Horizintal Fake Scrollbars -->\n <div class=\"d-flex justify-content-between\" *ngIf=\"dataSet.length\">\n <div\n [style.scrollbarWidth]=\"horizintalScrollbarWidth\"\n class=\"fake-horizintal-scrollbar\"\n #fakeScroll\n [style.width.px]=\"leftPinnedHeader.offsetWidth\"\n style=\"overflow-x: scroll\"\n ></div>\n <div\n [style.scrollbarWidth]=\"horizintalScrollbarWidth\"\n (scroll)=\"onHorizintalFakeScroll($event)\"\n class=\"fake-horizintal-scrollbar\"\n #horizintalFakeScroll\n [style.width.px]=\"centerPinnedHeader.offsetWidth\"\n >\n <div [style.width.px]=\"centerPinnedHeader.scrollWidth\"></div>\n </div>\n <div\n [style.scrollbarWidth]=\"horizintalScrollbarWidth\"\n class=\"fake-horizintal-scrollbar\"\n #fakeScroll\n [style.width.px]=\"rightPinnedHeader.offsetWidth\"\n style=\"overflow-x: scroll\"\n ></div>\n </div>\n </div>\n\n <!-- Side Menu Implemented Here -->\n <div\n *ngIf=\"showSideMenu && !hasOpenAccordion\"\n [style.width.px]=\"sideMenuVisible ? 280 : 30\"\n class=\"right-menu h-100\"\n [style.backgroundColor]=\"sidemenuBackgroundColor\"\n >\n <div class=\"h-100 d-flex flex-row-reverse\">\n <div\n style=\"width: 30px\"\n class=\"d-flex flex-column align-items-center cursor-pointer\"\n [class.border-start]=\"sideMenuVisible\"\n >\n <div\n (click)=\"toggleSideMenu('cols')\"\n [class.bg-white]=\"\n currentOpenedSideMenue == 'cols' && sideMenuVisible\n \"\n [class.border-below]=\"sideMenuVisible\"\n class=\"columns-button d-flex flex-column align-items-center\"\n >\n <div>\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/ui-checks-grid.svg'\n \"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n </div>\n <div class=\"side-menue-text\">Columns</div>\n </div>\n\n <div\n (click)=\"toggleSideMenu('filtrs')\"\n [class.bg-white]=\"\n currentOpenedSideMenue == 'filtrs' && sideMenuVisible\n \"\n [class.border-below]=\"\n sideMenuVisible && currentOpenedSideMenue == 'filtrs'\n \"\n class=\"columns-button d-flex flex-column align-items-center\"\n >\n <div>\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\n \"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n </div>\n <div class=\"side-menue-text\">Filter</div>\n </div>\n </div>\n <div\n class=\"h-100\"\n *ngIf=\"sideMenuVisible\"\n [ngStyle]=\"{ width: sideMenuVisible ? '250px' : '' }\"\n >\n <div class=\"h-100\">\n <ng-container\n *ngIf=\"currentOpenedSideMenue == 'cols' && sideMenuVisible\"\n >\n <ng-container *ngTemplateOutlet=\"columnPannel\"></ng-container>\n <!-- Column Items -->\n <div class=\"column-panel-body px-3\">\n <ng-container\n *ngFor=\"let col of columns; trackBy: trackByField\"\n >\n <ng-container\n *ngTemplateOutlet=\"columnPanelItem; context: { col: col }\"\n ></ng-container>\n </ng-container>\n </div>\n <hr />\n\n <div class=\"side-menu-row-groups\" style=\"height: 30%\">\n <ng-container\n *ngTemplateOutlet=\"sideMenuRowGroups\"\n ></ng-container>\n </div>\n </ng-container>\n <ng-container\n *ngIf=\"currentOpenedSideMenue == 'filtrs' && sideMenuVisible\"\n >\n <ng-container *ngTemplateOutlet=\"sideFilters\"></ng-container>\n </ng-container>\n </div>\n </div>\n </div>\n </div>\n </div>\n <div [style.height.px]=\"footerRowHeight\" class=\"border-top\">\n <!-- Rows: <span class=\"fw-500 ms-1\">{{ dataSet.length }}</span> -->\n <div\n class=\"pagination-container\"\n [style.height.px]=\"footerRowHeight\"\n [style.padding.px]=\"footerPadding\"\n >\n <div class=\"page-size\">\n <select\n [(ngModel)]=\"paginationConfig.selectedPageSize\"\n (change)=\"onPageSizeChange()\"\n >\n <option *ngFor=\"let size of pageSizeOptions\" [value]=\"size\">\n {{ size }}\n </option>\n </select>\n <span class=\"\"> per page </span>\n </div>\n\n <div class=\"page-info\">\n Results: {{ startPageIndex }}-{{ endPageIndex }}\n of\n {{ paginationConfig.totalResults }}\n </div>\n\n <div class=\"page-buttons\">\n <button\n (click)=\"goToPage(paginationConfig.page - 1)\"\n [disabled]=\"paginationConfig.page === 1\"\n >\n \u2039\n </button>\n\n <ng-container *ngFor=\"let page of visiblePages\">\n <button\n *ngIf=\"page !== '...'\"\n (click)=\"goToPage(page)\"\n [class.active]=\"page === paginationConfig.page\"\n >\n {{ page }}\n </button>\n <span *ngIf=\"page === '...'\">...</span>\n </ng-container>\n\n <button\n (click)=\"goToPage(paginationConfig.page + 1)\"\n [disabled]=\"paginationConfig.page === paginationConfig.totalResults\"\n >\n \u203A\n </button>\n </div>\n </div>\n </div>\n </div>\n</div>\n\n<!-- ------------------------------------------------------------------------------------------------------------------------ -->\n<!-- ------------------------------------------------------------------------------------------------------------------------ -->\n<!-- Header Cell Template -->\n<!-- ------------------------------------------------------------------------------------------------------------------------ -->\n<!-- ------------------------------------------------------------------------------------------------------------------------ -->\n\n<ng-template\n #headerCell\n let-col\n let-pinnedRight=\"pinnedRight\"\n let-i=\"index\"\n let-sections=\"section\"\n let-calledFromNestedPlaceholder=\"calledFromNestedPlaceholder\"\n>\n <div>\n <!-- Group Header -->\n <ng-container *ngIf=\"col.children?.length > 0; else flatHeader\">\n <div cdkDroplistGroup class=\"group-column-wrapper\">\n <!-- Parent Header -->\n <div\n *ngIf=\"shouldTheGroupHeaderShow(col)\"\n class=\"header-cell group-header\"\n [style.height.px]=\"headerRowHeight\"\n [style.min-height.px]=\"headerRowHeight\"\n [style.max-height.px]=\"headerRowHeight\"\n [class.border-right]=\"showVerticalBorder\"\n [style.gridColumn]=\"'span ' + col.children.length\"\n [style.fontWeight]=\"headerFontWeight\"\n [class.flex-row-reverse]=\"pinnedRight\"\n [class.justify-content-end]=\"pinnedRight\"\n style=\"grid-row: 1\"\n >\n <div\n class=\"group-header-content\"\n [title]=\"col.header\"\n [class.ms-2]=\"pinnedRight\"\n >\n {{ col.header }}\n </div>\n <div\n class=\"resize-handle\"\n (dblclick)=\"autosizeColumn(col.children)\"\n (mousedown)=\"onResizeGroup($event, col, pinnedRight)\"\n >\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/resize-handle.svg'\n \"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n </div>\n </div>\n\n <!-- Child Headers and Filters -->\n\n <div\n class=\"d-flex\"\n cdkDropList\n cdkDropListOrientation=\"horizontal\"\n [cdkDropListData]=\"col.children\"\n (cdkDropListSorted)=\"onChildDroplistSorted($event, sections)\"\n (cdkDropListDropped)=\"onChildDroplistDroped($event)\"\n [cdkDropListSortingDisabled]=\"false\"\n [cdkDropListConnectedTo]=\"\n showRowsGrouping ? ['rows-grouping-top-container'] : []\n \"\n >\n <div\n cdkDrag\n [cdkDragData]=\"child\"\n *ngFor=\"let child of col.children; let i = index\"\n >\n <!-- Child Header -->\n <ng-container *ngIf=\"child.is_visible && !child['isRowGrouped']\">\n <div\n cdkDragHandle\n class=\"header-cell one-row-header-cells cursor-pointer\"\n [class.border-right]=\"showVerticalBorder\"\n [attr.field]=\"child.field\"\n [style.width.px]=\"child.width\"\n [style.min-width.px]=\"child.width\"\n [style.min-height.px]=\"headerRowHeight\"\n [style.max-height.px]=\"headerRowHeight\"\n [style.fontWeight]=\"headerFontWeight\"\n style=\"grid-row: 2\"\n [class.filter-applied-on-text]=\"isFilterAppliedOnColumn(child)\"\n >\n <div\n class=\"d-flex justify-content-between h-100 align-items-center w-100\"\n >\n <div\n class=\"d-flex justify-content-between w-100\"\n [class.flex-row-reverse]=\"pinnedRight\"\n >\n <div\n class=\"text-ellipsis h-100 d-flex align-items-center w-100\"\n [title]=\"col.header\"\n [class.w-100]=\"pinnedRight\"\n >\n <div\n class=\"text-ellipsis h-100\"\n [class.editable-header]=\"child?.is_editable\"\n (click)=\"openThreeDotsMenu($event, child); openFilteronThreeDotsClick(child)\"\n >\n {{ child.header }}\n </div>\n </div>\n\n <div\n class=\"position-relative d-flex\"\n [class.flex-row-reverse]=\"pinnedRight\"\n >\n <div\n [class.me-2]=\"pinnedRight\"\n class=\"d-flex align-items-center\"\n *ngIf=\"child.pinned\"\n >\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/pin-blue.svg'\n \"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n </div>\n <div\n class=\"three-dots p-1\"\n (click)=\"openThreeDotsMenu($event, child)\"\n style=\"cursor: pointer\"\n >\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath +\n 'data-grid/icons/three-dots-vertical.svg'\n \"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n </div>\n\n <!-- Only show menu if this column is active -->\n <div\n class=\"position-absolute\"\n *ngIf=\"activeCol === child\"\n style=\"top: -50%; z-index: 21\"\n [style.left.px]=\"\n -(!child?.pinned ? centerPinnedHeader.scrollLeft : 0)\n \"\n >\n <ng-container\n *ngTemplateOutlet=\"\n columnMenu;\n context: { col: child }\n \"\n ></ng-container>\n </div>\n\n <div\n class=\"resize-handle\"\n (dblclick)=\"autosizeColumn(child)\"\n (mousedown)=\"onResizeColumn($event, child)\"\n >\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath +\n 'data-grid/icons/resize-handle.svg'\n \"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n </div>\n </div>\n </div>\n </div>\n </div>\n\n <!-- Filter Cell -->\n <div\n *ngIf=\"showFilterRow\"\n [style.backgroundColor]=\"headerBackgroundColor\"\n class=\"header-cell filter-cell\"\n [class.border-right]=\"showVerticalBorder\"\n [attr.field]=\"child.field\"\n [style.width.px]=\"child.width\"\n [style.min-width.px]=\"child.width\"\n [style.height.px]=\"headerRowHeight\"\n [style.min-height.px]=\"headerRowHeight\"\n [style.max-height.px]=\"headerRowHeight\"\n [class.border-right]=\"showVerticalBorder\"\n style=\"grid-row: 3\"\n >\n <div\n class=\"header-cell filter-cell\"\n [attr.field]=\"col.field\"\n [style.width.px]=\"col.width\"\n [style.min-width.px]=\"col.width\"\n [style.height.px]=\"headerRowHeight\"\n [style.min-height.px]=\"headerRowHeight\"\n [style.max-height.px]=\"headerRowHeight\"\n >\n <input\n type=\"text\"\n class=\"form-control form-control-sm\"\n placeholder=\"Filter\"\n [(ngModel)]=\"col.filterValue\"\n (ngModelChange)=\"onFilterChange(col)\"\n />\n <span\n class=\"filter-icon-wrapper\"\n (click)=\"$event.stopPropagation(); openFilter(child)\"\n [class.filter-applied]=\"isFilterAppliedOnColumn(child)\"\n ><span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\n \"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n <span\n *ngIf=\"isFilterAppliedOnColumn(child)\"\n style=\"\n width: 7px;\n height: 7px;\n box-shadow: 0px 0px 3px #7486ff;\n background-color: rgb(0 163 233);\n position: absolute;\n right: 4px;\n top: 12px;\n \"\n class=\"rounded-circle d-block\"\n ></span\n ></span>\n\n <div\n class=\"position-absolute filter-row-filter-wrapper\"\n *ngIf=\"activeFilterCell?.field == child?.field\"\n style=\"top: 100%; right: 0; z-index: 99\"\n [style.left.px]=\"\n child?.pinned ? 0 : -centerPinnedHeader.scrollLeft\n \"\n >\n <ng-container\n *ngTemplateOutlet=\"filterMenu; context: { col: child }\"\n ></ng-container>\n </div>\n </div>\n </div>\n </ng-container>\n <ng-template cdkDragPreview\n ><div class=\"p-2 border d-flex gap-2\">\n <div\n *ngIf=\"\n !draggingInGroupArea ||\n (child.is_groupable && draggingInGroupArea)\n \"\n >\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/arrows-move.svg'\n \"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n </div>\n <div *ngIf=\"draggingInGroupArea && !child.is_groupable\">\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/ban.svg'\n \"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n </div>\n <div>{{ child.header }}</div>\n </div>\n </ng-template>\n <ng-template cdkDragPlaceholder>\n <div *ngIf=\"!draggingInGroupArea\" class=\"position-relative\">\n <div\n *ngTemplateOutlet=\"\n childHeaderPlaceholder;\n context: {\n $implicit: child,\n index: i,\n sections: sections,\n calledFromNestedPlaceholder: true,\n }\n \"\n ></div>\n </div>\n <div\n *ngIf=\"draggingInGroupArea && child?.is_groupable\"\n class=\"d-flex gap-2 ms-2\"\n style=\"opacity: 0.6\"\n >\n <ng-container\n *ngTemplateOutlet=\"\n topGroupingRowPlaceholder;\n context: {\n $implicit: child,\n showChevron: false,\n pinnedRight: pinnedRight,\n sections: sections,\n index: i\n }\n \"\n ></ng-container>\n </div>\n </ng-template>\n </div>\n </div>\n </div>\n </ng-container>\n\n <!-- Flat Header || Single Header Cell-->\n <ng-template #flatHeader>\n <div class=\"group-column-wrapper\">\n <!-- Full-height Header Cell (spans 2 rows visually) -->\n <div\n class=\"header-cell one-row-header-cells\"\n [attr.field]=\"col.field\"\n [style.width.px]=\"col.width\"\n [style.min-width.px]=\"col.width\"\n [class.border-right]=\"showVerticalBorder\"\n [style.min-height.px]=\"\n showColumnsGrouping ? headerRowHeight * 2 : headerRowHeight\n \"\n [style.height.px]=\"\n showColumnsGrouping ? headerRowHeight * 2 : headerRowHeight\n \"\n [style.fontWeight]=\"headerFontWeight\"\n style=\"grid-row: 1 / span 2\"\n >\n <div\n class=\"d-flex justify-content-between h-100 align-items-center w-100\"\n >\n <div\n class=\"d-flex justify-content-between w-100\"\n [class.flex-row-reverse]=\"pinnedRight\"\n >\n <div\n class=\"text-ellipsis h-100 d-flex align-items-center w-100\"\n [title]=\"col.header\"\n >\n <div\n class=\"text-ellipsis h-100 cursor-pointer\"\n [class.editable-header]=\"col?.is_editable\"\n [class.filter-applied-on-text]=\"isFilterAppliedOnColumn(col)\"\n (click)=\"openThreeDotsMenu($event, col); openFilteronThreeDotsClick(col)\"\n >\n {{ col.header }}\n </div>\n </div>\n\n <div\n class=\"position-relative d-flex\"\n [class.flex-row-reverse]=\"pinnedRight\"\n >\n <div\n [class.me-2]=\"pinnedRight\"\n class=\"d-flex align-items-center\"\n *ngIf=\"col?.pinned\"\n >\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/pin-blue.svg'\n \"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n </div>\n <div\n [class.me-2]=\"col.order_by\"\n class=\"d-flex align-items-center\"\n *ngIf=\"sortingConfig?.field == col.field\"\n >\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath +\n (sortingConfig?.order_by == 'desc'\n ? 'data-grid/icons/sort-desc.svg'\n : 'data-grid/icons/sort-asc.svg')\n \"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center mt-1\"\n ></span>\n </div>\n <div\n class=\"three-dots p-1\"\n (click)=\"openThreeDotsMenu($event, col)\"\n style=\"cursor: pointer\"\n >\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath +\n 'data-grid/icons/three-dots-vertical.svg'\n \"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n </div>\n\n <!-- Only show menu if this column is active -->\n <div\n class=\"position-absolute\"\n *ngIf=\"activeCol === col\"\n style=\"top: -50%; z-index: 21\"\n [style.left.px]=\"\n -(!col?.pinned ? centerPinnedHeader.scrollLeft : 0)\n \"\n >\n <ng-container\n *ngTemplateOutlet=\"columnMenu; context: { col: col }\"\n ></ng-container>\n </div>\n\n <div\n class=\"resize-handle\"\n [class.w-100]=\"col.pinned == 'right'\"\n (dblclick)=\"autosizeColumn(col)\"\n (mousedown)=\"onResizeColumn($event, col)\"\n >\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/resize-handle.svg'\n \"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n </div>\n </div>\n </div>\n </div>\n </div>\n\n <!-- Filter Cell -->\n <div\n *ngIf=\"showFilterRow\"\n [style.backgroundColor]=\"headerBackgroundColor\"\n class=\"header-cell filter-cell\"\n [class.border-right]=\"showVerticalBorder\"\n [attr.field]=\"col.field\"\n [style.width.px]=\"col.width\"\n [style.min-width.px]=\"col.width\"\n [style.height.px]=\"headerRowHeight\"\n [style.min-height.px]=\"headerRowHeight\"\n [style.max-height.px]=\"headerRowHeight\"\n >\n <input\n type=\"text\"\n class=\"form-control form-control-sm\"\n placeholder=\"Filter\"\n [(ngModel)]=\"col.filterValue\"\n (ngModelChange)=\"onFilterChange(col)\"\n />\n <span\n class=\"filter-icon-wrapper\"\n (click)=\"$event.stopPropagation(); openFilter(col)\"\n [class.filter-applied]=\"isFilterAppliedOnColumn(col)\"\n ><span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n <span\n *ngIf=\"isFilterAppliedOnColumn(col)\"\n style=\"\n width: 7px;\n height: 7px;\n box-shadow: 0px 0px 3px #7486ff;\n background-color: rgb(0 163 233);\n position: absolute;\n right: 4px;\n top: 12px;\n \"\n class=\"rounded-circle d-block\"\n ></span\n ></span>\n\n <div\n class=\"position-absolute filter-row-filter-wrapper\"\n *ngIf=\"activeFilterCell === col\"\n style=\"top: 100%; right: 0; z-index: 99\"\n [style.left.px]=\"col?.pinned ? 0 : -centerPinnedHeader.scrollLeft\"\n >\n <ng-container\n *ngTemplateOutlet=\"filterMenu; context: { col: col }\"\n ></ng-container>\n </div>\n </div>\n </div>\n </ng-template>\n </div>\n</ng-template>\n\n<!-- -------------------------------------------------------------------------------------------------------------------------------------------------------------------- -->\n<!-- -------------------------------------------------------------------------------------------------------------------------------------------------------------------- -->\n<!-- Body Cell Template -->\n<!-- -------------------------------------------------------------------------------------------------------------------------------------------------------------------- -->\n<!-- -------------------------------------------------------------------------------------------------------------------------------------------------------------------- -->\n\n<ng-template\n #rowCell\n let-row\n let-columns=\"columns\"\n let-isEven=\"isEven\"\n let-isOdd=\"isOdd\"\n let-isLeftSection=\"isLeft\"\n let-section=\"section\"\n let-rowIndex=\"rowIndex\"\n>\n <!-- Check if row is a group -->\n <ng-container\n *ngTemplateOutlet=\"groupRowTemplate; context: { $implicit: row, depth: 0 }\"\n ></ng-container>\n <ng-template #groupRowTemplate let-row let-depth=\"depth\">\n <ng-container *ngIf=\"row.isGroup; else regularRow\">\n <!-- Group Header -->\n <div\n class=\"group-header-row border-below d-flex align-items-center\"\n [style.height.px]=\"rowHeight\"\n [style.width]=\"\n section == 'center'\n ? centerScrollableBody?.nativeElement?.scrollWidth + 'px'\n : '100%'\n \"\n >\n <div\n *ngIf=\"section == 'left'\"\n class=\"h-100 d-flex\"\n [style.width.px]=\"leftPinnedHeader.offsetWidth - 1\"\n [class.row-selected]=\"rowSelectedIndexes.has(row.__virtualIndex)\"\n >\n <div\n *ngIf=\"showSerialNumber\"\n style=\"width: 50px\"\n class=\"d-flex align-items-center h-100 border-right justify-content-end pe-2 s-no\"\n [style.backgroundColor]=\"checkboxesBackgroundColor\"\n [style.width.px]=\"65\"\n [style.cursor]=\"\n 'url(' +\n singleSpaAssetsPath +\n 'data-grid/icons/arrow-right.svg), auto'\n \"\n (mousedown)=\"onRowMouseDown(row.__virtualIndex, $event)\"\n (mouseover)=\"onRowMouseOver(row.__virtualIndex, $event)\"\n >\n {{ row.__virtualIndex }}\n </div>\n <div\n style=\"width: 50px\"\n class=\"d-flex align-items-center justify-content-center h-100 border-right\"\n [style.backgroundColor]=\"checkboxesBackgroundColor\"\n [class.row-selected]=\"rowSelectedIndexes.has(row.__virtualIndex)\"\n [class.left-selection-border]=\"\n rowSelectedIndexes.has(row.__virtualIndex)\n \"\n [class.first-row-selected]=\"firstSelectedRow == row.__virtualIndex\"\n [class.last-row-selected]=\"lastSelectedRow == row.__virtualIndex\"\n >\n <input style=\"width: 16px; height: 16px\" type=\"checkbox\" />\n </div>\n </div>\n\n <div\n *ngIf=\"section == 'center'\"\n [style.width.px]=\"centerPinnedHeader.scrollWidth\"\n class=\"d-flex align-items-center ps-2 h-100\"\n [class.row-selected]=\"rowSelectedIndexes.has(row.__virtualIndex)\"\n [class.first-row-selected]=\"firstSelectedRow == row.__virtualIndex\"\n [class.last-row-selected]=\"lastSelectedRow == row.__virtualIndex\"\n >\n <div\n class=\"d-flex align-items-center justify-content-between\"\n [style.paddingLeft.px]=\"depth > 0 ? depth * 16 : 0\"\n >\n <span class=\"me-2 filter-icon-wrapper\" (click)=\"toggleExpand(row)\">\n <span\n class=\"data-grid-svg-icon\"\n [inlineSVG]=\"\n row.isExpand\n ? singleSpaAssetsPath + 'data-grid/icons/chevron-down.svg'\n : singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\n \"\n ></span>\n </span>\n <strong (click)=\"toggleExpand(row)\" class=\"cursor-pointer\">\n {{ row.groupValue }} ({{ countLeafRows(row) }})\n </strong>\n </div>\n </div>\n\n <div\n *ngIf=\"section == 'right'\"\n [style.width.px]=\"rightPinnedHeader.offsetWidth\"\n [class.row-selected]=\"rowSelectedIndexes.has(row.__virtualIndex)\"\n [class.first-row-selected]=\"firstSelectedRow == row.__virtualIndex\"\n [class.last-row-selected]=\"lastSelectedRow == row.__virtualIndex\"\n ></div>\n </div>\n\n <!-- Recursive Children -->\n <div class=\"group-children\" *ngIf=\"row.isExpand\">\n <ng-container\n *ngFor=\"let child of row.children; let i = index; trackBy: trackById\"\n >\n <ng-container *ngIf=\"child.isGroup; else dataRow\">\n <!-- Recursive call for nested group -->\n <ng-container\n *ngTemplateOutlet=\"\n groupRowTemplate;\n context: { $implicit: child, depth: depth + 1 }\n \"\n ></ng-container>\n </ng-container>\n\n <ng-template #dataRow>\n <!-- Regular data row -->\n <ng-container\n *ngTemplateOutlet=\"\n rowCell;\n context: {\n $implicit: child,\n columns: columns,\n isEven: i % 2 === 0,\n isOdd: i % 2 !== 0,\n isLeft: isLeftSection,\n section: section\n }\n \"\n ></ng-container>\n </ng-template>\n </ng-container>\n </div>\n </ng-container>\n </ng-template>\n\n <!-- Regular row (not a group) -->\n <ng-template #regularRow>\n <div class=\"d-flex\" [style.height.px]=\"rowHeight\">\n <span\n class=\"d-flex align-items-center justify-content-center cursor-pointer border-below\"\n style=\"min-width: 30px; height: 100%;\"\n *ngIf=\"section == 'center' && gridType === 'TimeSheet' && detailsIconPosition === 'start' && !areDatesSelectedAndEqual\"\n [ngStyle]=\"{\n 'background-color':\n hoveredRowId === (row._id || row.id)\n ? rowHoverColor\n : isRowSelected(row)\n ? checkedRowBackgroundColor\n : isEven\n ? evenRowsBackgroundColor\n : oddRowsBackgroundColor\n }\"\n (click)=\"toggleExpand(row)\"\n >\n <span\n class=\"data-grid-svg-icon\"\n [inlineSVG]=\"\n row.isDetailsExpand\n ? singleSpaAssetsPath + 'data-grid/icons/chevron-down.svg'\n : singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\n \"\n ></span>\n </span>\n <div\n [style.min-width.px]=\"\n section == 'center' && groupedColumns!.length ? groupBoxPadding : 0\n \"\n [class.row-selected]=\"rowSelectedIndexes.has(row.__virtualIndex)\"\n [class.first-row-selected]=\"firstSelectedRow == row.__virtualIndex\"\n [class.last-row-selected]=\"lastSelectedRow == row.__virtualIndex\"\n (contextmenu)=\"onRightClick($event, row, row?.details?.data?.length ? 'accordion-parent' : 'main')\"\n [style.height.px]=\"rowHeight\"\n class=\"data-grid-row h-100\"\n [class.even-row]=\"isEven\"\n [class.odd-row]=\"isOdd\"\n [class.hovered-row]=\"hoveredRowId === (row._id || row.id)\"\n (mouseenter)=\"onRowHover(row)\"\n (mouseleave)=\"onRowLeave()\"\n [ngStyle]=\"{\n 'background-color':\n hoveredRowId === (row._id || row.id)\n ? rowHoverColor\n : isRowSelected(row)\n ? checkedRowBackgroundColor\n : isEven\n ? evenRowsBackgroundColor\n : oddRowsBackgroundColor\n }\"\n ></div>\n <div\n (contextmenu)=\"onRightClick($event, row, row?.details?.data?.length ? 'accordion-parent' : 'main')\"\n [style.height.px]=\"rowHeight\"\n class=\"data-grid-row\"\n [class.even-row]=\"isEven\"\n [class.odd-row]=\"isOdd\"\n [class.hovered-row]=\"hoveredRowId === (row._id || row.id)\"\n (mouseenter)=\"onRowHover(row)\"\n (mouseleave)=\"onRowLeave()\"\n [ngStyle]=\"{\n 'background-color':\n hoveredRowId === (row._id || row.id)\n ? rowHoverColor\n : isRowSelected(row)\n ? checkedRowBackgroundColor\n : isEven\n ? evenRowsBackgroundColor\n : oddRowsBackgroundColor\n }\"\n >\n <div\n [style.backgroundColor]=\"checkboxesBackgroundColor\"\n class=\"select-all-checkbox-cell justify-content-end pe-2 s-no\"\n [style.width.px]=\"65\"\n *ngIf=\"isLeftSection && showSerialNumber\"\n [style.cursor]=\"\n 'url(' +\n singleSpaAssetsPath +\n 'data-grid/icons/arrow-right.svg), auto'\n \"\n (mousedown)=\"onRowMouseDown(row.__virtualIndex, $event)\"\n (mouseover)=\"onRowMouseOver(row.__virtualIndex, $event)\"\n >\n {{ row.__virtualIndex }}\n </div>\n <div\n [style.backgroundColor]=\"\n rowSelectedIndexes.has(row.__virtualIndex)\n ? selectedRowsBackgroundColor\n : checkboxesBackgroundColor\n \"\n class=\"select-all-checkbox-cell\"\n *ngIf=\"isLeftSection\"\n [class.left-selection-border]=\"\n rowSelectedIndexes.has(row.__virtualIndex)\n \"\n [class.first-row-selected]=\"firstSelectedRow == row.__virtualIndex\"\n [class.last-row-selected]=\"lastSelectedRow == row.__virtualIndex\"\n >\n <input\n *ngIf=\"hasAnyVisibleColumn\"\n type=\"checkbox\"\n [checked]=\"isRowSelected(row)\"\n (change)=\"toggleRowSelection(row)\"\n />\n </div>\n\n <!-- Render all columns -->\n <ng-container\n *ngFor=\"\n let col of columns;\n trackBy: trackByField;\n let colIndex = index\n \"\n >\n <ng-container *ngIf=\"col.children?.length > 0; else flatColumn\">\n <ng-container\n *ngFor=\"\n let child of col.children;\n trackBy: trackByField;\n let subColIndex = index\n \"\n >\n <ng-container *ngIf=\"child?.is_visible && !child?.isRowGrouped\">\n <ng-container\n *ngTemplateOutlet=\"\n cellTemplate;\n context: {\n col: child,\n row: row,\n rowIndex: rowIndex,\n colIndex: colIndex,\n subColIndex: subColIndex,\n section: section\n }\n \"\n ></ng-container>\n </ng-container>\n </ng-container>\n </ng-container>\n\n <ng-template #flatColumn>\n <ng-container\n *ngTemplateOutlet=\"\n cellTemplate;\n context: {\n col: col,\n row: row,\n rowIndex: rowIndex,\n colIndex: colIndex,\n subColIndex: null,\n section: section\n }\n \"\n ></ng-container>\n </ng-template>\n </ng-container>\n </div>\n\n <span\n class=\"d-flex align-items-center justify-content-center cursor-pointer border-below\"\n style=\"min-width: 30px; height: 100%;\"\n *ngIf=\"section == 'center' && gridType === 'TimeSheet' && detailsIconPosition === 'end' && !areDatesSelectedAndEqual\"\n [ngStyle]=\"{\n 'background-color':\n hoveredRowId === (row._id || row.id)\n ? rowHoverColor\n : isRowSelected(row)\n ? checkedRowBackgroundColor\n : isEven\n ? evenRowsBackgroundColor\n : oddRowsBackgroundColor\n }\"\n (click)=\"toggleExpand(row)\"\n >\n <span\n class=\"data-grid-svg-icon\"\n [inlineSVG]=\"\n row.isDetailsExpand\n ? singleSpaAssetsPath + 'data-grid/icons/chevron-down.svg'\n : singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\n \"\n ></span>\n </span>\n </div>\n <!-- LEFT PINNED: Empty table to keep alignment -->\n <div *ngIf=\"section === 'left' && row.isDetailsExpand && !isSingleDay\" class=\"accordion-details data-grid-accordion-section\" [style.color]=\"headerTextColor\" style=\"max-height: 350px; min-height: 150px ; overflow: hidden;\">\n <table class=\"nested-table table table-sm w-100 mb-0 data-grid-accordion-table\" [class.show-shadow]=\"rowShadingEnabled\">\n <thead>\n <tr [style.height.px]=\"nestedTableHeaderRowHeight\" [style.backgroundColor]=\"headerBackgroundColor\" [style.color]=\"headerTextColor\" [style.fontSize.px]=\"headerTextFontsSize\" [style.fontWeight]=\"headerFontWeight\">\n <th *ngFor=\"let _ of [1, 2, 3, 4, 5]\"></th>\n </tr>\n </thead>\n <tbody>\n <tr [style.height.px]=\"nestedTablerowHeight\" *ngFor=\"let _ of row.details.data\" [style.backgroundColor]=\"headerBackgroundColor\">\n <td *ngFor=\"let __ of [1, 2, 3, 4, 5]\"></td>\n </tr>\n </tbody>\n </table>\n </div>\n\n<!-- CENTER SECTION: Actual details table -->\n\n<div *ngIf=\"section === 'center' && row.isDetailsExpand && !isSingleDay\" class=\"accordion-details-wrapper data-grid-accordion\" [style.fontFamily]=\"fontFaimly\" [style.fontSize.px]=\"bodyTextFontsSize\" style=\"display: flex; width: 100%; max-height: 350px; min-height: 150px ; overflow: hidden ; \">\n <!-- LEFT SECTION OF ACCORDION -->\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;\">\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;\">\n <thead>\n <tr [style.height.px]=\"nestedTableHeaderRowHeight\" [style.backgroundColor]=\"headerBackgroundColor\" [style.color]=\"headerTextColor\" [style.fontSize.px]=\"headerTextFontsSize\" [style.fontWeight]=\"headerFontWeight\">\n <ng-container *ngFor=\"let col of row.details.columns | pinnedColumns:'left'; trackBy: trackByField\">\n <th *ngIf=\"col.is_visible !== false\"\n class=\"px-4\"\n [class.filter-applied]=\"isAccordionColumnFiltered(row, col)\"\n [style.color]=\"isAccordionColumnFiltered(row, col) ? '#007bff' : headerTextColor\"\n [attr.field]=\"col.field\"\n [attr.pinned]=\"col.pinned\"\n [style.width.px]=\"col.width || 200\"\n [style.min-width.px]=\"col.width || 200\">\n <div class=\"d-flex justify-content-between align-items-center\" style=\"width: 100%;\">\n <span class=\"d-flex align-items-center gap-1\" style=\"overflow: hidden; width: 100%;\">\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>\n <span class=\"text-truncate\" style=\"flex: 1; min-width: 0;\" title=\"{{ col.header }}\">{{ col.header }}</span>\n <span *ngIf=\"isAccordionColumnFiltered(row, col)\"\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\"\n class=\"data-grid-svg-icon text-primary ms-1\"\n style=\"font-size: 12px;\"></span>\n </span>\n <span class=\"three-dots p-1\"\n (click)=\"openDetailThreeDotsMenus($event, col, row, $any($event.currentTarget))\">\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/three-dots-vertical.svg'\" class=\"data-grid-svg-icon\"></span>\n </span>\n </div>\n <!-- <div class=\"resize-handles\" (mousedown)=\"onResizeDetailColumn($event, row, col)\">\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/resize-handle.svg'\" class=\"data-grid-svg-icon text-primary\"></span>\n </div> -->\n <ng-container *ngIf=\"activeDetailCol?.field == col.field && activeDetailRow === row\">\n <div class=\"position-absolute detail-column-menu-wrapper\"\n [style.top.px]=\"nestedTableHeaderRowHeight\"\n [style.left.px]=\"0\">\n <ng-container *ngTemplateOutlet=\"detailColumnMenu; context: { col: col, row: row }\"></ng-container>\n </div>\n </ng-container>\n </th>\n </ng-container>\n </tr>\n </thead>\n <tbody>\n <tr [style.height.px]=\"nestedTablerowHeight\" *ngFor=\"let d of row.details.data; let j = index; trackBy: trackById\" [ngStyle]=\"getAccordionRowStyle(j, row)\">\n <ng-container *ngFor=\"let col of row.details.columns | pinnedColumns:'left'; let localK = index; trackBy: trackByField\">\n <td *ngIf=\"col.is_visible !== false\"\n class=\"px-4\"\n (mousedown)=\"startDetailSelection(row, j, localK, col.field, $event, 'left')\"\n (mouseenter)=\"extendDetailSelection(row, j, localK, col.field, $event, 'left')\"\n [class.selected-cell]=\"isDetailCellSelected(row, j, localK, col.field, 'left')\"\n [attr.field]=\"col.field\"\n [attr.pinned]=\"col.pinned\"\n [style.fontSize.px]=\"bodyTextFontsSize\"\n (dblclick)=\"enableDetailEdits(row, d, col)\"\n [class.active-cell-detail]=\"isActiveDetailCell(row, d, col)\">\n <!-- Use the same rendering logic as center section -->\n <ng-container [ngSwitch]=\"col.field\">\n\n <ng-container *ngSwitchCase=\"'manually_logs'\" class=\"d-flex justify-content-start align-items-center pointer position-relative\">\n <ng-container *ngIf=\"d.manually_logs?.length > 0; else noManualLogsIcon\">\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/eye.svg'\"\n class=\"data-grid-svg-icon text-primary\"\n style=\"cursor: pointer; font-size: 16px;\"\n (mouseenter)=\"showManualLogsTooltip($event, row, d)\"\n (mouseleave)=\"hideManualLogsTooltip()\">\n </span>\n </ng-container>\n <ng-template #noManualLogsIcon>\u2013</ng-template>\n</ng-container>\n <!-- Breaks -->\n <ng-container *ngSwitchCase=\"'breaks'\">\n <ng-container *ngIf=\"d[col.field]?.length; else noBreaksLeft\">\n <app-badge-overflow\n [badges]=\"getBreakBadges(d[col.field])\"\n [maxWidth]=\"col.width || 200\"\n (badgeMouseEnter)=\"showBreakTooltip($event.event, $event.badge.data)\"\n (badgeMouseLeave)=\"hideBreakTooltip()\"\n (overflowCountClick)=\"onDetailBadgeOverflowCountClick(col, d)\">\n</app-badge-overflow>\n </ng-container>\n <ng-template #noBreaksLeft>\n <div >\n -\n </div>\n </ng-template>\n </ng-container>\n\n <!-- Short Breaks -->\n <ng-container *ngSwitchCase=\"'short_breaks'\">\n <ng-container *ngIf=\"d[col.field]?.short_break_duration; else noShortBreakLeft\">\n <div (dblclick)=\"onShortBreakClick.emit(d)\">\n <app-badge-overflow\n [badges]=\"getShortBreakBadges(d[col.field])\"\n [maxWidth]=\"col.width || 200\"\n (badgeMouseEnter)=\"showShortBreakTooltip($event.event, d)\"\n (badgeMouseLeave)=\"hideShortBreakTooltip()\"\n (badgeClick)=\"handleShortBreakClick(d, $event)\"\n (overflowCountClick)=\"onDetailBadgeOverflowCountClick(col, d)\">\n </app-badge-overflow>\n </div>\n </ng-container>\n <ng-template #noShortBreakLeft>\n <div >-</div>\n </ng-template>\n </ng-container>\n\n <!-- Short Leave -->\n <!-- Short Leave -->\n<ng-container *ngSwitchCase=\"'short_leave'\">\n <ng-container *ngIf=\"row.short_leave && row.short_leave.length > 0; else noShortLeaveMain\">\n <div class=\"w-100 d-flex main-progress-bar justify-content-center align-items-center\" \n style=\"background-color: rgb(111, 97, 207); height: 20px; border-radius: 4px; position: relative;\"\n (mouseenter)=\"showShortLeaveTooltip($event, row)\"\n (mouseleave)=\"hideShortLeaveTooltip()\">\n <span class=\"d-block\" [style.min-width.%]=\"row.short_leave[0].short_leave_time_percentage\" \n style=\"background-color: rgb(238, 99, 82); height: 100%; border-radius: 4px;\"></span>\n <span style=\"position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); color: white; font-size: 12px; font-weight: bold;\">\n {{ row.short_leave[0].short_leave_time_percentage }}%\n </span>\n </div>\n </ng-container>\n <ng-template #noShortLeaveMain>-</ng-template>\n</ng-container>\n\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()\">\n <div style=\"overflow: hidden; text-overflow: ellipsis; white-space: nowrap; width: 100%;\" [class.restriction-indicator]=\"row.attendance_log_detail?.length > 0\" title=\"{{ d.is_un_restricted ? 'Yes' : 'No' }}\">\n {{ d.is_un_restricted ? 'Yes' : 'No' }}\n </div>\n</div>\n\n <div *ngSwitchCase=\"'is_payroll_processed'\" class=\"d-flex justify-content-start flex-column pointer position-relative\" >\n <div style=\"overflow: hidden; text-overflow: ellipsis; white-space: nowrap; width: 100%;\">\n {{ d.is_payroll_processed ? 'Yes' : 'No' }}\n </div>\n </div>\n\n\n <!-- Status -->\n <ng-container *ngSwitchCase=\"'status'\">\n <ng-container *ngIf=\"getNestedValue(d, col.field); else noStatus\">\n <span class=\"badge\" [class]=\"getStatusBadgeClass(getNestedValue(d, col.field))\">\n {{ transformStatus(getNestedValue(d, col.field)) }}\n </span>\n </ng-container>\n <ng-template #noStatus>-</ng-template>\n</ng-container>\n\n<!-- Attendance Status -->\n<ng-container *ngSwitchCase=\"'attendanceStatus'\">\n <ng-container *ngIf=\"getNestedValue(d, col.field); else noAttendanceStatus\">\n <span class=\"badge\" [class]=\"getAttendanceStatusBadgeClass(getNestedValue(d, col.field))\">\n {{ transformStatus(getNestedValue(d, col.field)) }}\n </span>\n </ng-container>\n <ng-template #noAttendanceStatus>-</ng-template>\n</ng-container>\n\n <!-- Default fallback -->\n <ng-container *ngSwitchDefault>\n <div style=\"overflow: hidden; text-overflow: ellipsis; white-space: nowrap; width: 100%;\" title=\"{{\n col.type === 'date'\n ? (getNestedValue(d, col.field) ? (getNestedValue(d, col.field) | timezoneFormat:prefs:'date') : '-')\n : col.type === 'time'\n ? ((getTimeValue(getNestedValue(d, col.field)) | timezoneFormat:prefs:'time'))\n : (getNestedValue(d, col.field)?.value || getNestedValue(d, col.field)?.name || getNestedValue(d, col.field) || '-')\n }}\">{{ col.type === 'date'\n ? (getNestedValue(d, col.field) ? (getNestedValue(d, col.field) | timezoneFormat:prefs:'date') : '-')\n : col.type === 'time'\n ? ((getTimeValue(getNestedValue(d, col.field)) | timezoneFormat:prefs:'time'))\n : (getNestedValue(d, col.field)?.value || getNestedValue(d, col.field)?.name || getNestedValue(d, col.field) || '-')\n }}</div>\n </ng-container>\n </ng-container>\n </td>\n </ng-container>\n </tr>\n</tbody>\n </table>\n </div>\n\n <!-- CENTER SECTION OF ACCORDION (WITH VIRTUAL SCROLL) -->\n\n<div class=\"accordion-center-section data-grid-accordion-section\" style=\"flex: 1; min-width: 0; display: flex; flex-direction: column; overflow: hidden;\">\n <!-- Header Section -->\n <div class=\"header-container\" style=\"overflow-x: auto; scrollbar-width: none; -ms-overflow-style: none;\" #headerContainer (scroll)=\"syncScroll($event)\">\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%;\">\n <thead>\n <tr\n [style.height.px]=\"nestedTableHeaderRowHeight\"\n cdkDropList\n [cdkDropListData]=\"row?.details.columns\"\n cdkDropListOrientation=\"horizontal\"\n (cdkDropListDropped)=\"dropColumn($event, row)\"\n >\n <ng-container *ngFor=\"let col of row.details.columns; let i = index\">\n <th\n *ngIf=\"col.is_visible !== false && !col.pinned\"\n class=\"px-4\"\n cdkDrag\n [attr.field]=\"col.field\"\n [class.filter-applied]=\"isAccordionColumnFiltered(row, col)\"\n [style.width.px]=\"col.width || 200\"\n [style.min-width.px]=\"col.width || 200\"\n [style.backgroundColor]=\"headerBackgroundColor\"\n [style.color]=\"isAccordionColumnFiltered(row, col) ? '#007bff' : headerTextColor\"\n [style.fontSize.px]=\"headerTextFontsSize\"\n [style.fontWeight]=\"headerFontWeight\"\n style=\"cursor: move; position: relative;\">\n <div class=\"d-flex justify-content-between align-items-center\" style=\"width: 100%;\">\n <span class=\"d-flex align-items-center gap-1\" style=\"overflow: hidden; width: 100%;\">\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>\n <span class=\"text-truncate\" style=\"flex: 1; min-width: 0;\" title=\"{{ col.header }}\">{{ col.header }}</span>\n <span *ngIf=\"isAccordionColumnFiltered(row, col)\"\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\"\n class=\"data-grid-svg-icon text-primary ms-1\"\n style=\"font-size: 12px;\"></span>\n </span>\n <span class=\"three-dots p-1\"\n (click)=\"openDetailThreeDotsMenus($event, col, row, $any($event.currentTarget))\">\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/three-dots-vertical.svg'\" class=\"data-grid-svg-icon\"></span>\n </span>\n </div>\n <!-- <div class=\"resize-handles\" (mousedown)=\"onResizeDetailColumn($event, row, col)\">\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/resize-handle.svg'\" class=\"data-grid-svg-icon text-primary\"></span>\n </div> -->\n <ng-container *ngIf=\"activeDetailCol?.field == col.field && activeDetailRow === row\">\n <div class=\"position-absolute detail-column-menu-wrapper\" [style.top.px]=\"nestedTableHeaderRowHeight\" [style.left.px]=\"0\">\n <ng-container *ngTemplateOutlet=\"detailColumnMenu; context: { col: col, row: row }\"></ng-container>\n </div>\n </ng-container>\n </th>\n </ng-container>\n </tr>\n </thead>\n </table>\n </div>\n\n <!-- Group Badges (if any) -->\n <div *ngIf=\"row.details?.groupedColumns?.length\" class=\"detail-group-badges\">\n <span *ngFor=\"let g of row.details.groupedColumns; trackBy: trackByField\" class=\"badge bg-light text-dark me-1\">\n {{ g.header }}\n <span class=\"ms-1 cursor-pointer\" (click)=\"ungroupDetailColumn(g, row)\" [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/x.svg'\"></span>\n </span>\n </div>\n\n <!-- No Data Message when filtered results are empty -->\n <div *ngIf=\"row.details.data.length === 0\" class=\"d-flex justify-content-center align-items-center\" style=\"flex: 1; min-height: 104px ;\">\n <div class=\"text-center text-muted\">\n <div class=\"mb-2\">\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\" class=\"data-grid-svg-icon text-muted\" style=\"font-size: 24px;\"></span>\n </div>\n <div class=\"fw-bold\">No records found for this filter.</div>\n </div>\n </div>\n\n <!-- Data Table Section with Virtual Scroll -->\n <cdk-virtual-scroll-viewport\n *ngIf=\"row.details.data.length > 0\"\n itemSize=\"{{ nestedTablerowHeight }}\"\n minBufferPx=\"200\"\n maxBufferPx=\"400\"\n class=\"detail-virtual-scroll\"\n [attr.data-detail-row-id]=\"row._id || row.id\"\n style=\"flex: 1; overflow: auto;\"\n #dataContainer\n (scroll)=\"syncVerticalScroll($event)\"\n (scroll)=\"syncScroll($event)\">\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%;\">\n <tbody>\n <tr\n class=\"cursor-pointer data-grid-accordion-row\"\n *cdkVirtualFor=\"let d of row.details.data; trackBy: trackById; let j = index\"\n (contextmenu)=\"onRightClick($event, d, 'accordion-child')\"\n [style.height.px]=\"nestedTablerowHeight\"\n [ngStyle]=\"getAccordionRowStyle(j, row)\">\n <ng-container *ngFor=\"let col of row.details.columns; let k = index\">\n <td\n *ngIf=\"col.is_visible !== false && !col.pinned\"\n class=\"px-4\"\n (mousedown)=\"startDetailSelection(row, j, k, col.field, $event, 'center')\"\n (mouseenter)=\"extendDetailSelection(row, j, k, col.field, $event, 'center')\"\n [class.selected-cell]=\"isDetailCellSelected(row, j, k, col.field, 'center')\"\n [attr.field]=\"col.field\"\n [style.width.px]=\"col.width || 200\"\n [style.min-width.px]=\"col.width || 200\"\n [style.fontSize.px]=\"bodyTextFontsSize\"\n [class.active-cell-detail]=\"isActiveDetailCell(row, d, col)\"\n style=\"cursor: pointer; position: relative; overflow: visible; cursor: cell; \">\n <div class=\"time-sheet-container\" style=\"overflow: visible; display: flex; gap: 4px; align-items: center; height: 100%; \">\n <ng-container *ngIf=\"col.field === 'breaks' || col.field === 'short_breaks'; else defaultDetailCell\">\n <ng-container *ngIf=\"col.field === 'breaks'\">\n <ng-container *ngIf=\"d[col.field]?.length; else noBreaks\">\n <span\n *ngFor=\"let breakItem of d[col.field]; let breakIndex = index\"\n class=\"circle-value badge-outline break-on text-center\"\n [ngClass]=\"(breakItem.break_type?.data_value_name?.toLowerCase() || breakItem.breakType?.toLowerCase()) === 'paid' \n ? 'break-color-paid' \n : (breakItem.break_type?.data_value_name?.toLowerCase() || breakItem.breakType?.toLowerCase()) === 'unpaid' \n ? 'break-color-unpaid' \n : (breakItem.break_type?.data_value_name?.toLowerCase() || breakItem.breakType?.toLowerCase()) === 'lunch' \n ? 'break-color-lunch' \n : 'break-color-default'\"\n (mouseenter)=\"showBreakTooltip($event, breakItem)\"\n (mouseleave)=\"hideBreakTooltip()\"\n >\n <!-- Show total_minutes_logged if available and truthy, else break_duration -->\n {{ (breakItem.total_minutes_logged || breakItem.break_duration) }}m\n </span>\n </ng-container>\n\n <ng-template #noBreaks>\n <div>-</div>\n </ng-template>\n</ng-container>\n <ng-container *ngIf=\"col.field === 'short_breaks' && !isDetailEditing(row, d, col)\">\n <ng-container *ngIf=\"d[col.field]?.short_break_duration; else noShortBreak\">\n <div (dblclick)=\"onShortBreakClick.emit(d)\">\n <app-badge-overflow\n [badges]=\"getShortBreakBadges(d[col.field])\"\n [maxWidth]=\"col.width || 200\"\n (badgeMouseEnter)=\"showShortBreakTooltip($event.event, d)\"\n (badgeMouseLeave)=\"hideShortBreakTooltip()\"\n (badgeClick)=\"handleShortBreakClick(d, $event)\"\n (overflowCountClick)=\"onDetailBadgeOverflowCountClick(col, d)\">\n </app-badge-overflow>\n </div>\n </ng-container>\n <ng-template #noShortBreak>\n <div >-</div>\n </ng-template>\n</ng-container>\n <ng-container *ngIf=\"isDetailEditing(row, d, col)\">\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;\" />\n </ng-container>\n </ng-container>\n <ng-template #defaultDetailCell>\n <span class=\"d-flex align-items-center h-100\">\n <ng-container *ngIf=\"!isDetailEditing(row, d, col)\">\n <ng-container [ngSwitch]=\"col.field\">\n <!-- \u2705 SHORT LEAVE: Progress bar in detail rows -->\n <div *ngSwitchCase=\"'short_leave'\" class=\"position-relative\" style=\"min-width: 100px; width: 200px;\">\n <ng-container *ngIf=\"d.short_leave && d.short_leave.length > 0; else noShortLeaveDetail\">\n <div\n class=\"w-100 d-flex main-progress-bar\"\n style=\"background-color: rgb(111, 97, 207); height: 20px; border-radius: 4px; position: relative;\"\n (mouseenter)=\"showShortLeaveTooltip($event, d)\"\n (mouseleave)=\"hideShortLeaveTooltip()\"\n >\n <span\n class=\"d-block\"\n [style.min-width.%]=\"d.short_leave[0].short_leave_time_percentage\"\n style=\"background-color: rgb(238, 99, 82); height: 100%; border-radius: 4px;\"\n ></span>\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>\n </div>\n </ng-container>\n <ng-template #noShortLeaveDetail>\n <div >-</div>\n </ng-template>\n </div>\n\n <!-- Status -->\n<ng-container *ngSwitchCase=\"'status'\">\n <ng-container *ngIf=\"getNestedValue(d, col.field); else noStatus\">\n <span class=\"badge\" [class]=\"getStatusBadgeClass(getNestedValue(d, col.field))\">\n {{ transformStatus(getNestedValue(d, col.field)) }}\n </span>\n </ng-container>\n <ng-template #noStatus>-</ng-template>\n</ng-container>\n\n<!-- Attendance Status -->\n<ng-container *ngSwitchCase=\"'attendanceStatus'\">\n <ng-container *ngIf=\"getNestedValue(d, col.field); else noAttendanceStatus\">\n <span class=\"badge\" [class]=\"getAttendanceStatusBadgeClass(getNestedValue(d, col.field))\">\n {{ transformStatus(getNestedValue(d, col.field)) }}\n </span>\n </ng-container>\n <ng-template #noAttendanceStatus>-</ng-template>\n</ng-container>\n\n <!-- Existing cases -->\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()\">\n <div class=\"popover__wrapper\" style=\"overflow: hidden; text-overflow: ellipsis; white-space: nowrap; width: 100%;\" [class.restriction-indicator]=\"row.attendance_log_detail?.length > 0\">\n {{ d.is_un_restricted ? 'Yes' : 'No' }}\n </div>\n </div>\n\n <div *ngSwitchCase=\"'is_payroll_processed'\" class=\"d-flex justify-content-start flex-column pointer position-relative\" >\n <div style=\"overflow: hidden; text-overflow: ellipsis; white-space: nowrap; width: 100%;\" title=\"{{ d.is_payroll_processed ? 'Yes' : 'No' }}\">\n {{ d.is_payroll_processed ? 'Yes' : 'No' }}\n </div>\n </div>\n <div *ngSwitchCase=\"'manually_logs'\" class=\"d-flex justify-content-start align-items-center pointer position-relative\">\n <ng-container *ngIf=\"d.manually_logs?.length > 0; else noManualLogsIcon\">\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>\n </ng-container>\n <ng-template #noManualLogsIcon>\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>\n </ng-template>\n </div>\n\n <!-- Default fallback -->\n <div *ngSwitchDefault style=\"overflow: hidden; text-overflow: ellipsis; white-space: nowrap; width: 100%;\" title=\"{{\n col.type === 'date'\n ? (getNestedValue(d, col.field) ? (getNestedValue(d, col.field) | timezoneFormat:prefs:'date') : '-')\n : col.type === 'time'\n ? ((getTimeValue(getNestedValue(d, col.field)) | timezoneFormat:prefs:'time'))\n : (getNestedValue(d, col.field)?.value || getNestedValue(d, col.field)?.name || getNestedValue(d, col.field) || '-')\n }}\">\n {{\n col.type === 'date'\n ? (getNestedValue(d, col.field) ? (getNestedValue(d, col.field) | timezoneFormat:prefs:'date') : '-')\n : col.type === 'time'\n ? ((getTimeValue(getNestedValue(d, col.field)) | timezoneFormat:prefs:'time'))\n : (getNestedValue(d, col.field)?.value || getNestedValue(d, col.field)?.name || getNestedValue(d, col.field) || '-')\n }}\n </div>\n</ng-container>\n </ng-container>\n <ng-container *ngIf=\"isDetailEditing(row, d, col)\">\n <ng-container [ngSwitch]=\"col.type\">\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;\" />\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;\" />\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;\" />\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;\" />\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;\" />\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;\">\n <option *ngFor=\"let option of col.column_dropdown_value\" [ngValue]=\"option?.value || option\">\n {{ option?.label || option?.name || option }}\n </option>\n </select>\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;\" />\n </ng-container>\n </ng-container>\n </span>\n </ng-template>\n </div>\n </td>\n </ng-container>\n </tr>\n </tbody>\n </table>\n </cdk-virtual-scroll-viewport>\n</div>\n\n <!-- RIGHT SECTION OF ACCORDION -->\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;\">\n <table class=\"nested-table table-sm mb-0 data-grid-accordion-table\" [class.show-shadow]=\"rowShadingEnabled\" style=\"table-layout: fixed; width: auto;\">\n <thead>\n <tr [style.height.px]=\"nestedTableHeaderRowHeight\" [style.backgroundColor]=\"headerBackgroundColor\" [style.color]=\"headerTextColor\" [style.fontSize.px]=\"headerTextFontsSize\" [style.fontWeight]=\"headerFontWeight\">\n <ng-container *ngFor=\"let col of row.details.columns | pinnedColumns:'right'; trackBy: trackByField\">\n <th *ngIf=\"col.is_visible !== false\"\n class=\"px-4\"\n [class.filter-applied]=\"isAccordionColumnFiltered(row, col)\"\n [style.width.px]=\"col.width || 200\"\n [style.min-width.px]=\"col.width || 200\"\n [style.color]=\"isAccordionColumnFiltered(row, col) ? '#007bff' : headerTextColor\"\n [attr.field]=\"col.field\"\n [attr.pinned]=\"col.pinned\">\n <div class=\"d-flex justify-content-between align-items-center\" style=\"width: 100%;\">\n <span class=\"d-flex align-items-center gap-1\" style=\"overflow: hidden; width: 100%;\">\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/pin-blue.svg'\"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"></span>\n <span class=\"text-truncate\" style=\"flex: 1; min-width: 0;\" title=\"{{ col.header }}\">{{ col.header }}</span>\n <span *ngIf=\"isAccordionColumnFiltered(row, col)\"\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\"\n class=\"data-grid-svg-icon text-primary ms-1\"\n style=\"font-size: 12px;\"></span>\n </span>\n <span class=\"three-dots p-1\"\n (click)=\"openDetailThreeDotsMenus($event, col, row, $any($event.currentTarget))\">\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/three-dots-vertical.svg'\" class=\"data-grid-svg-icon\"></span>\n </span>\n </div>\n\n <!-- <div class=\"resize-handles\" (mousedown)=\"onResizeDetailColumn($event, row, col)\">\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/resize-handle.svg'\" class=\"data-grid-svg-icon text-primary\"></span>\n </div> -->\n <ng-container *ngIf=\"activeDetailCol?.field == col.field && activeDetailRow === row\">\n <div class=\"position-absolute detail-column-menu-wrapper\"\n [style.top.px]=\"nestedTableHeaderRowHeight\"\n [style.left.px]=\"0\">\n <ng-container *ngTemplateOutlet=\"detailColumnMenu; context: { col: col, row: row }\"></ng-container>\n </div>\n </ng-container>\n </th>\n </ng-container>\n </tr>\n </thead>\n <tbody>\n <tr [style.height.px]=\"nestedTablerowHeight\" *ngFor=\"let d of row.details.data; let j = index; trackBy: trackById\" [ngStyle]=\"getAccordionRowStyle(j, row)\">\n <ng-container *ngFor=\"let col of row.details.columns | pinnedColumns:'right'; let localK = index; trackBy: trackByField\">\n <td *ngIf=\"col.is_visible !== false\"\n class=\"px-4\"\n [attr.field]=\"col.field\"\n [attr.pinned]=\"col.pinned\"\n (mousedown)=\"startDetailSelection(row, j, localK, col.field, $event, 'right')\"\n (mouseenter)=\"extendDetailSelection(row, j, localK, col.field, $event, 'right')\"\n [class.selected-cell]=\"isDetailCellSelected(row, j, localK, col.field, 'right')\"\n [style.fontSize.px]=\"bodyTextFontsSize\"\n [class.active-cell-detail]=\"isActiveDetailCell(row, d, col)\">\n <ng-container [ngSwitch]=\"col.field\">\n\n <ng-container *ngSwitchCase=\"'manually_logs'\" class=\"d-flex justify-content-start align-items-center pointer position-relative\">\n <ng-container *ngIf=\"d.manually_logs?.length > 0; else noManualLogsIcon\">\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/eye.svg'\"\n class=\"data-grid-svg-icon text-primary\"\n style=\"cursor: pointer; font-size: 16px;\"\n (mouseenter)=\"showManualLogsTooltip($event, row, d)\"\n (mouseleave)=\"hideManualLogsTooltip()\">\n </span>\n </ng-container>\n <ng-template #noManualLogsIcon>\u2013</ng-template>\n</ng-container>\n <!-- Breaks -->\n <ng-container *ngSwitchCase=\"'breaks'\">\n <ng-container *ngIf=\"d[col.field]?.length; else noBreaksLeft\">\n <app-badge-overflow\n [badges]=\"getBreakBadges(d[col.field])\"\n [maxWidth]=\"col.width || 200\"\n (badgeMouseEnter)=\"showBreakTooltip($event.event, $event.badge.data)\"\n (badgeMouseLeave)=\"hideBreakTooltip()\"\n (overflowCountClick)=\"onDetailBadgeOverflowCountClick(col, d)\">\n</app-badge-overflow>\n </ng-container>\n <ng-template #noBreaksLeft>\n <div>\n -\n </div>\n </ng-template>\n </ng-container>\n\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()\">\n <div style=\"overflow: hidden; text-overflow: ellipsis; white-space: nowrap; width: 100%;\" [class.restriction-indicator]=\"row.attendance_log_detail?.length > 0\" title=\"{{ d.is_un_restricted ? 'Yes' : 'No' }}\">\n {{ d.is_un_restricted ? 'Yes' : 'No' }}\n </div>\n </div>\n\n <div *ngSwitchCase=\"'is_payroll_processed'\" class=\"d-flex justify-content-start flex-column pointer position-relative\" >\n <div style=\"overflow: hidden; text-overflow: ellipsis; white-space: nowrap; width: 100%;\" title=\"{{ d.is_payroll_processed ? 'Yes' : 'No' }}\">\n {{ d.is_payroll_processed ? 'Yes' : 'No' }}\n </div>\n </div>\n\n <!-- Short Breaks -->\n <ng-container *ngSwitchCase=\"'short_breaks'\">\n <ng-container *ngIf=\"d[col.field]?.short_break_duration; else noShortBreakLeft\">\n <div (dblclick)=\"onShortBreakClick.emit(d)\">\n <app-badge-overflow\n [badges]=\"getShortBreakBadges(d[col.field])\"\n [maxWidth]=\"col.width || 200\"\n (badgeMouseEnter)=\"showShortBreakTooltip($event.event, d)\"\n (badgeMouseLeave)=\"hideShortBreakTooltip()\"\n (badgeClick)=\"handleShortBreakClick(d, $event)\"\n (overflowCountClick)=\"onDetailBadgeOverflowCountClick(col, d)\">\n </app-badge-overflow>\n </div>\n </ng-container>\n <ng-template #noShortBreakLeft>\n <div >-</div>\n </ng-template>\n </ng-container>\n\n <!-- Short Leave -->\n <!-- Short Leave -->\n<ng-container *ngSwitchCase=\"'short_leave'\">\n <ng-container *ngIf=\"row.short_leave && row.short_leave.length > 0; else noShortLeaveMain\">\n <div class=\"w-100 d-flex main-progress-bar justify-content-center align-items-center\" \n style=\"background-color: rgb(111, 97, 207); height: 20px; border-radius: 4px; position: relative;\"\n (mouseenter)=\"showShortLeaveTooltip($event, row)\"\n (mouseleave)=\"hideShortLeaveTooltip()\">\n <span class=\"d-block\" [style.min-width.%]=\"row.short_leave[0].short_leave_time_percentage\" \n style=\"background-color: rgb(238, 99, 82); height: 100%; border-radius: 4px;\"></span>\n <span style=\"position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); color: white; font-size: 12px; font-weight: bold;\">\n {{ row.short_leave[0].short_leave_time_percentage }}%\n </span>\n </div>\n </ng-container>\n <ng-template #noShortLeaveMain>-</ng-template>\n</ng-container>\n\n<ng-container *ngSwitchCase=\"'status'\">\n <ng-container *ngIf=\"getNestedValue(d, col.field); else noStatus\">\n <span class=\"badge\" [class]=\"getStatusBadgeClass(getNestedValue(d, col.field))\">\n {{ transformStatus(getNestedValue(d, col.field)) }}\n </span>\n </ng-container>\n <ng-template #noStatus>-</ng-template>\n</ng-container>\n\n<!-- Attendance Status -->\n<ng-container *ngSwitchCase=\"'attendanceStatus'\">\n <ng-container *ngIf=\"getNestedValue(d, col.field); else noAttendanceStatus\">\n <span class=\"badge\" [class]=\"getAttendanceStatusBadgeClass(getNestedValue(d, col.field))\">\n {{ transformStatus(getNestedValue(d, col.field)) }}\n </span>\n </ng-container>\n <ng-template #noAttendanceStatus>-</ng-template>\n</ng-container>\n\n <!-- Default -->\n <ng-container *ngSwitchDefault>\n<div style=\"overflow: hidden; text-overflow: ellipsis; white-space: nowrap; width: 100%;\" title=\"{{\n col.type === 'date'\n ? (getNestedValue(d, col.field) ? (getNestedValue(d, col.field) | timezoneFormat:prefs:'date') : '-')\n : col.type === 'time'\n ? ((getTimeValue(getNestedValue(d, col.field)) | timezoneFormat:prefs:'time'))\n : (getNestedValue(d, col.field)?.value || getNestedValue(d, col.field)?.name || getNestedValue(d, col.field) || '-')\n}}\">{{ col.type === 'date'\n ? (getNestedValue(d, col.field) ? (getNestedValue(d, col.field) | timezoneFormat:prefs:'date') : '-')\n : col.type === 'time'\n ? ((getTimeValue(getNestedValue(d, col.field)) | timezoneFormat:prefs:'time'))\n : (getNestedValue(d, col.field)?.value || getNestedValue(d, col.field)?.name || getNestedValue(d, col.field) || '-')\n}}</div>\n</ng-container>\n</ng-container>\n </td>\n </ng-container>\n </tr>\n</tbody>\n </table>\n\n </div>\n\n <!-- DETAIL SIDE MENU (Sticky on right end) -->\n <!-- <div class=\"detail-side-menu-wrapper\" >\n <div style=\"width: 30px\" class=\"d-flex flex-column align-items-center \">\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\">\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/ui-checks-grid.svg'\" class=\"data-grid-svg-icon\"></span>\n <div class=\"side-menue-text\">Columns</div>\n </div>\n \n </div>\n\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);\">\n <ng-container *ngIf=\"row.details.sideMenu.currentTab === 'cols'\">\n <div class=\"px-3 py-2 border-bottom d-flex align-items-center\">\n <strong class=\"me-auto\">Columns</strong>\n <input type=\"text\" class=\"form-control form-control-sm\" placeholder=\"Search...\" [(ngModel)]=\"row.details.sideMenu.columnSearch\" style=\"width: 120px; font-size: 12px;\" />\n </div>\n <div class=\"side-menu-scrollable\">\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\">\n <input type=\"checkbox\" class=\"form-check-input me-2\" [(ngModel)]=\"col.is_visible\" (change)=\"onDetailColumnVisibilityChange(row)\" />\n <span>{{ col.header }}</span>\n </div>\n </div>\n </ng-container>\n\n <ng-container *ngIf=\"row.details.sideMenu.currentTab === 'filtrs'\">\n <div class=\"px-3 py-2 border-bottom d-flex align-items-center\">\n <strong class=\"me-auto\">Filters</strong>\n <input type=\"text\" class=\"form-control form-control-sm\" placeholder=\"Search...\" [(ngModel)]=\"row.details.sideMenu.columnSearch\" style=\"width: 120px; font-size: 12px;\" />\n </div>\n <div class=\"side-menu-scrollable\">\n <div *ngFor=\"let col of row.details.columns | filter: row.details.sideMenu.columnSearch:'header'; trackBy: trackByField\" class=\"mb-3\">\n <div class=\"d-flex justify-content-between align-items-center cursor-pointer\" (click)=\"col.expandedFilter = !col.expandedFilter\">\n <label class=\"mb-0 small\">{{ col.header }}</label>\n <span class=\"toggle-icon data-grid-svg-icon\" [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\" [class.rotate]=\"col.expandedFilter\"></span>\n </div>\n <div *ngIf=\"col.expandedFilter\" class=\"mt-2 filter-input-container ps-3 pe-3\">\n <ng-container *ngIf=\"col.type === 'dropdown'; else textFilter\">\n <div class=\"p-1\">\n <input\n type=\"text\"\n class=\"form-control form-control-sm mb-2\"\n placeholder=\"Search...\"\n [(ngModel)]=\"col.searchValue\"\n />\n\n <div class=\"form-check mb-1 ms-1\">\n <input\n class=\"form-check-input\"\n type=\"checkbox\"\n [checked]=\"\n row.details.filters[col.field]?._ids?.length == col.column_dropdown_value?.length\n \"\n (change)=\"toggleSelectAllDetailFilters(col, row, $event)\"\n id=\"detail_selectAll_{{ col.field }}\"\n />\n <label class=\"form-check-label\" for=\"detail_selectAll_{{ col.field }}\">\n Select All\n </label>\n </div>\n\n <div class=\"dropdown-options\">\n <div\n class=\"form-check mb-1 ms-1\"\n *ngFor=\"\n let option of col?.column_dropdown_value\n | filter : col.searchValue : 'value';\n trackBy: trackById\n \"\n >\n <input\n class=\"form-check-input\"\n type=\"checkbox\"\n [value]=\"option\"\n [checked]=\"\n row.details.filters[col.field]?._ids?.includes(option?._id || option?.id || option)\n \"\n (change)=\"onDetailOptionToggle(col, option, row)\"\n id=\"detail_option_{{ col.field }}_{{\n option?.id || option?._id || option\n }}\"\n />\n <label\n class=\"form-check-label\"\n [for]=\"\n 'detail_option_' +\n col.field +\n '_' +\n (option?.id || option?._id || option)\n \"\n >\n {{ option.value || option }}\n </label>\n </div>\n </div>\n </div>\n </ng-container>\n\n <ng-template #textFilter>\n <div class=\"filter-text-section\">\n <div class=\"form-group mb-2\">\n <select\n class=\"form-select form-select-sm\"\n [(ngModel)]=\"row.details.filters[col.field].first_condition\"\n (ngModelChange)=\"applyDetailRowFilter(row)\"\n >\n <option value=\"contain\">Contains</option>\n <option value=\"equal\">Equals</option>\n <option value=\"before\">Begins With</option>\n <option value=\"after\">Ends With</option>\n </select>\n </div>\n\n <input\n [type]=\"col.type == 'date' ? 'date' : 'text'\"\n class=\"form-control form-control-sm mb-3\"\n placeholder=\"Value\"\n [(ngModel)]=\"row.details.filters[col.field].first_value\"\n (ngModelChange)=\"applyDetailRowFilter(row)\"\n />\n\n <ng-container *ngIf=\"row.details.filters[col.field]?.first_value\">\n <div class=\"form-group mb-2\">\n <div class=\"form-check form-check-inline\">\n <input\n class=\"form-check-input filter-radio-inputs\"\n type=\"radio\"\n name=\"detail_condition_{{ col.field }}\"\n [(ngModel)]=\"row.details.filters[col.field].condition\"\n (ngModelChange)=\"applyDetailRowFilter(row)\"\n value=\"and\"\n id=\"detail_and_{{ col.field }}\"\n />\n <label class=\"form-check-label\" for=\"detail_and_{{ col.field }}\"\n >AND</label\n >\n </div>\n <div class=\"form-check form-check-inline\">\n <input\n class=\"form-check-input filter-radio-inputs\"\n type=\"radio\"\n name=\"detail_condition_{{ col.field }}\"\n [(ngModel)]=\"row.details.filters[col.field].condition\"\n (ngModelChange)=\"applyDetailRowFilter(row)\"\n value=\"or\"\n id=\"detail_or_{{ col.field }}\"\n />\n <label class=\"form-check-label\" for=\"detail_or_{{ col.field }}\"\n >OR</label\n >\n </div>\n <div class=\"form-check form-check-inline\">\n <input\n class=\"form-check-input filter-radio-inputs\"\n type=\"radio\"\n name=\"detail_condition_{{ col.field }}\"\n [(ngModel)]=\"row.details.filters[col.field].condition\"\n (ngModelChange)=\"applyDetailRowFilter(row)\"\n value=\"none\"\n id=\"detail_none_{{ col.field }}\"\n />\n <label class=\"form-check-label\" for=\"detail_none_{{ col.field }}\"\n >None</label\n >\n </div>\n </div>\n\n <ng-container *ngIf=\"row.details.filters[col.field].condition !== 'none'\">\n <div class=\"form-group mb-2\">\n <select\n class=\"form-select form-select-sm\"\n [(ngModel)]=\"row.details.filters[col.field].second_condition\"\n (ngModelChange)=\"applyDetailRowFilter(row)\"\n >\n <option value=\"contain\">Contains</option>\n <option value=\"equal\">Equals</option>\n <option value=\"before\">Begins With</option>\n <option value=\"after\">Ends With</option>\n </select>\n </div>\n\n <input\n [type]=\"col.type == 'date' ? 'date' : 'text'\"\n class=\"form-control form-control-sm mb-2\"\n placeholder=\"Second Value\"\n [(ngModel)]=\"row.details.filters[col.field].second_value\"\n (ngModelChange)=\"applyDetailRowFilter(row)\"\n />\n </ng-container>\n </ng-container>\n </div>\n </ng-template>\n </div>\n </div>\n </div>\n </ng-container>\n </div>\n </div> -->\n</div>\n\n<!-- Detail Side Menu -->\n\n\n\n<!-- Popover for Restriction Logs (is_un_restricted) -->\n<!-- <div\n *ngIf=\"restrictionTooltipVisible\"\n class=\"popover__content m-l-10 popoverRestriction position-absolute border rounded bg-white p-3\"\n [style.left.px]=\"restrictionTooltipPosition.x\"\n [style.top.px]=\"restrictionTooltipPosition.y\"\n (mouseenter)=\"preventRestrictionTooltipHide()\"\n (mouseleave)=\"hideRestrictionTooltip()\"\n style=\"z-index: 1000; min-width: 300px; font-size: 12px;\"\n @tooltipAnimation\n>\n <div class=\"modal-area px-0 py-0\">\n <div class=\"table-responsive\">\n <table class=\"table table-row-primary-100 gs-0 gy-2 mb-0\">\n <thead>\n <tr class=\"fw-bolder text-muted bg-light\">\n <th class=\"center ps-2\">Clock in</th>\n <th class=\"center\">Clock out</th>\n <th class=\"center\">Log Hr</th>\n <th class=\"center\">Log Min</th>\n <th class=\"center pe-2\">Status</th>\n </tr>\n </thead>\n <tbody>\n <tr *ngFor=\"let item of currentRestrictionLogs\">\n <td class=\"center ps-2\">\n <span class=\"text-primary\"> {{ item?.clock_in_time | date:'shortTime'}}</span>\n </td>\n <td class=\"center\">\n <span class=\"text-primary\">{{ item?.clock_out_time | date:'shortTime'}}</span>\n </td>\n <td class=\"center\">\n <span class=\"text-primary\">{{ item?.logged_hours }}</span>\n </td>\n <td class=\"center\">\n <span class=\"text-primary\">{{ item?.logged_minutes }}</span>\n </td>\n <td class=\"center\">\n <span class=\"badge bg-light text-dark border\">\n {{ item?.status ? (item.status | titlecase) : 'N/A' }}\n </span>\n </td>\n </tr>\n </tbody>\n </table>\n </div>\n </div>\n</div> -->\n\n<!-- Popover for Manual Logs -->\n<!-- <div\n *ngIf=\"manualLogsTooltipVisible\"\n class=\"popover__content position-absolute border rounded bg-white p-3\"\n [style.left.px]=\"manualLogsTooltipPosition.x\"\n [style.top.px]=\"manualLogsTooltipPosition.y\"\n (mouseenter)=\"preventManualLogsTooltipHide()\"\n (mouseleave)=\"hideManualLogsTooltip()\"\n style=\"z-index: 1000; min-width: 500px; font-size: 12px;\"\n @tooltipAnimation\n>\n <div class=\"modal-area px-0 py-0\">\n <ng-container *ngIf=\"currentManualLogs.length > 0; else noManualLogs\">\n <div class=\"table-responsive\">\n <table class=\"table table-row-primary-100 gs-0 gy-2 mb-0\">\n <thead>\n <tr class=\"fw-bolder text-muted bg-light\">\n <th class=\"center ps-2\" style=\"width: 18%;\">Name</th>\n <th class=\"center\">Date/Time</th>\n <th class=\"center\">Previous Time</th>\n <th class=\"center\">Updated Time</th>\n <th class=\"center\">Status</th>\n <th class=\"center pe-2\">Remarks</th>\n </tr>\n </thead>\n <tbody>\n <tr *ngFor=\"let log of currentManualLogs\">\n <td class=\"center ps-2\">\n <span class=\"text-primary\">{{ log.name }}</span>\n </td>\n <td class=\"center\">\n <span class=\"text-primary\">{{ log.date_time }}</span>\n </td>\n <td class=\"center\">\n <span class=\"text-primary\">{{ log.previous_time }}</span>\n </td>\n <td class=\"center\">\n <span class=\"text-primary\">{{ log.updated_time }}</span>\n </td>\n <td class=\"center\">\n <span class=\"badge bg-light text-dark border\">\n {{ log.log_status ? (log.log_status | titlecase) : 'N/A' }}\n </span>\n </td>\n <td class=\"center pe-2\">\n <span class=\"text-primary\">{{ log.remarks }}</span>\n </td>\n </tr>\n </tbody>\n </table>\n </div>\n </ng-container>\n </div>\n\n <ng-template #noManualLogs>\n <div class=\"text-center p-3\">\n <p class=\"text-muted mb-0\">No manual logs available for this record.</p>\n </div>\n </ng-template>\n</div> -->\n\n\n\n\n<!-- Existing Custom Tooltip for Breaks -->\n\n\n\n\n\n <!-- RIGHT PINNED: Empty table to keep alignment -->\n <div *ngIf=\"section === 'right' && row.isDetailsExpand && !isSingleDay\" class=\"accordion-details data-grid-accordion-section\" style=\"max-height: 350px; min-height: 150px ; overflow: hidden;\">\n <table class=\"nested-table table table-sm w-100 mb-0 data-grid-accordion-table\" [class.show-shadow]=\"rowShadingEnabled\">\n <thead>\n <tr [style.height.px]=\"nestedTableHeaderRowHeight\" [style.backgroundColor]=\"headerBackgroundColor\">\n <th *ngFor=\"let _ of [1, 2, 3, 4, 5]\">&nbsp;</th>\n </tr>\n </thead>\n <tbody>\n <tr [style.height.px]=\"nestedTablerowHeight\" *ngFor=\"let _ of row.details.data\" [style.backgroundColor]=\"headerBackgroundColor\">\n <td *ngFor=\"let __ of [1, 2, 3, 4, 5]\">&nbsp;</td>\n </tr>\n </tbody>\n </table>\n </div>\n\n </ng-template>\n</ng-template>\n\n<!-- Actual Cell is Here -->\n<ng-template\n #cellTemplate\n let-col=\"col\"\n let-row=\"row\"\n let-section=\"section\"\n let-subColIndex=\"subColIndex\"\n let-rowIndex=\"rowIndex\"\n let-colIndex=\"colIndex\"\n>\n <div\n (click)=\"disableEdit(row, col); setActiveCell(row, col)\"\n [style.fontWeight]=\"bodyFontWeight\"\n [class.border-right]=\"showVerticalBorder\"\n class=\"cell overflow-visible position-relative\"\n [attr.field]=\"col.field\"\n [style.width.px]=\"col.width\"\n [style.min-width.px]=\"col.width\"\n [style.fontSize.px]=\"bodyTextFontsSize\"\n [class.active-cell]=\"\n isActiveCell(row, col) && !isEditing(row, col) && selectedKeys.size == 1\n \"\n (dblclick)=\"$event.preventDefault(); enableEdit(row, col)\"\n [class.row-selected]=\"rowSelectedIndexes.has(row.__virtualIndex)\"\n [class.first-row-selected]=\"firstSelectedRow === row.__virtualIndex\"\n [class.last-row-selected]=\"lastSelectedRow === row.__virtualIndex\"\n tabindex=\"0\"\n (keydown.enter)=\"$event.preventDefault(); enableEdit(row, col)\"\n (mousedown)=\"\n startSelection(\n row.__virtualIndex,\n colIndex,\n subColIndex ?? 0,\n col.field,\n $event,\n section\n )\n \"\n (mouseenter)=\"\n extendSelection(\n row.__virtualIndex,\n colIndex,\n subColIndex ?? 0,\n col.field,\n $event,\n section\n )\n \"\n (mouseup)=\"endSelection()\"\n [class.selected-cell]=\"\n isSelected(\n row.__virtualIndex,\n colIndex,\n subColIndex ?? 0,\n col.field,\n section\n )\n \"\n [class.top-border]=\"\n isTopBorder(row.__virtualIndex, colIndex, subColIndex, section)\n \"\n [class.bottom-border]=\"\n isBottomBorder(row.__virtualIndex, colIndex, subColIndex, section)\n \"\n [class.left-border]=\"\n isLeftBorder(row.__virtualIndex, colIndex, subColIndex, section)\n \"\n [class.right-border]=\"\n isRightBorder(row.__virtualIndex, colIndex, subColIndex, section)\n \"\n [class.top-left-corner]=\"\n isTopLeftCorner(row.__virtualIndex, colIndex, subColIndex, section)\n \"\n [class.top-right-corner]=\"\n isTopRightCorner(row.__virtualIndex, colIndex, subColIndex, section)\n \"\n [class.bottom-left-corner]=\"\n isBottomLeftCorner(row.__virtualIndex, colIndex, subColIndex, section)\n \"\n [class.bottom-right-corner]=\"\n isBottomRightCorner(row.__virtualIndex, colIndex, subColIndex, section)\n \"\n >\n <!-- (mousedown)=\"startSelection(row.__virtualIndex, colIndex, subColIndex ?? 0, col.field, $event)\"\n (mouseenter)=\"extendSelection(row.__virtualIndex, colIndex, subColIndex ?? 0, col.field, $event)\"\n (mouseup)=\"endSelection()\"\n [class.selected-cell]=\"isSelected(row.__virtualIndex, colIndex, subColIndex ?? 0, col.field)\" -->\n <div class=\"table-cell\" [class.active-for-editing]=\"isEditing(row, col) && getNestedValue(row, col.field)?.length <= 50\">\n <div\n (click)=\"$event.stopPropagation()\"\n *ngIf=\"isEditing(row, col) && getNestedValue(row, col.field)?.length <= 50; else viewMode\"\n >\n <ng-container [ngSwitch]=\"col.type\">\n <!-- Text Input -->\n <input\n [style.height.px]=\"rowHeight - 10\"\n *ngSwitchCase=\"'input'\"\n type=\"text\"\n [(ngModel)]=\"row[col.field]\"\n (blur)=\"disableEdit(row, col)\"\n autofocus\n class=\"form-control form-control-sm\"\n (mousedown)=\"$event.stopPropagation()\"\n />\n\n <!-- Number Input -->\n <input\n [style.height.px]=\"rowHeight - 8\"\n *ngSwitchCase=\"'number'\"\n #numberInput=\"ngModel\"\n #numberRef\n (keypress)=\"allowOnlyNumbers($event)\"\n type=\"number\"\n required\n [(ngModel)]=\"row[col.field]\"\n (blur)=\"disableEdit(row, col)\"\n autofocus\n (keydown.enter)=\"numberRef.blur()\"\n class=\"form-control form-control-sm\"\n [ngClass]=\"{\n 'is-invalid': numberInput.invalid\n }\"\n (mousedown)=\"$event.stopPropagation()\"\n />\n\n <!-- Date Input -->\n <input\n [style.height.px]=\"rowHeight - 8\"\n *ngSwitchCase=\"'date'\"\n type=\"date\"\n [(ngModel)]=\"row[col.field]\"\n (blur)=\"disableEdit(row, col)\"\n autofocus\n class=\"form-control form-control-sm\"\n #dateInput=\"ngModel\"\n [ngClass]=\"{\n 'is-invalid': dateInput.invalid\n }\"\n (mousedown)=\"$event.stopPropagation()\"\n />\n\n <!-- Dropdown -->\n <!-- ng-select like dropdown -->\n <div\n *ngSwitchCase=\"'dropdown'\"\n class=\"dropdown w-100\"\n (blur)=\"disableEdit(row, col)\"\n >\n <!-- Trigger -->\n <button\n class=\"form-select form-select-sm text-start w-100 text-ellipsis\"\n type=\"button\"\n data-bs-toggle=\"dropdown\"\n aria-expanded=\"false\"\n [style.minHeight.px]=\"rowHeight - 10\"\n data-bs-display=\"static\"\n (mousedown)=\"$event.stopPropagation()\"\n >\n <ng-container>\n {{\n getNestedValue(row, col.field)?.value ||\n getNestedValue(row, col.field)?.name ||\n getNestedValue(row, col.field)\n }}\n </ng-container>\n <ng-template #placeholder> Select options... </ng-template>\n </button>\n\n <!-- Menu -->\n <div\n class=\"dropdown-menu w-100 p-0 cell-editing-dropdown-menu rounded-3\"\n [class.show]=\"isEditing(row, col)\"\n >\n <!-- Search -->\n <div class=\"px-2 py-1\">\n <input\n type=\"text\"\n class=\"form-control form-control-sm\"\n placeholder=\"Search...\"\n [(ngModel)]=\"editinDropdownSearch\"\n />\n </div>\n\n <!-- Options -->\n <div\n class=\"cell-editin-dropdown\"\n style=\"max-height: 200px; overflow: auto\"\n >\n <div\n (click)=\"\n setNestedValue(row, col, option, true);\n disableEdit(row, col)\n \"\n class=\"px-2 py-1 d-flex align-items-center item\"\n *ngFor=\"\n let option of col.column_dropdown_value\n | filter : editinDropdownSearch : 'value'\n \"\n >\n <label\n class=\"form-check-label d-flex align-items-center mb-0\"\n [for]=\"col.field + '-' + option.value || option\"\n >\n {{ option.value || option }}\n </label>\n </div>\n </div>\n </div>\n </div>\n\n <input\n *ngSwitchCase=\"'email'\"\n [style.height.px]=\"rowHeight - 10\"\n [style.maxHeight.px]=\"rowHeight - 10\"\n #emailModel=\"ngModel\"\n #emailInput\n type=\"email\"\n [(ngModel)]=\"row[col.field]\"\n name=\"{{ col.field }}\"\n required\n pattern=\"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$\"\n (blur)=\"disableEdit(row, col, emailModel)\"\n (keydown.enter)=\"\n emailModel.control.markAsTouched(); emailInput.blur()\n \"\n autofocus\n class=\"form-control form-control-sm\"\n [ngClass]=\"{\n 'is-invalid': emailModel.invalid\n }\"\n (mousedown)=\"$event.stopPropagation()\"\n />\n <!-- Default fallback -->\n <input\n *ngSwitchDefault\n [style.height.px]=\"rowHeight - 10\"\n [style.maxHeight.px]=\"rowHeight - 10\"\n #textModel=\"ngModel\"\n #textInput\n type=\"text\"\n [(ngModel)]=\"row[col.field]\"\n name=\"{{ col.field }}\"\n required\n (blur)=\"disableEdit(row, col, textModel)\"\n (keydown.enter)=\"\n textModel.control.markAsTouched(); textInput.blur()\n \"\n autofocus\n class=\"form-control form-control-sm\"\n [ngClass]=\"{\n 'is-invalid': textModel.invalid\n }\"\n (mousedown)=\"$event.stopPropagation()\"\n />\n </ng-container>\n </div>\n\n <!-- Display mode -->\n <ng-template #viewMode>\n <div\n class=\"d-flex justify-between items-center w-100\"\n [ngClass]=\"getCellClasses(col, getNestedValue(row, col.field))\"\n >\n <!-- Text cell -->\n <div class=\"d-flex align-items-center w-100\">\n <div\n #cellText\n class=\"text-ellipsis flex-grow-1\"\n \n >\n <ng-container *ngIf=\"col.type !== 'image'\">\n <ng-container [ngSwitch]=\"col.field\">\n <!-- Breaks -->\n <ng-container *ngSwitchCase=\"'breaks'\">\n <ng-container *ngIf=\"getNestedValue(row, 'breaks')?.length; else noBreaksMain\">\n <app-badge-overflow\n [badges]=\"getBreakBadges(getNestedValue(row, 'breaks'))\"\n [maxWidth]=\"col.width || 200\"\n (badgeMouseEnter)=\"showBreakTooltip($event.event, $event.badge.data)\"\n (badgeMouseLeave)=\"hideBreakTooltip()\"\n (overflowCountClick)=\"onBadgeOverflowCountClick(col)\">\n </app-badge-overflow>\n </ng-container>\n <ng-template #noBreaksMain>\n <div >\n -\n </div>\n </ng-template>\n </ng-container>\n\n <!-- Short Breaks -->\n <ng-container *ngSwitchCase=\"'short_breaks'\">\n <ng-container *ngIf=\"row.short_breaks?.short_break_duration && row.short_breaks.short_break_duration > 0; else noShortBreak\">\n <div (dblclick)=\"onShortBreakClick.emit(row)\"> <app-badge-overflow\n [badges]=\"getShortBreakBadges(row.short_breaks)\"\n [maxWidth]=\"col.width || 200\"\n (badgeMouseEnter)=\"showShortBreakTooltip($event.event, row)\"\n (badgeMouseLeave)=\"hideShortBreakTooltip()\"\n (badgeClick)=\"handleShortBreakClick(row, $event)\"\n (overflowCountClick)=\"onShortBreakOverflowCountClick(col)\">\n </app-badge-overflow> </div>\n \n \n </ng-container>\n <ng-template #noShortBreak>\n <div >-</div>\n </ng-template>\n </ng-container>\n\n <!-- Short Leave -->\n <!-- Short Leave -->\n<ng-container *ngSwitchCase=\"'short_leave'\">\n <ng-container *ngIf=\"row.short_leave && row.short_leave.length > 0; else noShortLeaveMain\">\n <div class=\"w-100 d-flex main-progress-bar justify-content-center align-items-center\" \n style=\"background-color: rgb(111, 97, 207); height: 20px; border-radius: 4px; position: relative;\"\n (mouseenter)=\"showShortLeaveTooltip($event, row)\"\n (mouseleave)=\"hideShortLeaveTooltip()\">\n <span class=\"d-block\" [style.min-width.%]=\"row.short_leave[0].short_leave_time_percentage\" \n style=\"background-color: rgb(238, 99, 82); height: 100%; border-radius: 4px;\"></span>\n <span style=\"position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); color: white; font-size: 12px; font-weight: bold;\">\n {{ row.short_leave[0].short_leave_time_percentage }}%\n </span>\n </div>\n </ng-container>\n <ng-template #noShortLeaveMain>-</ng-template>\n</ng-container>\n\n <!-- Status -->\n <ng-container *ngSwitchCase=\"'status'\">\n <span class=\"badge\" [class]=\"getStatusBadgeClass(getNestedValue(row, col.field))\">\n {{ transformStatus(getNestedValue(row, col.field)) || '-' }}\n </span>\n </ng-container>\n\n <!-- Attendance Status -->\n <ng-container *ngSwitchCase=\"'attendanceStatus'\">\n <span class=\"badge\" [class]=\"getAttendanceStatusBadgeClass(getNestedValue(row, col.field))\">\n {{ transformStatus(getNestedValue(row, col.field)) || '-' }}\n </span>\n </ng-container>\n\n <!-- Payroll Processed -->\n <ng-container *ngSwitchCase=\"'is_payroll_processed'\">\n <span class=\"badge\" [class]=\"getNestedValue(row, col.field) ? 'badge-success' : 'badge-secondary'\">\n {{ getNestedValue(row, col.field) ? 'Yes' : 'No' }}\n </span>\n </ng-container>\n\n <!-- Restriction -->\n <ng-container *ngSwitchCase=\"'is_un_restricted'\">\n <span class=\"badge\" [class]=\"getNestedValue(row, col.field) ? 'badge-success' : 'badge-secondary'\">\n {{ getNestedValue(row, col.field) ? 'Yes' : 'No' }}\n </span>\n </ng-container>\n\n <!-- Default -->\n <ng-container *ngSwitchDefault>\n {{\n !isNestedValueArray(row, col.field)\n ? col.type === 'date'\n ? (isDate(getNestedValue(row, col.field))\n ? ((getNestedValue(row, col.field)) | timezoneFormat:prefs:'date' )\n : (getNestedValue(row, col.field)?.value ||\n getNestedValue(row, col.field)?.name ||\n getNestedValue(row, col.field) ||\n '-'))\n : col.type === 'time'\n ? ((getTimeValue(getNestedValue(row, col.field)) | timezoneFormat:prefs:'time'))\n : (getNestedValue(row, col.field)?.value ||\n getNestedValue(row, col.field)?.name ||\n getNestedValue(row, col.field) ||\n '-')\n : (getNestedValue(row, col.field)?.[0]?.department_name ||\n getNestedValue(row, col.field)?.[0]?.roleName ||\n '-')\n }}\n </ng-container>\n </ng-container>\n </ng-container>\n <ng-container *ngIf=\"col.type == 'image'\">\n <ng-container\n *ngTemplateOutlet=\"\n defaultImagePlaceholder;\n context: {\n row: row,\n col: col,\n }\n \"\n ></ng-container>\n </ng-container>\n </div>\n\n <!-- Active dot and eye icon for employee name -->\n <span *ngIf=\"col.field === 'User' && hasManualLogs(row) && !row.isDetailsExpand\" class=\"badge badge-dot badge-success ms-1\" (mouseenter)=\"showManualLogsTooltip($event, row, row)\"></span>\n <i *ngIf=\"col.field === 'User' && hasManualLogs(row)\" class=\"bi bi-eye ms-1\" (mouseenter)=\"showManualLogsTooltip($event, row, row)\"></i>\n </div>\n\n <!-- Expand / Collapse icon for multiple data showing in one coll-->\n\n <!-- <span\n *ngIf=\"\n (isOverflowing(cellText) &&\n showCellDetailsBox &&\n getNestedValue(row, col.field)?.length > 50) ||\n (isNestedValueArray(row, col.field) &&\n getNestedValue(row, col.field)?.length > 1)\n \"\n class=\"toggle-icon data-grid-svg-icon ms-2 cursor-pointer\"\n [inlineSVG]=\"\n isExpanded(row, col)\n ? singleSpaAssetsPath + 'data-grid/icons/chevron-down.svg'\n : singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\n \"\n (click)=\"\n $event.stopPropagation();\n toggleExpandOfLongCellText(row, col, columns, true)\n \"\n (dblclick)=\"$event.preventDefault(); $event.stopPropagation()\"\n ></span> -->\n </div>\n\n <!-- Expanded text -->\n <div\n class=\"position-absolute w-100\"\n *ngIf=\"isExpanded(row, col)\"\n [style.zIndex]=\"getZIndex(row, col)\"\n style=\"top: 100%; left: 0\"\n >\n <ng-container\n *ngTemplateOutlet=\"\n fullTextTemplate;\n context: {\n row: row,\n col: col,\n isArray: isNestedValueArray(row, col.field)\n }\n \"\n ></ng-container>\n </div>\n </ng-template>\n\n\n \n\n\n\n </div>\n </div>\n</ng-template>\n\n<div\n *ngIf=\"currentBreakTooltip\"\n class=\"custom-break-tooltip\"\n [style.--tooltip-x.px]=\"tooltipPosition.x\"\n [style.--tooltip-y.px]=\"tooltipPosition.y\"\n @tooltipAnimationBottom\n>\n <div class=\"break-tooltip-header\">\n <strong>{{ currentBreakTooltip.break_type?.data_value_name || 'Break' }}</strong>\n <span class=\"text-muted ms-2\">\n {{ currentBreakTooltip.breakInstatus === 'breakOut' ? 'Taken' : 'On Break' }}\n </span>\n </div>\n\n <div class=\"break-tooltip-body\">\n <div>\n <i class=\"bi bi-play-circle\"></i>\n In: {{ currentBreakTooltip.break_in_time | timezoneFormat:prefs:'time' }}\n </div>\n \n <div>\n <i class=\"bi bi-stop-circle\"></i>\n Out: {{ currentBreakTooltip.break_out_time | timezoneFormat:prefs:'time' }}\n </div>\n \n <div>\n <i class=\"bi bi-clock\"></i>\n Duration: {{ (currentBreakTooltip.total_minutes_logged || currentBreakTooltip.break_duration) }} min\n</div>\n </div>\n</div>\n\n\n\n\n\n\n<!-- Short Break Tooltip (Table Format) -->\n<div\n *ngIf=\"currentShortBreakTooltip\"\n class=\"custom-break-tooltip\"\n [style.--tooltip-x.px]=\"tooltipPosition.x\"\n [style.--tooltip-y.px]=\"tooltipPosition.y\"\n @tooltipAnimationBottom\n>\n <div class=\"break-tooltip-header\">\n <strong>{{ currentShortBreakTooltip.name }}</strong>\n </div>\n <div class=\"break-tooltip-body\">\n <table class=\"short-break-table\">\n <thead>\n <tr>\n <th>Start Time</th>\n <th>End Time</th>\n <th>Duration</th>\n </tr>\n </thead>\n <tbody>\n <tr *ngFor=\"let detail of currentShortBreakTooltip.details\">\n <td>\n {{\n detail.start_time\n ? (detail.start_time | timezoneFormat:prefs:'time')\n : 'N/A'\n }}\n </td>\n <td>\n {{\n detail.end_time\n ? (detail.end_time | timezoneFormat:prefs:'time')\n : 'N/A'\n }}\n </td>\n <td>{{ detail.duration }} min</td>\n </tr>\n <tr *ngIf=\"currentShortBreakTooltip.details.length === 0\">\n <td colspan=\"3\" class=\"text-center text-muted\">No timing details</td>\n </tr>\n </tbody>\n </table>\n </div>\n</div>\n\n\n\n\n<!-- Headers Action List On clicking three dots -->\n\n<ng-template #columnMenu let-col=\"col\">\n <div\n class=\"column-menu three-dots-col-menu\"\n [class.visually-hidden]=\"isMenueHidden\"\n *ngIf=\"activeCol && !isThreeDotsFilterOpen && !loading\"\n [style.backgroundColor]=\"dropdownsBackgroundColor\"\n >\n <!-- Sort Ascending -->\n <div class=\"border-below pb-2\" [class.disable-sorting]=\"!col.is_sortable\">\n <span class=\"muted-text fs-7\" style=\"margin-left: 12px\">Sort</span>\n <div\n *ngIf=\"\n columnThreedotsMunuConfig?.showAscending &&\n (sortingConfig?.field != col.field ||\n sortingConfig?.order_by == 'desc')\n \"\n class=\"column-menu-item\"\n (click)=\"sortAsc(activeCol)\"\n >\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrow-up.svg'\"\n class=\"data-grid-svg-icon me-2\"\n ></span>\n Sort Ascending\n </div>\n\n <!-- Sort Descending -->\n <div\n *ngIf=\"\n columnThreedotsMunuConfig?.showDescending &&\n (sortingConfig?.field != col.field ||\n sortingConfig?.order_by == 'asc')\n \"\n class=\"column-menu-item\"\n (click)=\"sortDesc(activeCol)\"\n >\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrow-down.svg'\"\n class=\"data-grid-svg-icon me-2\"\n ></span>\n Sort Descending\n </div>\n\n <div\n *ngIf=\"\n sortingConfig?.field === col.field &&\n (sortingConfig?.order_by === 'asc' ||\n sortingConfig?.order_by === 'desc')\n \"\n class=\"column-menu-item\"\n (click)=\"resetSort(activeCol)\"\n >\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/arrow-counterclockwise.svg'\n \"\n class=\"data-grid-svg-icon me-2\"\n ></span>\n Reset Sort\n </div>\n </div>\n <div class=\"py-2 border-below three-dots-filter\">\n <div\n *ngIf=\"columnThreedotsMunuConfig?.showFilter && !(col.is_search_able === false )\"\n class=\"column-menu-item three-dots-filter\"\n (click)=\"openFilteronThreeDotsClick(col)\"\n >\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\"\n class=\"data-grid-svg-icon me-2\"\n ></span>\n Filter\n </div>\n </div>\n\n <div class=\"py-2 border-below\">\n <span class=\"muted-text fs-7\" style=\"margin-left: 12px\">Pin</span>\n <div\n *ngIf=\"columnThreedotsMunuConfig?.showPinleft && col?.pinned !== 'left'\"\n class=\"column-menu-item\"\n (click)=\"updateColumnPinInSourceByField(activeCol, 'left')\"\n >\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/pin-left.svg'\"\n class=\"data-grid-svg-icon me-2\"\n ></span\n >Pin Left\n </div>\n\n <div\n *ngIf=\"\n columnThreedotsMunuConfig?.showPinright && col?.pinned !== 'right'\n \"\n class=\"column-menu-item\"\n (click)=\"updateColumnPinInSourceByField(activeCol, 'right')\"\n >\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/pin-right.svg'\"\n class=\"data-grid-svg-icon data-grid-svg-icon me-2\"\n ></span\n >Pin Right\n </div>\n\n <div\n *ngIf=\"col?.pinned\"\n class=\"column-menu-item\"\n (click)=\"updateColumnPinInSourceByField(activeCol, null)\"\n >\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/layout-three-columns.svg'\n \"\n class=\"data-grid-svg-icon me-2\"\n ></span\n >Unpin\n </div>\n </div>\n\n <div\n *ngIf=\"columnThreedotsMunuConfig?.showAutosizeThisColumn\"\n class=\"column-menu-item\"\n (click)=\"autosizeColumn(activeCol)\"\n >\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/arrows-expand-vertical.svg'\n \"\n class=\"me-2\"\n ></span>\n Autosize This Column\n </div>\n\n <!-- Autosize All Columns -->\n <div\n *ngIf=\"columnThreedotsMunuConfig?.showAutosizeAllColumns\"\n class=\"column-menu-item\"\n (click)=\"autosizeAllColumns()\"\n >\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/arrows-angle-expand.svg'\n \"\n class=\"data-grid-svg-icon me-2\"\n ></span\n >Autosize All Columns\n </div>\n\n <!-- Group By -->\n <div\n *ngIf=\"showRowsGrouping && !(col.is_groupable === false)\"\n class=\"column-menu-item\"\n (click)=\"groupBy(activeCol)\"\n >\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/diagram-3.svg'\"\n class=\"data-grid-svg-icon me-2\"\n ></span>\n Group by {{ col.header }}\n </div>\n\n <!-- Choose Columns -->\n <!-- <div\n *ngIf=\"columnThreedotsMunuConfig?.showChoseColumns\"\n class=\"column-menu-item\"\n (click)=\"chooseColumns()\"\n >\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/ui-checks-grid.svg'\"\n class=\"data-grid-svg-icon me-2\"\n ></span>\n Choose Columns\n </div> -->\n\n <!-- Reset Columns -->\n <!-- <div\n *ngIf=\"columnThreedotsMunuConfig?.showResetColumns\"\n class=\"column-menu-item\"\n (click)=\"resetColumns()\"\n >\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/arrow-counterclockwise.svg'\n \"\n class=\"data-grid-svg-icon me-2\"\n ></span\n >Reset Columns\n </div> -->\n </div>\n <div *ngIf=\"isThreeDotsFilterOpen\" class=\"three-dots-col-menu position-relative\" [style.left.px]=\"-140\" >\n <ng-container\n *ngTemplateOutlet=\"filterMenu; context: { col: col }\"\n ></ng-container>\n </div>\n</ng-template>\n\n\n\n<!-- Filter Menue -->\n<ng-template #filterMenu let-col=\"col\">\n <div\n class=\"filter-menu-container filter-menu\"\n [style.backgroundColor]=\"dropdownsBackgroundColor\"\n >\n <!-- Dropdown Type -->\n <ng-container *ngIf=\"col.type === 'dropdown'; else textFilter\">\n <div class=\"filter-dropdown-section p-1\">\n <input\n type=\"text\"\n class=\"form-control form-control-sm mb-2\"\n placeholder=\"Search...\"\n [(ngModel)]=\"addFilterDropdownSearch\"\n #filterMenueSearchInput\n />\n\n <div class=\"form-check mb-1\">\n <input\n class=\"form-check-input\"\n type=\"checkbox\"\n [checked]=\"isAllSideFilterOptionsSelected(col)\"\n (change)=\"toggleSelectAllSideFilters(col, $event)\"\n id=\"selectAll_{{ col.field }}\"\n />\n <label class=\"form-check-label\" for=\"selectAll_{{ col.field }}\">\n Select All\n </label>\n </div>\n\n <div class=\"dropdown-options\">\n <div class=\"form-check mb-1\"\n *ngFor=\"\n let option of getColumnOptions(col)\n | filter : addFilterDropdownSearch : 'value';\n trackBy: trackById\n\">\n <input\n class=\"form-check-input\"\n type=\"checkbox\"\n [checked]=\"isOptionSelected(col, option)\"\n [value]=\"option\"\n (change)=\"onOptionToggle(col, option)\"\n />\n <label class=\"form-check-label\">\n {{ option.value || option }}\n </label>\n </div>\n</div>\n </div>\n </ng-container>\n\n <!-- Text Filter Section -->\n <ng-template #textFilter>\n <div class=\"filter-text-section\">\n <div class=\"form-group mb-2\">\n <select\n class=\"form-select form-select-sm\"\n [ngModel]=\"col.query.first_condition || (col.type === 'date' || col.type === 'time' ? 'equal' : 'contain')\"\n (ngModelChange)=\"col.query.first_condition = $event\"\n >\n <ng-container *ngIf=\"col.type === 'date' || col.type === 'time'; else textOptions\">\n <option value=\"equal\">Equal to</option>\n <option value=\"not_equal\">Not Equal</option>\n <option value=\"after\">After</option>\n <option value=\"before\">Before</option>\n </ng-container>\n <ng-template #textOptions>\n <option value=\"contain\">Contains</option>\n <option value=\"equal\">Equals</option>\n <option value=\"before\">Begins With</option>\n <option value=\"after\">Ends With</option>\n </ng-template>\n </select>\n </div>\n\n <input\n [type]=\"col.type == 'string' ? 'text' : col.type\"\n class=\"form-control form-control-sm mb-3\"\n placeholder=\"Value\"\n [(ngModel)]=\"col.query.first_value\"\n [min]=\"col.type == 'number' ? 0 : null\"\n (input)=\"col.type == 'number' && $any($event.target).value < 0 ? $any($event.target).value = 0 : null\"\n (keydown)=\"col.type == 'number' && $event.key === '-' ? $event.preventDefault() : null\"\n [class.number-input]=\"col.type == 'number'\"\n #filterMenueTextchInput\n />\n\n <ng-container >\n <div class=\"form-group mb-2\">\n <div class=\"form-check form-check-inline\">\n <input\n class=\"form-check-input filter-radio-inputs\"\n type=\"radio\"\n name=\"condition\"\n [(ngModel)]=\"condition\"\n value=\"and\"\n id=\"and_{{ col.field }}\"\n />\n <label class=\"form-check-label\" for=\"and_{{ col.field }}\"\n >AND</label\n >\n </div>\n <div class=\"form-check form-check-inline\">\n <input\n class=\"form-check-input filter-radio-inputs\"\n type=\"radio\"\n name=\"condition\"\n [(ngModel)]=\"condition\"\n value=\"or\"\n id=\"or_{{ col.field }}\"\n />\n <label class=\"form-check-label\" for=\"or_{{ col.field }}\"\n >OR</label\n >\n </div>\n <div class=\"form-check form-check-inline\">\n <input\n class=\"form-check-input filter-radio-inputs\"\n type=\"radio\"\n name=\"condition\"\n [(ngModel)]=\"condition\"\n value=\"none\"\n id=\"none_{{ col.field }}\"\n />\n <label class=\"form-check-label\" for=\"none_{{ col.field }}\"\n >None</label\n >\n </div>\n </div>\n\n <ng-container *ngIf=\"col.query?.first_value && condition !== 'none'\">\n <div class=\"form-group mb-2\">\n <select\n class=\"form-select form-select-sm\"\n [ngModel]=\"col.query.second_condition || (col.type === 'date' || col.type === 'time' ? 'equal' : 'contain')\"\n (ngModelChange)=\"col.query.second_condition = $event\"\n >\n <ng-container *ngIf=\"col.type === 'date' || col.type === 'time'; else textOptionsSecond\">\n <option value=\"equal\">Equal to</option>\n <option value=\"not_equal\">Not Equal</option>\n <option value=\"after\">After</option>\n <option value=\"before\">Before</option>\n </ng-container>\n <ng-template #textOptionsSecond>\n <option value=\"contain\">Contains</option>\n <option value=\"equal\">Equals</option>\n <option value=\"before\">Begins With</option>\n <option value=\"after\">Ends With</option>\n </ng-template>\n </select>\n </div>\n\n <input\n [type]=\"col.type == 'string' ? 'text' : col.type\"\n class=\"form-control form-control-sm mb-2\"\n placeholder=\"Second Value\"\n [(ngModel)]=\"col.query.second_value\"\n [min]=\"col.type == 'number' ? 0 : null\"\n (input)=\"col.type == 'number' && $any($event.target).value < 0 ? $any($event.target).value = 0 : null\"\n (keydown)=\"col.type == 'number' && $event.key === '-' ? $event.preventDefault() : null\"\n [class.number-input]=\"col.type == 'number'\"\n />\n </ng-container>\n </ng-container>\n </div>\n </ng-template>\n\n <!-- Actions -->\n <div class=\"d-flex gap-2 mt-2\">\n <div\n class=\"btn btn-sm btn-primary d-flex justify-content-center align-items-center w-100\"\n style=\"height: 22px\"\n (click)=\"applyFilterFromFilterRow(col)\"\n >\n Apply\n </div>\n <div\n class=\"btn btn-sm btn-secondary d-flex justify-content-center align-items-center w-100\"\n style=\"height: 22px\"\n (click)=\"resetSideFilter(col)\"\n >\n Reset\n </div>\n </div>\n </div>\n</ng-template>\n\n<!-- Side Menue -->\n\n<!-- Add this new template for accordion detail column menu -->\n<ng-template #detailColumnMenu let-col=\"col\" let-row=\"row\">\n <div\n class=\"column-menu three-dots-col-menu detail-column-menu\"\n [class.visually-hidden]=\"isDetailMenueHidden\"\n *ngIf=\"activeDetailCol\"\n [style.backgroundColor]=\"dropdownsBackgroundColor\"\n >\n <!-- Sort Ascending -->\n <!-- <div class=\"border-below pb-2\" [class.disable-sorting]=\"!col.is_sortable\">\n <span class=\"muted-text fs-7\" style=\"margin-left: 12px\">Sort</span> -->\n <!-- <div\n *ngIf=\"columnThreedotsMunuConfig?.showAscending\"\n class=\"column-menu-item\"\n (click)=\"sortDetailAsc(activeDetailCol, row)\"\n >\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrow-up.svg'\"\n class=\"data-grid-svg-icon me-2\"\n ></span>\n Sort Ascending\n </div> -->\n\n <!-- Sort Descending -->\n <!-- <div\n *ngIf=\"columnThreedotsMunuConfig?.showDescending\"\n class=\"column-menu-item\"\n (click)=\"sortDetailDesc(activeDetailCol, row)\"\n >\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrow-down.svg'\"\n class=\"data-grid-svg-icon me-2\"\n ></span>\n Sort Descending\n </div> -->\n\n <!-- <div\n *ngIf=\"col?.sortOrder\"\n class=\"column-menu-item\"\n (click)=\"resetDetailSort(activeDetailCol, row)\"\n >\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/arrow-counterclockwise.svg'\n \"\n class=\"data-grid-svg-icon me-2\"\n ></span>\n Reset Sort\n </div> -->\n <!-- </div> -->\n\n <div class=\"py-2 border-below\" *ngIf=\"isColumnFilterable(col)\">\n <span class=\"muted-text fs-7\" style=\"margin-left: 12px\">Filter</span>\n <div\n *ngIf=\"columnThreedotsMunuConfig?.showFilter\"\n class=\"column-menu-item\"\n (click)=\"openDetailFilterMenu($event, col, row)\"\n >\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\"\n class=\"data-grid-svg-icon me-2\"\n ></span>\n Filter\n </div>\n </div>\n\n <div class=\"py-2 border-below\">\n <span class=\"muted-text fs-7\" style=\"margin-left: 12px\">Pin</span>\n <div\n *ngIf=\"columnThreedotsMunuConfig?.showPinleft && col?.pinned !== 'left'\"\n class=\"column-menu-item\"\n (click)=\"updateDetailColumnPin(activeDetailCol, row, 'left')\"\n >\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/pin-left.svg'\"\n class=\"data-grid-svg-icon me-2\"\n ></span\n >Pin Left\n </div>\n\n <div\n *ngIf=\"\n columnThreedotsMunuConfig?.showPinright && col?.pinned !== 'right'\n \"\n class=\"column-menu-item\"\n (click)=\"updateDetailColumnPin(activeDetailCol, row, 'right')\"\n >\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/pin-right.svg'\"\n class=\"data-grid-svg-icon data-grid-svg-icon me-2\"\n ></span\n >Pin Right\n </div>\n\n <div\n *ngIf=\"col?.pinned\"\n class=\"column-menu-item\"\n (click)=\"updateDetailColumnPin(activeDetailCol, row, null)\"\n >\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/layout-three-columns.svg'\n \"\n class=\"data-grid-svg-icon me-2\"\n ></span\n >Unpin\n </div>\n </div>\n\n <div\n *ngIf=\"columnThreedotsMunuConfig?.showAutosizeThisColumn\"\n class=\"column-menu-item\"\n (click)=\"autosizeDetailColumn(activeDetailCol, row)\"\n >\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/arrows-expand-vertical.svg'\n \"\n class=\"me-2\"\n ></span>\n Autosize This Column\n </div>\n\n <!-- Autosize All Columns -->\n <div\n *ngIf=\"columnThreedotsMunuConfig?.showAutosizeAllColumns\"\n class=\"column-menu-item\"\n (click)=\"autosizeAllDetailColumns(row)\"\n >\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/arrows-angle-expand.svg'\n \"\n class=\"data-grid-svg-icon me-2\"\n ></span\n >Autosize All Columns\n </div>\n\n\n <!-- Choose Columns -->\n <div\n *ngIf=\"columnThreedotsMunuConfig?.showChoseColumns\"\n class=\"column-menu-item\"\n (click)=\"openDetailChooseColumns(row)\"\n>\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/ui-checks-grid.svg'\"\n class=\"data-grid-svg-icon me-2\"\n ></span>\n Choose Columns\n</div>\n\n <!-- Reset Columns -->\n <!-- <div\n *ngIf=\"columnThreedotsMunuConfig?.showResetColumns\"\n class=\"column-menu-item\"\n (click)=\"resetDetailColumns(row)\"\n >\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/arrow-counterclockwise.svg'\n \"\n class=\"data-grid-svg-icon me-2\"\n ></span\n >Reset Columns\n </div> -->\n </div>\n</ng-template>\n\n<!-- Column Pannel / Pivot Mode / Searching -->\n\n<ng-template #columnPannel>\n <div class=\"column-panel-header\">\n <!-- Pivot Toggle -->\n <div\n class=\"form-check form-switch d-flex align-items-center mb-2 pivot-mode px-5 ms-2\"\n >\n <input\n class=\"form-check-input me-2\"\n type=\"checkbox\"\n id=\"pivotToggle\"\n [(ngModel)]=\"pivotMode\"\n />\n <label class=\"form-check-label\" for=\"pivotToggle\">Pivot Mode</label>\n </div>\n\n <!-- Select All & Search -->\n <div class=\"d-flex align-items-center mb-2 px-3\">\n <span class=\"filter-icon-wrapper me-2\" *ngIf=\"showColumnsGrouping\">\n <span\n class=\"toggle-icon data-grid-svg-icon\"\n [inlineSVG]=\"\n accordionState === 'all'\n ? singleSpaAssetsPath + 'data-grid/icons/chevron-down.svg'\n : accordionState === 'some'\n ? singleSpaAssetsPath + 'data-grid/icons/dash.svg'\n : singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\n \"\n (click)=\"toggleAllAccordions()\"\n ></span>\n </span>\n <input\n type=\"checkbox\"\n class=\"form-check-input me-2\"\n [checked]=\"allColumnsSelected()\"\n (change)=\"toggleAllColumnsVisibility()\"\n />\n <input\n type=\"text\"\n class=\"form-control form-control-sm\"\n placeholder=\"Search columns...\"\n [(ngModel)]=\"columnSearch\"\n />\n </div>\n\n <!-- Separator -->\n <hr class=\"my-2\" />\n </div>\n</ng-template>\n\n<!-- Right Columns Menue -->\n\n<!-- Column Panel Item Template -->\n<ng-template #columnPanelItem let-col=\"col\">\n <!-- Group Column -->\n <ng-container *ngIf=\"col.children?.length\">\n <div class=\"column-group d-flex align-items-center mb-2\">\n <span class=\"filter-icon-wrapper me-2\">\n <span\n class=\"toggle-icon data-grid-svg-icon\"\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\n \"\n [class.rotate]=\"col.expanded\"\n (click)=\"col.expanded = !col.expanded\"\n ></span>\n </span>\n <input\n type=\"checkbox\"\n class=\"form-check-input me-2\"\n [id]=\"'group_' + col.header\"\n [checked]=\"isColumnVisible(col)\"\n (change)=\"toggleGroupVisibility(col)\"\n />\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/grid-3x2-gap.svg'\"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center me-2\"\n ></span>\n <label\n class=\"d-flex align-items-center mb-0 w-100\"\n [for]=\"'group_' + col.header\"\n style=\"cursor: pointer\"\n >\n <span class=\"text-truncate\">{{ col.header }}</span>\n </label>\n </div>\n <div *ngIf=\"col.expanded\" class=\"ps-4\">\n <ng-container *ngFor=\"let child of col.children; trackBy: trackByField\">\n <ng-container\n *ngTemplateOutlet=\"columnPanelItem; context: { col: child }\"\n ></ng-container>\n </ng-container>\n </div>\n </ng-container>\n\n <!-- Leaf Column -->\n <ng-container *ngIf=\"!col.children?.length\">\n <div class=\"d-flex align-items-center mb-2\">\n <span class=\"me-2\" style=\"width: 1.5rem\"></span>\n <input\n type=\"checkbox\"\n class=\"form-check-input me-2\"\n [(ngModel)]=\"col.is_visible\"\n [id]=\"'col_' + col.field\"\n (change)=\"onSideMenuColumnsVisibilityChange()\"\n />\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/grid-3x2-gap.svg'\"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center me-2\"\n ></span>\n <label\n class=\"d-flex align-items-center mb-0 w-100\"\n [for]=\"'col_' + col.field\"\n style=\"cursor: pointer\"\n >\n <span class=\"text-truncate\">{{ col.header }}</span>\n </label>\n </div>\n </ng-container>\n</ng-template>\n<!-- Columns Side Filter -->\n<ng-template #sideFilters>\n <div class=\"py-3 px-2 pe-3 h-100\">\n <div class=\"d-flex align-items-center mb-2\">\n <span class=\"filter-icon-wrapper me-2\">\n <span\n class=\"toggle-icon data-grid-svg-icon\"\n [inlineSVG]=\"\n filterAccordionState === 'all'\n ? singleSpaAssetsPath + 'data-grid/icons/chevron-down.svg'\n : filterAccordionState === 'some'\n ? singleSpaAssetsPath + 'data-grid/icons/dash.svg'\n : singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\n \"\n (click)=\"toggleAllFilterAccordions()\"\n ></span>\n </span>\n\n <input\n type=\"text\"\n class=\"form-control form-control-sm\"\n placeholder=\"Search...\"\n [(ngModel)]=\"columnSearch\"\n />\n </div>\n <div\n class=\"overflow-auto side-filter-columns-wrapper\"\n style=\"height: calc(100% - 120px); scrollbar-width: thin\"\n >\n <ng-container\n *ngFor=\"\n let col of columns | filter : columnSearch : 'header';\n trackBy: trackByField\n \"\n >\n <ng-container\n *ngTemplateOutlet=\"filterPannelItem; context: { col: col }\"\n ></ng-container>\n </ng-container>\n </div>\n <!-- Apply and Reset Buttons -->\n <!-- <div class=\"d-flex gap-2 mt-3 px-2\">\n <button\n class=\"btn btn-sm btn-primary d-flex justify-content-center align-items-center flex-fill\"\n style=\"height: 32px;\"\n (click)=\"applySideMenuFilters()\"\n >\n Apply\n </button>\n <button\n class=\"btn btn-sm btn-secondary d-flex justify-content-center align-items-center flex-fill\"\n style=\"height: 32px;\"\n (click)=\"resetSideMenuFilters()\"\n >\n Reset\n </button>\n </div> -->\n </div>\n</ng-template>\n\n<ng-template #filterPannelItem let-col=\"col\">\n <!-- Group Column -->\n <ng-container *ngIf=\"col.children?.length\">\n <div class=\"column-group d-flex align-items-center mb-2\">\n <!-- Chevron toggle -->\n <span class=\"filter-icon-wrapper me-2\">\n <span\n class=\"toggle-icon data-grid-svg-icon\"\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\n \"\n [class.rotate]=\"col.expandedFilter\"\n (click)=\"col.expandedFilter = !col.expandedFilter\"\n ></span>\n </span>\n\n <!-- Group label toggle -->\n <label\n class=\"d-flex align-items-center mb-0 w-100\"\n style=\"cursor: pointer\"\n (click)=\"col.expandedFilter = !col.expandedFilter\"\n >\n <span class=\"fw-bold text-truncate\"\n >{{ col.header }}\n <span\n class=\"text-primary ms-1\"\n *ngIf=\"col?.query?._ids?.length || col?.query?._first_value\"\n >*</span\n >\n </span>\n </label>\n </div>\n\n <!-- Children columns -->\n <div *ngIf=\"col.expandedFilter\" class=\"ps-4\">\n <ng-container *ngFor=\"let child of col.children; trackBy: trackByField\">\n <ng-container\n *ngTemplateOutlet=\"filterPannelItem; context: { col: child }\"\n ></ng-container>\n </ng-container>\n </div>\n </ng-container>\n\n <!-- Leaf Column -->\n <ng-container *ngIf=\"!col.children?.length\">\n <div class=\"d-flex align-items-center mb-2\">\n <span\n class=\"me-2 filter-icon-wrapper me-2\"\n (click)=\"col.expandedFilter = !col.expandedFilter\"\n >\n <span\n class=\"toggle-icon data-grid-svg-icon\"\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\n \"\n [class.rotate]=\"col.expandedFilter\"\n ></span>\n </span>\n\n <label\n class=\"d-flex align-items-center mb-0 w-100\"\n style=\"cursor: pointer\"\n (click)=\"col.expandedFilter = !col.expandedFilter\"\n >\n <span class=\"text-truncate fw-bold\">{{ col.header }}</span>\n </label>\n </div>\n\n <!-- Show filter when expanded -->\n <div *ngIf=\"col.expandedFilter\" class=\"ps-4 pe-3\">\n <ng-container\n *ngTemplateOutlet=\"sideNestedFilter; context: { col: col }\"\n ></ng-container>\n </div>\n </ng-container>\n</ng-template>\n\n<!-- Side Nested Filters -->\n<ng-template #sideNestedFilter let-col=\"col\">\n <div class=\"\">\n <!-- Dropdown Type -->\n <ng-container *ngIf=\"col.type === 'dropdown'; else textFilter\">\n <div class=\"p-1\">\n <!-- Search -->\n <input\n type=\"text\"\n class=\"form-control form-control-sm mb-2\"\n placeholder=\"Search...\"\n [(ngModel)]=\"col.searchValue\"\n />\n\n <!-- Select All -->\n <div class=\"form-check mb-1 ms-1\">\n <input\n class=\"form-check-input\"\n type=\"checkbox\"\n [checked]=\"\n col.query?._ids?.length == col?.column_dropdown_value?.length\n \"\n (change)=\"toggleSelectAllSideFilters(col, $event)\"\n id=\"selectAll_{{ col.field }}\"\n />\n <label class=\"form-check-label\" for=\"selectAll_{{ col.field }}\">\n Select All\n </label>\n </div>\n\n <!-- Options -->\n <div class=\"dropdown-options\">\n <div\n class=\"form-check mb-1 ms-1\"\n *ngFor=\"\n let option of col?.column_dropdown_value\n | filter : addFilterDropdownSearch : 'header'\n \"\n >\n <input\n class=\"form-check-input\"\n type=\"checkbox\"\n [value]=\"option\"\n [checked]=\"isOptionSelected(col, option)\"\n (change)=\"onOptionToggle(col, option)\"\n id=\"option_{{ col.field }}_{{\n option?.id || option?._id || option\n }}\"\n />\n <label\n class=\"form-check-label\"\n [for]=\"\n 'option_' +\n col.field +\n '_' +\n (option?.id || option?._id || option)\n \"\n >\n {{ option.value || option }}\n </label>\n </div>\n </div>\n\n <!-- Actions -->\n <!-- <div class=\"d-flex gap-2 mt-2\">\n <div\n class=\"btn btn-sm btn-primary d-flex justify-content-center align-items-center\"\n style=\"height: 22px;\"\n (click)=\"applySideMenuFilters()\"\n >\n Apply\n </div>\n <div\n class=\"btn btn-sm btn-secondary d-flex justify-content-center align-items-center\"\n style=\"height: 22px;\"\n (click)=\"resetSideMenuFilters()\"\n >\n Reset\n </div>\n </div> -->\n </div>\n </ng-container>\n\n <!-- Text Filter Section -->\n <ng-template #textFilter>\n <div class=\"filter-text-section\">\n <div class=\"form-group mb-2\">\n <select\n class=\"form-select form-select-sm\"\n [ngModel]=\"col!.query!.first_condition || (col.type === 'date' || col.type === 'time' ? 'equal' : 'contain')\"\n (ngModelChange)=\"col!.query!.first_condition = $event\"\n >\n <ng-container *ngIf=\"col.type === 'date' || col.type === 'time'; else textOptions\">\n <option value=\"equal\">Equal to</option>\n <option value=\"not_equal\">Not Equal</option>\n <option value=\"after\">After</option>\n <option value=\"before\">Before</option>\n </ng-container>\n <ng-template #textOptions>\n <option value=\"contain\">Contains</option>\n <option value=\"equal\">Equals</option>\n <option value=\"before\">Begins With</option>\n <option value=\"after\">Ends With</option>\n </ng-template>\n </select>\n </div>\n\n <input\n [type]=\"col.type == 'date' ? 'date' : col.type == 'number' ? 'number' : 'text'\"\n class=\"form-control form-control-sm mb-3\"\n placeholder=\"Value\"\n [(ngModel)]=\"col!.query!.first_value\"\n [min]=\"col.type == 'number' ? 0 : null\"\n (input)=\"col.type == 'number' && $any($event.target).value < 0 ? $any($event.target).value = 0 : null\"\n (keydown)=\"col.type == 'number' && $event.key === '-' ? $event.preventDefault() : null\"\n [class.number-input]=\"col.type == 'number'\"\n />\n\n <ng-container *ngIf=\"col?.query?.first_value && col?.query?.condition !== 'none'\">\n <div class=\"form-group mb-2\">\n <div class=\"form-check form-check-inline\">\n <input\n class=\"form-check-input filter-radio-inputs\"\n type=\"radio\"\n name=\"condition\"\n [(ngModel)]=\"col!.query.condition\"\n value=\"and\"\n id=\"and_{{ col.field }}\"\n />\n <label class=\"form-check-label\" for=\"and_{{ col.field }}\"\n >AND</label\n >\n </div>\n <div class=\"form-check form-check-inline\">\n <input\n class=\"form-check-input filter-radio-inputs\"\n type=\"radio\"\n name=\"condition\"\n [(ngModel)]=\"col!.query.condition\"\n value=\"or\"\n id=\"or_{{ col.field }}\"\n />\n <label class=\"form-check-label\" for=\"or_{{ col.field }}\"\n >OR</label\n >\n </div>\n <div class=\"form-check form-check-inline\">\n <input\n class=\"form-check-input filter-radio-inputs\"\n type=\"radio\"\n name=\"condition\"\n [(ngModel)]=\"col!.query.condition\"\n value=\"none\"\n id=\"none_{{ col.field }}\"\n />\n <label class=\"form-check-label\" for=\"none_{{ col.field }}\"\n >None</label\n >\n </div>\n </div>\n\n <div class=\"form-group mb-2\">\n <select\n class=\"form-select form-select-sm\"\n [ngModel]=\"col!.query.second_condition || (col.type === 'date' || col.type === 'time' ? 'equal' : 'contain')\"\n (ngModelChange)=\"col!.query.second_condition = $event\"\n >\n <ng-container *ngIf=\"col.type === 'date' || col.type === 'time'; else textOptionsSecond\">\n <option value=\"equal\">Equal to</option>\n <option value=\"not_equal\">Not Equal</option>\n <option value=\"after\">After</option>\n <option value=\"before\">Before</option>\n </ng-container>\n <ng-template #textOptionsSecond>\n <option value=\"contain\">Contains</option>\n <option value=\"equal\">Equals</option>\n <option value=\"before\">Begins With</option>\n <option value=\"after\">Ends With</option>\n </ng-template>\n </select>\n </div>\n\n <input\n [type]=\"col.type == 'date' ? 'date' : col.type == 'number' ? 'number' : 'text'\"\n class=\"form-control form-control-sm mb-2\"\n placeholder=\"Second Value\"\n [(ngModel)]=\"col!.query.second_value\"\n [min]=\"col.type == 'number' ? 0 : null\"\n (input)=\"col.type == 'number' && $any($event.target).value < 0 ? $any($event.target).value = 0 : null\"\n (keydown)=\"col.type == 'number' && $event.key === '-' ? $event.preventDefault() : null\"\n [class.number-input]=\"col.type == 'number'\"\n />\n </ng-container>\n\n <!-- Apply and Reset Buttons -->\n <div class=\"d-flex gap-2 mt-2\">\n <div\n class=\"btn btn-sm btn-primary d-flex justify-content-center align-items-center w-100\"\n style=\"height: 22px\"\n (click)=\"applyFilterFromFilterRow(col)\"\n >\n Apply\n </div>\n <div\n class=\"btn btn-sm btn-secondary d-flex justify-content-center align-items-center w-100\"\n style=\"height: 22px\"\n (click)=\"resetSideFilter(col)\"\n >\n Reset\n </div>\n </div>\n </div>\n </ng-template>\n </div>\n</ng-template>\n\n<!-- Centr Overlay for showing the chose columns -->\n\n<div *ngIf=\"showColumnPanel\" class=\"custom-modal-overlay\" (click)=\"closeModalColumnPanel()\">\n <div\n class=\"custom-modal-content\"\n [style.backgroundColor]=\"dropdownsBackgroundColor\"\n (click)=\"$event.stopPropagation()\"\n >\n <ng-container *ngTemplateOutlet=\"modalColumnPannel\"></ng-container>\n </div>\n</div>\n\n<!-- The existing ng-template you provided -->\n<ng-template #modalColumnPannel>\n <div class=\"column-panel-header\">\n <div\n class=\"d-flex justify-content-between align-items-center px-2 ps-3 rounded-top-2 moda-header\"\n [style.height.px]=\"48\"\n >\n Choose Columns\n <span class=\"filter-icon-wrapper\" (click)=\"closeModalColumnPanel()\"\n ><span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/x.svg'\"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span\n ></span>\n </div>\n <hr class=\"my-0\" />\n <div>\n <div class=\"d-flex align-items-center px-2 pe-3\" [style.height.px]=\"48\">\n <span class=\"filter-icon-wrapper me-2\" *ngIf=\"showColumnsGrouping\">\n <span\n class=\"toggle-icon data-grid-svg-icon\"\n [inlineSVG]=\"\n accordionState === 'all'\n ? singleSpaAssetsPath + 'data-grid/icons/chevron-down.svg'\n : accordionState === 'some'\n ? singleSpaAssetsPath + 'data-grid/icons/dash.svg'\n : singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\n \"\n (click)=\"toggleAllAccordions()\"\n ></span>\n </span>\n <input\n type=\"checkbox\"\n class=\"form-check-input me-2\"\n [checked]=\"allColumnsSelected()\"\n (change)=\"toggleAllColumnsVisibility()\"\n />\n <input\n type=\"text\"\n class=\"form-control form-control-sm\"\n placeholder=\"Search columns...\"\n [(ngModel)]=\"choseColumnsSearch\"\n />\n </div>\n\n <hr class=\"mt-0 mb-1\" />\n <div class=\"px-2 overlay-scrollable\">\n <ng-container\n *ngFor=\"\n let col of columns | filter : choseColumnsSearch : 'header';\n trackBy: trackByField\n \"\n >\n <ng-container\n *ngTemplateOutlet=\"columnPanelItem; context: { col: col }\"\n ></ng-container>\n </ng-container>\n </div>\n </div>\n </div>\n</ng-template>\n\n<ng-template #sideMenuRowGroups>\n <div class=\"d-flex flex-column h-100\">\n <div class=\"px-3 h-100\">\n <div class=\"d-flex gap-3 mb-4\">\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/justify.svg'\"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n <span>Row Groups</span>\n </div>\n <div class=\"h-50\">\n <div\n class=\"px-3 py-2 border-dashed h-100 d-flex justify-content-center align-items-center\"\n style=\"font-size: 14px\"\n >\n Drag here to set row Groups\n </div>\n </div>\n </div>\n\n <hr class=\"mt-4\" />\n\n <div class=\"px-3 h-100\">\n <div class=\"d-flex gap-3 mb-4\">\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/justify.svg'\"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n <span>Values</span>\n </div>\n <div class=\"h-50 d-flex\">\n <div\n class=\"px-3 py-2 border-dashed h-100 d-flex justify-content-center align-items-center\"\n style=\"font-size: 14px\"\n >\n Drag here aggregate\n </div>\n </div>\n </div>\n </div>\n</ng-template>\n\n<!-- *************************************************** -->\n<!-- *************************************************** -->\n<!-- *************************************************** -->\n<!-- Drag Preview Template -->\n<!-- *************************************************** -->\n<!-- *************************************************** -->\n<ng-template #dragPreview let-col>\n <div class=\"p-2 border d-flex gap-2\">\n <div>\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrows-move.svg'\"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n </div>\n <div>{{ col.header }}</div>\n </div>\n</ng-template>\n\n<!-- Drag Placeholder Template -->\n<ng-template\n #dragPlaceholder\n let-col\n let-i=\"index\"\n let-section=\"section\"\n let-draggingInGroupArea=\"draggingInGroupArea\"\n>\n <div *ngIf=\"!draggingInGroupArea\">\n <div\n *ngTemplateOutlet=\"\n headerCell;\n context: { $implicit: col, index: i, section: section }\n \"\n ></div>\n </div>\n <div *ngIf=\"draggingInGroupArea\">New Placeholder</div>\n</ng-template>\n\n<!-- Top Group Row Placeholder -->\n<ng-template #topGroupingRowPlaceholder let-col let-showChevron=\"showChevron\">\n <div class=\"d-flex gap-2\">\n <div\n class=\"d-flex gap-2 top-row-grouping-placeholder\"\n [style.backgroundColor]=\"topGroupedBadgesBackgroundColor\"\n >\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/grid-3x2-gap.svg'\"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n <span>{{ col.header }}</span>\n <span\n (click)=\"ungroupColumn(col)\"\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/x.svg'\"\n class=\"cursor-pointer data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n </div>\n </div>\n <div *ngIf=\"showChevron\" style=\"opacity: 0.6; font-size: 14px\">\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n </div>\n</ng-template>\n\n<ng-template\n #childHeaderPlaceholder\n let-col\n let-pinnedRight=\"pinnedRight\"\n let-i=\"index\"\n let-sections=\"sections\"\n>\n <div\n class=\"header-cell one-row-header-cells\"\n [class.border-right]=\"showVerticalBorder\"\n [style.width.px]=\"col.width\"\n [style.min-width.px]=\"col.width\"\n [style.min-height.px]=\"headerRowHeight\"\n [style.max-height.px]=\"headerRowHeight\"\n [class.border-right]=\"showVerticalBorder\"\n [style.fontWeight]=\"headerFontWeight\"\n >\n <div class=\"d-flex justify-content-between h-100 align-items-center w-100\">\n <div\n class=\"d-flex justify-content-between w-100\"\n [class.flex-row-reverse]=\"pinnedRight\"\n >\n <div\n class=\"text-ellipsis h-100 d-flex align-items-center\"\n [title]=\"col.header\"\n [class.w-100]=\"pinnedRight\"\n >\n {{ col.header }}\n </div>\n\n <div\n class=\"position-relative d-flex\"\n [class.flex-row-reverse]=\"pinnedRight\"\n >\n <div class=\"three-dots p-1\" style=\"cursor: pointer\">\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/three-dots-vertical.svg'\n \"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n </div>\n\n <div class=\"resize-handle\">\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/resize-handle.svg'\n \"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n </div>\n </div>\n </div>\n </div>\n </div>\n <div\n *ngIf=\"showFilterRow\"\n [style.backgroundColor]=\"headerBackgroundColor\"\n class=\"header-cell filter-cell\"\n [class.border-right]=\"showVerticalBorder\"\n [style.width.px]=\"col.width\"\n [style.min-width.px]=\"col.width\"\n [style.height.px]=\"headerRowHeight\"\n [style.min-height.px]=\"headerRowHeight\"\n [style.max-height.px]=\"headerRowHeight\"\n [class.border-right]=\"showVerticalBorder\"\n style=\"grid-row: 3\"\n >\n <div\n class=\"header-cell filter-cell\"\n [style.backgroundColor]=\"headerBackgroundColor\"\n [style.width.px]=\"col.width\"\n [style.min-width.px]=\"col.width\"\n [style.height.px]=\"headerRowHeight\"\n [style.min-height.px]=\"headerRowHeight\"\n [style.max-height.px]=\"headerRowHeight\"\n >\n <input\n type=\"text\"\n class=\"form-control form-control-sm\"\n placeholder=\"Filter\"\n [(ngModel)]=\"col.filterValue\"\n />\n <span\n class=\"filter-icon-wrapper\"\n (click)=\"activeFilterCell = col; activeCol = null\"\n ><span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span\n ></span>\n\n <div\n class=\"position-absolute\"\n *ngIf=\"activeFilterCell === col\"\n style=\"top: 100%; right: 0; z-index: 10; left: 0\"\n ></div>\n </div>\n </div>\n</ng-template>\n\n<ng-template #tableLayout>\n <div\n (click)=\"$event.stopPropagation()\"\n class=\"p-3 shadow rounded-3 bg-white actions-dropdown mt-1 dropdown-menu show shadow custom-menu table-layout\"\n style=\"width: 320px\"\n >\n <div class=\"d-flex align-items-center mb-3\">\n <button\n class=\"btn btn-link p-0\"\n style=\"margin-left: -10px\"\n (click)=\"toggleActions('setting')\"\n >\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrow-left.svg'\"\n class=\"data-grid-svg-icon me-2\"\n ></span>\n </button>\n <h6 class=\"mb-0 ms-2\" style=\"font-weight: 500\">Table Layout</h6>\n </div>\n <hr class=\"my-2\" />\n <div class=\"w-100 mb-3 d-flex\" role=\"group\">\n <input\n type=\"radio\"\n class=\"btn-check layout-button-check\"\n name=\"layoutSize\"\n id=\"small\"\n autocomplete=\"off\"\n (change)=\"changeTableLayout($event, 'small')\"\n [checked]=\"selectedTableLayout == 'small'\"\n />\n <label\n class=\"border d-flex flex-column align-items-center layout-button\"\n for=\"small\"\n [ngStyle]=\"{\n color: selectedTableLayout == 'small' ? '#000' : '#727272'\n }\"\n >\n <div class=\"preview-box border mb-1\" style=\"height: 8px\"></div>\n Small\n </label>\n\n <input\n type=\"radio\"\n class=\"btn-check layout-button-check\"\n name=\"layoutSize\"\n id=\"medium\"\n autocomplete=\"off\"\n [checked]=\"selectedTableLayout == 'medium'\"\n (change)=\"changeTableLayout($event, 'medium')\"\n />\n <label\n class=\"border mx-3 d-flex flex-column align-items-center layout-button\"\n for=\"medium\"\n [ngStyle]=\"{\n color: selectedTableLayout == 'medium' ? '#000' : '#727272'\n }\"\n >\n <div class=\"preview-box border mb-1\" style=\"height: 12px\"></div>\n Medium\n </label>\n\n <input\n type=\"radio\"\n class=\"btn-check layout-button-check\"\n name=\"layoutSize\"\n id=\"large\"\n autocomplete=\"off\"\n (change)=\"changeTableLayout($event, 'large')\"\n [checked]=\"selectedTableLayout == 'large'\"\n />\n <label\n class=\"border d-flex flex-column align-items-center layout-button\"\n for=\"large\"\n [ngStyle]=\"{\n color: selectedTableLayout == 'large' ? '#000' : '#727272'\n }\"\n >\n <div class=\"preview-box border mb-1\" style=\"height: 16px\"></div>\n Large\n </label>\n </div>\n\n <hr class=\"my-2\" />\n <div class=\"d-flex justify-content-between align-items-center mb-2\">\n <span>Show separators</span>\n <div class=\"form-check form-switch m-0\">\n <input\n class=\"form-check-input\"\n type=\"checkbox\"\n id=\"separators\"\n [(ngModel)]=\"showVerticalBorder\"\n (change)=\"emitConfigUpdate()\"\n />\n </div>\n </div>\n <div class=\"d-flex justify-content-between align-items-center\">\n <span>Row shading</span>\n <div class=\"form-check form-switch m-0\">\n <input\n class=\"form-check-input\"\n [(ngModel)]=\"rowShadingEnabled\"\n (change)=\"toggleRowShading()\"\n type=\"checkbox\"\n id=\"rowShading\"\n />\n </div>\n </div>\n </div>\n</ng-template>\n\n<ng-template #tablePreset>\n <div\n *ngIf=\"activeSubButton !== 'save-preset'\"\n (click)=\"$event.stopPropagation();\"\n class=\"p-3 shadow rounded-3 bg-white actions-dropdown mt-1 dropdown-menu show shadow custom-menu table-layout\"\n style=\"width: 280px\"\n >\n <!-- Header -->\n <div class=\"d-flex justify-content-between align-items-center mb-3\">\n <div class=\"d-flex align-items-center\">\n <button\n class=\"btn btn-link p-0\"\n style=\"margin-left: -10px\"\n (click)=\"toggleActions('setting')\"\n >\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrow-left.svg'\"\n class=\"data-grid-svg-icon\"\n ></span>\n </button>\n <h6 class=\"mb-0 ms-2\" style=\"font-weight: 500\">Table Presets</h6>\n </div>\n <!-- Save/Update Preset Button -->\n <div>\n <a\n class=\"text-decoration-none btn btn-link\"\n type=\"button\"\n id=\"savePresetDropdown\"\n (click)=\"$event.stopPropagation(); toggleSubActions('save-preset')\"\n >\n {{ tableFilterViewId && tableFilterViewId !== 'default' ? 'Update Preset' : 'Save Preset' }}\n </a>\n </div>\n </div>\n\n <!-- Search -->\n <div class=\"mb-3\">\n <div class=\"col-12 global-search\">\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/search.svg'\"\n class=\"data-grid-svg-icon mx-2 position-absolute icon\"\n ></span>\n <input\n class=\"form-control form-control-sm\"\n placeholder=\"Search...\"\n [(ngModel)]=\"searchTextPresetTable\"\n type=\"search\"\n />\n </div>\n </div>\n\n <!-- Preset List -->\n <ng-container\n *ngIf=\"\n tableView | filter : searchTextPresetTable : 'name' as filteredList\n \"\n >\n <!-- If filteredList exists and none is default -> show fallback -->\n <div class=\"\" (click)=\"selectDefault()\">\n <div class=\"fw-semibold\">Default View\n <span\n *ngIf=\"tableFilterViewId === 'default'\"\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/check-blue.svg'\"\n class=\"me-2\"\n ></span>\n </div>\n </div>\n <div class=\"d-flex justify-content-between\">\n <small class=\"text-dark\">Created by system</small>\n <span\n *ngIf=\"tableFilterViewId === 'default'\"\n class=\"badge bg-light text-primary ms-2\"\n >Default</span\n >\n <div\n class=\"dropdown d-flex justify-content-end\"\n *ngIf=\"tableFilterViewId\"\n >\n <a\n href=\"javascript:void(0)\"\n class=\"muted-text\"\n data-bs-toggle=\"dropdown\"\n >\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/horizontal-dots.svg'\n \"\n class=\"me-2\"\n ></span>\n </a>\n <ul class=\"dropdown-menu dropdown-menu-end\">\n <a\n (click)=\"actionPreset({ id: 'default' }, 'setPreset')\"\n class=\"dropdown-item d-flex align-items-center\"\n >\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/star.svg'\"\n class=\"me-2\"\n ></span>\n Set as default\n </a>\n </ul>\n </div>\n </div>\n\n <!-- The list: render each table from filteredList -->\n <div\n class=\"list-group list-group-flush\"\n *ngFor=\"let table of filteredList; trackBy: trackByTable\"\n >\n <!-- Item -->\n <div\n class=\"list-group-item px-0 d-flex justify-content-between align-items-center\"\n >\n <div (click)=\"selectFilter(table)\">\n <div class=\"fw-semibold\" style=\"cursor: pointer;\">\n {{ table?.name }}\n <!-- {{table?.is_temp}} -->\n <span\n *ngIf=\"table?.is_temp\"\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/check-blue.svg'\n \"\n class=\"me-2\"\n ></span>\n <span\n *ngIf=\"table?.is_default\"\n class=\"badge bg-light text-primary ms-2\"\n >Default</span\n >\n </div>\n <small class=\"text-dark\"\n >Created {{ table?.createdAt | timezoneFormat:prefs:'date' }}</small\n >\n </div>\n\n <div class=\"d-flex align-items-center\">\n <span\n *ngIf=\"table?.is_default\"\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/check-blue.svg'\n \"\n class=\"me-2\"\n ></span>\n\n <div class=\"dropdown position-relative\" *ngIf=\"!table?.is_default\">\n <a href=\"javascript:void(0)\" class=\"muted-text\" (click)=\"togglePresetDropdown(table.id)\">\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/horizontal-dots.svg'\" class=\"me-2\"></span>\n </a>\n\n <div\n *ngIf=\"activePresetDropdownId === table.id\"\n class=\"dropdown-menu dropdown-menu-end show position-absolute\"\n style=\"z-index: 1000; top: 100%; right: 0; min-width: 180px\"\n (click)=\"$event.stopPropagation()\"\n >\n <a\n [class.d-none]=\"confirmDeletePresetId === table.id\"\n (click)=\"setPresetAsDefault(table); activePresetDropdownId = null;\"\n class=\"dropdown-item d-flex align-items-center\"\n >\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/star.svg'\" class=\"me-2\"></span>\n Set as default\n </a>\n\n <ng-container *ngIf=\"confirmDeletePresetId !== table.id; else confirmBlock\">\n <a\n (click)=\"confirmDeletePresetId = table.id\"\n class=\"dropdown-item d-flex align-items-center text-danger\"\n >\n <span style=\"margin-top: -4px\" [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/trash-red.svg'\" class=\"me-2\"></span>\n Delete\n </a>\n </ng-container>\n\n <ng-template #confirmBlock>\n <div class=\"dropdown-item\"><b>Delete preset</b></div>\n <div class=\"dropdown-item text-center\">\n <div class=\"mb-2\">\n Are you sure you want to delete the <br />\n <b>\u201C{{ table?.name }}\u201D</b> preset?\n </div>\n <button\n class=\"btn btn-sm btn-light me-2\"\n (click)=\"confirmDeletePresetId = null\"\n >\n Cancel\n </button>\n <button\n class=\"btn btn-sm btn-danger delete-preset\"\n (click)=\"actionPreset(table, 'deletePreset'); confirmDeletePresetId = null; activePresetDropdownId = null;\"\n >\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/trash-red.svg'\" class=\"confirm-preset-delete\"></span>\n Delete\n </button>\n </div>\n </ng-template>\n </div>\n</div>\n </div>\n </div>\n <!-- Item End Here -->\n </div>\n\n </ng-container>\n </div>\n\n <div\n (click)=\"$event.stopPropagation()\"\n *ngIf=\"activeSubButton == 'save-preset'\"\n class=\"dropdown-menu p-3 badge mt-4 save-preset-dropdown mt-1\"\n aria-labelledby=\"savePresetDropdown\"\n style=\"min-width: 250px\"\n >\n <div class=\"fw-bold fs-14px mb-2\">Save preset</div>\n <div class=\"fs-14px mb-2\" style=\"line-height: 20px\">\n This will save the current table adjustments as a preset.\n </div>\n <!-- Input -->\n <div class=\"mb-2\">\n <label for=\"presetName\" class=\"form-label fs-12px fw-bold\"\n >Preset Name</label\n >\n <div class=\"col-12 global-search\">\n <input\n #presetNameCtrl=\"ngModel\"\n required\n [(ngModel)]=\"presetName\"\n [ngClass]=\"{\n 'is-invalid':\n presetNameCtrl.invalid &&\n (presetNameCtrl.dirty || presetNameCtrl.touched)\n }\"\n class=\"form-control form-control-sm ps-2\"\n placeholder=\"Enter preset name\"\n type=\"text\"\n />\n </div>\n </div>\n\n <!-- Checkbox -->\n <div class=\"form-check mb-2\">\n <input\n class=\"form-check-input\"\n [(ngModel)]=\"presetFilter\"\n type=\"checkbox\"\n id=\"saveFilters\"\n />\n <label class=\"form-check-label mt-1\" for=\"saveFilters\">\n Save active filters\n </label>\n </div>\n\n <!-- Save Button -->\n <div class=\"d-flex justify-content-center gap-2\" style=\"height: 32px\">\n <button\n type=\"button\"\n style=\"height: 32px\"\n class=\"btn border w-100 d-flex align-items-center justify-content-center btn-light\"\n (click)=\"$event.stopPropagation(); toggleActions('table-presets')\"\n style=\"margin-top: -2px\"\n >\n <span>Cancel</span>\n </button>\n <button\n [disabled]=\"closeDropdown.preset.loading\"\n (click)=\"savePreset(presetNameCtrl)\"\n type=\"button\"\n style=\"height: 32px\"\n class=\"btn btn-primary w-100 d-flex align-items-center justify-content-center\"\n >\n <span style=\"margin-top: -2px\">\n <ng-container *ngIf=\"!closeDropdown.preset.loading && (!tableFilterViewId || tableFilterViewId === 'default')\"\n >Save</ng-container\n >\n <ng-container *ngIf=\"!closeDropdown.preset.loading && tableFilterViewId && tableFilterViewId !== 'default'\"\n >Update</ng-container\n >\n <ng-container *ngIf=\"closeDropdown.preset.loading\"\n ><span class=\"spinner-border spinner-border-sm\"></span\n ></ng-container>\n </span>\n </button>\n </div>\n </div>\n</ng-template>\n\n<ng-template #showHideColumns>\n <div\n (click)=\"$event.stopPropagation()\"\n class=\"p-3 shadow rounded-3 bg-white actions-dropdown mt-1 dropdown-menu show shadow custom-menu table-layout\"\n style=\"width: 280px\"\n >\n <!-- Header -->\n <div class=\"d-flex justify-content-between align-items-center mb-3\">\n <div class=\"d-flex align-items-center\">\n <button\n class=\"btn btn-link p-0\"\n style=\"margin-left: -10px\"\n (click)=\"toggleActions('setting')\"\n >\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrow-left.svg'\"\n class=\"data-grid-svg-icon\"\n ></span>\n </button>\n <h6 class=\"mb-0 ms-2\" style=\"font-weight: 500\">Columns</h6>\n </div>\n <a\n (click)=\"resetColumns()\"\n href=\"javascript:void(0)\"\n class=\"text-primary text-decoration-none\"\n >Reset</a\n >\n </div>\n\n <!-- Search -->\n <div class=\"mb-3\">\n <div class=\"col-12 global-search\">\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/search.svg'\"\n class=\"mx-2 position-absolute icon data-grid-svg-icon\"\n ></span>\n <input\n class=\"form-control form-control-sm\"\n placeholder=\"Search column\"\n type=\"search\"\n [(ngModel)]=\"topShowHideColumns\"\n />\n </div>\n </div>\n <!-- Preset List -->\n <div\n class=\"list-group list-group-flush\"\n style=\"\n max-height: calc(100vh - 300px);\n overflow: auto;\n scrollbar-width: thin;\n \"\n >\n <div class=\"muted-text show-hide-table-label d-flex justify-content-between\" *ngIf=\"hasAnyVisibleColumn\">\n Show in table\n <div class=\"form-check\">\n <input\n type=\"checkbox\"\n id=\"show_hide_all\"\n class=\"form-check-input\"\n [checked]=\"areAllNonMandatoryVisible()\"\n (change)=\"toggleAllVisibleColumns()\"\n />\n <label for=\"show_hide_all\" class=\"form-check-label fw-semibold\">Show/Hide All</label>\n </div>\n </div>\n <!-- <div class=\"d-flex align-items-center mb-2\" *ngIf=\"hasAnyVisibleColumn\">\n <input\n type=\"checkbox\"\n class=\"form-check-input me-2\"\n [checked]=\"areAllNonMandatoryVisible()\"\n (change)=\"toggleAllVisibleColumns()\"\n />\n <label class=\"form-check-label fw-semibold\">Show All</label>\n </div> -->\n <!-- Item -->\n <ng-container\n *ngFor=\"\n let col of columns | filter : topShowHideColumns : 'header';\n trackBy: trackByField\n \"\n >\n <div\n *ngIf=\"col.is_visible\"\n class=\"list-group-item border-0 px-0 d-flex justify-content-between align-items-center\"\n >\n <div class=\"d-flex gap-1\">\n <div>\n <span\n *ngIf=\"!col?.pinned\"\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/grip-vertical.svg'\n \"\n class=\"cursor-grap data-grid-svg-icon\"\n (mousedown)=\"$event.preventDefault()\"\n ></span>\n <span\n *ngIf=\"col?.pinned\"\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/pin-blue.svg'\n \"\n class=\"cursor-grap data-grid-svg-icon\"\n (mousedown)=\"$event.preventDefault()\"\n ></span>\n </div>\n <div class=\"fw-semibold\">\n {{ col.header }}\n </div>\n </div>\n <div\n *ngIf=\"!col?.query?.first_value && !col?.query?._ids?.length && !isMandatory(col)\"\n class=\"d-flex align-items-center cursor-pointer\"\n (click)=\"toggleColumnVisibility(col, false)\"\n >\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/eye.svg'\"\n class=\"data-grid-svg-icon me-2\"\n ></span>\n </div>\n <div\n *ngIf=\"(!col?.query?.first_value && !col?.query?._ids?.length && isMandatory(col)) || (col?.query?.first_value || col?.query?._ids?.length)\"\n class=\"d-flex align-items-center\"\n style=\"opacity: 0.5\"\n >\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/eye.svg'\"\n class=\"data-grid-svg-icon me-2\"\n ></span>\n </div>\n </div>\n </ng-container>\n\n <!-- Item End Here -->\n\n <div\n class=\"dropdown-divider\"\n *ngIf=\"hasAnyVisibleColumn && hasAnyInVisibleColumn\"\n ></div>\n\n <!-- <div\n class=\"muted-text show-hide-table-label\"\n *ngIf=\"hasAnyInVisibleColumn\"\n >\n Hide in table\n </div>\n <div class=\"d-flex align-items-center mb-2\" *ngIf=\"hasAnyInVisibleColumn\">\n <input\n type=\"checkbox\"\n id=\"hide_show_all\"\n class=\"form-check-input me-2\"\n [checked]=\"areAllNonMandatoryHidden()\"\n (change)=\"toggleAllInvisibleColumns()\"\n />\n <label class=\"form-check-label fw-semibold\">Hide All</label>\n </div> -->\n\n \n\n\n\n <div class=\"muted-text show-hide-table-label d-flex justify-content-between\" *ngIf=\"hasAnyInVisibleColumn\">\n Hide in table\n <div class=\"form-check\">\n <input\n type=\"checkbox\"\n id=\"hide_show_all\"\n class=\"form-check-input\"\n [checked]=\"areAllNonMandatoryHidden()\"\n (change)=\"toggleAllInvisibleColumns()\"\n />\n <label for=\"hide_show_all\" class=\"form-check-label fw-semibold\">Hide/Show All</label>\n </div>\n </div>\n <div class=\"list-group list-group-flush\">\n <ng-container *ngFor=\"let col of columns; trackBy: trackByField\">\n <div\n *ngIf=\"!col.is_visible\"\n class=\"list-group-item border-0 px-0 d-flex justify-content-between align-items-center\"\n >\n <div class=\"d-flex gap-1\">\n <div>\n <span\n *ngIf=\"!col?.pinned\"\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/grip-vertical.svg'\n \"\n class=\"data-grid-svg-icon cursor-grap\"\n (mousedown)=\"$event.preventDefault()\"\n ></span>\n <span\n *ngIf=\"col?.pinned\"\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/pin-blue.svg'\n \"\n class=\"data-grid-svg-icon cursor-grap\"\n (mousedown)=\"$event.preventDefault()\"\n ></span>\n </div>\n <div class=\"fw-semibold\">\n {{ col.header }}\n </div>\n </div>\n <div\n class=\"d-flex align-items-center cursor-pointer\"\n (click)=\"toggleColumnVisibility(col, true)\"\n >\n <span\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/eye-cross.svg'\n \"\n class=\"data-grid-svg-icon me-2\"\n ></span>\n </div>\n </div>\n </ng-container>\n </div>\n\n <!-- Item End Here -->\n </div>\n </div>\n</ng-template>\n\n<ng-template #filterColumns let-col=\"column\">\n <div\n @slideToggle\n *ngIf=\"!isFilterOpen && activeTopButton == 'filter-columns'\"\n (click)=\"$event.stopPropagation()\"\n class=\"shadow rounded-3 bg-white actions-dropdown mt-1 show shadow custom-menu table-layout filter-columns\"\n style=\"width: 280px; right: unset; max-width: 230px\"\n >\n <div class=\"mb-2 px-3\">\n <div class=\"col-12 global-search\">\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/search.svg'\"\n class=\"data-grid-svg-icon mx-2 position-absolute icon\"\n ></span>\n <input\n class=\"form-control form-control-sm\"\n placeholder=\"Filter by\"\n type=\"search\"\n [(ngModel)]=\"addFilterColumnInput\"\n />\n </div>\n </div>\n <div\n class=\"list-group list-group-flush\"\n style=\"max-height: calc(100vh - 500px); overflow: auto\"\n >\n <ng-container\n *ngFor=\"\n let col of columns | filter : addFilterColumnInput : 'header';\n trackBy: trackByField\n \"\n >\n <div\n (click)=\"openFilter(col)\"\n *ngIf=\"\n col.is_visible &&\n !col?.query?.first_value &&\n !col?.query?._ids?.length\n \"\n class=\"list-group-item border-0 px-0 d-flex justify-content-between align-items-center dropdown-item cursor-pointer\"\n >\n <div class=\"d-flex gap-1\">\n <div style=\"margin-top: -3px\"></div>\n <div class=\"fw-semibold\">\n {{ col.header }}\n </div>\n </div>\n </div>\n </ng-container>\n </div>\n </div>\n\n <!-- Dropdown -->\n <div\n @slideToggle\n *ngIf=\"isFilterOpen && selectedColumnForFilter.type == 'dropdown'\"\n (click)=\"$event.stopPropagation()\"\n class=\"shadow rounded-3 bg-white actions-dropdown mt-1 show shadow custom-menu table-layout filter-columns\"\n style=\"width: 280px; right: unset; max-width: 230px\"\n >\n <div class=\"px-3 my-2 border-below py-1 pb-2 mb-3 d-flex ps-1\">\n <span\n (click)=\"toggleActions('filter-columns'); isActiveFilterOpen = false\"\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrow-left.svg'\"\n class=\"data-grid-svg-icon me-2 cursor-pointer\"\n ></span\n ><b>{{ selectedColumnForFilter?.header }}</b>\n </div>\n <div class=\"mb-2 px-3\">\n <div\n class=\"col-12 global-search position-relative border rounded d-flex align-items-center flex-wrap px-2 filter-serach-inpt\"\n >\n <span\n *ngFor=\"let selected of selectedFilterOptions\"\n class=\"badge d-flex align-items-center gap-1 me-1 mb-1\"\n >\n {{ selected?.value ? selected.value : selected }}\n <span\n (click)=\"toggleSelectionInFilter(selected)\"\n [inlineSVG]=\"\n singleSpaAssetsPath + 'data-grid/icons/cross-primary.svg'\n \"\n class=\"me-2\"\n ></span>\n </span>\n <input\n class=\"form-control form-control-sm border-0 flex-grow-1\"\n style=\"padding: 0\"\n [placeholder]=\"selectedFilterOptions!.length ? '' : 'Filter by'\"\n type=\"search\"\n [(ngModel)]=\"searchTextForFilterDropDown\"\n (keydown.backspace)=\"handleBackspace($event)\"\n (ngModelChange)=\"selectedFilterOptions.length === 0 ? condition = 'none' : null\"\n />\n </div>\n </div>\n <div\n class=\"list-group list-group-flush\"\n style=\"max-height: calc(100vh - 600px); overflow: auto\"\n >\n <ng-container\n *ngFor=\"\n let col of selectedColumnForFilter.column_dropdown_value\n | filter : searchTextForFilterDropDown : 'value';\n let i = index\n \"\n >\n <div\n class=\"list-group-item border-0 px-2 d-flex justify-content-between align-items-center dropdown-item cursor-pointer\"\n >\n <div class=\"form-check\">\n <input\n class=\"form-check-input\"\n type=\"checkbox\"\n [id]=\"i\"\n [checked]=\"currentFilterSelectedIds.has(col.id || col._id || col)\"\n (change)=\"toggleSelectionInFilter(col)\"\n />\n <label class=\"form-check-label fw-semibold\" [for]=\"i\">\n {{ col?.value || col?.name || col }}\n </label>\n </div>\n </div>\n </ng-container>\n </div>\n <div\n class=\"d-flex justify-content-center gap-2 px-2 border-top\"\n style=\"height: 38px\"\n >\n <button\n type=\"button\"\n style=\"height: 32px\"\n class=\"btn btn-outline-secondary btn-light border w-100 d-flex align-items-center justify-content-center mt-1 btn-light\"\n (click)=\"$event.stopPropagation(); resetFilterChanges()\"\n >\n <span>Cancel</span>\n </button>\n <button\n type=\"button\"\n style=\"height: 32px\"\n class=\"btn btn-primary w-100 d-flex align-items-center justify-content-center mt-1\"\n (click)=\"applyDropdownFilter()\"\n >\n <span style=\"margin-top: -2px\">Save</span>\n </button>\n </div>\n </div>\n\n <!-- For Text fields and number fields-->\n\n <div\n @slideToggle\n *ngIf=\"\n isFilterOpen &&\n (selectedColumnForFilter.type == 'string' ||\n selectedColumnForFilter.type == 'number' ||\n selectedColumnForFilter.type == 'date')\n \"\n (click)=\"$event.stopPropagation()\"\n class=\"shadow rounded-3 bg-white actions-dropdown mt-1 show shadow custom-menu table-layout filter-columns\"\n style=\"width: 280px; right: unset; max-width: 230px\"\n >\n <div class=\"px-3 border-below py-1 pb-2 d-flex ps-1\">\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrow-left.svg'\"\n (click)=\"toggleActions('filter-columns'); isActiveFilterOpen = false\"\n class=\"data-grid-svg-icon me-2 cursor-pointer\"\n ></span\n ><b>{{ selectedColumnForFilter?.header }}</b>\n </div>\n <div class=\"col-12 position-relative p-2 text-filter\">\n <div class=\"mb-2\">\n <select\n class=\"form-select form-select-sm custom-select\"\n [(ngModel)]=\"firstCondition\"\n >\n <ng-container *ngIf=\"selectedColumnForFilter.type === 'date' || selectedColumnForFilter.type === 'time'; else textOptions\">\n <option value=\"equal\">Equal to</option>\n <option value=\"not_equal\">Not Equal</option>\n <option value=\"after\">After</option>\n <option value=\"before\">Before</option>\n </ng-container>\n <ng-template #textOptions>\n <option value=\"equal\">Equals</option>\n <!-- <option value=\"not_equal\">Not Equals</option> -->\n <option value=\"contain\">Contains</option>\n <option value=\"before\">Begins With</option>\n <option value=\"after\">Ends With</option>\n </ng-template>\n </select>\n </div>\n <div class=\"mb-2\">\n <input\n class=\"form-control form-control-sm\"\n placeholder=\"Enter first value\"\n [type]=\"\n selectedColumnForFilter.type == 'string'\n ? 'text'\n : selectedColumnForFilter.type\n \"\n [(ngModel)]=\"firstValue\"\n [min]=\"selectedColumnForFilter.type == 'number' ? 0 : null\"\n [class.number-input]=\"selectedColumnForFilter.type == 'number'\"\n (input)=\"selectedColumnForFilter.type == 'number' && $any($event.target).value < 0 ? $any($event.target).value = 0 : null\"\n (ngModelChange)=\"!firstValue ? condition = 'none' : null\"\n (keydown)=\"selectedColumnForFilter.type == 'number' && $event.key === '-' ? $event.preventDefault() : null\"\n />\n </div>\n <div class=\"d-flex my-3\">\n <div class=\"form-check form-check-inline\">\n <input\n class=\"form-check-input\"\n type=\"radio\"\n id=\"logicalAnd\"\n name=\"logicalOperator\"\n value=\"and\"\n [(ngModel)]=\"condition\"\n />\n <label class=\"form-check-label\" for=\"logicalAnd\">AND</label>\n </div>\n\n <div class=\"form-check form-check-inline\">\n <input\n class=\"form-check-input\"\n type=\"radio\"\n id=\"logicalOr\"\n name=\"logicalOperator\"\n value=\"or\"\n [(ngModel)]=\"condition\"\n />\n <label class=\"form-check-label\" for=\"logicalOr\">OR</label>\n </div>\n\n <div class=\"form-check form-check-inline\">\n <input\n class=\"form-check-input\"\n type=\"radio\"\n id=\"logicalNone\"\n name=\"logicalOperator\"\n value=\"none\"\n [(ngModel)]=\"condition\"\n />\n <label class=\"form-check-label\" for=\"logicalNone\">None</label>\n </div>\n </div>\n\n <div *ngIf=\"firstValue && condition !== 'none'\">\n <div class=\"my-3\">\n <!-- Second condition select -->\n <select\n class=\"form-select form-select-sm\"\n [(ngModel)]=\"secondCondition\"\n >\n <ng-container *ngIf=\"selectedColumnForFilter.type === 'date' || selectedColumnForFilter.type === 'time'; else textOptionsSecond\">\n <option value=\"equal\">Equal to</option>\n <option value=\"not_equal\">Not Equal</option>\n <option value=\"after\">After</option>\n <option value=\"before\">Before</option>\n </ng-container>\n <ng-template #textOptionsSecond>\n <option value=\"equal\">Equals</option>\n <!-- <option value=\"not_equal\">Not Equals</option> -->\n <option value=\"contain\">Contains</option>\n <option value=\"before\">Begins With</option>\n <option value=\"after\">Ends With</option>\n </ng-template>\n </select>\n </div>\n\n <div class=\"mb-2\">\n <!-- Second value input -->\n <input\n [type]=\"\n selectedColumnForFilter.type == 'string'\n ? 'text'\n : selectedColumnForFilter.type\n \"\n class=\"form-control form-control-sm\"\n placeholder=\"Enter second value\"\n [(ngModel)]=\"secondValue\"\n [min]=\"selectedColumnForFilter.type == 'number' ? 0 : null\"\n [class.number-input]=\"selectedColumnForFilter.type == 'number'\"\n (input)=\"selectedColumnForFilter.type == 'number' && $any($event.target).value < 0 ? $any($event.target).value = 0 : null\"\n (keydown)=\"selectedColumnForFilter.type == 'number' && $event.key === '-' ? $event.preventDefault() : null\"\n />\n </div>\n </div>\n </div>\n\n <div\n class=\"d-flex justify-content-center gap-2 px-2 border-top\"\n style=\"height: 38px\"\n >\n <button\n type=\"button\"\n style=\"height: 32px\"\n class=\"btn btn-outline-secondary btn-light border w-100 d-flex align-items-center justify-content-center mt-1 btn-light\"\n (click)=\"$event.stopPropagation(); resetTextFilterChanges()\"\n >\n <span>Cancel</span>\n </button>\n <button\n type=\"button\"\n style=\"height: 32px\"\n class=\"btn btn-primary w-100 d-flex align-items-center justify-content-center mt-1\"\n (click)=\"applyDropdownFilter()\"\n >\n <span style=\"margin-top: -2px\">Save</span>\n </button>\n </div>\n </div>\n</ng-template>\n\n<!-- Detail Filter Menu -->\n <div\n *ngIf=\"activeAccordionFilterMenu && detailFilterMenuPosition\"\n class=\"detail-filter-menu\"\n [style.backgroundColor]=\"dropdownsBackgroundColor\"\n [style.left.px]=\"detailFilterMenuPosition.x\"\n [style.top.px]=\"detailFilterMenuPosition.y\"\n (click)=\"$event.stopPropagation()\"\n >\n <div class=\"px-3 border-below py-1 pb-2 d-flex ps-1\">\n <span\n (click)=\"closeDetailFilterMenu()\"\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrow-left.svg'\"\n class=\"data-grid-svg-icon me-2 cursor-pointer\"\n ></span\n ><b>{{ activeDetailFilterCol?.header }}</b>\n </div>\n\n <!-- Text Filter -->\n <div *ngIf=\"detailFilterType === 'string'\" class=\"col-12 position-relative p-2 text-filter\">\n <div class=\"mb-2\">\n <select\n class=\"form-select form-select-sm custom-select\"\n [(ngModel)]=\"detailFilterCondition\"\n >\n <option value=\"contain\">Contains</option>\n <option value=\"equal\">Equals</option>\n <option value=\"before\">Begins With</option>\n <option value=\"after\">Ends With</option>\n </select>\n </div>\n <div class=\"mb-2\">\n <input\n class=\"form-control form-control-sm\"\n placeholder=\"Enter value\"\n [(ngModel)]=\"detailFilterValue\"\n (keydown.enter)=\"applyDetailFilter()\"\n />\n </div>\n </div>\n\n <!-- Date Filter -->\n <div *ngIf=\"detailFilterType === 'date'\" class=\"col-12 position-relative p-2 text-filter\">\n <div class=\"mb-2\">\n <select\n class=\"form-select form-select-sm custom-select\"\n [(ngModel)]=\"detailFilterCondition\"\n >\n <option value=\"equal\">Equal to</option>\n <option value=\"before\">Before</option>\n <option value=\"after\">After</option>\n </select>\n </div>\n <div class=\"mb-2\">\n <input\n type=\"date\"\n class=\"form-control form-control-sm\"\n placeholder=\"Select date\"\n [(ngModel)]=\"detailFilterDateValue\"\n (keydown.enter)=\"applyDetailFilter()\"\n />\n <small class=\"text-muted d-block mt-1\">{{ detailFilterDateValue | timezoneFormat:prefs:'date' }}</small>\n </div>\n </div>\n\n <!-- Time Filter -->\n <div *ngIf=\"detailFilterType === 'time'\" class=\"col-12 position-relative p-2 text-filter\">\n <div class=\"mb-2\">\n <select\n class=\"form-select form-select-sm custom-select\"\n [(ngModel)]=\"detailFilterCondition\"\n >\n <option value=\"equal\">Equal to</option>\n <option value=\"before\">Before</option>\n <option value=\"after\">After</option>\n </select>\n </div>\n <div class=\"mb-2\">\n <input\n type=\"time\"\n class=\"form-control form-control-sm\"\n placeholder=\"Select time\"\n [(ngModel)]=\"detailFilterTimeValue\"\n (keydown.enter)=\"applyDetailFilter()\"\n />\n </div>\n </div>\n\n <!-- Dropdown Filter -->\n <div *ngIf=\"detailFilterType === 'dropdown'\" class=\"col-12 position-relative p-2 text-filter\">\n <div class=\"mb-2\">\n <input\n type=\"text\"\n class=\"form-control form-control-sm\"\n placeholder=\"Search options...\"\n [(ngModel)]=\"detailFilterSearch\"\n (input)=\"filterDetailDropdownOptions()\"\n />\n </div>\n <div class=\"dropdown-options\" style=\"max-height: 150px; overflow-y: auto;\">\n <div\n *ngFor=\"let option of filteredDetailDropdownOptions; let i = index\"\n class=\"form-check mb-1 ms-1\"\n >\n <input\n class=\"form-check-input\"\n type=\"checkbox\"\n [id]=\"'detail-filter-option-' + i\"\n [checked]=\"detailSelectedFilterOptions.includes(option._id || option.id || option.value)\"\n (change)=\"toggleDetailFilterOption(option)\"\n />\n <label\n class=\"form-check-label\"\n [for]=\"'detail-filter-option-' + i\"\n >\n {{ option.value || option.name || option }}\n </label>\n </div>\n </div>\n </div>\n\n <!-- <div class=\"d-flex gap-2\">\n <button\n type=\"button\"\n class=\"btn btn-primary w-100 d-flex align-items-center justify-content-center mt-1\"\n (click)=\"applyDetailFilter()\"\n >\n <span>Apply</span>\n </button>\n <button\n type=\"button\"\n class=\"btn btn-danger w-100 d-flex align-items-center justify-content-center mt-1\"\n (click)=\"resetDetailFilter()\"\n >\n <span>Reset</span>\n </button>\n \n</div> -->\n\n <div class=\"d-flex gap-2 mt-2\">\n <div\n class=\"btn btn-sm btn-primary d-flex justify-content-center align-items-center w-100\"\n style=\"height: 22px\"\n (click)=\"applyDetailFilter()\"\n >\n Apply\n </div>\n <div\n class=\"btn btn-sm btn-secondary d-flex justify-content-center align-items-center w-100\"\n style=\"height: 22px\"\n (click)=\"resetDetailFilter()\"\n >\n Reset\n </div>\n </div>\n</div>\n\n<!-- Edit dropdown here -->\n<ng-template let-col>\n <div class=\"drop-down-edit\"></div>\n</ng-template>\n\n<ng-template\n #fullTextTemplate\n let-row=\"row\"\n let-col=\"col\"\n let-isArray=\"isArray\"\n>\n <div\n class=\"full-text-box\"\n (dblclick)=\"$event.stopPropagation(); $event.preventDefault();\"\n (click)=\"$event.stopPropagation(); $event.preventDefault()\"\n >\n <ng-container *ngIf=\"!isEditing(row, col)\">\n <div\n *ngIf=\"!isArray\"\n class=\"full-text-content\"\n (dblclick)=\"$event.stopPropagation(); $event.preventDefault(); enableEdit(row, col)\"\n (click)=\"$event.stopPropagation(); $event.preventDefault()\"\n >\n {{\n getNestedValue(row, col.field)?.value ||\n getNestedValue(row, col.field)?.name ||\n getNestedValue(row, col.field)\n }}\n </div>\n <div *ngIf=\"isArray\">\n <ul>\n <ng-container\n *ngFor=\"let item of getNestedValue(row, col.field); let i = index\"\n >\n <li *ngIf=\"i !== 0\">\n <ng-container>\n {{ item?.department_name || item?.roleName || \"-\" }}\n </ng-container>\n </li>\n </ng-container>\n </ul>\n </div>\n </ng-container>\n <ng-container *ngIf=\"isEditing(row, col)\">\n <textarea\n #textModel=\"ngModel\"\n rows=\"4\"\n #textAreadInput\n [(ngModel)]=\"row[col.field]\"\n name=\"{{ col.field }}\"\n required\n (blur)=\"disableEdit(row, col, textModel)\"\n (keydown.enter)=\"textAreadInput.blur()\"\n autofocus\n class=\"form-control\"\n [ngClass]=\"{\n 'is-invalid': textModel.invalid\n }\"\n (mousedown)=\"$event.stopPropagation()\"\n ></textarea>\n\n </ng-container>\n </div>\n</ng-template>\n\n<ng-template #defaultImagePlaceholder let-row=\"row\" let-col=\"col\">\n <span\n class=\"px-2 d-flex align-items-center w-100 cell-content image-placeholder cursor-pointer position-relative\"\n \n (click)=\"onEmployeeClick(row)\"\n >\n <!-- Blue dot for manual logs -->\n <span\n *ngIf=\"row?.manually_logs && row.manually_logs.length > 0\"\n class=\"manual-logs-indicator\"\n (mouseenter)=\"openManualLogsModal($event, row)\"\n (mouseleave)=\"closeManualLogsModal()\"\n ></span>\n <ng-container\n *ngIf=\"\n row?.User?.logo || row?.User?.profile_pictures?.length || row?.logo || row?.profile_pictures?.length || row?.assetImage || row?.invoice?.invoice_image;\n else placeholder\n \"\n >\n <span class=\"pic\">\n <img\n [width]=\"rowHeight - 12\"\n [height]=\"rowHeight - 12\"\n [src]=\"row?.User?.profile_pictures?.[4]?.path || row?.User?.logo || row?.profile_pictures?.[4]?.path || row?.logo || row?.assetImage || row?.invoice?.invoice_image\"\n alt=\"icon\"\n />\n </span>\n </ng-container>\n\n <ng-template #placeholder>\n <span\n [ngClass]=\"getDynamicClass(row?.User?.full_name || row?.full_name || row?.name)\"\n class=\"pic d-flex align-items-center rounded-circle\"\n [style.width.px]=\"rowHeight - 12\"\n [style.height.px]=\"rowHeight - 12\"\n [style.fontSize.px]=\"rowHeight / 3\"\n >\n {{ getInitials(row?.User?.full_name || row?.full_name) }}\n </span>\n </ng-template>\n </span>\n</ng-template>\n\n<!-- Cell Content Template for Card View -->\n<ng-template #cellContent let-row=\"row\" let-parentRow=\"parentRow\" let-col=\"col\">\n <ng-container [ngSwitch]=\"col.type\">\n <!-- String/Text -->\n <ng-container *ngSwitchCase=\"'string'\">\n {{ getNestedValue(row, col.field) || getNestedValue(parentRow, col.field) || '-' }}\n </ng-container>\n\n <!-- Number -->\n <ng-container *ngSwitchCase=\"'number'\">\n {{ getNestedValue(row, col.field) || getNestedValue(parentRow, col.field) || '-' }}\n </ng-container>\n\n <!-- Date -->\n <ng-container *ngSwitchCase=\"'date'\">\n {{ getNestedValue(row, col.field) || getNestedValue(parentRow, col.field) ? (getNestedValue(row, col.field) || getNestedValue(parentRow, col.field) | timezoneFormat:prefs:'date') : '-' }}\n </ng-container>\n\n <!-- Time -->\n <ng-container *ngSwitchCase=\"'time'\">\n {{ (getNestedValue(row, col.field) || getNestedValue(parentRow, col.field)) !== null && (getNestedValue(row, col.field) || getNestedValue(parentRow, col.field)) !== undefined ? ((getTimeValue(getNestedValue(row, col.field) || getNestedValue(parentRow, col.field)) | timezoneFormat:prefs:'time')) : '-' }}\n </ng-container>\n\n <!-- Boolean -->\n <ng-container *ngSwitchCase=\"'boolean'\">\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'\">\n {{ (getNestedValue(row, col.field) || getNestedValue(parentRow, col.field) === true || getNestedValue(row, col.field) || getNestedValue(parentRow, col.field) === 'true') ? 'Yes' : 'No' }}\n </span>\n </ng-container>\n\n <!-- <div *ngSwitchCase=\"'is_payroll_processed'\" class=\"d-flex justify-content-start flex-column pointer position-relative\" >\n <span class=\"popover__wrapper\" >none\n {{ row.is_payroll_processed ? 'Yes' : 'No' }}\n </span>\n </div> -->\n\n <!-- Status -->\n <ng-container *ngSwitchCase=\"'status'\">\n <span class=\"badge\" [class]=\"getStatusBadgeClass(getNestedValue(row, col.field) || getNestedValue(parentRow, col.field))\">\n {{ transformStatus(getNestedValue(row, col.field) || getNestedValue(parentRow, col.field)) || '-' }}\n </span>\n </ng-container>\n\n <!-- Array -->\n <ng-container *ngSwitchCase=\"'array'\">\n <ng-container *ngIf=\"isArray(getNestedValue(row, col.field) || getNestedValue(parentRow, col.field))\">\n <ng-container *ngIf=\"col.field === 'breaks' || col.header?.toLowerCase().includes('break')\">\n <app-badge-overflow\n [badges]=\"getBreakBadges(getNestedValue(row, col.field) || getNestedValue(parentRow, col.field) || [])\"\n [maxWidth]=\"col.width || 200\"\n (badgeMouseEnter)=\"showBreakTooltip($event.event, $event.badge.data)\"\n (badgeMouseLeave)=\"hideBreakTooltip()\"\n (overflowCountClick)=\"onBadgeOverflowCountClick(col)\">\n </app-badge-overflow>\n </ng-container>\n <ng-container *ngIf=\"!(col.field === 'breaks' || col.header?.toLowerCase().includes('break'))\">\n {{ (getNestedValue(row, col.field) || getNestedValue(parentRow, col.field) || []).length }} items\n </ng-container>\n </ng-container>\n <ng-container *ngIf=\"!isArray(getNestedValue(row, col.field) || getNestedValue(parentRow, col.field))\">\n {{ getNestedValue(row, col.field) || getNestedValue(parentRow, col.field) || '-' }}\n </ng-container>\n </ng-container>\n\n <!-- Default -->\n <ng-container *ngSwitchDefault>\n {{ getNestedValue(row, col.field) || getNestedValue(parentRow, col.field) || '-' }}\n </ng-container>\n \n </ng-container>\n</ng-template>\n\n<!-- Right Click Menue -->\n<div\n [class.invisible]=\"!positionedYet\"\n class=\"context-menu p-2\"\n *ngIf=\"actionHide && actions?.length\"\n [ngStyle]=\"{ 'top.px': yPos, 'left.px': xPos }\"\n [class.show]=\"isVisible\"\n appendTo=\"body\"\n>\n <ul>\n <li\n *ngFor=\"let action of actions\"\n class=\"rounded d-flex align-items-center\"\n (click)=\"onActionClick(action)\"\n >\n <ng-container *ngIf=\"action === 'add Leave'\">\n <i class=\"fas fa-clock me-2\"></i>\n </ng-container>\n <ng-container *ngIf=\"action !== 'add Leave'\">\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/' + action + '.svg'\"\n class=\"data-grid-svg-icon me-2\"\n ></span>\n </ng-container>\n <span class=\"text-capitalize fw-500\">{{ action }}</span>\n </li>\n </ul>\n</div>\n\n<!-- Details Toggle from bottom -->\n <div\n [style.bottom.px]=\"footerRowHeight + 50\"\n *ngIf=\"selectedRows.size > 0 && showTaskbar\"\n class=\"taskbar\"\n >\n <div class=\"selected-rows-action-bar\" [@slideUp]>\n <span class=\"selected-count\">\n {{ selectedRows.size }} selected of\n {{\n paginationConfig.totalResults ||\n config?.paginationParams?.totalItems\n }}\n Total\n </span>\n <div class=\"action-buttons\">\n <ng-container *ngFor=\"let action of computedTaskbarActions; let i = index\">\n <span\n class=\"action-btn verified btn {{ action }}\"\n (click)=\"action === 'Export' ? onExportClick() : action === 'Delete' ? onDeleteClick() : onVerifyClick(action)\"\n >{{ action }}</span\n >\n <span\n *ngIf=\"computedTaskbarActions.length > 1 && i !== computedTaskbarActions.length - 1\"\n class=\"separator\"\n >|</span\n >\n </ng-container>\n </div>\n </div>\n </div>\n\n<!-- Detail Row Choose Columns Modal -->\n<div *ngIf=\"showDetailColumnPanel\" class=\"custom-modal-overlay\" (click)=\"closeDetailColumnPanel()\">\n <div\n class=\"custom-modal-content\"\n [style.backgroundColor]=\"dropdownsBackgroundColor\"\n (click)=\"$event.stopPropagation()\"\n >\n <ng-container *ngTemplateOutlet=\"detailModalColumnPannel\"></ng-container>\n </div>\n</div>\n\n<!-- Paste Confirmation Modal -->\n<div *ngIf=\"showPasteConfirmationModal\" class=\"custom-modal-overlay\" (click)=\"cancelPaste()\">\n <div class=\"custom-modal-content\" [style.backgroundColor]=\"dropdownsBackgroundColor\" (click)=\"$event.stopPropagation()\">\n <div class=\"column-panel-header\">\n <div class=\"d-flex justify-content-between align-items-center px-2 ps-3 rounded-top-2 moda-header\" style=\"height: 48px;\">\n Confirm Paste Operation\n <span class=\"filter-icon-wrapper\" (click)=\"cancelPaste()\">\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/x.svg'\" class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"></span>\n </span>\n </div>\n <hr class=\"my-0\" />\n <div class=\"p-3\">\n <div class=\"mb-3\">\n <h6 class=\"mb-3\">You are about to paste the following data:</h6>\n <div class=\"border rounded p-3 bg-light\">\n <pre class=\"mb-0 text-dark small\">{{ pastePreviewData }}</pre>\n </div>\n </div>\n <div class=\"alert alert-warning\" role=\"alert\">\n <strong>Warning:</strong> This action will overwrite existing data in the selected cells. This cannot be undone.\n </div>\n <div class=\"d-flex justify-content-end gap-2 mt-4\">\n <button type=\"button\" class=\"btn btn-secondary\" (click)=\"cancelPaste()\">Cancel</button>\n <button type=\"button\" class=\"btn btn-primary\" (click)=\"confirmPaste()\">Confirm Paste</button>\n </div>\n </div>\n </div>\n </div>\n</div>\n\n<!-- Short Leave Tooltip Modal -->\n<div *ngIf=\"showShortLeaveTooltipModal\"\n class=\"custom-break-tooltips\"\n @tooltipAnimationBottom\n [style.--tooltip-x.px]=\"shortLeaveTooltipPosition.x\"\n [style.--tooltip-y.px]=\"shortLeaveTooltipPosition.y\"\n (mouseenter)=\"preventShortLeaveTooltipHide()\"\n (mouseleave)=\"hideShortLeaveTooltip()\">\n <div class=\"modal-body\">\n <div class=\"table-responsive\">\n <table class=\"table table-striped text-dark\">\n <thead>\n <tr>\n <th>Leave Type</th>\n <th>Start Time</th>\n <th>End Time</th>\n <th>Duration (min)</th>\n </tr>\n </thead>\n <tbody>\n <tr *ngFor=\"let item of currentShortLeaveData\">\n <td>{{ item.leave_type || 'N/A' }}</td>\n\n <!-- Start Time -->\n <td>\n {{\n item.star_time\n ? (getTimeValue(item.star_time) | timezoneFormat:prefs:'time')\n : 'N/A'\n }}\n </td>\n\n <!-- End Time -->\n <td>\n {{\n item.end_time\n ? (getTimeValue(item.end_time) | timezoneFormat:prefs:'time')\n : 'N/A'\n }}\n </td>\n\n <td>{{ item.minutes || 'N/A' }}</td>\n</tr>\n\n </tbody>\n </table>\n </div>\n </div>\n </div>\n\n<!-- Paste Confirmation Modal -->\n<div *ngIf=\"showPasteConfirmationModal\" class=\"custom-modal-overlay\" (click)=\"cancelPaste()\">\n <div class=\"custom-modal-content\" [style.backgroundColor]=\"dropdownsBackgroundColor\" (click)=\"$event.stopPropagation()\">\n <div class=\"column-panel-header\">\n <div class=\"d-flex justify-content-between align-items-center px-2 ps-3 rounded-top-2 moda-header\" style=\"height: 48px;\">\n <span class=\"fw-bold\">Confirm Paste</span>\n <span class=\"filter-icon-wrapper\" (click)=\"cancelPaste()\">\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/x.svg'\" class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"></span>\n </span>\n </div>\n <hr class=\"my-0\" />\n <div class=\"p-3\">\n <div class=\"mb-3\">\n <p class=\"mb-2\">Are you sure you want to paste the following data?</p>\n <div class=\"border rounded p-2 bg-light\">\n <small class=\"text-muted\">{{ pastePreviewData }}</small>\n </div>\n </div>\n <div class=\"d-flex gap-2 justify-content-end\">\n <button type=\"button\" class=\"btn btn-secondary\" (click)=\"cancelPaste()\">Cancel</button>\n <button type=\"button\" class=\"btn btn-primary\" (click)=\"confirmPaste()\">Confirm Paste</button>\n </div>\n </div>\n </div>\n </div>\n</div>\n\n<!-- Paste Confirmation Modal -->\n<div *ngIf=\"showPasteConfirmationModal\" class=\"custom-modal-overlay\" (click)=\"cancelPaste()\">\n <div class=\"custom-modal-content\" [style.backgroundColor]=\"dropdownsBackgroundColor\" (click)=\"$event.stopPropagation()\">\n <div class=\"modal-header d-flex justify-content-between align-items-center p-3\">\n <h5 class=\"modal-title mb-0\">Confirm Paste</h5>\n <button type=\"button\" class=\"btn-close\" (click)=\"cancelPaste()\"></button>\n </div>\n <div class=\"modal-body p-3\">\n <p class=\"mb-3\">Are you sure you want to paste the clipboard data into the selected cells?</p>\n <div class=\"alert alert-info\" *ngIf=\"pastePreviewData\">\n <strong>Paste Preview:</strong>\n <pre class=\"mt-2\">{{ pastePreviewData }}</pre>\n </div>\n </div>\n <div class=\"modal-footer p-3\">\n <button type=\"button\" class=\"btn btn-secondary\" (click)=\"cancelPaste()\">Cancel</button>\n <button type=\"button\" class=\"btn btn-primary\" (click)=\"confirmPaste()\">Paste</button>\n </div>\n </div>\n</div>\n\n<!-- Tooltip for accordion manual logs -->\n<!-- Tooltip for accordion manual logs -->\n<div *ngIf=\"showManualLogsTooltipModal\" class=\"custom-break-tooltips\"\n [style.--tooltip-x.px]=\"manualLogsTooltipPosition.x\"\n [style.--tooltip-y.px]=\"manualLogsTooltipPosition.y\"\n \n (mouseenter)=\"preventManualLogsTooltipHide()\"\n (mouseleave)=\"hideManualLogsTooltip()\">\n\n <div class=\"modal-body\">\n <div class=\"table-responsive\">\n <table class=\"table table-striped text-dark\">\n <thead>\n <tr>\n <th>Name</th>\n <th>Date/Time</th>\n <th>Previous</th>\n <th>Updated</th>\n <th>Status</th>\n <th>Remarks</th>\n </tr>\n </thead>\n <tbody>\n <ng-container *ngFor=\"let item of selectedManualLogs; let i = index\">\n <tr>\n <td>{{ item?.updated_by?.full_name || selectedManualLogsRow?.User?.full_name }}</td>\n <td>{{ item?.log_date && item.log_date !== '--' ? (item.log_date | timezoneFormat:prefs:'datetime') : (selectedManualLogsRow?.attendanceDate && selectedManualLogsRow?.attendanceDate !== '--' ? (selectedManualLogsRow?.attendanceDate | timezoneFormat:prefs:'datetime') : '-') }}</td>\n <td>\n <ng-container [ngSwitch]=\"isDate(item?.log_details?.previous_state)\">\n \n <!-- If it is a date -->\n <span *ngSwitchCase=\"true\">\n {{ formatLogState(item?.log_details?.previous_state) | timezoneFormat:prefs:'time' }}\n </span>\n\n <!-- If it is NOT a date -->\n <span *ngSwitchDefault>\n {{ item?.log_details?.previous_state || '-' }}\n </span>\n\n </ng-container>\n</td>\n\n\n<td>\n <ng-container [ngSwitch]=\"isDate(item?.log_details?.updated_state)\">\n \n <!-- If it is a date -->\n <span *ngSwitchCase=\"true\">\n {{ formatLogState(item?.log_details?.updated_state) | timezoneFormat:prefs:'time' }}\n </span>\n\n <!-- If it is NOT a date -->\n <span *ngSwitchDefault>\n {{ item?.log_details?.updated_state || '-' }}\n </span>\n\n </ng-container>\n</td>\n\n <td>{{ item?.log_details?.status ? transformStatus(item.log_details.status) : (item.log_details?.status || '-') }}</td>\n <td>{{ item?.log_details?.remarks || item?.remarks || selectedManualLogsRow?.message || '-' }}</td>\n </tr>\n </ng-container>\n\n <!-- Fallback for empty manual logs -->\n <tr *ngIf=\"!selectedManualLogs || selectedManualLogs.length === 0\">\n <td colspan=\"6\" class=\"text-center\">No manual logs available</td>\n </tr>\n </tbody>\n </table>\n </div>\n </div>\n </div>\n<!-- </div> -->\n\n<ng-template #detailModalColumnPannel>\n <div class=\"column-panel-header detail-column-modal\">\n <div\n class=\"d-flex justify-content-between align-items-center px-2 ps-3 rounded-top-2 moda-header\"\n [style.height.px]=\"48\"\n >\n Choose Detail Columns\n <span class=\"filter-icon-wrapper\" (click)=\"closeDetailColumnPanel()\">\n <span\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/x.svg'\"\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\n ></span>\n </span>\n </div>\n <hr class=\"my-0\" />\n <div>\n <div class=\"d-flex align-items-center px-2 pe-3\" [style.height.px]=\"48\">\n <input\n type=\"checkbox\"\n class=\"form-check-input me-2\"\n [checked]=\"allDetailColumnsSelected()\"\n (change)=\"toggleAllDetailColumnsVisibility()\"\n />\n <input\n type=\"text\"\n class=\"form-control form-control-sm\"\n placeholder=\"Search detail columns...\"\n [(ngModel)]=\"choseColumnsSearch\"\n />\n </div>\n <hr class=\"mt-0 mb-1\" />\n <div class=\"px-2 overlay-scrollable\">\n <ng-container\n *ngFor=\"\n let col of (currentDetailRowForColumnSelection?.details?.columns || [])\n | filter : choseColumnsSearch : 'header';\n trackBy: trackByField\n \"\n >\n <div class=\"d-flex align-items-center mb-2\">\n <input\n type=\"checkbox\"\n class=\"form-check-input me-2\"\n [checked]=\"col.is_visible !== false\"\n (change)=\"toggleDetailColumnVisibility(col, !col.is_visible)\"\n [id]=\"'detail_col_' + col.field\"\n />\n <label\n class=\"d-flex align-items-center mb-0 w-100\"\n [for]=\"'detail_col_' + col.field\"\n style=\"cursor: pointer\"\n >\n <span class=\"text-truncate\">{{ col.header }}</span>\n </label>\n </div>\n </ng-container>\n </div>\n </div>\n <!-- <div class=\"px-3 py-2 border-top d-flex justify-content-end\">\n <button class=\"btn btn-sm btn-link\" (click)=\"resetDetailColumnsInModal()\">Reset</button>\n </div> -->\n </div>\n</ng-template>\n\n\n\n\n\n\n\n\n\n\n\n", styles: ["@charset \"UTF-8\";@keyframes fadeInUp{0%{opacity:0;transform:translateY(8px)}to{opacity:1;transform:translateY(0)}}@keyframes fadeInScale{0%{opacity:0;transform:scale(.95)}to{opacity:1;transform:scale(1)}}@keyframes slideInRight{0%{opacity:0;transform:translate(16px)}to{opacity:1;transform:translate(0)}}@keyframes pulse{0%{transform:scale(1)}50%{transform:scale(1.02)}to{transform:scale(1)}}@keyframes shimmer{0%{background-position:-200px 0}to{background-position:calc(200px + 100%) 0}}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.loading-overlay{animation:fadeInScale .25s cubic-bezier(.4,0,.2,1);transform:translateZ(0)}.loading-overlay .spinner-border{animation:spin 1s linear infinite}.data-grid-table-wrapper{height:100%;width:100%;border:1px solid #d9d9db;border-radius:12px;box-shadow:none!important;position:relative;animation:fadeInScale .35s cubic-bezier(.4,0,.2,1);transform:translateZ(0)}.data-grid-table-wrapper[data-theme=white]{border-color:#d9d9db;background-color:#f6f8ff;color:#000}.data-grid-table-wrapper[data-theme=white] *,.data-grid-table-wrapper[data-theme=white] *:before,.data-grid-table-wrapper[data-theme=white] *:after{color:#000!important}.data-grid-table-wrapper[data-theme=white] ::selection{background-color:#007bff!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=white] ::-moz-selection{background-color:#007bff!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=white] .data-grid-header-wrapper{background-color:#f8f9fa;color:#000!important}.data-grid-table-wrapper[data-theme=white] .data-grid-body-wrapper{background-color:#f6f8ff;box-shadow:none!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .data-grid-row{border-bottom-color:#d9d9db;box-shadow:none!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .data-grid-row:nth-child(2n){background-color:#f8f9fa!important}.data-grid-table-wrapper[data-theme=white] .data-grid-row:nth-child(odd){background-color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=white] .data-grid-row:hover{background-color:#007bff1a!important}.data-grid-table-wrapper[data-theme=white] .selected-cell,.data-grid-table-wrapper[data-theme=white] .row-selected{background-color:#e3f2fd!important}.data-grid-table-wrapper[data-theme=white] .cell,.data-grid-table-wrapper[data-theme=white] .header-cell,.data-grid-table-wrapper[data-theme=white] .data-grid-row,.data-grid-table-wrapper[data-theme=white] .data-grid-header,.data-grid-table-wrapper[data-theme=white] .cell-content,.data-grid-table-wrapper[data-theme=white] .full-text-content,.data-grid-table-wrapper[data-theme=white] .circle-value,.data-grid-table-wrapper[data-theme=white] .pic,.data-grid-table-wrapper[data-theme=white] .image-placeholder,.data-grid-table-wrapper[data-theme=white] .s-no,.data-grid-table-wrapper[data-theme=white] .fw-500{color:#000!important}.data-grid-table-wrapper[data-theme=white] span,.data-grid-table-wrapper[data-theme=white] div,.data-grid-table-wrapper[data-theme=white] p,.data-grid-table-wrapper[data-theme=white] td,.data-grid-table-wrapper[data-theme=white] th,.data-grid-table-wrapper[data-theme=white] label,.data-grid-table-wrapper[data-theme=white] a:not(.text-primary){color:#000!important}.data-grid-table-wrapper[data-theme=white] svg,.data-grid-table-wrapper[data-theme=white] svg path,.data-grid-table-wrapper[data-theme=white] svg circle,.data-grid-table-wrapper[data-theme=white] svg rect,.data-grid-table-wrapper[data-theme=white] svg polygon{color:#000!important;fill:#000!important;stroke:#000!important}.data-grid-table-wrapper[data-theme=white] .data-grid-svg-icon{color:#000!important}.data-grid-table-wrapper[data-theme=white] .data-grid-svg-icon path{stroke:#000!important;fill:#000!important}.data-grid-table-wrapper[data-theme=white] .badge.badge-danger{background-color:#ea5353!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=white] .badge.badge-success{background-color:#84ca81!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=white] .badge.badge-warning{background-color:#fff3dc!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .badge.badge-info{background-color:#e8fbfd!important;color:#00bad1!important}.data-grid-table-wrapper[data-theme=white] .context-menu{background:#f6f8ff;border-color:#d9d9db;color:#000!important}.data-grid-table-wrapper[data-theme=white] .context-menu li{color:#000!important}.data-grid-table-wrapper[data-theme=white] .context-menu li:hover{background-color:#007bff1a!important}.data-grid-table-wrapper[data-theme=white] .custom-tooltip,.data-grid-table-wrapper[data-theme=white] .popover__content,.data-grid-table-wrapper[data-theme=white] .custom-break-tooltip{background:#f6f8ff!important;border-color:#d9d9db!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .actions-dropdown,.data-grid-table-wrapper[data-theme=white] .custom-menu{background-color:#f6f8ff!important;border-color:#d9d9db!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .actions-dropdown .dropdown-item,.data-grid-table-wrapper[data-theme=white] .custom-menu .dropdown-item{color:#000!important}.data-grid-table-wrapper[data-theme=white] .actions-dropdown .dropdown-item:hover,.data-grid-table-wrapper[data-theme=white] .custom-menu .dropdown-item:hover{background-color:#007bff1a!important}.data-grid-table-wrapper[data-theme=white] .taskbar .selected-rows-action-bar{background-color:#343a40!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=white] .taskbar .selected-rows-action-bar .action-btn{color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=white] .manual-logs-modal .modal-header{background:linear-gradient(135deg,#343a40,#495057)!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=white] .manual-logs-modal .modal-header .modal-title{color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=white] .manual-logs-modal .modal-body{background-color:#f6f8ff!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .manual-logs-modal .modal-body .table{color:#000!important}.data-grid-table-wrapper[data-theme=white] .manual-logs-modal .modal-body .table thead th{background:linear-gradient(135deg,#f8f9fa,#e9ecef)!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .manual-logs-modal .modal-body .table tbody tr{color:#000!important}.data-grid-table-wrapper[data-theme=white] .manual-logs-modal .modal-body .table tbody tr:nth-child(2n){background-color:#f8f9fa!important}.data-grid-table-wrapper[data-theme=white] .manual-logs-modal .modal-body .table tbody tr:hover{background-color:#007bff1a!important}.data-grid-table-wrapper[data-theme=white] .manual-logs-modal .modal-body .table tbody tr td{color:#000!important;border-color:#d9d9db!important}.data-grid-table-wrapper[data-theme=white] .form-control,.data-grid-table-wrapper[data-theme=white] .form-select{background-color:#f6f8ff!important;border-color:#d9d9db!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .form-control::placeholder,.data-grid-table-wrapper[data-theme=white] .form-select::placeholder{color:#6c757d!important}.data-grid-table-wrapper[data-theme=white] .form-control option,.data-grid-table-wrapper[data-theme=white] .form-select option{background-color:#f6f8ff!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .filter-serach-inpt{background-color:#f6f8ff!important;border-color:#d9d9db!important}.data-grid-table-wrapper[data-theme=white] .filter-serach-inpt input{background-color:#f6f8ff!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .active-filters{background-color:#f8f9fa!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .custom-modal-overlay .custom-modal-content{background-color:#f6f8ff!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .circle-value{background-color:#f8f9fa!important;border-color:#d9d9db!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .pagination-container,.data-grid-table-wrapper[data-theme=white] .page-size,.data-grid-table-wrapper[data-theme=white] .page-info,.data-grid-table-wrapper[data-theme=white] .page-buttons{color:#000!important}.data-grid-table-wrapper[data-theme=white] .pagination-container select,.data-grid-table-wrapper[data-theme=white] .pagination-container button,.data-grid-table-wrapper[data-theme=white] .pagination-container span,.data-grid-table-wrapper[data-theme=white] .page-size select,.data-grid-table-wrapper[data-theme=white] .page-size button,.data-grid-table-wrapper[data-theme=white] .page-size span,.data-grid-table-wrapper[data-theme=white] .page-info select,.data-grid-table-wrapper[data-theme=white] .page-info button,.data-grid-table-wrapper[data-theme=white] .page-info span,.data-grid-table-wrapper[data-theme=white] .page-buttons select,.data-grid-table-wrapper[data-theme=white] .page-buttons button,.data-grid-table-wrapper[data-theme=white] .page-buttons span{background-color:#f6f8ff!important;border-color:#d9d9db!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .pagination-container button.active,.data-grid-table-wrapper[data-theme=white] .page-size button.active,.data-grid-table-wrapper[data-theme=white] .page-info button.active,.data-grid-table-wrapper[data-theme=white] .page-buttons button.active{background-color:#e3f2fd!important}.data-grid-table-wrapper[data-theme=white] .footer-row{background-color:#f8f9fa!important;border-top-color:#d9d9db!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] ::-webkit-scrollbar{background-color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=white] ::-webkit-scrollbar-thumb{background-color:#d9d9db!important}.data-grid-table-wrapper[data-theme=white] ::-webkit-scrollbar-thumb:hover{background-color:#adb5bd!important}.data-grid-table-wrapper[data-theme=white] ::-webkit-scrollbar-track{background-color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker{background-color:#f6f8ff!important;color:#000!important;border-color:#d9d9db!important}.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker .bs-datepicker-head{background:linear-gradient(135deg,#343a40,#495057)!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker .bs-datepicker-body{background-color:#f6f8ff!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker table td,.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker table th{color:#000!important}.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker table td.is-other-month,.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker table th.is-other-month{color:#6c757d!important}.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker table td.active,.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker table th.active{background-color:#e3f2fd!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker table td span.in-range,.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker table th span.in-range{background-color:#e3f2fd!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker table td:hover:not(.active),.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker table th:hover:not(.active){background-color:#007bff1a!important}.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker .bs-datepicker-buttons{background-color:#f8f9fa!important;border-top-color:#d9d9db!important}.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker .bs-datepicker-buttons .btn-primary{background:linear-gradient(135deg,#007bff,#0056b3)!important;color:#f6f8ff!important;border-color:#007bff!important}.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker .bs-datepicker-buttons .btn-secondary{background-color:#f6f8ff!important;color:#000!important;border-color:#d9d9db!important}.data-grid-table-wrapper[data-theme=white] button,.data-grid-table-wrapper[data-theme=white] .btn,.data-grid-table-wrapper[data-theme=white] .button{background-color:#f6f8ff!important;border-color:#d9d9db!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] button:hover,.data-grid-table-wrapper[data-theme=white] .btn:hover,.data-grid-table-wrapper[data-theme=white] .button:hover{background-color:#007bff1a!important}.data-grid-table-wrapper[data-theme=white] button.btn-primary,.data-grid-table-wrapper[data-theme=white] .btn.btn-primary,.data-grid-table-wrapper[data-theme=white] .button.btn-primary{background-color:#007bff!important;border-color:#007bff!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=white] button.btn-outline-primary,.data-grid-table-wrapper[data-theme=white] .btn.btn-outline-primary,.data-grid-table-wrapper[data-theme=white] .button.btn-outline-primary{border-color:#007bff!important;color:#007bff!important;background-color:transparent!important}.data-grid-table-wrapper[data-theme=white] a:not(.text-primary){color:#007bff!important}.data-grid-table-wrapper[data-theme=white] a:not(.text-primary):hover{color:#0056b3!important}.data-grid-table-wrapper[data-theme=white] .text-primary{color:#007bff!important}.data-grid-table-wrapper[data-theme=white] .text-danger{color:#dc3545!important}.data-grid-table-wrapper[data-theme=white] .text-success{color:#28a745!important}.data-grid-table-wrapper[data-theme=white] .text-warning{color:#ffc107!important}.data-grid-table-wrapper[data-theme=white] .text-info{color:#17a2b8!important}.data-grid-table-wrapper[data-theme=white] .text-muted,.data-grid-table-wrapper[data-theme=white] .muted-text{color:#6c757d!important}.data-grid-table-wrapper[data-theme=white] .border,.data-grid-table-wrapper[data-theme=white] .border-top,.data-grid-table-wrapper[data-theme=white] .border-bottom,.data-grid-table-wrapper[data-theme=white] .border-left,.data-grid-table-wrapper[data-theme=white] .border-right,.data-grid-table-wrapper[data-theme=white] .border-below,.data-grid-table-wrapper[data-theme=white] .border-start,.data-grid-table-wrapper[data-theme=white] .border-end{border-color:#d9d9db!important}.data-grid-table-wrapper[data-theme=white] .accordion-details,.data-grid-table-wrapper[data-theme=white] .nested-table,.data-grid-table-wrapper[data-theme=white] .detail-virtual-scroll{background-color:#f6f8ff!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .accordion-details td,.data-grid-table-wrapper[data-theme=white] .accordion-details th,.data-grid-table-wrapper[data-theme=white] .nested-table td,.data-grid-table-wrapper[data-theme=white] .nested-table th,.data-grid-table-wrapper[data-theme=white] .detail-virtual-scroll td,.data-grid-table-wrapper[data-theme=white] .detail-virtual-scroll th{color:#000!important;border-color:#d9d9db!important}.data-grid-table-wrapper[data-theme=blue]{border-color:#b3d9ff;background-color:#f0f8ff;color:#1e3a5f}.data-grid-table-wrapper[data-theme=blue] *,.data-grid-table-wrapper[data-theme=blue] *:before,.data-grid-table-wrapper[data-theme=blue] *:after{color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] ::selection{background-color:#007cf5!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=blue] ::-moz-selection{background-color:#007cf5!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=blue] .data-grid-header-wrapper{background-color:#e6f3ff;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .data-grid-body-wrapper{background-color:#f0f8ff;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .data-grid-row{border-bottom-color:#b3d9ff;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .data-grid-row:nth-child(2n){background-color:#f0f8ff!important}.data-grid-table-wrapper[data-theme=blue] .data-grid-row:nth-child(odd){background-color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=blue] .data-grid-row:hover{background-color:#1e3a5f1a!important}.data-grid-table-wrapper[data-theme=blue] .selected-cell,.data-grid-table-wrapper[data-theme=blue] .row-selected{background-color:#cce5ff!important}.data-grid-table-wrapper[data-theme=blue] .cell,.data-grid-table-wrapper[data-theme=blue] .header-cell,.data-grid-table-wrapper[data-theme=blue] .data-grid-row,.data-grid-table-wrapper[data-theme=blue] .data-grid-header,.data-grid-table-wrapper[data-theme=blue] .cell-content,.data-grid-table-wrapper[data-theme=blue] .full-text-content,.data-grid-table-wrapper[data-theme=blue] .circle-value,.data-grid-table-wrapper[data-theme=blue] .pic,.data-grid-table-wrapper[data-theme=blue] .image-placeholder,.data-grid-table-wrapper[data-theme=blue] .s-no,.data-grid-table-wrapper[data-theme=blue] .fw-500{color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] span,.data-grid-table-wrapper[data-theme=blue] div,.data-grid-table-wrapper[data-theme=blue] p,.data-grid-table-wrapper[data-theme=blue] td,.data-grid-table-wrapper[data-theme=blue] th,.data-grid-table-wrapper[data-theme=blue] label,.data-grid-table-wrapper[data-theme=blue] a:not(.text-primary){color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] svg,.data-grid-table-wrapper[data-theme=blue] svg path,.data-grid-table-wrapper[data-theme=blue] svg circle,.data-grid-table-wrapper[data-theme=blue] svg rect,.data-grid-table-wrapper[data-theme=blue] svg polygon{color:#1e3a5f!important;fill:#1e3a5f!important;stroke:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .data-grid-svg-icon{color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .data-grid-svg-icon path{stroke:#1e3a5f!important;fill:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .badge.badge-danger{background-color:#ff8787!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=blue] .badge.badge-success{background-color:#69db7c!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=blue] .badge.badge-warning{background-color:#ffd43b!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .badge.badge-info{background-color:#74c0fc!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=blue] .context-menu{background:#e6f3ff;border-color:#b3d9ff;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .context-menu li{color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .context-menu li:hover{background-color:#1e3a5f1a!important}.data-grid-table-wrapper[data-theme=blue] .custom-tooltip,.data-grid-table-wrapper[data-theme=blue] .popover__content,.data-grid-table-wrapper[data-theme=blue] .custom-break-tooltip{background:#e6f3ff!important;border-color:#b3d9ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .actions-dropdown,.data-grid-table-wrapper[data-theme=blue] .custom-menu{background-color:#e6f3ff!important;border-color:#b3d9ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .actions-dropdown .dropdown-item,.data-grid-table-wrapper[data-theme=blue] .custom-menu .dropdown-item{color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .actions-dropdown .dropdown-item:hover,.data-grid-table-wrapper[data-theme=blue] .custom-menu .dropdown-item:hover{background-color:#1e3a5f1a!important}.data-grid-table-wrapper[data-theme=blue] .taskbar .selected-rows-action-bar{background-color:#1e3a5f!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=blue] .taskbar .selected-rows-action-bar .action-btn{color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=blue] .manual-logs-modal .modal-header{background:linear-gradient(135deg,#1e3a5f,#2d4a6b)!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=blue] .manual-logs-modal .modal-header .modal-title{color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=blue] .manual-logs-modal .modal-body{background-color:#f0f8ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .manual-logs-modal .modal-body .table{color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .manual-logs-modal .modal-body .table thead th{background:linear-gradient(135deg,#e6f3ff,#cce5ff)!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .manual-logs-modal .modal-body .table tbody tr{color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .manual-logs-modal .modal-body .table tbody tr:nth-child(2n){background-color:#f0f8ff!important}.data-grid-table-wrapper[data-theme=blue] .manual-logs-modal .modal-body .table tbody tr:hover{background-color:#1e3a5f1a!important}.data-grid-table-wrapper[data-theme=blue] .manual-logs-modal .modal-body .table tbody tr td{color:#1e3a5f!important;border-color:#b3d9ff!important}.data-grid-table-wrapper[data-theme=blue] .form-control,.data-grid-table-wrapper[data-theme=blue] .form-select{background-color:#f6f8ff!important;border-color:#b3d9ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .form-control::placeholder,.data-grid-table-wrapper[data-theme=blue] .form-select::placeholder{color:#888!important}.data-grid-table-wrapper[data-theme=blue] .form-control option,.data-grid-table-wrapper[data-theme=blue] .form-select option{background-color:#f6f8ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .filter-serach-inpt{background-color:#f6f8ff!important;border-color:#b3d9ff!important}.data-grid-table-wrapper[data-theme=blue] .filter-serach-inpt input{background-color:#f6f8ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .active-filters,.data-grid-table-wrapper[data-theme=blue] .custom-modal-overlay .custom-modal-content{background-color:#e6f3ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .circle-value{background-color:#f6f8ff!important;border-color:#b3d9ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .pagination-container,.data-grid-table-wrapper[data-theme=blue] .page-size,.data-grid-table-wrapper[data-theme=blue] .page-info,.data-grid-table-wrapper[data-theme=blue] .page-buttons{color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .pagination-container select,.data-grid-table-wrapper[data-theme=blue] .pagination-container button,.data-grid-table-wrapper[data-theme=blue] .pagination-container span,.data-grid-table-wrapper[data-theme=blue] .page-size select,.data-grid-table-wrapper[data-theme=blue] .page-size button,.data-grid-table-wrapper[data-theme=blue] .page-size span,.data-grid-table-wrapper[data-theme=blue] .page-info select,.data-grid-table-wrapper[data-theme=blue] .page-info button,.data-grid-table-wrapper[data-theme=blue] .page-info span,.data-grid-table-wrapper[data-theme=blue] .page-buttons select,.data-grid-table-wrapper[data-theme=blue] .page-buttons button,.data-grid-table-wrapper[data-theme=blue] .page-buttons span{background-color:#f6f8ff!important;border-color:#b3d9ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .pagination-container button.active,.data-grid-table-wrapper[data-theme=blue] .page-size button.active,.data-grid-table-wrapper[data-theme=blue] .page-info button.active,.data-grid-table-wrapper[data-theme=blue] .page-buttons button.active{background-color:#cce5ff!important}.data-grid-table-wrapper[data-theme=blue] .footer-row{background-color:#e6f3ff!important;border-top-color:#b3d9ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] ::-webkit-scrollbar{background-color:#f0f8ff!important}.data-grid-table-wrapper[data-theme=blue] ::-webkit-scrollbar-thumb{background-color:#b3d9ff!important}.data-grid-table-wrapper[data-theme=blue] ::-webkit-scrollbar-thumb:hover{background-color:#74c0fc!important}.data-grid-table-wrapper[data-theme=blue] ::-webkit-scrollbar-track{background-color:#f0f8ff!important}.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker{background-color:#e6f3ff!important;color:#1e3a5f!important;border-color:#b3d9ff!important}.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker .bs-datepicker-head{background:linear-gradient(135deg,#1e3a5f,#2d4a6b)!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker .bs-datepicker-body{background-color:#f0f8ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker table td,.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker table th{color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker table td.is-other-month,.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker table th.is-other-month{color:#888!important}.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker table td.active,.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker table th.active{background-color:#cce5ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker table td span.in-range,.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker table th span.in-range{background-color:#cce5ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker table td:hover:not(.active),.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker table th:hover:not(.active){background-color:#1e3a5f1a!important}.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker .bs-datepicker-buttons{background-color:#f6f8ff!important;border-top-color:#b3d9ff!important}.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker .bs-datepicker-buttons .btn-primary{background:linear-gradient(135deg,#1e3a5f,#2d4a6b)!important;color:#f6f8ff!important;border-color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker .bs-datepicker-buttons .btn-secondary{background-color:#f0f8ff!important;color:#1e3a5f!important;border-color:#b3d9ff!important}.data-grid-table-wrapper[data-theme=blue] button,.data-grid-table-wrapper[data-theme=blue] .btn,.data-grid-table-wrapper[data-theme=blue] .button{background-color:#f6f8ff!important;border-color:#b3d9ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] button:hover,.data-grid-table-wrapper[data-theme=blue] .btn:hover,.data-grid-table-wrapper[data-theme=blue] .button:hover{background-color:#1e3a5f1a!important}.data-grid-table-wrapper[data-theme=blue] button.btn-primary,.data-grid-table-wrapper[data-theme=blue] .btn.btn-primary,.data-grid-table-wrapper[data-theme=blue] .button.btn-primary{background-color:#007cf5!important;border-color:#007cf5!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=blue] button.btn-outline-primary,.data-grid-table-wrapper[data-theme=blue] .btn.btn-outline-primary,.data-grid-table-wrapper[data-theme=blue] .button.btn-outline-primary{border-color:#007cf5!important;color:#007cf5!important;background-color:transparent!important}.data-grid-table-wrapper[data-theme=blue] a:not(.text-primary){color:#007cf5!important}.data-grid-table-wrapper[data-theme=blue] a:not(.text-primary):hover{color:#0056b3!important}.data-grid-table-wrapper[data-theme=blue] .text-primary{color:#007cf5!important}.data-grid-table-wrapper[data-theme=blue] .text-danger{color:#dc3545!important}.data-grid-table-wrapper[data-theme=blue] .text-success{color:#28a745!important}.data-grid-table-wrapper[data-theme=blue] .text-warning{color:#ffc107!important}.data-grid-table-wrapper[data-theme=blue] .text-info{color:#17a2b8!important}.data-grid-table-wrapper[data-theme=blue] .text-muted,.data-grid-table-wrapper[data-theme=blue] .muted-text{color:#6c757d!important}.data-grid-table-wrapper[data-theme=blue] .border,.data-grid-table-wrapper[data-theme=blue] .border-top,.data-grid-table-wrapper[data-theme=blue] .border-bottom,.data-grid-table-wrapper[data-theme=blue] .border-left,.data-grid-table-wrapper[data-theme=blue] .border-right,.data-grid-table-wrapper[data-theme=blue] .border-below,.data-grid-table-wrapper[data-theme=blue] .border-start,.data-grid-table-wrapper[data-theme=blue] .border-end{border-color:#b3d9ff!important}.data-grid-table-wrapper[data-theme=blue] .accordion-details,.data-grid-table-wrapper[data-theme=blue] .nested-table,.data-grid-table-wrapper[data-theme=blue] .detail-virtual-scroll{background-color:#f0f8ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .accordion-details td,.data-grid-table-wrapper[data-theme=blue] .accordion-details th,.data-grid-table-wrapper[data-theme=blue] .nested-table td,.data-grid-table-wrapper[data-theme=blue] .nested-table th,.data-grid-table-wrapper[data-theme=blue] .detail-virtual-scroll td,.data-grid-table-wrapper[data-theme=blue] .detail-virtual-scroll th{color:#1e3a5f!important;border-color:#b3d9ff!important}.data-grid-header{position:sticky;top:0}.data-grid-header{display:flex}.header-row{display:grid;width:100%}.header-cell{display:flex;align-items:center;position:relative;width:100%;padding:8px 0 8px 8px;font-weight:700;border-bottom:1px solid #d9d9db;white-space:nowrap;min-width:30px}.header-cell .filter-applied-on-text{color:#5d9cff!important}.filter-cell{padding:4px!important;display:flex;align-items:center;gap:8px;width:100%}.filter-cell .filter-applied{background-color:#bddef9}.border-right{border-right:1px solid #d9d9db}.merged-grid{display:grid;grid-auto-rows:40px;border-bottom:1px solid #ccc}.span-two-rows{grid-row:span 2;display:flex;justify-content:space-between;align-items:center}.group-header{display:flex;justify-content:space-between;position:relative}.group-header-content{position:sticky;left:10px;overflow:hidden;text-overflow:ellipsis}.resize-handle{width:6px;cursor:e-resize;right:0;top:0;color:#00000026;position:relative}.resize-handle.resizing{z-index:9999!important;opacity:1!important;background-color:#007bff1a;border-right:2px solid #007bff;box-shadow:0 0 8px #007bff4d;position:relative!important;pointer-events:none!important}.group-header .resize-handle{top:25%}.h-100{height:100%}.data-grid-body{position:relative;overflow-y:auto;overflow-x:hidden;box-shadow:none!important}.cell{padding:8px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;height:100%;display:flex;align-items:center}.data-grid-row{display:flex;min-width:max-content;align-items:center;border-bottom:1px solid #d9d9db;transition:all .25s cubic-bezier(.4,0,.2,1);transform:translateZ(0);will-change:transform,box-shadow;backface-visibility:hidden}.data-grid-row:hover{transform:translate(2px);box-shadow:2px 0 8px #007bff1a}.hovered-row{background-color:#ccc}.checkbox-row{border-bottom:#d9d9db}.w-100{width:100%}.data-grid-header-wrapper{display:flex;position:relative;overflow:hidden;-webkit-user-select:none;user-select:none}.data-grid-header{display:flex;position:relative;z-index:1}.left-pinned,.right-pinned{position:sticky;top:0;background:#f6f8ff}.right-pinned-header{position:absolute;right:0;border-left:1px solid #d9d9db;z-index:unset}.left-pinned{left:0;border-right:1px solid #d9d9db}.right-pinned{right:0;border-left:1px solid #d9d9db}.center-scrollable{z-index:unset!important;overflow-x:auto;overflow-y:visible;white-space:nowrap;scrollbar-width:none;-ms-overflow-style:none}.center-scrollable::-webkit-scrollbar{display:none}.data-grid-body-wrapper{display:flex}.data-grid-body-wrapper{scrollbar-width:none;-ms-overflow-style:none}.data-grid-body-wrapper::-webkit-scrollbar{display:none}.center-scrollable-body{overflow-x:auto;scrollbar-width:none;-ms-overflow-style:none}.center-scrollable-body::-webkit-scrollbar{display:none}.left-pinned-body,.right-pinned-body{position:sticky;top:0;z-index:unset;background:#f6f8ff;scrollbar-width:none;-ms-overflow-style:none}.left-pinned-body::-webkit-scrollbar,.right-pinned-body::-webkit-scrollbar{display:none}.left-pinned-body{left:0}.border-end{border-right:1px solid #d9d9db!important}.right-pinned-body{right:-15px;border-left:1px solid #d9d9db}.fake-scroll-bar{height:14px;overflow:scroll;margin-bottom:10px}.text-ellipsis{overflow:hidden;text-overflow:ellipsis}.select-all-checkbox-cell{width:50px;display:flex;justify-content:center;align-items:center;height:100%;border-right:1px solid #d9d9db}.select-all-checkbox-cell input{width:16px;height:16px}.border-below{border-bottom:1px solid #d9d9db!important}.three-dots{width:22px;height:22px;display:flex;justify-content:center;align-items:center;border-radius:6px;margin-right:8px;cursor:pointer;transition:all .25s cubic-bezier(.4,0,.2,1);transform:translateZ(0);position:relative}.three-dots:before{content:\"\";position:absolute;top:50%;left:50%;width:0;height:0;background:#007bff1a;border-radius:50%;transform:translate(-50%,-50%);transition:width .25s,height .25s}.three-dots:hover{background-color:#007bff1a;transform:rotate(90deg)}.three-dots:hover:before{width:28px;height:28px}.three-dots:active{transform:rotate(90deg) scale(.95);transition-duration:.15s}.filter-icon-wrapper{min-height:22px;max-height:22px;min-width:22px;max-width:22px;display:flex;justify-content:center;align-items:center;border-radius:6px;cursor:pointer;transition:all .25s cubic-bezier(.4,0,.2,1);transform:translateZ(0);position:relative}.filter-icon-wrapper:before{content:\"\";position:absolute;top:50%;left:50%;width:0;height:0;background:#007bff1a;border-radius:50%;transform:translate(-50%,-50%);transition:width .25s,height .25s}.filter-icon-wrapper:hover{background-color:#007bff1a;transform:scale(1.05)}.filter-icon-wrapper:hover:before{width:32px;height:32px}.filter-icon-wrapper:active{transform:scale(.95);transition-duration:.15s}.column-panel-item{font-size:.875rem;color:#333;transition:all .25s cubic-bezier(.4,0,.2,1);transform:translateZ(0)}.column-panel-item:hover{background-color:#007bff0d;color:#007bff;transform:translate(2px)}.column-menu,.filter-menu{box-shadow:0 0 16px #00000026;border-radius:4px}.column-menu{background:#fff;width:100%;width:240px;border:1px solid #ddd;box-shadow:0 0 16px #00000026;border:1px solid #d9d9db;padding:4px 0;font-size:14px;position:fixed}.column-menu-item{padding:8px 12px;cursor:pointer;display:flex;align-items:center;transition:background-color .2s ease}.column-menu-item:hover{background-color:#deebf7}.pin-parent{position:relative;width:100%!important}.column-submenu{position:absolute;top:0;left:100%;background:#fff;border:1px solid #ddd;width:130px;box-shadow:0 0 16px #00000026;border:1px solid #d9d9db;display:none;padding:4px 0;z-index:10;border-radius:4px}.pin-parent:hover .column-submenu{display:block}.filter-menu-container{position:fixed;width:210px;background:#fff;border:1px solid #ddd;border-radius:4px;padding:12px;box-shadow:0 0 16px #00000026;border:1px solid #d9d9db;z-index:1000;font-size:14px}.filter-menu-header{font-weight:600;margin-bottom:10px}.filter-dropdown-section{max-height:350px;overflow-y:auto}.dropdown-options{overflow-y:auto;scrollbar-width:thin;height:100%}.filter-text-section select,.filter-text-section input{width:100%}.filter-radio-inputs{width:14px!important;height:14px!important}.right-menu{border-left:1px solid #d9d9db;font-size:14px}.border-start{border-left:1px solid #d9d9db!important}.column-panel-item{font-size:.875rem;color:#333}.toggle-icon{cursor:pointer;transition:all .25s cubic-bezier(.4,0,.2,1);transform:translateZ(0);border-radius:4px;padding:2px}.toggle-icon:hover{background-color:#007bff1a;transform:scale(1.1)}.toggle-icon:active{transform:scale(.95)}.grab-icon{cursor:grab;color:#6c757d;transition:all .25s cubic-bezier(.4,0,.2,1);transform:translateZ(0)}.grab-icon:hover{color:#007bff;transform:scale(1.1)}.grab-icon:active{cursor:grabbing;transform:scale(.95)}.text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:100%}.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:-3px}.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:20px;left:50%;transform:translate(-50%);display:flex;justify-content:center;z-index:1000;padding:0;width:auto;max-width:90vw}.taskbar .action-btn{transition:all .3s ease;font-weight:500;font-size:14px;padding:8px 16px;border-radius:6px;cursor:pointer;display:inline-flex;align-items:center;gap:6px}.taskbar .action-btn:hover{transform:translateY(-1px);box-shadow:0 4px 12px #00000026}.taskbar .action-btn:active{transform:translateY(0)}.taskbar .delete{background-color:#dc3545;color:#fff;border:1px solid #dc3545}.taskbar .delete:hover{background-color:#c82333;border-color:#bd2130}.taskbar .export{background-color:#28a745;color:#fff;border:1px solid #28a745}.taskbar .export:hover{background-color:#218838;border-color:#1e7e34}.taskbar .verify{background-color:#007bff;color:#fff;border:1px solid #007bff}.taskbar .verify:hover{background-color:#0056b3;border-color:#004085}.selected-count,.action-btn,.dropdown-content a{font-weight:500;font-size:14px}.selected-rows-action-bar{background:linear-gradient(135deg,#667eea,#764ba2);color:#fff;padding:12px 24px;border-radius:12px;display:flex;align-items:center;justify-content:space-between;gap:16px;box-shadow:0 8px 32px #0003;backdrop-filter:blur(10px);border:1px solid rgba(255,255,255,.1);min-width:300px}.selected-rows-action-bar .selected-count{font-weight:600;font-size:14px;flex:1;text-align:center}.selected-rows-action-bar .action-buttons{display:flex;align-items:center;gap:8px}.selected-rows-action-bar .action-buttons .separator{color:#ffffff80;font-weight:700;font-size:16px}.selected-rows-action-bar .action-buttons .action-btn{background:#fff3;color:#fff!important;border:1px solid rgba(255,255,255,.3);padding:8px 16px;border-radius:8px;font-weight:500;font-size:13px;transition:all .3s ease;cursor:pointer;display:inline-flex;align-items:center;gap:6px}.selected-rows-action-bar .action-buttons .action-btn:hover{background:#ffffff4d;transform:translateY(-1px);box-shadow:0 4px 12px #0003}.selected-rows-action-bar .action-buttons .action-btn:active{transform:translateY(0)}.selected-rows-action-bar .action-buttons .action-btn.Export{background:#28a745cc;border-color:#28a745e6}.selected-rows-action-bar .action-buttons .action-btn.Export:hover{background:#218838e6}.selected-rows-action-bar .action-buttons .action-btn.Delete{background:#dc3545cc;border-color:#dc3545e6}.selected-rows-action-bar .action-buttons .action-btn.Delete:hover{background:#c82333e6}.selected-rows-action-bar .action-buttons .action-btn.Verify{background:#007bffcc;border-color:#007bffe6}.selected-rows-action-bar .action-buttons .action-btn.Verify:hover{background:#0056b3e6}.selected-rows-action-bar .btn:active,.selected-rows-action-bar .btn:focus{outline:0!important;border:0!important;border-color:transparent!important}@media (max-width: 768px){.taskbar{bottom:10px;max-width:95vw}.taskbar .selected-rows-action-bar{padding:8px 16px;min-width:280px;flex-direction:column;gap:12px}.taskbar .selected-rows-action-bar .selected-count{font-size:13px;text-align:center}.taskbar .selected-rows-action-bar .action-buttons{justify-content:center;flex-wrap:wrap;gap:6px}.taskbar .selected-rows-action-bar .action-buttons .action-btn{padding:6px 12px;font-size:12px;min-width:80px}.taskbar .selected-rows-action-bar .action-buttons .separator{display:none}}@media (max-width: 480px){.taskbar .selected-rows-action-bar{min-width:250px;padding:6px 12px}.taskbar .selected-rows-action-bar .action-buttons .action-btn{padding:5px 10px;font-size:11px;min-width:70px}}.cell .dropdown-menu,.cell .form-select,.cell input{color:#000!important}.cell input::placeholder{color:#727272!important}.cell .badge{font-size:14px;padding:6px 12px;border-radius:6px;text-align:center;height:auto;min-height:28px;display:inline-flex;align-items:center;justify-content:center;font-weight:500;line-height:1.5;white-space:nowrap;transition:all .2s cubic-bezier(.4,0,.2,1);will-change:transform,opacity;backface-visibility:hidden;transform:translateZ(0)}.cell .badge-danger{color:#ea5353!important;border:1px solid #ea5353!important;background-color:#ff00000d!important}.cell .badge-success{background-color:#84ca8130!important;border:1.5px solid rgb(70,227,114)!important;color:#46e372!important}.cell .badge-warning{background-color:#fff3dc!important;color:orange!important;border:1px solid #ffa000!important}.cell .badge-info{color:#00bad1;background-color:#e8fbfd;border:1px solid #00bad1}.header-tag ::ng-deep svg path{stroke:#727272!important}.cross-secondary:hover ::ng-deep svg path{stroke:#000!important}.disable-sorting{pointer-events:none;opacity:.5}.rows-grouping-top-container ::ng-deep .cdk-drag-placeholder{background-color:transparent!important}input.is-invalid:focus{border:2.5px solid red!important;outline:none}.table-cell input.is-invalid:focus{border:2.5px solid red!important;outline-color:red!important;outline:none!important;box-shadow:none!important}.active-for-editing:has(input.is-invalid:focus){outline:none!important;box-shadow:none!important;border:0!important}.selected-cell,.row-selected{background-color:#c2e0fe;animation:pulse .25s cubic-bezier(.4,0,.2,1);transform:translateZ(0);position:relative}.selected-cell:before,.row-selected:before{content:\"\";position:absolute;inset:0;background:linear-gradient(45deg,transparent,rgba(255,255,255,.1),transparent);animation:shimmer 1.5s ease-in-out infinite}.first-row-selected{border-top:2px solid #2196f3!important}.last-row-selected{border-bottom:2px solid #2196f3!important}.left-selection-border{border-left:2px solid #2196f3!important}.s-no{font-size:14px;font-weight:500}.top-border{border-top:2px solid #2196f3!important}.bottom-border{border-bottom:2px solid #2196f3!important}.left-border{border-left:2px solid #2196f3!important}.right-border{border-right:2px solid #2196f3!important}.top-left-corner{border-top-left-radius:4px}.top-right-corner{border-top-right-radius:4px}.bottom-left-corner{border-bottom-left-radius:4px}.bottom-right-corner{border-bottom-right-radius:4px}.flash-bg{animation:flashAnim 1000s ease}@keyframes flashAnim{0%{background-color:#48a2fc}50%{background-color:#c2e0fe}to{background-color:#c2e0fe}}.cut-flash-bg{animation:cut-flash .8s ease}@keyframes cut-flash{0%{background-color:#f006}50%{background-color:#f00c}to{background-color:#c2e0fe}}.accordion-details.dragging th,.accordion-details.dragging td{pointer-events:none}.accordion-details.dragging th{z-index:2}.drag-handle{cursor:move;opacity:.5;transition:opacity .2s}.drag-handle:hover{opacity:1}.detail-edit-input{z-index:100;position:relative}.detail-filter-menu{position:fixed;width:210px;background:#fff;border:1px solid #ddd;border-radius:4px;padding:12px;box-shadow:0 0 16px #00000026;border:1px solid #d9d9db;z-index:1000;font-size:14px}.detail-filter-menu-positioned{width:280px;right:unset;max-width:230px;z-index:99;left:375px;top:225px}.resize-handle{cursor:col-resize;opacity:.5;width:8px;display:flex;align-items:center;justify-content:center}.resize-handle:hover{opacity:1;background-color:#f0f0f0}.detail-header-row{transition:all .3s ease}.detail-header-row.dragging{opacity:.7;transform:translate(5px)}.detail-cell{transition:background-color .2s ease,transform .3s ease}.detail-cell.active-drag{background-color:#f0f0f0;transform:scale(1.02)}.break-color-paid{background-color:#4caf50!important}.break-color-unpaid{background-color:#f44336!important}.break-color-lunch{background-color:#2196f3!important}.break-color-default{background-color:#f44336!important}.circle-value{display:flex;align-items:center;justify-content:center;width:32px;height:32px;border-radius:50%;background-color:#f8f9fa;border:2px solid #d9d9db;font-size:12px;font-weight:600;color:#fff;text-align:center;line-height:1;vertical-align:middle;box-sizing:border-box;white-space:nowrap;overflow:hidden;cursor:pointer;transition:all .3s cubic-bezier(.4,0,.2,1);transform:translateZ(0);will-change:transform,box-shadow,background-color;backface-visibility:hidden}.circle-value:hover{background-color:#e9ecef;box-shadow:0 6px 16px #007bff40;transform:scale(1.15) translateY(-2px);border-color:#007bff}.circle-value:active{transform:scale(1.08) translateY(-1px);transition-duration:.15s}.break-tooltip-wrapper{position:relative;display:inline-block}.break-tooltip-wrapper:hover .custom-break-tooltip{opacity:1;visibility:visible}.circle-value[title]{position:relative}.circle-value[title]:after{content:attr(title);position:absolute;bottom:100%;left:50%;transform:translate(-50%);background-color:#333;color:#fff;padding:4px 8px;border-radius:4px;font-size:12px;white-space:nowrap;opacity:0;transition:opacity .2s ease;pointer-events:none}.circle-value[title]:hover:after{opacity:1}.custom-tooltip{position:fixed;background:#fff;border:1px solid #dcdcdc;border-radius:8px;padding:12px 16px;max-width:300px;z-index:9999;font-size:13px;animation:fadeIn .2s ease-in-out}.tooltip-title{font-size:14px;font-weight:600;margin-bottom:8px;color:#333}.tooltip-list{margin:0;padding-left:16px;list-style-type:disc}.tooltip-list li{margin-bottom:4px;line-height:1.4;color:#444}.tooltip-total{font-weight:700;margin-top:8px;color:#222}@keyframes fadeIn{0%{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:translateY(0)}}.restriction-indicator{position:absolute;display:inline-block;padding-right:10px}.restriction-indicator:after{content:\"\";position:absolute;top:0;right:0;width:8px;height:8px;background-color:#0d6efd;border-radius:50%}.manual-logs-indicator{position:absolute;top:2px;right:2px;width:8px;height:8px;background-color:#0d6efd;border-radius:50%;border:1px solid #fff;box-shadow:0 0 2px #0d6efd80;cursor:pointer;z-index:10;transition:all .2s ease}.manual-logs-indicator:hover{transform:scale(1.2);box-shadow:0 0 4px #0d6efdcc}.manual-logs-table-tooltip{background:#fff!important;border:1px solid #dcdcdc!important;border-radius:8px!important;box-shadow:0 4px 12px #00000026!important;font-size:13px!important;animation:fadeIn .2s ease-in-out!important;display:block!important;visibility:visible!important;opacity:1!important}.manual-logs-table-tooltip .popover__content,.manual-logs-table-tooltip .modal-area{padding:0!important;display:block!important;visibility:visible!important}.manual-logs-table-tooltip .table-responsive{max-height:300px;overflow-y:auto;display:block!important;visibility:visible!important}.manual-logs-table-tooltip table{margin:0!important;border-collapse:collapse!important;display:table!important;visibility:visible!important}.manual-logs-table-tooltip table th,.manual-logs-table-tooltip table td{padding:6px 8px!important;border:1px solid #f1f1f1!important;text-align:center!important;vertical-align:middle!important;display:table-cell!important;visibility:visible!important}.manual-logs-table-tooltip table th{background-color:#f8f9fa!important;font-weight:600!important;color:#495057!important;position:sticky!important;top:0!important;z-index:1!important}.manual-logs-table-tooltip table tbody tr:nth-child(2n){background-color:#f8f9fa!important}.manual-logs-table-tooltip table tbody tr:hover{background-color:#e3f2fd!important}.manual-logs-table-tooltip table .text-primary{color:#0d6efd!important;text-decoration:none!important}.manual-logs-table-tooltip table .capitalize{text-transform:capitalize!important}@keyframes fadeIn{0%{opacity:0;transform:translate(-50%) translateY(-110%)}to{opacity:1;transform:translate(-50%) translateY(-100%)}}.detail-column-menu{max-height:250px;overflow-y:auto;overflow-x:auto;white-space:nowrap;padding:8px 0;border-radius:6px;scrollbar-width:thin}.detail-column-menu-wrapper{z-index:1001;position:absolute}.accordion-details{position:relative;z-index:999}.detail-column-menu .column-menu-item{padding:8px 12px;cursor:pointer;display:flex;align-items:center;transition:all .25s cubic-bezier(.4,0,.2,1);font-size:14px;transform:translateZ(0);border-radius:4px}.detail-column-menu .column-menu-item:hover{background-color:#007bff1a;transform:translate(2px);color:#007bff}.detail-column-menu .column-menu-item:active{transform:translate(0) scale(.98)}.detail-column-menu .column-menu-item:hover{background-color:#deebf7}.nested-table th[pinned=left],.nested-table td[pinned=left]{border-right:2px solid #ccc;border-left:none;border-bottom:2px solid #ccc}.nested-table th[pinned=right],.nested-table td[pinned=right]{border-left:2px solid #ccc;border-right:none;border-bottom:2px solid #ccc}.data-grid-accordion-table.show-borders{border:1px solid #d9d9db;border-collapse:collapse}.data-grid-accordion-table.show-borders th,.data-grid-accordion-table.show-borders td{border:1px solid #d9d9db}.data-grid-accordion-table.show-shadow tbody tr:hover{box-shadow:0 4px 8px #0000001a;transition:box-shadow .3s ease}.data-grid-accordion-table tbody tr:hover{background-color:#deebf7;transition:background-color .3s ease}.data-grid-pin-icon{display:inline-block;vertical-align:middle;margin-left:4px}.accordion-details.center-section{position:relative;display:flex}.detail-side-menu-wrapper{display:flex;flex-shrink:0;position:sticky;right:0;top:0;height:100%;max-height:275px}.detail-side-menu-content{width:250px;box-shadow:-2px 0 5px #0000001a;display:flex;flex-direction:column}.side-menu-scrollable{flex:1;overflow-y:auto;padding:0 12px 12px;max-height:calc(100% - 40px)}.filter-input-container{padding:8px;background:#f9f9f9;border-radius:4px}.toggle-icon.rotate{transform:rotate(90deg)}.resize-handle{top:0;right:3px;bottom:0;width:8px;cursor:col-resize;z-index:10;display:flex;align-items:center;justify-content:center;opacity:1.4;transition:all .25s cubic-bezier(.4,0,.2,1);background:transparent;transform:translateZ(0)}.resize-handle:hover{opacity:1;background:#007bff1a}.resize-handle:active{opacity:1;background:#007bff33;transform:scaleX(1.2)}th:hover .resize-handle{opacity:40}.resize-handles{top:0;right:3px;bottom:0;width:8px;cursor:col-resize;z-index:10;display:flex;align-items:center;justify-content:center;position:absolute;opacity:1.4;transition:all .25s cubic-bezier(.4,0,.2,1);background:transparent;transform:translateZ(0)}.resize-handles:hover{opacity:1;background:#007bff1a}.resize-handles:active{opacity:1;background:#007bff33;transform:scaleX(1.2)}.resize-handles.resizing{z-index:9999!important;opacity:1!important;background-color:#007bff1a;border-right:2px solid #007bff;box-shadow:0 0 8px #007bff4d;pointer-events:none!important}th:hover .resize-handles{opacity:40}.resizing-highlight{background-color:#007bff1a!important}.accordion-details-wrapper{display:flex;width:100%;max-height:350px;overflow:hidden}.accordion-details.show-borders,.accordion-details-wrapper.show-borders{border:1px solid #d9d9db;border-radius:4px}.accordion-left-section,.accordion-right-section,.detail-side-menu-wrapper{flex-shrink:0;max-height:350px;overflow:hidden;height:fit-content}.accordion-center-section{flex:1;min-width:0;overflow:auto;max-height:350px}.detail-virtual-scroll{display:block;width:100%;height:250px;overflow:auto}.detail-virtual-scroll table{table-layout:fixed;width:100%}.detail-virtual-scroll td,.detail-virtual-scroll th{overflow:hidden!important;text-overflow:ellipsis!important;white-space:nowrap!important}.nested-table th{overflow:hidden!important}.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:10;background-color:#f6f8ff!important}.data-pin-body-wrapper{-webkit-user-select:none;user-select:none;display:flex}.data-pin-body-wrapper{scrollbar-width:none;-ms-overflow-style:none}.data-pin-body-wrapper::-webkit-scrollbar{display:none}.detail-virtual-scroll .selected-cell,.accordion-left-section .selected-cell,.accordion-right-section .selected-cell{background-color:#cce5ff!important}.custom-datepicker-buttons button{height:28px;padding:0 10px;font-size:12px}.manual-logs-modal{max-width:800px;max-height:80vh;overflow:hidden;border-radius:12px;box-shadow:0 10px 40px #0003}.manual-logs-modal .modal-header{background:linear-gradient(135deg,#4361ee,#3a0ca3);color:#fff;padding:16px 20px;border-bottom:none;border-radius:12px 12px 0 0}.manual-logs-modal .modal-header .modal-title{font-weight:600;font-size:18px;margin:0}.manual-logs-modal .modal-header .btn-close{background:#fff3;border:none;border-radius:50%;width:32px;height:32px;display:flex;align-items:center;justify-content:center;color:#fff;opacity:.8;transition:all .25s cubic-bezier(.4,0,.2,1);transform:translateZ(0)}.manual-logs-modal .modal-header .btn-close:hover{background:#ffffff4d;opacity:1;transform:scale(1.1) rotate(90deg)}.manual-logs-modal .modal-header .btn-close:active{transform:scale(.95) rotate(90deg)}.manual-logs-modal .modal-body{padding:20px;max-height:calc(80vh - 80px);overflow-y:auto}.manual-logs-modal .modal-body .table-responsive{border-radius:8px;overflow:hidden;box-shadow:0 2px 8px #0000001a}.manual-logs-modal .modal-body .table-responsive .table{margin-bottom:0;font-size:14px}.manual-logs-modal .modal-body .table-responsive .table thead th{background:linear-gradient(135deg,#f8f9fa,#e9ecef);border-bottom:2px solid #dee2e6;font-weight:600;color:#495057;padding:12px 16px;position:sticky;top:0;z-index:10}.manual-logs-modal .modal-body .table-responsive .table tbody tr{transition:background-color .2s ease}.manual-logs-modal .modal-body .table-responsive .table tbody tr:hover{background-color:#f8f9fa}.manual-logs-modal .modal-body .table-responsive .table tbody tr:nth-child(2n){background-color:#f8f9fa}.manual-logs-modal .modal-body .table-responsive .table tbody tr td{padding:10px 16px;vertical-align:middle;border-color:#e9ecef}.manual-logs-modal .modal-body .table-responsive .table tbody tr td .text-primary{color:#0d6efd!important;font-weight:500;text-decoration:none}.manual-logs-modal .modal-body .table-responsive .table tbody tr td .text-primary:hover{text-decoration:underline}.manual-logs-modal .modal-body .table-responsive .table tbody tr td .capitalize{text-transform:capitalize}::ng-deep bs-daterangepicker-container .bs-datepicker{border-radius:4px!important;box-shadow:0 2px 8px #0000001a!important;font-size:14px!important;display:flex!important;align-items:flex-start!important;left:142px!important}::ng-deep .bs-datepicker-head{background:#f8f9fa!important;color:#495057!important;border-bottom:1px solid #dee2e6!important;padding:8px 12px!important;border-radius:4px 4px 0 0!important}::ng-deep .bs-datepicker-head .current{font-weight:600!important;color:#495057!important;font-size:13px!important}::ng-deep .bs-datepicker-head .previous,::ng-deep .bs-datepicker-head .next{background:#fff!important;color:#495057!important;border:1px solid #dee2e6!important;width:24px!important;border-radius:4px!important;font-size:12px!important}::ng-deep .bs-datepicker-head .previous:hover,::ng-deep .bs-datepicker-head .next:hover{background:#e9ecef!important}::ng-deep .bs-datepicker .bs-datepicker-buttons{padding:8px!important;background:#f8f9fa!important;border-top:1px solid #dee2e6!important;border-radius:0 0 4px 4px!important}::ng-deep .bs-datepicker .bs-datepicker-buttons .btn-primary{background:#007bff!important;color:#fff!important;border:1px solid #007bff!important;font-weight:500!important;padding:4px 8px!important;border-radius:4px!important;font-size:12px!important}::ng-deep .bs-datepicker .bs-datepicker-buttons .btn-primary:hover{background:#0056b3!important;border-color:#0056b3!important}::ng-deep .bs-datepicker .bs-datepicker-buttons .btn-secondary{background:#fff!important;color:#495057!important;border:1px solid #dee2e6!important;font-weight:500!important;padding:4px 8px!important;border-radius:4px!important;font-size:12px!important}::ng-deep .bs-datepicker .bs-datepicker-buttons .btn-secondary:hover{background:#e9ecef!important}::ng-deep .bs-datepicker-body{background:#fff!important;padding:6px!important}::ng-deep .bs-datepicker-body table{background:#fff!important;border-collapse:separate!important;border-spacing:1px!important}::ng-deep .bs-datepicker-body table th,::ng-deep .bs-datepicker-body table td{border:1px solid #dee2e6!important;border-radius:4px!important;text-align:center!important;font-weight:500!important;color:#495057!important;cursor:pointer!important;transition:all .2s ease!important;font-size:12px!important;width:32px!important;height:32px!important;line-height:24px!important}::ng-deep .bs-datepicker-body table th{background:#f8f9fa!important;font-weight:600!important;font-size:11px!important;padding:2px!important;height:24px!important;line-height:20px!important}::ng-deep .bs-datepicker-body table td:hover:not(.disabled){background:#e9ecef!important}::ng-deep .bs-datepicker-body table td.active{background:#007bff!important;color:#fff!important;border-color:#007bff!important}::ng-deep .bs-datepicker-body table td.is-other-month{color:#6c757d!important;background:#f8f9fa!important}::ng-deep .bs-datepicker-body table td.disabled{color:#adb5bd!important;background:#e9ecef!important;cursor:not-allowed!important}::ng-deep .bs-datepicker-custom-range{background:transparent!important;border-right:1px solid #dee2e6!important;padding:6px!important;width:130px!important;margin-right:8px!important;align-self:flex-start!important}::ng-deep .bs-datepicker-predefined-btns{display:flex!important;flex-direction:column!important;gap:2px!important}::ng-deep .bs-datepicker-predefined-btns button{background:transparent!important;color:#495057!important;border:1px solid #dee2e6!important;border-radius:4px!important;padding:4px 6px!important;font-size:11px!important;font-weight:500!important;text-align:left!important;cursor:pointer!important;transition:all .2s ease!important;width:100%!important;margin:0!important}::ng-deep .bs-datepicker-predefined-btns button:hover{background:#e9ecef!important;border-color:#adb5bd!important}::ng-deep .bs-datepicker-predefined-btns button:active,::ng-deep .bs-datepicker-predefined-btns button:focus{outline:none!important;box-shadow:0 0 0 2px #007bff40!important;background:#007bff!important;color:#fff!important;border-color:#007bff!important}.manual-logs-modal-overlay{position:fixed;top:0;left:0;width:100%;height:100%;background-color:#00000080;display:flex;justify-content:center;align-items:center;z-index:9999}.manual-logs-modal-content{background:#fff;border-radius:8px;max-width:800px;max-height:80vh;overflow:auto;box-shadow:0 4px 8px #0000001a}.popover__wrapper{position:relative;display:inline-block}.popover__content{position:absolute;bottom:100%;left:50%;transform:translate(-50%);background:#fff;border:1px solid #ccc;border-radius:8px;padding:12px;box-shadow:0 4px 12px #00000026;z-index:1000;opacity:0;visibility:hidden;transition:opacity .3s ease,visibility .3s ease;min-width:250px;max-width:400px;font-size:14px}.popover__wrapper:hover .popover__content{opacity:1;visibility:visible}.popover__content .modal-area{padding:0}.popover__content h4{margin:0 0 8px;font-size:16px;font-weight:600;color:#333}.popover__content .break-status{font-size:12px;color:#666;margin-bottom:8px}.popover__content .d-flex{gap:12px}.popover__content p{margin:0 0 4px;font-size:12px;color:#666}.popover__content h5{margin:0;font-size:14px;font-weight:500;color:#333}.popover__content .break-footer{border-top:1px solid #eee;margin-top:8px;padding-top:8px}.popover__content .break-footer p{font-size:12px;color:#666;margin:0}.custom-break-tooltip{position:fixed;z-index:1000;background:#fff;border:1px solid #ddd;border-radius:8px;box-shadow:0 4px 12px #00000026;padding:12px;font-size:13px;max-width:220px;pointer-events:none;top:0;left:0;transform:translate(var(--tooltip-x, 0px),var(--tooltip-y, 0px))}.custom-break-tooltips{position:fixed;z-index:1000;background:#fff;border:1px solid #ddd;border-radius:8px;box-shadow:0 4px 12px #00000026;padding:8px;font-size:12px;max-width:500px;max-height:300px;top:0;left:0;transform:translate(var(--tooltip-x, 0px),var(--tooltip-y, 0px))}.custom-break-tooltips .modal-body{max-height:250px!important;overflow-y:auto;padding:0}.custom-break-tooltips .table-responsive{max-height:250px}.custom-break-tooltips thead th{position:sticky;top:0;background:#f8f9fa;z-index:10;border-bottom:2px solid #dee2e6;font-size:11px;padding:4px 8px;font-weight:600}.custom-break-tooltips table{font-size:11px;margin-bottom:0}.custom-break-tooltips table td{padding:4px 8px;white-space:nowrap}.custom-break-tooltips .table-striped tbody tr:nth-of-type(odd){background-color:#00000005}.popver_content_progress_bar{visibility:hidden}.badge-overflow-container{display:flex;flex-wrap:nowrap;gap:4px;align-items:center;min-width:0;overflow:hidden;width:100%}.badge-overflow-container .badge{flex-shrink:0;white-space:nowrap;font-size:12px;padding:4px 8px;border-radius:50%;display:inline-flex;align-items:center;justify-content:center;font-weight:600;line-height:1;text-transform:uppercase;letter-spacing:.5px;transition:all .3s cubic-bezier(.4,0,.2,1);border:2px solid transparent;width:32px;height:32px;box-sizing:border-box;cursor:pointer;transform:translateZ(0);will-change:transform,box-shadow,background-color;backface-visibility:hidden}.badge-overflow-container .badge:hover{transform:scale(1.15) translateY(-2px);box-shadow:0 6px 16px #007bff40}.badge-overflow-container .badge:active{transform:scale(1.08) translateY(-1px);transition-duration:.15s}.badge-overflow-container .badge-overflow-count{background-color:#6c757d!important;color:#fff!important;cursor:pointer;border:2px solid #6c757d!important;flex-shrink:0;border-radius:50%;width:32px;height:32px;display:inline-flex;align-items:center;justify-content:center;font-weight:600;transition:all .3s cubic-bezier(.4,0,.2,1);transform:translateZ(0);will-change:transform,box-shadow,background-color;backface-visibility:hidden}.badge-overflow-container .badge-overflow-count:hover{background-color:#5a6268!important;border-color:#5a6268!important;transform:scale(1.15) translateY(-2px);box-shadow:0 6px 16px #007bff40}.badge-overflow-container .badge-overflow-count:active{transform:scale(1.08) translateY(-1px);transition-duration:.15s}.timeline-view-container{padding:1rem;background-color:#f8f9fa}.timeline-view-container .timeline-header{margin-bottom:2rem}.timeline-view-container .timeline-header h5{color:#495057;font-weight:600;margin-bottom:1rem}.timeline-view-container .timeline-header .timeline-hours{display:flex;justify-content:space-between;padding:.5rem 0;border-bottom:1px solid #dee2e6;margin-bottom:1rem;background:#fff;border-radius:8px;padding:1rem}.timeline-view-container .timeline-header .timeline-hours .timeline-hour{font-size:.8rem;color:#6c757d;font-weight:500;min-width:40px;text-align:center;padding:.5rem;border-radius:4px;background:#f8f9fa}.timeline-view-container .timeline-body .timeline-row{background:#fff;border:1px solid #dee2e6;border-radius:8px;margin-bottom:1rem;padding:1rem;box-shadow:0 2px 4px #0000001a;transition:box-shadow .2s ease}.timeline-view-container .timeline-body .timeline-row:hover{box-shadow:0 4px 8px #00000026}.timeline-view-container .timeline-body .timeline-row .timeline-employee{margin-bottom:1rem}.timeline-view-container .timeline-body .timeline-row .timeline-employee .employee-name{font-weight:600;color:#495057;font-size:1.1rem}.timeline-view-container .timeline-body .timeline-row .timeline-track{position:relative;height:40px;background:#f8f9fa;border-radius:4px;border:1px solid #e9ecef}.timeline-view-container .timeline-body .timeline-row .timeline-track .work-duration-bar{position:absolute;height:100%;background:linear-gradient(135deg,#28a745,#20c997);border-radius:4px;box-shadow:0 2px 4px #28a7454d;transition:opacity .2s ease}.timeline-view-container .timeline-body .timeline-row .timeline-track .work-duration-bar:hover{opacity:.8}.timeline-view-container .timeline-body .timeline-row .timeline-track .break-bar{position:absolute;height:100%;border-radius:4px;box-shadow:0 2px 4px #0003;border:1px solid rgba(255,255,255,.5);transition:opacity .2s ease}.timeline-view-container .timeline-body .timeline-row .timeline-track .break-bar:hover{opacity:.8}.calendar-view-container .calendar-header{margin-bottom:2rem}.calendar-view-container .calendar-header h5{color:#495057;font-weight:600}.calendar-view-container .calendar-header .calendar-nav button{border:1px solid #dee2e6;background:#fff;color:#495057;padding:.375rem .75rem;border-radius:.375rem;transition:all .2s ease}.calendar-view-container .calendar-header .calendar-nav button:hover{background-color:#f8f9fa;border-color:#adb5bd}.calendar-view-container .calendar-header .calendar-nav button:first-child{border-top-right-radius:0;border-bottom-right-radius:0;border-right:none}.calendar-view-container .calendar-header .calendar-nav button:last-child{border-top-left-radius:0;border-bottom-left-radius:0}.calendar-view-container .calendar-grid .calendar-week-header{display:flex;background-color:#f8f9fa;border:1px solid #dee2e6;border-bottom:none}.calendar-view-container .calendar-grid .calendar-week-header .calendar-day-header{flex:1;padding:.75rem;text-align:center;font-weight:600;color:#495057;border-right:1px solid #dee2e6}.calendar-view-container .calendar-grid .calendar-week-header .calendar-day-header:last-child{border-right:none}.calendar-view-container .calendar-grid .calendar-weeks{border:1px solid #dee2e6;border-top:none}.calendar-view-container .calendar-grid .calendar-weeks .calendar-week{display:flex;border-bottom:1px solid #dee2e6}.calendar-view-container .calendar-grid .calendar-weeks .calendar-week:last-child{border-bottom:none}.calendar-view-container .calendar-grid .calendar-weeks .calendar-week .calendar-day{flex:1;min-height:100px;padding:.5rem;border-right:1px solid #dee2e6;background:#fff}.calendar-view-container .calendar-grid .calendar-weeks .calendar-week .calendar-day:last-child{border-right:none}.calendar-view-container .calendar-grid .calendar-weeks .calendar-week .calendar-day.current-month{background:#fff}.calendar-view-container .calendar-grid .calendar-weeks .calendar-week .calendar-day.today{background-color:#fff3cd;border:2px solid #ffc107}.calendar-view-container .calendar-grid .calendar-weeks .calendar-week .calendar-day .day-number{font-weight:600;color:#495057;margin-bottom:.25rem}.calendar-view-container .calendar-grid .calendar-weeks .calendar-week .calendar-day .day-entries .entry-dot{width:8px;height:8px;border-radius:50%;display:inline-block;margin-right:2px;margin-bottom:2px}.heatmap-view-container .heatmap-header{margin-bottom:2rem}.heatmap-view-container .heatmap-header h5{color:#495057;font-weight:600}.heatmap-view-container .heatmap-header .heatmap-legend .legend-colors{display:flex;margin:0 1rem}.heatmap-view-container .heatmap-header .heatmap-legend .legend-colors .legend-color{width:12px;height:12px;margin-right:2px;border-radius:2px}.heatmap-view-container .heatmap-header .heatmap-legend span{font-size:.875rem;color:#6c757d}.heatmap-view-container .heatmap-grid .heatmap-months{display:flex;margin-bottom:.5rem}.heatmap-view-container .heatmap-grid .heatmap-months .month-label{flex:1;text-align:center;font-size:.8rem;font-weight:600;color:#495057}.heatmap-view-container .heatmap-grid .heatmap-weeks .heatmap-week{display:flex;margin-bottom:2px}.heatmap-view-container .heatmap-grid .heatmap-weeks .heatmap-week .heatmap-day{flex:1;aspect-ratio:1;border-radius:2px;margin-right:2px;transition:opacity .2s ease}.heatmap-view-container .heatmap-grid .heatmap-weeks .heatmap-week .heatmap-day:hover{opacity:.8}.heatmap-view-container .heatmap-grid .heatmap-weeks .heatmap-week .heatmap-day:last-child{margin-right:0}.card-view-container{padding:1rem;height:100%;overflow-y:auto;overflow-x:hidden}.card-view-container[data-theme=white]{background-color:#f6f8ff;color:#000}.card-view-container[data-theme=white] .attendance-card{background-color:#f6f8ff;border-color:#d9d9db;color:#000}.card-view-container[data-theme=white] .attendance-card:hover{background-color:#007bff1a}.card-view-container[data-theme=white] .attendance-card .card-header{background-color:#f8f9fa;color:#000;border-bottom-color:#d9d9db}.card-view-container[data-theme=white] .attendance-card .card-body{background-color:#f6f8ff;color:#000}.card-view-container[data-theme=white] .attendance-card .badge.bg-success{background-color:#84ca81;color:#f6f8ff}.card-view-container[data-theme=white] .attendance-card .badge.bg-danger{background-color:#ea5353;color:#f6f8ff}.card-view-container[data-theme=white] .attendance-card .badge.bg-warning{background-color:#fff3dc;color:#000}.card-view-container[data-theme=white] .attendance-card .badge.bg-info{background-color:#e8fbfd;color:#00bad1}.card-view-container[data-theme=blue]{background-color:#f0f8ff;color:#1e3a5f}.card-view-container[data-theme=blue] .attendance-card{background-color:#f6f8ff;border-color:#b3d9ff;color:#1e3a5f}.card-view-container[data-theme=blue] .attendance-card:hover{background-color:#1e3a5f1a}.card-view-container[data-theme=blue] .attendance-card .card-header{background-color:#e6f3ff;color:#1e3a5f;border-bottom-color:#b3d9ff}.card-view-container[data-theme=blue] .attendance-card .card-body{background-color:#f6f8ff;color:#1e3a5f}.card-view-container[data-theme=blue] .attendance-card .badge.bg-success{background-color:#69db7c;color:#f6f8ff}.card-view-container[data-theme=blue] .attendance-card .badge.bg-danger{background-color:#ff8787;color:#f6f8ff}.card-view-container[data-theme=blue] .attendance-card .badge.bg-warning{background-color:#ffd43b;color:#1e3a5f}.card-view-container[data-theme=blue] .attendance-card .badge.bg-info{background-color:#74c0fc;color:#f6f8ff}.card-view-container .row{margin:0}.card-view-container .row .col-xl-4,.card-view-container .row .col-lg-6,.card-view-container .row .col-md-6,.card-view-container .row .col-sm-12{padding:.5rem}.card-view-container .attendance-card{transition:background-color .2s ease;border:1px solid #d9d9db;border-radius:4px;overflow:hidden;height:100%;display:flex;flex-direction:column;font-family:sans-serif;font-size:16px}.card-view-container .attendance-card:hover{box-shadow:0 2px 4px #0000001a}.card-view-container .attendance-card.expanded .card-body{max-height:none}.card-view-container .attendance-card .card-header{padding:8px;border-bottom:1px solid #d9d9db;flex-shrink:0;font-weight:500}.card-view-container .attendance-card .card-header .employee-avatar{margin-right:.75rem;flex-shrink:0}.card-view-container .attendance-card .card-header .employee-avatar img,.card-view-container .attendance-card .card-header .employee-avatar .avatar-placeholder{border:1px solid #d9d9db;width:40px;height:40px;border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:16px;font-weight:400}.card-view-container .attendance-card .card-header .flex-grow-1{min-width:0}.card-view-container .attendance-card .card-header h6{margin:0;font-weight:500;font-size:16px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.card-view-container .attendance-card .card-header small{opacity:.9;font-weight:400;font-size:16px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.card-view-container .attendance-card .card-header .card-actions{flex-shrink:0}.card-view-container .attendance-card .card-header .card-actions .btn{background-color:transparent;border:1px solid #d9d9db;color:inherit;padding:.25rem .5rem}.card-view-container .attendance-card .card-header .card-actions .btn:hover{background-color:#007bff1a}.card-view-container .attendance-card .card-header .card-actions .btn i{font-size:.8rem}.card-view-container .attendance-card .card-body{padding:8px;flex:1;display:flex;flex-direction:column}.card-view-container .attendance-card .card-body .info-item{text-align:center;margin-bottom:.5rem}.card-view-container .attendance-card .card-body .info-item small{display:block;font-weight:400;color:#6c757d;text-transform:uppercase;font-size:12px;letter-spacing:.5px;margin-bottom:.25rem}.card-view-container .attendance-card .card-body .info-item span{font-size:16px;font-weight:400;color:inherit}.card-view-container .attendance-card .card-body .badge{font-size:12px;padding:.25rem .5rem;border-radius:4px;font-weight:400;text-transform:uppercase;letter-spacing:.5px;border:none}.card-view-container .attendance-card .card-body .badge.bg-success,.card-view-container .attendance-card .card-body .badge.bg-danger{color:#f6f8ff}.card-view-container .attendance-card .card-body .badge.bg-warning{color:#000}.card-view-container .attendance-card .card-body .badge.bg-secondary{color:#f6f8ff}.card-view-container .attendance-card .card-body .card-details{margin-top:1rem}.card-view-container .attendance-card .card-body .card-details .section-title{font-size:14px;font-weight:500;color:inherit;margin-bottom:.75rem;display:flex;align-items:center}.card-view-container .attendance-card .card-body .card-details .section-title i{margin-right:.5rem;opacity:.8}.card-view-container .attendance-card .card-body .card-details .breaks-list .break-item,.card-view-container .attendance-card .card-body .card-details .breaks-list .leave-item,.card-view-container .attendance-card .card-body .card-details .short-leave-list .break-item,.card-view-container .attendance-card .card-body .card-details .short-leave-list .leave-item{background-color:inherit;border:1px solid #d9d9db;border-radius:4px;padding:8px;margin-bottom:.5rem;cursor:pointer;transition:all .25s cubic-bezier(.4,0,.2,1);transform:translateZ(0)}.card-view-container .attendance-card .card-body .card-details .breaks-list .break-item .d-flex,.card-view-container .attendance-card .card-body .card-details .breaks-list .leave-item .d-flex,.card-view-container .attendance-card .card-body .card-details .short-leave-list .break-item .d-flex,.card-view-container .attendance-card .card-body .card-details .short-leave-list .leave-item .d-flex{gap:.75rem;align-items:center}.card-view-container .attendance-card .card-body .card-details .breaks-list .break-item .d-flex small,.card-view-container .attendance-card .card-body .card-details .breaks-list .leave-item .d-flex small,.card-view-container .attendance-card .card-body .card-details .short-leave-list .break-item .d-flex small,.card-view-container .attendance-card .card-body .card-details .short-leave-list .leave-item .d-flex small{font-weight:500;color:inherit;margin-bottom:.25rem}.card-view-container .attendance-card .card-body .card-details .breaks-list .break-item .d-flex .text-muted,.card-view-container .attendance-card .card-body .card-details .breaks-list .leave-item .d-flex .text-muted,.card-view-container .attendance-card .card-body .card-details .short-leave-list .break-item .d-flex .text-muted,.card-view-container .attendance-card .card-body .card-details .short-leave-list .leave-item .d-flex .text-muted{font-size:12px;color:#6c757d}.card-view-container .attendance-card .card-body .card-details .breaks-list .break-item .d-flex .badge,.card-view-container .attendance-card .card-body .card-details .breaks-list .leave-item .d-flex .badge,.card-view-container .attendance-card .card-body .card-details .short-leave-list .break-item .d-flex .badge,.card-view-container .attendance-card .card-body .card-details .short-leave-list .leave-item .d-flex .badge{font-size:10px;padding:.2rem .4rem}.card-view-container .attendance-card .card-body .card-details .additional-details .row .col-6{margin-bottom:.5rem}.card-view-container .attendance-card .card-body .card-details .additional-details .row .col-6 small{font-weight:400;color:#6c757d;text-transform:uppercase;font-size:12px;letter-spacing:.5px;margin-bottom:.25rem}.card-view-container .attendance-card .card-body .card-details .additional-details .row .col-6 span{font-weight:400;color:inherit;font-size:14px}@media (max-width: 1200px){.card-view-container .row .col-xl-4{flex:0 0 50%;max-width:50%}}@media (max-width: 768px){.card-view-container .row .col-xl-4,.card-view-container .col-lg-6,.card-view-container .col-md-6{flex:0 0 100%;max-width:100%}.card-view-container .attendance-card .card-body{padding:8px}.card-view-container .attendance-card .card-body .info-item small{font-size:10px}.card-view-container .attendance-card .card-body .info-item span{font-size:14px}}@media (max-width: 576px){.card-view-container{padding:.5rem}.card-view-container .row .col-sm-12{padding:.25rem}.card-view-container .attendance-card .card-header{padding:8px}.card-view-container .attendance-card .card-header h6,.card-view-container .attendance-card .card-header small{font-size:14px}.card-view-container .attendance-card .card-body{padding:8px}}.btn-xs{padding:.125rem .3rem!important;font-size:.9rem!important;border-radius:.2rem!important;line-height:1.5!important}.form-select.form-select-sm:invalid{border-color:#d9d9db!important}.form-select.form-select-sm:valid{border-color:#d9d9db!important}.date-range-container{gap:8px;flex-wrap:nowrap;align-items:center}.date-range-btn{padding:6px 12px;font-size:14px;font-weight:500;border-radius:6px;transition:all .25s cubic-bezier(.4,0,.2,1);white-space:nowrap;display:inline-flex;align-items:center;justify-content:center;min-height:36px;transform:translateZ(0);position:relative;overflow:hidden}.date-range-btn:before{content:\"\";position:absolute;top:50%;left:50%;width:0;height:0;background:#fff3;border-radius:50%;transform:translate(-50%,-50%);transition:width .25s,height .25s}.date-range-btn:active:before{width:300px;height:300px}.calendar-btn{border-color:#0d6efd;color:#0d6efd;background-color:transparent}.calendar-btn:hover{background-color:#0d6efd;color:#fff;transform:translateY(-1px);box-shadow:0 4px 12px #0d6efd4d}.clear-btn{border-color:#dc3545;color:#dc3545;background-color:transparent}.clear-btn:hover{background-color:#dc3545;color:#fff;transform:translateY(-1px);box-shadow:0 4px 12px #dc35454d}.date-range-label{font-size:14px;font-weight:500;padding:4px 8px;min-width:180px;text-align:center;white-space:nowrap;cursor:pointer}.date-range-btn .bi{font-size:14px;transition:transform .2s ease}.date-range-btn:hover .bi{transform:scale(1.1)}@media (max-width: 768px){.date-range-container{flex-wrap:wrap;justify-content:flex-start}.date-range-label{min-width:100%;margin-top:8px;order:3}}.date-range-btn:focus{outline:none;box-shadow:0 0 0 3px #0d6efd40}.clear-btn:focus{box-shadow:0 0 0 3px #dc354540}.action-buttons-row .button{display:inline-flex;align-items:center;justify-content:center;overflow:hidden;color:#fff;border-radius:6px;height:34px;padding:0 10px;white-space:nowrap;transition:max-width .4s ease,background-color .3s ease;max-width:40px;background-color:transparent;border:1px solid #6F61CF}.action-buttons-row .button .label-hidden{opacity:0;margin-left:8px;transition:opacity .3s ease;pointer-events:none;display:none}.action-buttons-row .button:hover{max-width:200px;background-color:#6f61cf}.action-buttons-row .button:hover .label-hidden{opacity:1;pointer-events:auto;margin-left:8px!important;display:block}.action-buttons-row ::ng-deep .button .svg-icon svg path{stroke:#6f61cf;transition:fill .3s ease,stroke .3s ease}.action-buttons-row ::ng-deep .button:hover .svg-icon svg path{stroke:#fff!important}.action-buttons-row ::ng-deep .button:active .svg-icon svg path{stroke:#6f61cf!important}.action-buttons-row ::ng-deep .button:focus .svg-icon svg path{stroke:#6f61cf!important}.badge-overflow-wrapper{width:100%;min-width:0;display:flex;align-items:center}.custom-overlay-wrapper{position:fixed;top:0;left:0;width:100%;height:100%;background-color:#00000080;display:flex;justify-content:center;align-items:center;z-index:9999}.custom-overlay{background:#fff;border-radius:8px;box-shadow:0 4px 12px #00000026;min-width:300px;max-width:400px}.custom-modal-body{padding:20px;text-align:center}.custom-modal-body .modal-message{font-size:16px;margin-bottom:20px;color:#333}.custom-modal-body .modal-actions{display:flex;gap:10px;justify-content:center}.custom-modal-body .modal-actions button{padding:8px 16px;border:none;border-radius:4px;cursor:pointer;font-size:14px;transition:background-color .2s ease}.custom-modal-body .modal-actions button.btn-confirm{background-color:#007bff;color:#fff}.custom-modal-body .modal-actions button.btn-confirm:hover{background-color:#0056b3}.custom-modal-body .modal-actions button.btn-cancel{background-color:#6c757d;color:#fff}.custom-modal-body .modal-actions button.btn-cancel:hover{background-color:#545b62}.custom-break-tooltip .short-break-table{width:100%;border-collapse:collapse;font-size:12px}.custom-break-tooltip .short-break-table th,.custom-break-tooltip .short-break-table td{padding:4px 6px;text-align:center;border:1px solid #ddd}.custom-break-tooltip .short-break-table th{background-color:#f8f9fa;font-weight:600}.custom-break-tooltip .short-break-table tbody tr:nth-child(2n){background-color:#fafafa}.text-truncate{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;display:flex;align-items:center;min-width:0}\n"] }]
9589
9709
  }], ctorParameters: () => [{ type: i0.Injector }, { type: i0.ViewContainerRef }, { type: CommonService }], propDecorators: { rowAnimation: [{
9590
9710
  type: Input
9591
9711
  }], onShortBreakClick: [{
@@ -9812,6 +9932,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
9812
9932
  }], centerScrollableBody: [{
9813
9933
  type: ViewChild,
9814
9934
  args: ['centerScrollableBody']
9935
+ }], searchInput: [{
9936
+ type: ViewChild,
9937
+ args: ['searchInput']
9815
9938
  }], filterMenueSearchInput: [{
9816
9939
  type: ViewChild,
9817
9940
  args: ['filterMenueSearchInput']